From 7638df1ed1f0f314d78bd42e0aba084ba14ade0a Mon Sep 17 00:00:00 2001 From: chai Date: Sun, 4 Aug 2019 17:19:51 +0800 Subject: *misc --- Build/Asura.Runner/Asura.Runner.vcxproj | 3 + Build/Asura.Runner/Asura.Runner.vcxproj.filters | 13 +- Source/Asura.Runner/Runner.cpp | 0 Source/Asura.Runner/Runner.h | 21 - Source/Asura.Runner/runner.cpp | 0 Source/Asura.Runner/runner.h | 21 - bin/win64/01-window.exe | Bin 0 -> 1461760 bytes bin/win64/05-physfs.exe | Bin 0 -> 1210880 bytes bin/win64/05-physfs.exe.lastcodeanalysissucceeded | 0 bin/win64/Luax.lib.lastcodeanalysissucceeded | 0 bin/win64/LuaxTest.exe | Bin 0 -> 526848 bytes bin/win64/SDL2.dll | Bin 0 -> 2491904 bytes .../asura-lib-utils.lib.lastcodeanalysissucceeded | 0 bin/win64/bindingGen.exe | Bin 0 -> 10240 bytes bin/win64/bindingGen.exe.config | 6 + bin/win64/img.jpg | Bin 0 -> 59348 bytes bin/win64/img.png | Bin 0 -> 442 bytes bin/win64/physfs.txt | 1 + bin/win64/physfs2.txt | 4528 ++++++++++++++++++++ bin/win64/shader.png | Bin 0 -> 28025 bytes build/Asura.Runner/Asura.Runner.vcxproj | 3 + build/Asura.Runner/Asura.Runner.vcxproj.filters | 13 +- build/modules/asura-core/asura-core.vcxproj | 13 +- .../modules/asura-core/asura-core.vcxproj.filters | 39 +- build/modules/asura-utils/asura-utils.vcxproj | 1 + .../asura-utils/asura-utils.vcxproj.filters | 15 +- .../bindingGen.csproj.CoreCompileInputs.cache | 2 +- source/Asura.Editor/System/Input.cpp | 0 source/Asura.Editor/System/Input.h | 45 + source/Asura.Runner/Main.cpp | 13 + source/Asura.Runner/main.cpp | 8 +- source/Asura.Runner/runner.cpp | 0 source/Asura.Runner/runner.h | 21 - source/modules/asura-box2d/Physics/Body.h | 87 +- source/modules/asura-box2d/Physics/ChainShape.h | 2 +- source/modules/asura-box2d/Physics/Fixture.h | 17 + source/modules/asura-box2d/Physics/World.h | 17 +- source/modules/asura-box2d/physics/body.h | 87 +- source/modules/asura-box2d/physics/fixture.h | 17 + source/modules/asura-box2d/physics/world.h | 17 +- source/modules/asura-core/Application.h | 22 +- source/modules/asura-core/Graphics/DrawInfo.h | 1 + source/modules/asura-core/Graphics/DrawUtil.cpp | 0 source/modules/asura-core/Graphics/DrawUtil.h | 0 source/modules/asura-core/Graphics/GPUBuffer.h | 10 +- source/modules/asura-core/Graphics/GfxDevice.cpp | 20 - source/modules/asura-core/Graphics/GfxDevice.h | 52 +- .../modules/asura-core/Graphics/GraphicsHelper.cpp | 0 .../modules/asura-core/Graphics/GraphicsHelper.h | 15 + source/modules/asura-core/Graphics/Polygon2D.cpp | 0 source/modules/asura-core/Graphics/Polygon2D.h | 0 source/modules/asura-core/Graphics/VBO.cpp | 0 source/modules/asura-core/Graphics/VBO.h | 27 + source/modules/asura-core/Input/InputAxis.cpp | 0 source/modules/asura-core/Input/InputAxis.h | 15 + source/modules/asura-core/Input/InputDevice.cpp | 10 + source/modules/asura-core/Input/InputDevice.h | 26 +- source/modules/asura-core/Input/InputEvent.cpp | 0 source/modules/asura-core/Input/InputEvent.h | 21 + source/modules/asura-core/Input/InputManager.cpp | 124 + source/modules/asura-core/Input/InputManager.h | 338 +- source/modules/asura-core/Input/JoystickState.h | 16 + source/modules/asura-core/Input/Keys.h | 482 --- source/modules/asura-core/Input/MouseState.h | 16 + source/modules/asura-core/application.h | 22 +- source/modules/asura-core/input/keys.h | 482 --- source/modules/asura-utils/Classes.h | 2 +- source/modules/asura-utils/Math/Matrix44.h | 120 +- source/modules/asura-utils/Math/Rand/Rand.h | 1 - source/modules/asura-utils/Math/Vector2.hpp | 90 +- source/modules/asura-utils/Math/Vector3.hpp | 2 + source/modules/asura-utils/Type.h | 3 + source/modules/asura-utils/classes.h | 2 +- source/modules/asura-utils/dynamic_bitset.h | 1150 +++++ source/modules/asura-utils/math/matrix44.h | 120 +- source/modules/asura-utils/math/vector2.hpp | 90 +- source/modules/asura-utils/math/vector3.hpp | 2 + source/modules/asura-utils/type.h | 3 + 78 files changed, 6802 insertions(+), 1492 deletions(-) delete mode 100644 Source/Asura.Runner/Runner.cpp delete mode 100644 Source/Asura.Runner/Runner.h delete mode 100644 Source/Asura.Runner/runner.cpp delete mode 100644 Source/Asura.Runner/runner.h create mode 100644 bin/win64/01-window.exe create mode 100644 bin/win64/05-physfs.exe create mode 100644 bin/win64/05-physfs.exe.lastcodeanalysissucceeded create mode 100644 bin/win64/Luax.lib.lastcodeanalysissucceeded create mode 100644 bin/win64/LuaxTest.exe create mode 100644 bin/win64/SDL2.dll create mode 100644 bin/win64/asura-lib-utils.lib.lastcodeanalysissucceeded create mode 100644 bin/win64/bindingGen.exe create mode 100644 bin/win64/bindingGen.exe.config create mode 100644 bin/win64/img.jpg create mode 100644 bin/win64/img.png create mode 100644 bin/win64/physfs.txt create mode 100644 bin/win64/physfs2.txt create mode 100644 bin/win64/shader.png create mode 100644 source/Asura.Editor/System/Input.cpp create mode 100644 source/Asura.Editor/System/Input.h create mode 100644 source/Asura.Runner/Main.cpp delete mode 100644 source/Asura.Runner/runner.cpp delete mode 100644 source/Asura.Runner/runner.h create mode 100644 source/modules/asura-core/Graphics/DrawUtil.cpp create mode 100644 source/modules/asura-core/Graphics/DrawUtil.h create mode 100644 source/modules/asura-core/Graphics/GraphicsHelper.cpp create mode 100644 source/modules/asura-core/Graphics/GraphicsHelper.h create mode 100644 source/modules/asura-core/Graphics/Polygon2D.cpp create mode 100644 source/modules/asura-core/Graphics/Polygon2D.h create mode 100644 source/modules/asura-core/Graphics/VBO.cpp create mode 100644 source/modules/asura-core/Graphics/VBO.h create mode 100644 source/modules/asura-core/Input/InputAxis.cpp create mode 100644 source/modules/asura-core/Input/InputAxis.h create mode 100644 source/modules/asura-core/Input/InputEvent.cpp create mode 100644 source/modules/asura-core/Input/InputEvent.h delete mode 100644 source/modules/asura-core/Input/Keys.h delete mode 100644 source/modules/asura-core/input/keys.h create mode 100644 source/modules/asura-utils/dynamic_bitset.h diff --git a/Build/Asura.Runner/Asura.Runner.vcxproj b/Build/Asura.Runner/Asura.Runner.vcxproj index 0c18dc5..d145fa3 100644 --- a/Build/Asura.Runner/Asura.Runner.vcxproj +++ b/Build/Asura.Runner/Asura.Runner.vcxproj @@ -76,6 +76,7 @@ Disabled true true + $(SolutionDir)..\source\external;$(SolutionDir)..\source\modules;%(AdditionalIncludeDirectories) @@ -108,6 +109,7 @@ true true true + $(SolutionDir)..\source\external;$(SolutionDir)..\source\modules;%(AdditionalIncludeDirectories) true @@ -115,6 +117,7 @@ + diff --git a/Build/Asura.Runner/Asura.Runner.vcxproj.filters b/Build/Asura.Runner/Asura.Runner.vcxproj.filters index 3c6f4fd..ea4223b 100644 --- a/Build/Asura.Runner/Asura.Runner.vcxproj.filters +++ b/Build/Asura.Runner/Asura.Runner.vcxproj.filters @@ -1,17 +1,6 @@  - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - + \ No newline at end of file diff --git a/Source/Asura.Runner/Runner.cpp b/Source/Asura.Runner/Runner.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/Source/Asura.Runner/Runner.h b/Source/Asura.Runner/Runner.h deleted file mode 100644 index 52f4d65..0000000 --- a/Source/Asura.Runner/Runner.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __ASURA_RUNNER_H__ -#define __ASURA_RUNNER_H__ - -#include - -#include - -namespace AsuraRunner -{ - - class SDLInputDevice : public AEInput::InputDevice - { - public: - - - - }; - -} - -#endif \ No newline at end of file diff --git a/Source/Asura.Runner/runner.cpp b/Source/Asura.Runner/runner.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/Source/Asura.Runner/runner.h b/Source/Asura.Runner/runner.h deleted file mode 100644 index 52f4d65..0000000 --- a/Source/Asura.Runner/runner.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __ASURA_RUNNER_H__ -#define __ASURA_RUNNER_H__ - -#include - -#include - -namespace AsuraRunner -{ - - class SDLInputDevice : public AEInput::InputDevice - { - public: - - - - }; - -} - -#endif \ No newline at end of file diff --git a/bin/win64/01-window.exe b/bin/win64/01-window.exe new file mode 100644 index 0000000..7abc18a Binary files /dev/null and b/bin/win64/01-window.exe differ diff --git a/bin/win64/05-physfs.exe b/bin/win64/05-physfs.exe new file mode 100644 index 0000000..e325343 Binary files /dev/null and b/bin/win64/05-physfs.exe differ diff --git a/bin/win64/05-physfs.exe.lastcodeanalysissucceeded b/bin/win64/05-physfs.exe.lastcodeanalysissucceeded new file mode 100644 index 0000000..e69de29 diff --git a/bin/win64/Luax.lib.lastcodeanalysissucceeded b/bin/win64/Luax.lib.lastcodeanalysissucceeded new file mode 100644 index 0000000..e69de29 diff --git a/bin/win64/LuaxTest.exe b/bin/win64/LuaxTest.exe new file mode 100644 index 0000000..3acc2da Binary files /dev/null and b/bin/win64/LuaxTest.exe differ diff --git a/bin/win64/SDL2.dll b/bin/win64/SDL2.dll new file mode 100644 index 0000000..becc4ba Binary files /dev/null and b/bin/win64/SDL2.dll differ diff --git a/bin/win64/asura-lib-utils.lib.lastcodeanalysissucceeded b/bin/win64/asura-lib-utils.lib.lastcodeanalysissucceeded new file mode 100644 index 0000000..e69de29 diff --git a/bin/win64/bindingGen.exe b/bin/win64/bindingGen.exe new file mode 100644 index 0000000..016c299 Binary files /dev/null and b/bin/win64/bindingGen.exe differ diff --git a/bin/win64/bindingGen.exe.config b/bin/win64/bindingGen.exe.config new file mode 100644 index 0000000..731f6de --- /dev/null +++ b/bin/win64/bindingGen.exe.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/bin/win64/img.jpg b/bin/win64/img.jpg new file mode 100644 index 0000000..8987cfe Binary files /dev/null and b/bin/win64/img.jpg differ diff --git a/bin/win64/img.png b/bin/win64/img.png new file mode 100644 index 0000000..0d11f85 Binary files /dev/null and b/bin/win64/img.png differ diff --git a/bin/win64/physfs.txt b/bin/win64/physfs.txt new file mode 100644 index 0000000..00530bc --- /dev/null +++ b/bin/win64/physfs.txt @@ -0,0 +1 @@ +hello, world \ No newline at end of file diff --git a/bin/win64/physfs2.txt b/bin/win64/physfs2.txt new file mode 100644 index 0000000..c0f0d31 --- /dev/null +++ b/bin/win64/physfs2.txt @@ -0,0 +1,4528 @@ +// This file has been modified from Ken Silverman's original release + +#define NOSOUND + +/*************************************************************************************************** +WINMAIN.CPP & SYSMAIN.H + +Windows layer code written by Ken Silverman (http://advsys.net/ken) (1997-2005) +Additional modifications by Tom Dobrowolski (http://ged.ax.pl/~tomkh) +You may use this code for non-commercial purposes as long as credit is maintained. +***************************************************************************************************/ + + //To compile, link with ddraw.lib, dinput.lib AND dxguid.lib. Be sure ddraw.h and dinput.h + //are in include path + +#include "StdAfx.h" +#include "msvc.h" +#include "Engine/Minidump.h" +#define WIN32_LEAN_AND_MEAN +#include + +#ifndef NODRAW +#define DIRECTDRAW_VERSION 0x0700 +#include "ddraw.h" +#endif +#ifndef NOINPUT +#define DIRECTINPUT_VERSION 0x0800 +#include "dinput.h" +#endif +#ifndef NOSOUND +#define DIRECTSOUND_VERSION 0x0900 +#include //dsound.h requires this when using LEAN_AND_MEAN +#include "dsound.h" +#ifndef USEKZ +#include //for fopen +#else +extern long kzopen (const char *); +extern long kzread (void *, long); +extern long kzseek (long, long); +extern void kzclose (); +extern long kzeof (); +#endif +#define DSOUNDINITCOM 1 //0=Link DSOUND.DLL, 1=Use COM interface to init DSOUND +#ifndef USEKENSOUND +#define USEKENSOUND 1 //0=playsound undefined (umixer only), 1=Ken's fancy sound renderer, 2=Standard Directsound secondary buffers +#endif +#define USETHREADS 20 //0=Disable, nonzero=enable multithreading and this is sleep value (20 is good) + //Use threads to fix audio gaps (and possibly other bugs too!) +#else +#define USETHREADS 0 +#endif + +#if ((USEKENSOUND == 1) && (USETHREADS != 0)) + //WinXP:Sleep(0)=infinite,Sleep(1-16)=64hz,Sleep(17-32)=32hz,Sleep(33-48)=21.3hz, etc...) + //Remember to add /MD, /MT or /link libcmt.lib kernel32.lib /nodefaultlib to compile options! +#include +static HANDLE hmutx; +#define ENTERMUTX WaitForSingleObject(hmutx,USETHREADS) //Do NOT use ,INFINITE) - too dangerous! +#define LEAVEMUTX ReleaseMutex(hmutx) +#else +#define ENTERMUTX +#define LEAVEMUTX +#endif + +#pragma warning(disable:4730) +#pragma warning(disable:4731) + +char *prognam = "Voxelstein3D"; +long progresiz = 1; +long progwndflags, progwndx = 0x80000000, progwndy, progwndadd[2]; +#ifndef NOINPUT +long dinputkeyboardflags = DISCL_NONEXCLUSIVE|DISCL_FOREGROUND; +long dinputmouseflags = DISCL_EXCLUSIVE|DISCL_FOREGROUND; +#endif + +#define WM_MOUSEWHEEL 0x020A + +extern long initapp (long argc, char **argv); +extern void initapp2(); +extern void uninitapp (); +extern void doframe (); + +static long quitprogram = 0, quitparam; +void breath(); + +void (*MenuFunc)(int iID, HANDLE hComponent) = NULL; + + //Global window variables +static WNDCLASS wc; +HWND ghwnd; +HINSTANCE ghinst, ghpinst; +LPSTR gcmdline; +int gncmdshow; + +long ActiveApp = 1, alwaysactive = 0; +long xres = 640, yres = 480, colbits = 8, fullscreen = 1, maxpages = 8; + + // Note! Without clipper blit is faster but only with software bliter +//#define NO_CLIPPER + +//======================== CPU detection code begins ======================== + +static long cputype = 0; +static OSVERSIONINFO osvi; + +#ifdef __WATCOMC__ + +long testflag (long); +#pragma aux testflag =\ + "pushfd"\ + "pop eax"\ + "mov ebx, eax"\ + "xor eax, ecx"\ + "push eax"\ + "popfd"\ + "pushfd"\ + "pop eax"\ + "xor eax, ebx"\ + "mov eax, 1"\ + "jne menostinx"\ + "xor eax, eax"\ + "menostinx:"\ + parm nomemory [ecx]\ + modify exact [eax ebx]\ + value [eax] + +void cpuid (long, long *); +#pragma aux cpuid =\ + ".586"\ + "cpuid"\ + "mov dword ptr [esi], eax"\ + "mov dword ptr [esi+4], ebx"\ + "mov dword ptr [esi+8], ecx"\ + "mov dword ptr [esi+12], edx"\ + parm [eax][esi]\ + modify exact [eax ebx ecx edx]\ + value + +#endif +#ifdef _MSC_VER + +#pragma warning(disable:4799) //I know how to use EMMS + +static _inline long testflag (long c) +{ + _asm + { + mov ecx, c + pushfd + pop eax + mov edx, eax + xor eax, ecx + push eax + popfd + pushfd + pop eax + xor eax, edx + mov eax, 1 + jne menostinx + xor eax, eax + menostinx: + } +} + +static _inline void cpuid (long a, long *s) +{ + _asm + { + push ebx + push esi + mov eax, a + cpuid + mov esi, s + mov dword ptr [esi+0], eax + mov dword ptr [esi+4], ebx + mov dword ptr [esi+8], ecx + mov dword ptr [esi+12], edx + pop esi + pop ebx + } +} + +#endif + + //Bit numbers of return value: + //0:FPU, 4:RDTSC, 15:CMOV, 22:MMX+, 23:MMX, 25:SSE, 26:SSE2, 30:3DNow!+, 31:3DNow! +static long getcputype () +{ + long i, cpb[4], cpid[4]; + if (!testflag(0x200000)) return(0); + cpuid(0,cpid); if (!cpid[0]) return(0); + cpuid(1,cpb); i = (cpb[3]&~((1<<22)|(1<<30)|(1<<31))); + cpuid(0x80000000,cpb); + if (((unsigned long)cpb[0]) > 0x80000000) + { + cpuid(0x80000001,cpb); + i |= (cpb[3]&(1<<31)); + if (!((cpid[1]^0x68747541)|(cpid[3]^0x69746e65)|(cpid[2]^0x444d4163))) //AuthenticAMD + i |= (cpb[3]&((1<<22)|(1<<30))); + } + if (i&(1<<25)) i |= (1<<22); //SSE implies MMX+ support + return(i); +} + +//========================= CPU detection code ends ========================= + +//================== Fast & accurate TIMER FUNCTIONS begins ================== + +#if 0 +#ifdef __WATCOMC__ + +__int64 rdtsc64 (); +#pragma aux rdtsc64 = "rdtsc" value [edx eax] modify nomemory parm nomemory; + +#endif +#ifdef _MSC_VER + +static __forceinline __int64 rdtsc64 () { _asm rdtsc } + +#endif + +static __int64 pertimbase, rdtimbase, nextimstep; +static double perfrq, klockmul, klockadd; + +void initklock () +{ + __int64 q; + QueryPerformanceFrequency((LARGE_INTEGER *)&q); + perfrq = (double)q; + rdtimbase = rdtsc64(); + QueryPerformanceCounter((LARGE_INTEGER *)&pertimbase); + nextimstep = 4194304; klockmul = 0.000000001; klockadd = 0.0; +} + +void readklock (double *tim) +{ + __int64 q = rdtsc64()-rdtimbase; + if (q > nextimstep) + { + __int64 p; + double d; + QueryPerformanceCounter((LARGE_INTEGER *)&p); + d = klockmul; klockmul = ((double)(p-pertimbase))/(((double)q)*perfrq); + klockadd += (d-klockmul)*((double)q); + do { nextimstep <<= 1; } while (q > nextimstep); + } + (*tim) = ((double)q)*klockmul + klockadd; +} +#else + +static __int64 klocksub; +static double klockmul; + +void initklock () +{ + __int64 q; + QueryPerformanceFrequency((LARGE_INTEGER *)&q); + klockmul = 1.0/((double)q); + QueryPerformanceCounter((LARGE_INTEGER *)&klocksub); +} + +void readklock (double *tim) +{ + __int64 q; + QueryPerformanceCounter((LARGE_INTEGER *)&q); + (*tim) = ((double)(q-klocksub))*klockmul; +} + +#endif + +//=================== Fast & accurate TIMER FUNCTIONS ends =================== + +//DirectDraw VARIABLES & CODE--------------------------------------------------------------- +#ifndef NODRAW + +PALETTEENTRY pal[256]; +long ddrawuseemulation = 0; +long ddrawdebugmode = -1; // -1 = off, old ddrawuseemulation = on + +static __int64 mask8a = 0x00ff00ff00ff00ff; +static __int64 mask8b; //0x10000d0010000d00 (fullscreen), 0x10000c0010000c00 (windowed) +static __int64 mask8c = 0x0000f8000000f800; +static __int64 mask8d = 0xff000000ff000000; +static __int64 mask8e = 0x00ff000000ff0000; +static __int64 mask8f; //0x00d000d000d000d0 (fullscreen), 0x0aca0aca0aca0aca (windowed) +static __int64 mask8g; //0xd000d000d000d000 (fullscreen), 0xca0aca0aca0aca0a (windowed) +static long mask8cnt = 0; +static __int64 mask8h = 0x0007050500070505; +static __int64 mask8lut[8] = +{ + 0x0000000000000000,0x0000001300000013, + 0x0000080000000800,0x0000081300000813, + 0x0010000000100000,0x0010001300100013, + 0x0010080000100800,0x0010081300100813 +}; +static __int64 maskrb15 = 0x00f800f800f800f8; +static __int64 maskgg15 = 0x0000f8000000f800; +static __int64 maskml15 = 0x2000000820000008; +static __int64 maskrb16 = 0x00f800f800f800f8; +static __int64 maskgg16 = 0x0000fc000000fc00; +static __int64 maskml16 = 0x2000000420000004; +static __int64 mask16a = 0x0000800000008000; +static __int64 mask16b = 0x8000800080008000; +static __int64 mask24a = 0x00ffffff00000000; +static __int64 mask24b = 0x00000000ffffff00; +static __int64 mask24c = 0x0000000000ffffff; +static __int64 mask24d = 0xffffff0000000000; + +static long lpal[256]; + + //Beware of alignment issues!!! +void kblit32 (long rplc, long rbpl, long rxsiz, long rysiz, + long wplc, long cdim, long wbpl) +{ +#ifdef _MSC_VER + if ((rxsiz <= 0) || (rysiz <= 0)) return; + if (colbits == 8) + { + long x, y; + switch(cdim) + { + case 15: case 16: + //for(y=0;yx = x; valptr->y = y; + if (ddpf->dwFlags&DDPF_PALETTEINDEXED8) { valptr->c = 8; return; } + if (ddpf->dwFlags&DDPF_RGB) + { + valptr->c = (char)ddpf->dwRGBBitCount; + if (ddpf->dwRBitMask) + { + valptr->r0 = (char)bsf(ddpf->dwRBitMask); + valptr->rn = (char)(bsr(ddpf->dwRBitMask)-(valptr->r0)+1); + } + if (ddpf->dwGBitMask) + { + valptr->g0 = (char)bsf(ddpf->dwGBitMask); + valptr->gn = (char)(bsr(ddpf->dwGBitMask)-(valptr->g0)+1); + } + if (ddpf->dwBBitMask) + { + valptr->b0 = (char)bsf(ddpf->dwBBitMask); + valptr->bn = (char)(bsr(ddpf->dwBBitMask)-(valptr->b0)+1); + } + if (ddpf->dwRGBAlphaBitMask) + { + valptr->a0 = (char)bsf(ddpf->dwRGBAlphaBitMask); + valptr->an = (char)(bsr(ddpf->dwRGBAlphaBitMask)-(valptr->a0)+1); + } + } +} + +HRESULT WINAPI lpEnumModesCallback (LPDDSURFACEDESC dsd, LPVOID lpc) +{ + grabmodeinfo(dsd->dwWidth,dsd->dwHeight,&dsd->ddpfPixelFormat,&validmodelist[validmodecnt]); validmodecnt++; + if (validmodecnt >= MAXVALIDMODES) return(DDENUMRET_CANCEL); else return(DDENUMRET_OK); +} + +long getvalidmodelist (validmodetype **davalidmodelist) +{ + if (!lpdd) return(0); + if (!validmodecnt) lpdd->EnumDisplayModes(0,0,0,lpEnumModesCallback); + (*davalidmodelist) = validmodelist; + return(validmodecnt); +} + +void uninitdirectdraw () +{ + if (ddpal) { ddpal->Release(); ddpal = 0; } + if (lpdd) + { +#ifndef NO_CLIPPER + if (ddcliprd) { free(ddcliprd); ddcliprd = 0; ddcliprdbytes = 0; } + if (ddclip) { ddclip->Release(); ddclip = 0; } +#endif + if (ddsurf[0]) { ddsurf[0]->Release(); ddsurf[0] = 0; } + if (ddrawemulbuf) { free(ddrawemulbuf); ddrawemulbuf = 0; } + lpdd->Release(); lpdd = 0; + } +} + +void updatepalette (long start, long danum) +{ + long i; + if (colbits == 8) + { + switch(ddrawuseemulation) + { + case 15: + for(i=start+danum-1;i>=start;i--) + lpal[i] = (((pal[i].peRed>>3)&31)<<10) + (((pal[i].peGreen>>3)&31)<<5) + ((pal[i].peBlue>>3)&31); + return; + case 16: + for(i=start+danum-1;i>=start;i--) + lpal[i] = (((pal[i].peRed>>3)&31)<<11) + (((pal[i].peGreen>>2)&63)<<5) + ((pal[i].peBlue>>3)&31); + return; + case 24: case 32: + for(i=start+danum-1;i>=start;i--) + lpal[i] = ((pal[i].peRed)<<16) + ((pal[i].peGreen)<<8) + pal[i].peBlue; + return; + default: break; + } + } + if (!ddpal) return; + if (ddpal->SetEntries(0,start,danum,&pal[start]) == DDERR_SURFACELOST) + { ddsurf[0]->Restore(); ddpal->SetEntries(0,start,danum,&pal[start]); } +} + + //((z/(16-1))^.8)*255, ((z/(32-1))^.8)*255, ((z/((13 fullscreen/12 windowed)-1))^.8)*255 +static char palr[16] = {0,29,51,70,89,106,123,139,154,169,184,199,213,227,241,255}; +static char palg[32] = {0,16,28,39,50,59,69,78,86,95,103,111,119,127,135,143, + 150,158,165,172,180,187,194,201,208,215,222,228,235,242,248,255}; +static char palb[16] = {0,35,61,84,106,127,146,166,184,203,220,238,255,0,0,0}; + +void emul8setpal () +{ + long i, r, g, b; + + if (fullscreen) + { + //13 shades of blue in fullscreen mode + *(long *)&palb[0] = 0+( 35<<8)+( 61<<16)+( 84<<24); + *(long *)&palb[4] = 106+(127<<8)+(146<<16)+(166<<24); + *(long *)&palb[8] = 184+(203<<8)+(220<<16)+(238<<24); + mask8b = 0x10000d0010000d00; + mask8f = 0x00d000d000d000d0; + mask8g = 0xd000d000d000d000; + + i = 0; + for(b=0;b<13;b++) + for(r=0;r<16;r++) + { + pal[i].peRed = palr[r]; + pal[i].peGreen = 0; + pal[i].peBlue = palb[b]; + pal[i].peFlags = PC_NOCOLLAPSE; + i++; + } //224 cols + for(g=0;g<32;g++) + { + pal[i].peRed = 0; + pal[i].peGreen = palg[g]; + pal[i].peBlue = 0; + pal[i].peFlags = PC_NOCOLLAPSE; + i++; + } + } + else + { + //12 shades of blue in fullscreen mode + *(long *)&palb[0] = 0+( 37<<8)+( 65<<16)+( 90<<24); + *(long *)&palb[4] = 114+(136<<8)+(157<<16)+(178<<24); + *(long *)&palb[8] = 198+(217<<8)+(236<<16)+(255<<24); + mask8b = 0x10000c0010000c00; + mask8f = 0x0aca0aca0aca0aca; + mask8g = 0xca0aca0aca0aca0a; + + for(i=0;i<10;i++) { pal[i].peFlags = PC_EXPLICIT; pal[i].peRed = (char)i; pal[i].peGreen = pal[i].peBlue = 0; } + for(b=0;b<12;b++) + for(r=0;r<16;r++) + { + pal[i].peRed = palr[r]; + pal[i].peGreen = 0; + pal[i].peBlue = palb[b]; + pal[i].peFlags = PC_NOCOLLAPSE; + i++; + } //192 cols + for(g=0;g<32;g++) + { + pal[i].peRed = 0; + pal[i].peGreen = palg[g]; + pal[i].peBlue = 0; + pal[i].peFlags = PC_NOCOLLAPSE; + i++; + } + for(;i<256-10;i++) { pal[i].peFlags = PC_NOCOLLAPSE; pal[i].peRed = pal[i].peGreen = pal[i].peBlue = 0; } + for(;i<256;i++) { pal[i].peFlags = PC_EXPLICIT; pal[i].peRed = (char)i; pal[i].peGreen = pal[i].peBlue = 0; } + } +} + + // Note! + // debugmode is automatically turned off after changeres or initdirectdraw! + // do NOT call debugdirectdraw inside startdirectdraw()..stopdirectdraw() section +void debugdirectdraw () +{ +#ifndef NOINPUT + extern long mouse_acquire, kbd_acquire; + extern void setacquire (long mouse, long kbd); + static long old_acq = 0; +#endif + if (ddrawdebugmode == -1) { + if (!ddrawuseemulation) { + ddrawemulbuf = malloc(((xres*yres+7)&~7)*((colbits+7)>>3)+16); if (!ddrawemulbuf) return; // error! + ddrawemulbpl = ((colbits+7)>>3)*xres; + ddrawdebugmode = 0; + ddrawuseemulation = 32; + } else + ddrawdebugmode = ddrawuseemulation; +#ifndef NOINPUT + old_acq = (mouse_acquire&1) + ((kbd_acquire&1)<<1); + setacquire(0,0); +#endif + } else { + ddrawuseemulation = ddrawdebugmode; + if (!ddrawuseemulation) { + if (ddrawemulbuf) { free(ddrawemulbuf); ddrawemulbuf = 0; } + } + ddrawdebugmode = -1; +#ifndef NOINPUT + setacquire(old_acq&1, old_acq>>1); +#endif + } +} + +long initdirectdraw (long daxres, long dayres, long dacolbits) +{ + HRESULT hr; + DDSCAPS ddscaps; + char buf[256]; + long ncolbits; + + xres = daxres; yres = dayres; colbits = dacolbits; +#ifndef REFRESHACK + if ((hr = DirectDrawCreate(0,&lpdd,0)) >= 0) + { +#else + if ((hr = DirectDrawCreate(0,&lpdd0,0)) >= 0) + { + lpdd0->QueryInterface(IID_IDirectDraw2,(void **)&lpdd); +#endif + if (fullscreen) + { + if ((hr = lpdd->SetCooperativeLevel(ghwnd,DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN)) >= 0) + { + ddrawdebugmode = -1; + ncolbits = dacolbits; ddrawuseemulation = 0; + //ncolbits = 8; //HACK FOR TESTING! + //ncolbits = 16; //HACK FOR TESTING! + do + { +#ifndef REFRESHACK + if ((hr = lpdd->SetDisplayMode(daxres,dayres,ncolbits)) >= 0) +#else + if ((hr = lpdd->SetDisplayMode(daxres,dayres,ncolbits,refreshz,0)) >= 0) +#endif + { + if (1)//(ncolbits != dacolbits) // FULLSCREEN ALPHA PERFORMANCE HACK! + { + ddrawemulbuf = malloc(((daxres*dayres+7)&~7)*((dacolbits+7)>>3)+16); + if (!ddrawemulbuf) { ncolbits = 0; break; } + ddrawemulbpl = ((dacolbits+7)>>3)*daxres; + ddrawuseemulation = ncolbits; + } + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_COMPLEX|DDSCAPS_FLIP; + if (maxpages > 2) ddsd.dwBackBufferCount = 2; + else ddsd.dwBackBufferCount = 1; + if ((hr = lpdd->CreateSurface(&ddsd,&ddsurf[0],0)) >= 0) + { + DDPIXELFORMAT ddpf; + ddpf.dwSize = sizeof(DDPIXELFORMAT); + if (!ddsurf[0]->GetPixelFormat(&ddpf)) + grabmodeinfo(daxres,dayres,&ddpf,&curvidmodeinfo); + + ddscaps.dwCaps = DDSCAPS_BACKBUFFER; + if ((hr = ddsurf[0]->GetAttachedSurface(&ddscaps,&ddsurf[1])) >= 0) + { +#if (OFFSCREENHACK) + DDSURFACEDESC nddsd; + ddsurf[2] = ddsurf[1]; + ZeroMemory(&nddsd,sizeof(nddsd)); + nddsd.dwSize = sizeof(nddsd); + nddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT; + nddsd.dwWidth = (daxres|1); //This hack (|1) ensures pitch isn't near multiple of 4096 (slow on P4)! + nddsd.dwHeight = dayres; + nddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY; + if ((hr = lpdd->CreateSurface(&nddsd,&ddsurf[1],0)) < 0) return(-1); +#endif + if (ncolbits != 8) return(1); + if (lpdd->CreatePalette(DDPCAPS_8BIT,pal,&ddpal,0) >= 0) + { + ddsurf[0]->SetPalette(ddpal); + if (ddrawuseemulation) + { emul8setpal(); updatepalette(0,256); } + return(1); + } + } + } + } + switch(dacolbits) + { + case 8: + switch (ncolbits) + { + case 8: ncolbits = 32; break; + case 32: ncolbits = 24; break; + case 24: ncolbits = 16; break; + case 16: ncolbits = 15; break; + default: ncolbits = 0; break; + } + break; + case 32: + switch (ncolbits) + { + case 32: ncolbits = 24; break; + case 24: ncolbits = 16; break; + case 16: ncolbits = 15; break; + case 15: ncolbits = 8; break; + default: ncolbits = 0; break; + } + break; + default: ncolbits = 0; break; + } + } while (ncolbits); + if (!ncolbits) + { + validmodetype *validmodelist; + char vidlistbuf[4096]; + long i, j; + + validmodecnt = getvalidmodelist(&validmodelist); + wsprintf(vidlistbuf,"Valid fullscreen %d-bit DirectDraw modes:\n",colbits); + j = 0; + for(i=0;iSetCooperativeLevel(ghwnd,DDSCL_NORMAL)) >= 0) + { + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + if ((hr = lpdd->CreateSurface(&ddsd,&ddsurf[0],0)) >= 0) + { +#ifndef NO_CLIPPER + //Create clipper object for windowed mode + if ((hr = lpdd->CreateClipper(0,&ddclip,0)) == DD_OK) + { + ddclip->SetHWnd(0,ghwnd); //Associate clipper with window + hr = ddsurf[0]->SetClipper(ddclip); + if (hr == DD_OK) + { +#endif + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; +#if (OFFSCREENHACK == 0) + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; +#else + ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY; +#endif + ddsd.dwWidth = xres; + ddsd.dwHeight = yres; + if ((hr = lpdd->CreateSurface(&ddsd,&ddsurf[1],0)) >= 0) + { + DDCAPS ddcaps; + HDC hDC = GetDC(0); + ncolbits = GetDeviceCaps(hDC,BITSPIXEL); + ReleaseDC(0,hDC); + + ddcaps.dwSize = sizeof(ddcaps); + if (lpdd->GetCaps(&ddcaps,0) == DD_OK) //Better to catch DDERR_CANTLOCKSURFACE here than in startdirectdraw() + if (ddcaps.dwCaps&DDCAPS_NOHARDWARE) cantlockprimary = 1; //For LCD screens mainly + if (osvi.dwMajorVersion >= 6) cantlockprimary = 1; //Longhorn/Vista + + //03/08/2004: Now that clipper works for ddrawemulbuf, ddrawemulbuf is not only + //faster, but it supports WM_SIZE dragging better than ddsurf[0]->Blt! :) + // + //kblit32 currently supports these modes: + // colbits -> ncolbits + // 8 -> . 15 16 24 32 + // 15 -> . . . . . + // 16 -> . . . . . + // 24 -> . . . . . + // 32 -> 8 15 16 24 32 + if ((ncolbits != colbits) || ((colbits == 32) && (!cantlockprimary))) + { +#if (OFFSCREENHACK) + if (colbits != colbits) +#endif + { + ddrawemulbuf = malloc(((xres*yres+7)&~7)*((colbits+7)>>3)+16); + if (ddrawemulbuf) + { + ddrawemulbpl = ((colbits+7)>>3)*xres; + ddrawuseemulation = ncolbits; + if ((ncolbits == 8) && (colbits == 32)) emul8setpal(); + } + } + } + + if ((ncolbits == 8) || (colbits == 8)) updatepalette(0,256); + + DDPIXELFORMAT ddpf; + ddpf.dwSize = sizeof(DDPIXELFORMAT); + if (!ddsurf[0]->GetPixelFormat(&ddpf)) //colbits = ddpf.dwRGBBitCount; + { + grabmodeinfo(daxres,dayres,&ddpf,&curvidmodeinfo); + + //If mode is 555 color (and not 565), use 15-bit emulation code... + if ((colbits != 16) && (ncolbits == 16) + && (curvidmodeinfo.r0 == 10) && (curvidmodeinfo.rn == 5) + && (curvidmodeinfo.g0 == 5) && (curvidmodeinfo.gn == 5) + && (curvidmodeinfo.b0 == 0) && (curvidmodeinfo.bn == 5)) + ddrawuseemulation = 15; + } + + if (ncolbits == 8) + if (lpdd->CreatePalette(DDPCAPS_8BIT,pal,&ddpal,0) >= 0) + ddsurf[0]->SetPalette(ddpal); + + return(1); + } +#ifndef NO_CLIPPER + } + } +#endif + } + } + } + } + uninitdirectdraw(); + wsprintf(buf,"initdirectdraw failed: 0x%08lx",hr); + MessageBox(ghwnd,buf,"ERROR",MB_OK); + return(0); +} + +void stopdirectdraw () +{ + if (!ddlocked) return; + if (!ddrawuseemulation) ddsurf[1]->Unlock(ddsd.lpSurface); + ddlocked = 0; +} + +long startdirectdraw (long *vidplc, long *dabpl, long *daxres, long *dayres) +{ + HRESULT hr; + + if (ddlocked) { stopdirectdraw(); ddlocked = 0; } //{ return(0); } + + if (ddrawuseemulation) + { + *vidplc = (long)ddrawemulbuf; *dabpl = xres*((colbits+7)>>3); + *daxres = xres; *dayres = yres; ddlocked = 1; + return(1); + } + + while (1) + { + if ((hr = ddsurf[1]->Lock(0,&ddsd,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,0)) == DD_OK) break; + if (hr == DDERR_SURFACELOST) + { + if (ddsurf[0]->Restore() != DD_OK) return(0); + if (ddsurf[1]->Restore() != DD_OK) return(0); + } + if (hr == DDERR_CANTLOCKSURFACE) return(-1); //if true, set cantlockprimary = 1; + if (hr != DDERR_WASSTILLDRAWING) return(0); + } + + //DDLOCK_WAIT MANDATORY! (to prevent sudden exit back to windows)! + //if (hr = ddsurf[1]->Lock(0,&ddsd,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,0) != DD_OK) + // return(0); + + *vidplc = (long)ddsd.lpSurface; *dabpl = ddsd.lPitch; + *daxres = xres; *dayres = yres; ddlocked = 1; + return(1); +} + +static HDC ghdc; +HDC startdc () +{ + ddsurf[1]->GetDC(&ghdc); + return(ghdc); +} + +void stopdc () +{ + ddsurf[1]->ReleaseDC(ghdc); +} + +void nextpage () +{ + HRESULT hr; + + if (ddrawdebugmode != -1) return; + + //Note: windowed mode could be faster by having kblit go directly + // to the ddsurf[0] (windows video memory) + if (ddrawuseemulation) + { + long i, fplace, bpl, xsiz, ysiz; + if (!fullscreen) + { + POINT topLeft, p2; + long j; +#ifndef NO_CLIPPER + RECT *r; + unsigned long siz; +#endif + + //Note: this hack for windowed mode saves an unnecessary blit by + // going directly to primary buffer (ddsurf[0]) + // Unfortunately, this means it ignores the clipper & you can't + // use the ddraw stretch function :/ + topLeft.x = 0; topLeft.y = 0; + if (!cantlockprimary) + { + ddsurf[2] = ddsurf[0]; ddsurf[0] = ddsurf[1]; ddsurf[1] = ddsurf[2]; + ClientToScreen(ghwnd,&topLeft); + } + else + { + p2.x = 0; p2.y = 0; + ClientToScreen(ghwnd,&p2); + } + + //This is sort of a hack... but it works + i = ddrawuseemulation; ddrawuseemulation = 0; + j = startdirectdraw(&fplace,&bpl,&xsiz,&ysiz); + if (j == -1) + { + if (!cantlockprimary) + { + ddsurf[2] = ddsurf[0]; ddsurf[0] = ddsurf[1]; ddsurf[1] = ddsurf[2]; //Undo earlier surface swap + cantlockprimary = 1; ddrawuseemulation = i; return; + } + } + else if (j) + { +#ifndef NO_CLIPPER + ddclip->GetClipList(0,0,&siz); + if (siz > ddcliprdbytes) + { + ddcliprdbytes = siz; + ddcliprd = (RGNDATA *)realloc(ddcliprd,siz); + } + if (!ddcliprd) + { +#endif + kblit32(max(-topLeft.y,0)*ddrawemulbpl + + max(-topLeft.x,0)*((colbits+7)>>3) + ((long)ddrawemulbuf), + ddrawemulbpl, + min(topLeft.x+xsiz,GetSystemMetrics(SM_CXSCREEN))-max(topLeft.x,0), + min(topLeft.y+ysiz,GetSystemMetrics(SM_CYSCREEN))-max(topLeft.y,0), + max(topLeft.y,0)*bpl+max(topLeft.x,0)*((i+7)>>3)+fplace, + i,bpl); +#ifndef NO_CLIPPER + } + else + { + ddclip->GetClipList(0,ddcliprd,&siz); + + r = (RECT *)ddcliprd->Buffer; + for(j=0;j<(long)ddcliprd->rdh.nCount;j++) + { + if (cantlockprimary) { r[j].left -= p2.x; r[j].top -= p2.y; r[j].right -= p2.x; r[j].bottom -= p2.y; } + kblit32(max(r[j].top -topLeft.y,0)*ddrawemulbpl + + max(r[j].left-topLeft.x,0)*((colbits+7)>>3) + ((long)ddrawemulbuf), + ddrawemulbpl, + min(topLeft.x+xsiz,r[j].right )-max(topLeft.x,r[j].left), + min(topLeft.y+ysiz,r[j].bottom)-max(topLeft.y,r[j].top ), + max(topLeft.x,r[j].left)*((i+7)>>3) + + max(topLeft.y,r[j].top )*bpl + fplace, + i,bpl); + } + } +#endif + stopdirectdraw(); + } + ddrawuseemulation = i; + + //Finish windowed mode hack to primary buffer + if (!cantlockprimary) { ddsurf[2] = ddsurf[0]; ddsurf[0] = ddsurf[1]; ddsurf[1] = ddsurf[2]; return; } + } + else + { + //This is sort of a hack... but it works + i = ddrawuseemulation; ddrawuseemulation = 0; + if (startdirectdraw(&fplace,&bpl,&xsiz,&ysiz)) + { + kblit32((long)ddrawemulbuf,ddrawemulbpl,min(xsiz,xres),min(ysiz,yres),fplace,i,bpl); + stopdirectdraw(); + } + ddrawuseemulation = i; + } + } + + if (fullscreen) + { +#if (OFFSCREENHACK) + RECT r; r.left = 0; r.top = 0; r.right = xres; r.bottom = yres; //with width hack, src rect not always: xres,yres + if (ddsurf[2]->GetBltStatus(DDGBS_CANBLT) == DDERR_WASSTILLDRAWING) return; + if (ddsurf[2]->BltFast(0,0,ddsurf[1],&r,DDBLTFAST_NOCOLORKEY) == DDERR_SURFACELOST) + { ddsurf[0]->Restore(); if (ddsurf[2]->BltFast(0,0,ddsurf[1],&r,DDBLTFAST_NOCOLORKEY) != DD_OK) return; } + if (ddsurf[0]->GetFlipStatus(DDGFS_CANFLIP) == DDERR_WASSTILLDRAWING) return; //wait for blit to complete + if (ddsurf[0]->Flip(0,0) == DDERR_SURFACELOST) { ddsurf[0]->Restore(); ddsurf[0]->Flip(0,0); } +#elif 1 + //NOTE! If not using DDFLIP_WAIT, >70fps only works + // when ddsd.dwBackBufferCount > 1 (triple+ buffering) + while (1) //Recommended flipper from 1997 DirectDraw 3.0 MSDN CD: + { + if ((hr = ddsurf[0]->Flip(0,DDFLIP_WAIT)) == DD_OK) break; + if (hr == DDERR_SURFACELOST) + { + if (ddsurf[0]->Restore() != DD_OK) break; + if (ddsurf[1]->Restore() != DD_OK) break; + } + if (hr != DDERR_WASSTILLDRAWING) break; + } +#else + //This loop allows windows to breath while waiting for the flip + // so, it gives smoother execution + // WARNING: bad things can happen if breath() receives WM_CLOSE!!! + while (1) + { + if ((hr = ddsurf[0]->Flip(0,0)) == DD_OK) break; + if (hr == DDERR_WASSTILLDRAWING) { breath(); continue; } + if (hr == DDERR_SURFACELOST) + { + if (ddsurf[0]->Restore() != DD_OK) break; + if (ddsurf[1]->Restore() != DD_OK) break; + } + break; + } +#endif + } + else + { + RECT rcSrc, rcDst; + POINT topLeft; + + rcSrc.left = 0; rcSrc.top = 0; + rcSrc.right = xres; rcSrc.bottom = yres; +#ifndef ZOOM_TEST + rcDst = rcSrc; +#else + GetClientRect(ghwnd, &rcDst); +#endif + topLeft.x = 0; topLeft.y = 0; + ClientToScreen(ghwnd,&topLeft); + rcDst.left += topLeft.x; rcDst.right += topLeft.x; + rcDst.top += topLeft.y; rcDst.bottom += topLeft.y; +#ifdef NO_CLIPPER + if (ddsurf[0]->BltFast(rcDst.left,rcDst.top,ddsurf[1],&rcSrc,DDBLTFAST_WAIT|DDBLTFAST_NOCOLORKEY) < 0) +#else + if (ddsurf[0]->Blt(&rcDst,ddsurf[1],&rcSrc,DDBLT_WAIT|DDBLT_ASYNC,0) < 0) +#endif + { + if (ddsurf[0]->IsLost() == DDERR_SURFACELOST) ddsurf[0]->Restore(); + if (ddsurf[1]->IsLost() == DDERR_SURFACELOST) ddsurf[1]->Restore(); +#ifdef NO_CLIPPER + ddsurf[0]->BltFast(rcDst.left,rcDst.top,ddsurf[1],&rcSrc,DDBLTFAST_WAIT|DDBLTFAST_NOCOLORKEY); +#else + ddsurf[0]->Blt(&rcDst,ddsurf[1],&rcSrc,DDBLT_WAIT|DDBLT_ASYNC,0); +#endif + } + } +} + +void ddflip2gdi () +{ + if (lpdd) lpdd->FlipToGDISurface(); +} + +long clearscreen (long fillcolor) +{ + DDBLTFX blt; + HRESULT hr; + + if (ddrawuseemulation) + { + long c = ((xres*yres+7)&~7)*((colbits+7)>>3); c >>= 3; + if (cputype&(1<<25)) //SSE + { + _asm + { + mov edx, ddrawemulbuf + mov ecx, c + movd mm0, fillcolor + punpckldq mm0, mm0 + clear32a: movntq qword ptr [edx], mm0 + add edx, 8 + sub ecx, 1 + jnz short clear32a + emms + } + } + else if (cputype&(1<<23)) //MMX + { + _asm + { + mov edx, ddrawemulbuf + mov ecx, c + movd mm0, fillcolor + punpckldq mm0, mm0 + clear32b: movq qword ptr [edx], mm0 + add edx, 8 + sub ecx, 1 + jnz short clear32b + emms + } + } + else + { + long q[2]; q[0] = q[1] = fillcolor; + _asm + { + mov edx, ddrawemulbuf + mov ecx, c + clear32c: fild qword ptr q + fistp qword ptr [edx] ;NOTE: fist doesn't have a 64-bit form! + add edx, 8 + sub ecx, 1 + jnz short clear32c + } + } + return(1); + } + + //Can't clear when locked: would SUPERCRASH! + if (ddlocked) + { + long i, j, x, p, pe; + + p = (long)ddsd.lpSurface; pe = ddsd.lPitch*yres + p; + if (colbits != 24) + { + switch(colbits) + { + case 8: fillcolor = (fillcolor&255)*0x1010101; i = xres ; break; + case 15: case 16: fillcolor = (fillcolor&65535)*0x10001; i = xres*2; break; + case 32: i = xres*4; break; + } + for(;p>3); + if (cputype&(1<<25)) //SSE + { + _asm + { + mov edx, p + mov ecx, j + movd mm0, fillcolor + punpckldq mm0, mm0 + clear32d: movntq qword ptr [edx], mm0 + add edx, 8 + sub ecx, 1 + jnz short clear32d + emms + } + } + else if (cputype&(1<<23)) //MMX + { + _asm + { + mov edx, p + mov ecx, j + movd mm0, fillcolor + punpckldq mm0, mm0 + clear32e: movq qword ptr [edx], mm0 + add edx, 8 + sub ecx, 1 + jnz short clear32e + emms + } + } + else + { + long q[2]; q[0] = q[1] = fillcolor; + _asm + { + mov edx, p + mov ecx, j + clear32f: fild qword ptr q + fistp qword ptr [edx] ;NOTE: fist doesn't have a 64-bit form! + add edx, 8 + sub ecx, 1 + jnz short clear32f + } + } + x = (i&~7)+p; + if (i&4) { *(long *)x = fillcolor; x += 4; } +#endif + if (i&2) { *(short *)x = (short)fillcolor; x += 2; } + if (i&1) { *(char *)x = (char)fillcolor; } + } + if (cputype&(1<<25)) _asm emms //SSE + } + else + { + long dacol[3]; + fillcolor &= 0xffffff; + dacol[0] = (fillcolor<<24)+fillcolor; //BRGB + dacol[1] = (fillcolor>>8)+(fillcolor<<16); //GBRG + dacol[2] = (fillcolor>>16)+(fillcolor<<8); //RGBR + i = xres*3; + for(;pBlt(0,0,0,DDBLT_COLORFILL,&blt); //Try |DDBLT_WAIT + if (hr == DD_OK) return(1); + if (hr == DDERR_SURFACELOST) + { + if (ddsurf[0]->Restore() != DD_OK) return(0); + if (ddsurf[1]->Restore() != DD_OK) return(0); + } + } +} + +long changeres (long daxres, long dayres, long dacolbits, long dafullscreen) +{ + uninitdirectdraw(); + + ShowWindow(ghwnd,FALSE); + if (dafullscreen) + { + SetWindowLong(ghwnd,GWL_EXSTYLE,WS_EX_TOPMOST); + SetWindowLong(ghwnd,GWL_STYLE,WS_POPUP); + MoveWindow(ghwnd,0,0,GetSystemMetrics(SM_CXSCREEN), + GetSystemMetrics(SM_CYSCREEN),0); + } + else + { + RECT rw; + SystemParametersInfo(SPI_GETWORKAREA,0,&rw,0); + + SetWindowLong(ghwnd,GWL_EXSTYLE, 0); + SetWindowLong(ghwnd,GWL_STYLE,progwndflags); + MoveWindow(ghwnd,((rw.right -rw.left-(daxres+progwndadd[0]))>>1) + rw.left, + ((rw.bottom-rw.top -(dayres+progwndadd[1]))>>1) + rw.top, + daxres+progwndadd[0], dayres+progwndadd[1], 0); + } + ShowWindow(ghwnd,TRUE); + + fullscreen = dafullscreen; + return(initdirectdraw(daxres,dayres,dacolbits)); +} + +// //How to use dc & draw text: +//HDC hdc; +//if (ddsurf[1]->GetDC(&hdc) == DD_OK) +//{ +// SetBkColor(hdc,RGB(0,0,255)); //SetBkMode(hdc,TRANSPARENT); +// SetTextColor(hdc,RGB(255,255,0)); +// //HFONT fontInUse = CreateFont(size,0,0,0,FW_NORMAL,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS, +// // CLIP_DEFAULT_PRECIS,NONANTIALIASED_QUALITY,VARIABLE_PITCH,"Arial"); +// //oldFont = SelectObject(hdc,fontInUse); +// TextOut(hdc,x,y,message,strlen(message)); +// //SelectObject(hdc,oldFont); +// //DeleteObject(fontInUse); +// ddsurf[1]->ReleaseDC(hdc); +//} + +// //Do this to ensure GDI stuff is on the screen: +//lpdd->FlipToGDISurface(); + +// //Use real timers, (forget SetTimer/WM_TIMER crap): +//#include +//void CALLBACK OneShotTimer(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2) +// { printf("Alarm!"); } +//timeSetEvent(msInterval,msInterval,OneShotTimer,(DWORD)npSeq,TIME_PERIODIC); +#endif + +//DirectInput VARIABLES & CODE------------------------------------------------------- +char keystatus[256]; +static long shkeystatus = 0; +#define KEYBUFSIZ 256 +static long keybuf[KEYBUFSIZ], keybufr = 0, keybufw = 0, keybufw2 = 0; + +char ext_keystatus[256]; // +TD +char ext_mbstatus[8] = {0}; // +TD extended mouse button status +long ext_mwheel = 0; +#ifdef NOINPUT +long mouse_acquire = 0; +#else +long mouse_acquire = 1, kbd_acquire = 1; +static void (*setmousein)(long, long) = NULL; +static long mouse_out_x, mouse_out_y; +static HANDLE dinputevent[2] = {0,0}; + +static LPDIRECTINPUT gpdi = 0; +long initdirectinput (HWND hwnd) +{ + HRESULT hr; + char buf[256]; + + if ((hr = DirectInput8Create(ghinst,DIRECTINPUT_VERSION,IID_IDirectInput8A,(LPVOID*)&gpdi,0)) >= 0) return(1); + wsprintf(buf,"initdirectinput failed: %08lx\n",hr); + MessageBox(ghwnd,buf,"ERROR",MB_OK); + return(0); +} + +void uninitdirectinput () +{ + if (gpdi) { gpdi->Release(); gpdi = 0; } +} + +//DirectInput (KEYBOARD) VARIABLES & CODE------------------------------------------------------- +static LPDIRECTINPUTDEVICE gpKeyboard = 0; +#define KBDBUFFERSIZE 64 +DIDEVICEOBJECTDATA KbdBuffer[KBDBUFFERSIZE]; + +//#define KEYBUFSIZ 256 +//static long keybuf[KEYBUFSIZ], keybufr = 0, keybufw = 0, keybufw2 = 0; + +void uninitkeyboard () +{ + if (gpKeyboard) + { + if (dinputevent[1]) + { + gpKeyboard->SetEventNotification(dinputevent[1]); + CloseHandle(dinputevent[1]); dinputevent[1] = 0; + } + gpKeyboard->Unacquire(); gpKeyboard->Release(); gpKeyboard = 0; + } +} + +long initkeyboard (HWND hwnd) +{ + HRESULT hr; + DIPROPDWORD dipdw; + char buf[256]; + + if ((hr = gpdi->CreateDevice(GUID_SysKeyboard,&gpKeyboard,0)) < 0) goto initkeyboard_bad; + if ((hr = gpKeyboard->SetDataFormat(&c_dfDIKeyboard)) < 0) goto initkeyboard_bad; + if ((hr = gpKeyboard->SetCooperativeLevel(hwnd,dinputkeyboardflags)) < 0) goto initkeyboard_bad; + + dinputevent[1] = CreateEvent(0,0,0,0); if (!dinputevent[1]) goto initkeyboard_bad; + if ((hr = gpKeyboard->SetEventNotification(dinputevent[1])) < 0) goto initkeyboard_bad; + + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = KBDBUFFERSIZE; + if ((hr = gpKeyboard->SetProperty(DIPROP_BUFFERSIZE,&dipdw.diph)) < 0) goto initkeyboard_bad; + if (kbd_acquire) { gpKeyboard->Acquire(); shkeystatus = 0; } + return(1); + +initkeyboard_bad:; + uninitkeyboard(); + wsprintf(buf,"initdirectinput(keyboard) failed: %08lx\n",hr); + MessageBox(ghwnd,buf,"ERROR",MB_OK); + return(0); +} + +long readkeyboard () +{ + HRESULT hr; + long i; + unsigned long dwItems; + DIDEVICEOBJECTDATA *lpdidod; + + dwItems = KBDBUFFERSIZE; + hr = gpKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),KbdBuffer,&dwItems,0); + //if (hr == DI_BUFFEROVERFLOW) ?; + if (hr == DIERR_INPUTLOST) + { + gpKeyboard->Acquire(); shkeystatus = 0; + hr = gpKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),KbdBuffer,&dwItems,0); + } + if (hr < 0) return(0); + for(i=0;i<(long)dwItems;i++) + { + lpdidod = &KbdBuffer[i]; + + if (lpdidod->dwData&128) keystatus[lpdidod->dwOfs] = 1; + else keystatus[lpdidod->dwOfs] = 0; + //event occured "GetTickCount()-lpdidod->dwTimeStamp" milliseconds ago + + // +TD: + if (lpdidod->dwData&128) ext_keystatus[lpdidod->dwOfs] = 1|2; + else ext_keystatus[lpdidod->dwOfs] &= ~1; // preserve bit 2 only + } + return(dwItems); +} + + +//DirectInput (MOUSE) VARIABLES & CODE------------------------------------------------------- + +static LPDIRECTINPUTDEVICE gpMouse = 0; +#define MOUSBUFFERSIZE 64 +DIDEVICEOBJECTDATA MousBuffer[MOUSBUFFERSIZE]; +static long gbstatus = 0, gkillbstatus = 0; + + //Mouse smoothing variables: +long mousmoth = 1; +static double dmoutsc; +float mousper; +static float mousince, mougoalx, mougoaly, mougoalz, moutscale; +static long moult[4], moultavg, moultavgcnt; + +void uninitmouse () +{ + if (gpMouse) + { + if (dinputevent[0]) + { + gpMouse->SetEventNotification(dinputevent[0]); + CloseHandle(dinputevent[0]); dinputevent[0] = 0; + } + gpMouse->Unacquire(); gpMouse->Release(); gpMouse = 0; + } +} + +long initmouse (HWND hwnd) +{ + HRESULT hr; + DIPROPDWORD dipdw; + char buf[256]; + + if ((hr = gpdi->CreateDevice(GUID_SysMouse,&gpMouse,0)) < 0) goto initmouse_bad; + if ((hr = gpMouse->SetDataFormat(&c_dfDIMouse)) < 0) goto initmouse_bad; +#ifndef PROJECT_ANIMATOR + if ((hr = gpMouse->SetCooperativeLevel(hwnd,dinputmouseflags)) < 0) goto initmouse_bad; +#endif + + dinputevent[0] = CreateEvent(0,0,0,0); if (!dinputevent[0]) goto initmouse_bad; + if ((hr = gpMouse->SetEventNotification(dinputevent[0])) < 0) goto initmouse_bad; + + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = MOUSBUFFERSIZE; + if ((hr = gpMouse->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)) < 0) goto initmouse_bad; + + if (mouse_acquire) { gpMouse->Acquire(); gbstatus = 0; } + mousper = 1.0; mousince = mougoalx = mougoaly = mougoalz = 0.0; + moult[0] = -1; moultavg = moultavgcnt = 0; + readklock(&dmoutsc); + return(1); + +initmouse_bad:; + uninitmouse(); + wsprintf(buf,"initdirectinput(mouse) failed: %08lx\n",hr); + MessageBox(ghwnd,buf,"ERROR",MB_OK); + return(0); +} + +void readmouse (float *fmousx, float *fmousy, float *fmousz, long *bstatus) +{ + double odmoutsc; + float f, fmousynctics; + long i, got, ltmin, ltmax, nlt0, nlt1, nlt2; + long mousx, mousy, mousz; + HRESULT hr; + unsigned long dwItems; + DIDEVICEOBJECTDATA *lpdidod; + + if ((!mouse_acquire) || (!gpMouse)) { *fmousx = 0; *fmousy = 0; *fmousz = 0; *bstatus = 0; return; } + + dwItems = MOUSBUFFERSIZE; + hr = gpMouse->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),MousBuffer,&dwItems,0); + if (hr == DI_BUFFEROVERFLOW) moult[0] = -1; + if (hr == DIERR_INPUTLOST) + { + gpMouse->Acquire(); gbstatus = 0; + hr = gpMouse->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),MousBuffer,&dwItems,0); + } + + //Estimate mouse period (mousper) in units of CPU cycles: + mousx = mousy = mousz = 0; got = 0; + i = 0; lpdidod = &MousBuffer[i]; + while (i < (long)dwItems) + { + moult[3] = moult[2]; moult[2] = moult[1]; moult[1] = moult[0]; + moult[0] = lpdidod->dwTimeStamp; + do + { + switch(lpdidod->dwOfs) + { + case DIMOFS_X: mousx += lpdidod->dwData; break; + case DIMOFS_Y: mousy += lpdidod->dwData; break; + case DIMOFS_Z: mousz += lpdidod->dwData; break; + case DIMOFS_BUTTON0: if (lpdidod->dwData&128) ext_mbstatus[0] = 1|2; else ext_mbstatus[0] &= 2; + gbstatus = ((gbstatus&~1)|((lpdidod->dwData>>7)&1)); moult[0] = -1; break; + case DIMOFS_BUTTON1: if (lpdidod->dwData&128) ext_mbstatus[1] = 1|2; else ext_mbstatus[1] &= 2; + gbstatus = ((gbstatus&~2)|((lpdidod->dwData>>6)&2)); moult[0] = -1; break; + case DIMOFS_BUTTON2: if (lpdidod->dwData&128) ext_mbstatus[2] = 1|2; else ext_mbstatus[2] &= 2; + gbstatus = ((gbstatus&~4)|((lpdidod->dwData>>5)&4)); moult[0] = -1; break; + case DIMOFS_BUTTON3: if (lpdidod->dwData&128) ext_mbstatus[3] = 1|2; else ext_mbstatus[3] &= 2; + gbstatus = ((gbstatus&~8)|((lpdidod->dwData>>4)&8)); moult[0] = -1; break; + } + i++; lpdidod = &MousBuffer[i]; + } while ((i < (long)dwItems) && ((long)lpdidod->dwTimeStamp == moult[0])); + + if (moult[0] != -1) + { + got++; + if ((moult[1] != -1) && (moult[2] != -1) && (moult[3] != -1)) + { + nlt0 = moult[0]-moult[1]; + nlt1 = moult[1]-moult[2]; + nlt2 = moult[2]-moult[3]; + ltmin = nlt0; ltmax = nlt0; + if (nlt1 < ltmin) ltmin = nlt1; + if (nlt2 < ltmin) ltmin = nlt2; + if (nlt1 > ltmax) ltmax = nlt1; + if (nlt2 > ltmax) ltmax = nlt2; + if (ltmin*2 >= ltmax) //WARNING: NT's timer has 10ms resolution! + { + moultavg += moult[0]-moult[3]; moultavgcnt += 3; + mousper = (float)moultavg/(float)moultavgcnt; + } + } + } + } + if (gkillbstatus) { gkillbstatus = 0; gbstatus = 0; } //Flush packets after task switch + (*bstatus) = gbstatus; + + //Calculate and return smoothed mouse data in: (fmousx, fmousy) + odmoutsc = dmoutsc; readklock(&dmoutsc); + fmousynctics = (float)((dmoutsc-odmoutsc)*1000.0); + + //At one time, readklock() wasn't always returning increasing values. + //This made fmousynctics <= 0 possible, causing /0. Fixed now :) + if ((!moultavgcnt) || (!mousmoth)) //|| ((*(long *)&fmousynctics) <= 0)) + { (*fmousx) = (float)mousx; (*fmousy) = (float)mousy; (*fmousz) = (float)mousz; return; } + + mousince = min(mousince+mousper*(float)got,mousper+fmousynctics); + if (fmousynctics >= mousince) { f = 1; mousince = 0; } + else { f = fmousynctics / mousince; mousince -= fmousynctics; } + mougoalx += (float)mousx; (*fmousx) = mougoalx*f; mougoalx -= (*fmousx); + mougoaly += (float)mousy; (*fmousy) = mougoaly*f; mougoaly -= (*fmousy); + mougoalz += (float)mousz; (*fmousz) = mougoalz*f; mougoalz -= (*fmousz); +} +void readmouse (float *fmousx, float *fmousy, long *bstatus) +{ + float fmousz; + readmouse(fmousx,fmousy,&fmousz,bstatus); +} + +void smartsleep (long timeoutms) +{ + MsgWaitForMultipleObjects(2,dinputevent,0,timeoutms,QS_KEY|QS_PAINT); +} + +#endif + + +// Kensound code begins ------------------------------------------------------- + +#ifndef NOSOUND +//-------------------------------------------------------------------------------------------------- +#define MAXUMIXERS 256 +#define UMIXERBUFSIZ 65536 +typedef struct +{ + LPDIRECTSOUNDBUFFER streambuf; + long samplerate, numspeakers, bytespersample, oplaycurs; + void (*mixfunc)(void *dasnd, long danumbytes); +} umixertyp; +static umixertyp umixer[MAXUMIXERS]; +static long umixernum = 0; + +extern LPDIRECTSOUND dsound; //Defined later + +long umixerstart (void damixfunc (void *, long), long dasamprate, long danumspeak, long dabytespersamp) +{ + DSBUFFERDESC dsbdesc; + DSBCAPS dsbcaps; + WAVEFORMATEX wfx; + void *w0 = 0, *w1 = 0; + unsigned long l0 = 0, l1 = 0; + + if ((dasamprate <= 0) || (danumspeak <= 0) || (dabytespersamp <= 0) || (umixernum >= MAXUMIXERS)) return(-1); + + umixer[umixernum].samplerate = dasamprate; + umixer[umixernum].numspeakers = danumspeak; + umixer[umixernum].bytespersample = dabytespersamp; + + wfx.wFormatTag = WAVE_FORMAT_PCM; + wfx.nSamplesPerSec = dasamprate; + wfx.wBitsPerSample = (dabytespersamp<<3); + wfx.nChannels = danumspeak; + wfx.nBlockAlign = (wfx.wBitsPerSample>>3) * wfx.nChannels; + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + wfx.cbSize = 0; + + memset(&dsbdesc,0,sizeof(DSBUFFERDESC)); + dsbdesc.dwSize = sizeof(DSBUFFERDESC); + dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_LOCSOFTWARE|DSBCAPS_GLOBALFOCUS; + dsbdesc.dwBufferBytes = UMIXERBUFSIZ; + dsbdesc.lpwfxFormat = &wfx; + if (dsound->CreateSoundBuffer(&dsbdesc,&umixer[umixernum].streambuf,0) != DS_OK) return(-1); + + //Zero out streaming buffer before beginning play + umixer[umixernum].streambuf->Lock(0,UMIXERBUFSIZ,&w0,&l0,&w1,&l1,0); + if (w0) memset(w0,(dabytespersamp-2)&128,l0); + if (w1) memset(w1,(dabytespersamp-2)&128,l1); + umixer[umixernum].streambuf->Unlock(w0,l0,w1,l1); + + umixer[umixernum].streambuf->SetCurrentPosition(0); + umixer[umixernum].streambuf->Play(0,0,DSBPLAY_LOOPING); + + umixer[umixernum].oplaycurs = 0; + umixer[umixernum].mixfunc = damixfunc; + umixernum++; + + return(umixernum-1); +} + +void umixerkill (long i) +{ + if ((unsigned long)i >= umixernum) return; + if (umixer[i].streambuf) + { umixer[i].streambuf->Stop(); umixer[i].streambuf->Release(); umixer[i].streambuf = 0; } + umixernum--; if (i != umixernum) umixer[i] = umixer[umixernum]; +} + +void umixerbreathe () +{ + void *w0 = 0, *w1 = 0; + unsigned long l, l0 = 0, l1 = 0, playcurs, writcurs; + long i; + + for(i=0;iGetCurrentPosition(&playcurs,&writcurs) != DS_OK) continue; + playcurs += ((umixer[i].samplerate/8)<<(umixer[i].bytespersample+umixer[i].numspeakers-2)); + l = (((playcurs-umixer[i].oplaycurs)&(UMIXERBUFSIZ-1))>>(umixer[i].bytespersample+umixer[i].numspeakers-2)); + if (l <= 256) continue; + if (umixer[i].streambuf->Lock(umixer[i].oplaycurs&(UMIXERBUFSIZ-1),l<<(umixer[i].bytespersample+umixer[i].numspeakers-2),&w0,&l0,&w1,&l1,0) != DS_OK) continue; + if (w0) umixer[i].mixfunc(w0,l0); + if (w1) umixer[i].mixfunc(w1,l1); + umixer[i].oplaycurs += l0+l1; + umixer[i].streambuf->Unlock(w0,l0,w1,l1); + } +} +//-------------------------------------------------------------------------------------------------- +typedef struct { float x, y, z; } point3d; +#if (USEKENSOUND == 1) +#include + + //Internal streaming buffer variables: +#define SNDSTREAMSIZ 16384 //(16384) Keep this a power of 2! +#define MINBREATHREND 256 //(256) Keep this high to avoid clicks, but much smaller than SNDSTREAMSIZ! +#define LSAMPREC 10 //(11) No WAV file can have more than 2^(31-LSAMPREC) samples +#define MAXPLAYINGSNDS 256 //(256) +#define VOLSEPARATION 1.f //(1.f) Range: 0 to 1, .5 good for headphones, 1 good for speakers +#define EARSEPARATION 8.f //(8.f) Used for L/R sample shifting +#define SNDMINDIST 32.f //(32.f) Shortest distance where volume is max / volume scale factor +#define SNDSPEED 4096.f //(4096.f) Speed of sound in units per second +#define NUMCOEF 4 //(4) # filter coefficients (4 and 8 are good choices) +#define LOGCOEFPREC 5 //(5) number of fractional bits of precision: 5 is ok +#define COEFRANG 32757 //(32757) DON'T make this > 32757 (not a typo) or else it'll overflow +#define KSND_3D 1 +#define KSND_MOVE 2 +#define KSND_LOOP 4 +#define KSND_LOPASS 8 +#define KSND_MEM 16 +#define KSND_LOOPFADE 32 //for internal use only + +typedef struct //For sounds longer than SNDSTREAMSIZ +{ + point3d *ptr; //followstat (-1 means not 3D sound, 0 means 3D sound but don't follow, else follow 3D!) + point3d p; //current position + long flags; //Bit0:1=3D, Bit1:1=follow 3D, Bit2:1=loop + long ssnd; //source sound + long ispos; //sub-sample counter (before doppler delay) + long ispos0; //L sub-sample counter + long ispos1; //R sub-sample counter + long isinc; //sub-sample increment + long ivolsc; //volume scale + long ivolsc0; //L volume scale + long ivolsc1; //R volume scale + short *coefilt; //pointer to coef (for low pass filter, etc...) +} rendersndtyp; +static rendersndtyp rendersnd[MAXPLAYINGSNDS]; +static long numrendersnd = 0; + +LPDIRECTSOUNDBUFFER streambuf = 0; +#endif +LPDIRECTSOUND dsound = 0; +#if (USEKENSOUND == 1) + + //format: (used by audplay* to cache filenames&files themselves) + //[index to next hashindex or -1][index to last filnam][ptr to snd_buf][char snd_filnam[?]\0] +#define AUDHASHINITSIZE 8192 +static char *audhashbuf = 0; +#define AUDHASHEADSIZE 256 //must be power of 2 +static long audhashead[AUDHASHEADSIZE], audhashpos, audlastloadedwav, audhashsiz; + +static point3d audiopos, audiostr, audiohei, audiofor; +static float rsamplerate; +static long lsnd[SNDSTREAMSIZ>>1], samplerate, numspeakers, bytespersample, oplaycurs = 0; +static char gshiftval = 0; +__declspec(align(16)) static short coef[NUMCOEF<= 'a') && (ch0 <= 'z')) ch0 -= 32; + ch1 = st1[i]; if ((ch1 >= 'a') && (ch1 <= 'z')) ch1 -= 32; + if (ch0 == '/') ch0 = '\\'; + if (ch1 == '/') ch1 = '\\'; + if (ch0 != ch1) return(-1); + } + if (!st1[i]) return(0); + return(-1); +} + +static long audcalchash (const char *st) +{ + long i, hashind; + char ch; + + for(i=0,hashind=0;st[i];i++) + { + ch = st[i]; + if ((ch >= 'a') && (ch <= 'z')) ch -= 32; + if (ch == '/') ch = '\\'; + hashind = (ch - hashind*3); + } + return(hashind&(AUDHASHEADSIZE-1)); +} + +static long audcheckhashsiz (long siz) +{ + long i; + + if (!audhashbuf) //Initialize hash table on first call + { + memset(audhashead,-1,sizeof(audhashead)); + if (!(audhashbuf = (char *)malloc(AUDHASHINITSIZE))) return(0); + audhashpos = 0; audlastloadedwav = -1; audhashsiz = AUDHASHINITSIZE; + } + if (audhashpos+siz > audhashsiz) //Make sure string fits in audhashbuf + { + i = audhashsiz; do { i <<= 1; } while (audhashpos+siz > i); + if (!(audhashbuf = (char *)realloc(audhashbuf,i))) return(0); + audhashsiz = i; + } + return(1); +} + +static void kensoundclose () +{ + numrendersnd = 0; + + ENTERMUTX; + if (streambuf) streambuf->Stop(); + + if (audhashbuf) + { + long i; + for(i=audlastloadedwav;i>=0;i=(*(long *)&audhashbuf[i+4])) + free((void *)(*(long *)&audhashbuf[i+8])); + free(audhashbuf); audhashbuf = 0; + } + audhashpos = audhashsiz = 0; + + if (streambuf) { streambuf->Release(); streambuf = 0; } + LEAVEMUTX; +} + +#define PI 3.14159265358979323 +static void initfilters () +{ + float f, f2, f3, f4, fcoef[NUMCOEF]; + long i, j, k, cenbias; + + //Generate polynomial filter - fewer divides algo. (See PIANO.C for derivation) + f4 = 1.0 / (float)(1<>1); + for(i=0;i<(1<CreateSoundBuffer(&bufdesc,&streambuf,0) != DS_OK) return(-1); + + //streambuf->SetVolume(curmusicvolume); + //streambuf->SetFrequency(curmusicfrequency); + //streambuf->SetPan(curmusicpan); + + //Zero out streaming buffer before beginning play + streambuf->Lock(0,SNDSTREAMSIZ,&w0,&l0,&w1,&l1,0); + if (w0) memset(w0,(bytespersample-2)&128,l0); + if (w1) memset(w1,(bytespersample-2)&128,l1); + streambuf->Unlock(w0,l0,w1,l1); + + initfilters(); + + streambuf->SetCurrentPosition(0); + streambuf->Play(0,0,DSBPLAY_LOOPING); + + return(0); +} + +static __forceinline long mulshr16 (long a, long d) +{ + _asm + { + mov eax, a + imul d + shrd eax, edx, 16 + } +} + +static __forceinline long mulshr32 (long a, long d) +{ + _asm + { + mov eax, a + imul d + mov eax, edx + } +} + + // ssnd: source sound + // ispos: sub-sample counter + // isinc: sub-sample increment per destination sample + // ivolsc: 31-bit volume scale + //ivolsci: 31-bit ivolsc increment per destination sample + // lptr: 32-bit sound pointer (step by 8 because rendersamps only renders 1 channel!) + // nsamp: number of destination samples to render +static void rendersamps (long dasnd, long ispos, long isinc, long ivolsc, long ivolsci, long *lptr, long nsamp, short *coefilt) +{ + long i, j, k; + + i = isinc*nsamp + ispos; if (i < isinc) return; //ispos < 0 for all samples! + j = *(long *)(dasnd-8); if ((ispos>>LSAMPREC) >= j) return; //ispos >= j for all samples! + //Clip off low ispos + if (ispos < 0) { k = (isinc-1-ispos)/isinc; ivolsc += ivolsci*k; ispos += isinc*k; lptr += k*2; nsamp -= k; } + if (((i-isinc)>>LSAMPREC) >= j) nsamp = ((j<>LSAMPREC],ivolsc); + ivolsc += ivolsci; ispos += isinc; lptr += 2; nsamp--; + } while (nsamp); +#elif (NUMCOEF == 2) + short *ssnd; //Fast sound rendering; ok quality + do + { + ssnd = (short *)(((ispos>>LSAMPREC)<<1)+dasnd); + lptr[0] += mulshr32((long)(((((long)ssnd[1])-((long)ssnd[0]))*(ispos&((1<>LSAMPREC)+((long)ssnd[0]),ivolsc); + ivolsc += ivolsci; ispos += isinc; lptr += 2; nsamp--; + } while (nsamp); +#elif (NUMCOEF == 4) +#if 0 + short *soef, *ssnd; //Slow sound rendering; great quality + do + { + ssnd = (short *)(((ispos>>LSAMPREC)<<1)+dasnd); + soef = &coef[((ispos&((1<>(LSAMPREC-LOGCOEFPREC))<<2]; + lptr[0] += mulshr32((long)ssnd[0]*(long)soef[0]+ + (long)ssnd[1]*(long)soef[1]+ + (long)ssnd[2]*(long)soef[2]+ + (long)ssnd[3]*(long)soef[3],ivolsc>>15); + ivolsc += ivolsci; ispos += isinc; lptr += 2; nsamp--; + } while (nsamp); +#else + + //c = &coef[l]; + //h = &ssnd[u>>LSAMPREC] + // c[3] c[2] c[1] c[0] + //*h[3] *h[2] *h[1] *h[0] + //+p[3] +p[2] +p[1] +p[0] = s1 + if (cputype&(1<<23)) //MMX + { + _asm + { + push ebx + push esi + push edi + push ebp + mov esi, ispos + mov edi, lptr + mov ecx, nsamp + lea edi, [edi+ecx*8] + neg ecx + mov edx, dasnd + mov ebx, isinc + movd mm2, ivolsc + movd mm3, ivolsci + + test cputype, 1 shl 22 + mov ebp, coefilt + jnz short srndmmp + + mov eax, 0xffff0000 + movd mm7, eax + srndmmx:mov eax, esi ;MMX loop begins here + shr esi, LSAMPREC + movq mm0, [edx+esi*2] + lea esi, [eax+ebx] + and eax, (1< 1) + *(long *)(dasnd+(numsamps<<1) ) = *(long *)(dasnd+(repstart<<1) ); + *(long *)(dasnd+(numsamps<<1)+4) = *(long *)(dasnd+(repstart<<1)+4); + + while (i-isinc >= (numsamps<GetStatus(&u); if (!(u&DSBSTATUS_LOOPING)) return; + if (streambuf->GetCurrentPosition(&playcurs,&writcurs) != DS_OK) return; + leng = ((playcurs-oplaycurs)&(SNDSTREAMSIZ-1)); if (leng < minleng) return; + i = (oplaycurs&(SNDSTREAMSIZ-1)); + if (i < ((playcurs-1)&(SNDSTREAMSIZ-1))) + memset(&lsnd[i>>1],0,leng<<1); + else + { + memset(&lsnd[i>>1],0,((-oplaycurs)&(SNDSTREAMSIZ-1))<<1); + memset(lsnd,0,(playcurs&(SNDSTREAMSIZ-1))<<1); + } + + if (!numrendersnd) + { + streambuf->Lock(i,leng,&w[0],&l[0],&w[1],&l[1],0); + if (w[0]) memset(w[0],(bytespersample-2)&128,l[0]); + if (w[1]) memset(w[1],(bytespersample-2)&128,l[1]); + streambuf->Unlock(w[0],l[0],w[1],l[1]); + } + else + { + streambuf->Lock(i,leng,&w[0],&l[0],&w[1],&l[1],0); + + lptr[0] = &lsnd[i>>1]; lptr[1] = lsnd; + for(j=numrendersnd-1;j>=0;j--) + { + if (rendersnd[j].flags&KSND_MOVE) rendersnd[j].p = *rendersnd[j].ptr; //Get new 3D position + if (rendersnd[j].flags&KSND_3D) + { + n = (signed long)(leng>>gshiftval); + + float f, g, h; + f = (rendersnd[j].p.x-audiopos.x)*(rendersnd[j].p.x-audiopos.x)+(rendersnd[j].p.y-audiopos.y)*(rendersnd[j].p.y-audiopos.y)+(rendersnd[j].p.z-audiopos.z)*(rendersnd[j].p.z-audiopos.z); + g = (rendersnd[j].p.x-audiopos.x)*audiostr.x+(rendersnd[j].p.y-audiopos.y)*audiostr.y+(rendersnd[j].p.z-audiopos.z)*audiostr.z; + if (f <= SNDMINDIST*SNDMINDIST) { f = SNDMINDIST; h = (float)rendersnd[j].ivolsc; } else { f = sqrt(f); h = ((float)rendersnd[j].ivolsc)*SNDMINDIST/f; } + g /= f; //g=-1:pure left, g=0:center, g=1:pure right + //Should use exponential scaling to keep volume constant! + volsci0 = (long)((1.f-max(g*VOLSEPARATION,0))*h); + volsci1 = (long)((1.f+min(g*VOLSEPARATION,0))*h); + volsci0 = (volsci0-rendersnd[j].ivolsc0)/n; + volsci1 = (volsci1-rendersnd[j].ivolsc1)/n; + + //ispos? = ispos + (f voxels)*(.00025sec/voxel) * (isinc*samplerate subsamples/sec); + m = rendersnd[j].isinc*samplerate; + k = rendersnd[j].isinc*n + rendersnd[j].ispos; + h = max((f-SNDMINDIST)+g*(EARSEPARATION*.5f),0); nsinc0 = k - mulshr16((long)(h*(65536.f/SNDSPEED)),m); + h = max((f-SNDMINDIST)-g*(EARSEPARATION*.5f),0); nsinc1 = k - mulshr16((long)(h*(65536.f/SNDSPEED)),m); + nsinc0 = (nsinc0-rendersnd[j].ispos0)/n; + nsinc1 = (nsinc1-rendersnd[j].ispos1)/n; + } + else + { + nsinc0 = rendersnd[j].isinc; + nsinc1 = rendersnd[j].isinc; + volsci0 = 0; + volsci1 = 0; + } + if (rendersnd[j].flags&KSND_LOOPFADE) + { + n = -(signed long)(leng>>gshiftval); + volsci0 = rendersnd[j].ivolsc0/n; + volsci1 = rendersnd[j].ivolsc1/n; + } + for(m=0;m<2;m++) + if (w[m]) + { + k = (l[m]>>gshiftval); + if (!(rendersnd[j].flags&KSND_LOOP)) + { + rendersamps(rendersnd[j].ssnd,rendersnd[j].ispos0,nsinc0,rendersnd[j].ivolsc0,volsci0,lptr[m] ,k,rendersnd[j].coefilt); + rendersamps(rendersnd[j].ssnd,rendersnd[j].ispos1,nsinc1,rendersnd[j].ivolsc1,volsci1,lptr[m]+1,k,rendersnd[j].coefilt); + rendersnd[j].ispos += rendersnd[j].isinc*k; + rendersnd[j].ispos0 += nsinc0*k; rendersnd[j].ivolsc0 += volsci0*k; + rendersnd[j].ispos1 += nsinc1*k; rendersnd[j].ivolsc1 += volsci1*k; + + //Delete sound only when both L&R channels have played through all their samples + if (((rendersnd[j].ispos0>>LSAMPREC) >= (*(long *)(rendersnd[j].ssnd-8))) && + ((rendersnd[j].ispos1>>LSAMPREC) >= (*(long *)(rendersnd[j].ssnd-8)))) + { + (*(long *)(rendersnd[j].ssnd-16))--; numrendersnd--; + if (j != numrendersnd) rendersnd[j] = rendersnd[numrendersnd]; + break; + } + } + else + { + long numsamps, repleng; + numsamps = ((*(long *)(rendersnd[j].ssnd-8))<=numsamps;n-=repleng); + rendersampsloop(rendersnd[j].ssnd,n,nsinc0,rendersnd[j].ivolsc0,volsci0,lptr[m] ,k,rendersnd[j].coefilt); + for(n=rendersnd[j].ispos1;n>=numsamps;n-=repleng); + rendersampsloop(rendersnd[j].ssnd,n,nsinc1,rendersnd[j].ivolsc1,volsci1,lptr[m]+1,k,rendersnd[j].coefilt); + rendersnd[j].ispos += rendersnd[j].isinc*k; + rendersnd[j].ispos0 += nsinc0*k; + rendersnd[j].ispos1 += nsinc1*k; + rendersnd[j].ivolsc0 += volsci0*k; + rendersnd[j].ivolsc1 += volsci1*k; + + //Hack to keep sample pointers away from the limit... + while ((rendersnd[j].ispos0 >= numsamps) && (rendersnd[j].ispos1 >= numsamps)) + { + rendersnd[j].ispos -= repleng; + rendersnd[j].ispos0 -= repleng; rendersnd[j].ispos1 -= repleng; + } + } + } + if ((m >= 2) && (rendersnd[j].flags&KSND_LOOPFADE)) //Remove looping sound after fade-out + { + (*(long *)(rendersnd[j].ssnd-16))--; numrendersnd--; + if (j != numrendersnd) rendersnd[j] = rendersnd[numrendersnd]; + } + if (cputype&(1<<23)) _asm emms //MMX + } + for(m=0;m<2;m++) if (w[m]) audclipcopy(lptr[m],(short *)w[m],l[m]>>gshiftval); + if (cputype&(1<<23)) _asm emms //MMX + streambuf->Unlock(w[0],l[0],w[1],l[1]); + } + + oplaycurs = playcurs; +} + +#if (USETHREADS != 0) +static void kensoundthread (void *_) +{ + while (!quitprogram) + { + ENTERMUTX; + kensoundbreath(SNDSTREAMSIZ>>1); //WARNING: Don't call breath() here - WaitForSingleObject will fail :/ + LEAVEMUTX; + Sleep(USETHREADS); + } + quitprogram = 2; +} +#endif + + //Returns pointer to sound data; loads file if not already loaded. +long audgetfilebufptr (const char *filnam) +{ + WAVEFORMATEX wft; + long i, j, leng, hashind, newsnd, *lptr, repstart; + char tempbuf[12], *fptr; +#ifndef USEKZ + FILE *fil; +#endif + + if (audhashbuf) + { + for(i=audhashead[audcalchash(filnam)];i>=0;i=(*(long *)&audhashbuf[i])) + if (!filnamcmp(filnam,&audhashbuf[i+12])) return(*(long *)&audhashbuf[i+8]); + } + + //Load WAV file here! + repstart = 0x80000000; + if (filnam[0] == '<') //Sound is in memory! (KSND_MEM flag) + { + unsigned long u; //Filename is in weird hex format + for(i=1,u=0;i<9;i++) u = (u<<4)+(filnam[i]&15); + fptr = (char *)u; + + memcpy(tempbuf,fptr,12); fptr += 12; + if (*(long *)&tempbuf[0] != 0x46464952) return(0); //RIFF + if (*(long *)&tempbuf[8] != 0x45564157) return(0); //WAVE + for(j=16;j;j--) + { + memcpy(tempbuf,fptr,8); fptr += 8; i = *(long *)&tempbuf[0]; leng = *(long *)&tempbuf[4]; + if (i == 0x61746164) break; //data + if (i == 0x20746d66) //fmt + { + memcpy(&wft,fptr,16); fptr += 16; + if ((wft.wFormatTag != WAVE_FORMAT_PCM) || (wft.nChannels != 1)) return(0); + if (leng == 20) { memcpy(&repstart,fptr,4); fptr += 4; } + else if (leng > 16) fptr += ((leng-16+1)&~1); + continue; + } + fptr += ((leng+1)&~1); + //if (fptr > ?eof?) return(0); //corrupt WAV files in memory aren't detected :/ + } + if ((!j) || (!leng)) return(0); + } + else + { +#ifndef USEKZ + if (!(fil = fopen(filnam,"rb"))) return(0); + fread(tempbuf,12,1,fil); + if (*(long *)&tempbuf[0] != 0x46464952) { fclose(fil); return(0); } //RIFF + if (*(long *)&tempbuf[8] != 0x45564157) { fclose(fil); return(0); } //WAVE + for(j=16;j;j--) + { + fread(&tempbuf,8,1,fil); i = *(long *)&tempbuf[0]; leng = *(long *)&tempbuf[4]; + if (i == 0x61746164) break; //data + if (i == 0x20746d66) //fmt + { + fread(&wft,16,1,fil); + if ((wft.wFormatTag != WAVE_FORMAT_PCM) || (wft.nChannels != 1)) { fclose(fil); return(0); } + if (leng == 20) fread(&repstart,4,1,fil); + else if (leng > 16) fseek(fil,(leng-16+1)&~1,SEEK_CUR); + continue; + } + fseek(fil,(leng+1)&~1,SEEK_CUR); + if (feof(fil)) { fclose(fil); return(0); } + } + if ((!j) || (!leng)) { fclose(fil); return(0); } +#else + if (!kzopen(filnam)) return(0); + kzread(tempbuf,12); + if (*(long *)&tempbuf[0] != 0x46464952) { kzclose(); return(0); } //RIFF + if (*(long *)&tempbuf[8] != 0x45564157) { kzclose(); return(0); } //WAVE + for(j=16;j;j--) + { + kzread(tempbuf,8); i = *(long *)&tempbuf[0]; leng = *(long *)&tempbuf[4]; + if (i == 0x61746164) break; //data + if (i == 0x20746d66) //fmt + { + kzread(&wft,16); + if ((wft.wFormatTag != WAVE_FORMAT_PCM) || (wft.nChannels != 1)) { kzclose(); return(0); } + if (leng == 20) kzread(&repstart,4); + else if (leng > 16) kzseek((leng-16+1)&~1,SEEK_CUR); + continue; + } + kzseek((leng+1)&~1,SEEK_CUR); + if (kzeof()) { kzclose(); return(0); } + } + if ((!j) || (!leng)) { kzclose(); return(0); } +#endif + } + + if (wft.wBitsPerSample == 16) i = leng; else i = (leng<<1); //Convert 8-bit to 16-bit + + if (filnam[0] == '<') //Sound is in memory! (KSND_MEM flag) + { + if (!(newsnd = (long)malloc(16+i+8))) return(0); + memcpy((void *)(newsnd+16),fptr,leng); + } + else + { +#ifndef USEKZ + if (!(newsnd = (long)malloc(16+i+8))) { fclose(fil); return(0); } + fread((void *)(newsnd+16),leng,1,fil); + fclose(fil); +#else + if (!(newsnd = (long)malloc(16+i+8))) { kzclose(); return(0); } + kzread((void *)(newsnd+16),leng); + kzclose(); +#endif + } + + if (wft.wBitsPerSample == 8) //Convert 8-bit to 16-bit + { + j = newsnd+16; + for(i=leng-1;i>=0;i--) (*(short *)((i<<1)+j)) = (((short)((*(signed char *)(i+j))-128))<<8); + wft.wBitsPerSample = 16; leng <<= 1; + } + *(long *)(newsnd) = 0; //Allocation count + *(long *)(newsnd+4) = repstart; //Loop repeat start sample + *(long *)(newsnd+8) = (leng>>1); // /((wft.wBitsPerSample>>3)*wft.nChannels); //numsamples + *(float *)(newsnd+12) = (float)(wft.nSamplesPerSec<GetStatus(&u); if (!(u&DSBSTATUS_LOOPING)) { LEAVEMUTX; return; } + + if (flags&KSND_MEM) + { + char tempbuf[10]; //Convert to ASCII string so filnamcmp()&audcalchash() works right + tempbuf[9] = 0; u = (unsigned long)filnam; + for(i=8;i>0;i--) { tempbuf[i] = (u&15)+64; u >>= 4; } + tempbuf[0] = '<'; //This invalid filename char tells audgetfilebufptr it's KSND_MEM + if (!(newsnd = audgetfilebufptr(tempbuf))) { LEAVEMUTX; return; } + } + else + { + if (!(newsnd = audgetfilebufptr(filnam))) { LEAVEMUTX; return; } + } + newsnd += 16; + + ispos = 0; isinc = (long)((*(float *)(newsnd-4))*frqmul*rsamplerate); + ivolsc = (volperc<<15)/100; if (ivolsc >= 32768) ivolsc = 32767; ivolsc <<= 16; + + if (!pos) flags &= ~(KSND_3D|KSND_MOVE); //null pointers not allowed for 3D sound + if (flags&KSND_MOVE) flags |= KSND_3D; //moving sound must be 3D sound + if ((flags&KSND_LOOP) && ((*(long *)(newsnd-12)) == 0x80000000)) + flags &= ~KSND_LOOP; //WAV must support looping to allow looping + + if (!(flags&KSND_LOPASS)) coefilt = coef; else coefilt = coeflopass; + + if (flags&KSND_3D) + { + f = (((point3d *)pos)->x-audiopos.x)*(((point3d *)pos)->x-audiopos.x)+(((point3d *)pos)->y-audiopos.y)*(((point3d *)pos)->y-audiopos.y)+(((point3d *)pos)->z-audiopos.z)*(((point3d *)pos)->z-audiopos.z); + g = (((point3d *)pos)->x-audiopos.x)*audiostr.x+(((point3d *)pos)->y-audiopos.y)*audiostr.y+(((point3d *)pos)->z-audiopos.z)*audiostr.z; + if (f <= SNDMINDIST*SNDMINDIST) { f = SNDMINDIST; h = (float)ivolsc; } else { f = sqrt(f); h = ((float)ivolsc)*SNDMINDIST/f; } + g /= f; //g=-1:pure left, g=0:center, g=1:pure right + //Should use exponential scaling to keep volume constant! + ivolsc0 = (long)((1.f-max(g*VOLSEPARATION,0))*h); + ivolsc1 = (long)((1.f+min(g*VOLSEPARATION,0))*h); + //ispos? = ispos + (f voxels)*(.00025sec/voxel) * (isinc*samplerate subsamples/sec); + m = isinc*samplerate; + h = max((f-SNDMINDIST)+g*(EARSEPARATION*.5f),0); ispos0 = -mulshr16((long)(h*(65536.f/SNDSPEED)),m); + h = max((f-SNDMINDIST)-g*(EARSEPARATION*.5f),0); ispos1 = -mulshr16((long)(h*(65536.f/SNDSPEED)),m); + } + else { ispos0 = ispos1 = 0; ivolsc0 = ivolsc1 = ivolsc; } + + kensoundbreath(SNDSTREAMSIZ>>1); //Not necessary, but for good luck + if (streambuf->GetCurrentPosition(&playcurs,&writcurs) != DS_OK) { LEAVEMUTX; return; } + //If you use playcurs instead of writcurs, beginning of sound gets cut off :/ + //on WinXP: ((writcurs-playcurs)&(SNDSTREAMSIZ-1)) ranges from 6880 to 8820 (step 4) + i = (writcurs&(SNDSTREAMSIZ-1)); + if (streambuf->Lock(i,(oplaycurs-i)&(SNDSTREAMSIZ-1),&w[0],&l[0],&w[1],&l[1],0) != DS_OK) { LEAVEMUTX; return; } + lptr[0] = &lsnd[i>>1]; lptr[1] = lsnd; + for(m=0;m<2;m++) + if (w[m]) + { + j = (l[m]>>gshiftval); + if (!(flags&KSND_LOOP)) + { + rendersamps(newsnd,ispos0,isinc,ivolsc0,0,lptr[m] ,j,coefilt); + rendersamps(newsnd,ispos1,isinc,ivolsc1,0,lptr[m]+1,j,coefilt); + j *= isinc; ispos += j; ispos0 += j; ispos1 += j; + } + else + { + long numsamps, repleng, n; + numsamps = ((*(long *)(newsnd-8))<=numsamps;n-=repleng); + rendersampsloop(newsnd,n,isinc,ivolsc0,0,lptr[m] ,j,coefilt); + for(n=ispos1;n>=numsamps;n-=repleng); + rendersampsloop(newsnd,n,isinc,ivolsc1,0,lptr[m]+1,j,coefilt); + j *= isinc; ispos += j; ispos0 += j; ispos1 += j; + + //Hack to keep sample pointers away from the limit... + while ((ispos0 >= numsamps) && (ispos1 >= numsamps)) + { ispos -= repleng; ispos0 -= repleng; ispos1 -= repleng; } + } + } + for(m=0;m<2;m++) if (w[m]) audclipcopy(lptr[m],(short *)w[m],l[m]>>gshiftval); + if (cputype&(1<<23)) _asm emms //MMX + streambuf->Unlock(w[0],l[0],w[1],l[1]); + + //Save params to continue playing later (when both L&R channels haven't played through) + numsamps = *(long *)(newsnd-8); + if ((((ispos0>>LSAMPREC) < numsamps) || ((ispos1>>LSAMPREC) < numsamps) || (flags&KSND_LOOP)) && (numrendersnd < MAXPLAYINGSNDS)) + { + rendersnd[numrendersnd].ptr = (point3d *)pos; + if (flags&KSND_3D) rendersnd[numrendersnd].p = *((point3d *)pos); + else { rendersnd[numrendersnd].p.x = rendersnd[numrendersnd].p.y = rendersnd[numrendersnd].p.z = 0; } + rendersnd[numrendersnd].flags = flags; + rendersnd[numrendersnd].ssnd = newsnd; + rendersnd[numrendersnd].ispos = ispos; + rendersnd[numrendersnd].ispos0 = ispos0; + rendersnd[numrendersnd].ispos1 = ispos1; + rendersnd[numrendersnd].isinc = isinc; + rendersnd[numrendersnd].ivolsc = ivolsc; + rendersnd[numrendersnd].ivolsc0 = ivolsc0; + rendersnd[numrendersnd].ivolsc1 = ivolsc1; + rendersnd[numrendersnd].coefilt = coefilt; + numrendersnd++; + (*(long *)(newsnd-16))++; + } + + LEAVEMUTX; +} + + //Use this function to update a pointer location (if you need to move things around in memory) + //special cases: if (optr== 0) changes all pointers + // if (nptr== 0) changes KSND_MOVE to KSND_3D + // if (nptr==-1) changes KSND_MOVE to KSND_3D and stops sound (using KSND_LOOPFADE) + //examples: playsoundupdate(&spr[delete_me].p,&spr[--numspr].p); //update pointer location + // playsoundupdate(&spr[just_before_respawn],0); //stop position updates from pointer + // playsoundupdate(&my_looping_sound,(point3d *)-1); //turn off a looping sound + // playsoundupdate(0,0); //stop all position updates + // playsoundupdate(0,(point3d *)-1); //turn off all sounds +void playsoundupdate (void *optr, void *nptr) +{ + long i; + + if (!dsound) return; + ENTERMUTX; + for(i=numrendersnd-1;i>=0;i--) + { + if ((rendersnd[i].ptr != (point3d *)optr) && (optr)) continue; + if (((long)nptr) == -2) { rendersnd[i].flags |= KSND_LOPASS; rendersnd[i].coefilt = coeflopass; continue; } + if (((long)nptr) == -3) { rendersnd[i].flags &= ~KSND_LOPASS; rendersnd[i].coefilt = coef; continue; } + rendersnd[i].ptr = (point3d *)nptr; + if (!((((long)nptr)+1)&~1)) + { + rendersnd[i].flags &= ~KSND_MOVE; //nptr == {0,-1} + if (nptr) rendersnd[i].flags |= KSND_LOOPFADE; //nptr == {-1} + } + } + LEAVEMUTX; +} + +#endif +// Kensound code ends --------------------------------------------------------- + +// DirectSound variables & code ---------------------------------------------- + +#ifdef DSOUNDINITCOM +static HRESULT coinit; +#endif + +#define MAXSOUNDS 256 +LPDIRECTSOUNDBUFFER dsprim = 0; +#if (USEKENSOUND == 2) +LPDIRECTSOUNDBUFFER dsbuf[MAXSOUNDS]; +LPDIRECTSOUND3DBUFFER ds3dbuf[MAXSOUNDS]; +LPDIRECTSOUND3DLISTENER ds3dlis = 0; +static long sndindex = -1; +#endif +static long globvolume = 100; + + //0=-10000,1-100=CINT(log10(z/100)*1000) +signed short volperc2db100[104] = +{ + -10000,-2000,-1699,-1523,-1398,-1301,-1222,-1155,-1097,-1046, // 0 to 9 + -1000, -959, -921, -886, -854, -824, -796, -770, -745, -721, //10 to 19 + -699, -678, -658, -638, -620, -602, -585, -569, -553, -538, //20 to 29 + -523, -509, -495, -481, -469, -456, -444, -432, -420, -409, //30 to 39 + -398, -387, -377, -367, -357, -347, -337, -328, -319, -310, //40 to 49 + -301, -292, -284, -276, -268, -260, -252, -244, -237, -229, //50 to 59 + -222, -215, -208, -201, -194, -187, -180, -174, -167, -161, //60 to 69 + -155, -149, -143, -137, -131, -125, -119, -114, -108, -102, //70 to 79 + -97, -92, -86, -81, -76, -71, -66, -60, -56, -51, //80 to 89 + -46, -41, -36, -32, -27, -22, -18, -13, -9, -4, //90 to 99 + 0, //100 +}; + +void setvolume (long percentmax) +{ + if (!dsprim) return; + globvolume = min(max(percentmax,0),100); + dsprim->SetVolume(volperc2db100[globvolume]); +} + +void uninitdirectsound () +{ + long i; + + if (!dsound) return; +#if (USEKENSOUND == 1) + kensoundclose(); +#endif + +#if (USEKENSOUND == 2) + for(i=MAXSOUNDS-1;i>=0;i--) + if (ds3dbuf[i]) { ds3dbuf[i]->Release(); ds3dbuf[i] = 0; } + if (ds3dlis) { ds3dlis->Release(); ds3dlis = 0; } + for(i=MAXSOUNDS-1;i>=0;i--) + if (dsbuf[i]) { dsbuf[i]->Release(); dsbuf[i] = 0; } +#endif + dsound->Release(); dsound = 0; +} + +void initdirectsound () +{ + DSBUFFERDESC dsbdesc; + long i; + + if (dsound) uninitdirectsound(); + +#if (USEKENSOUND == 2) + for(i=0;iInitialize(NULL); + //dsrval = IDirectSound_Initialize(dsound,NULL); + //(dsound)->Release(lpds); + if (dsrval != S_OK) { dsound = NULL; return; } + } + } +#else + if (DirectSoundCreate(0,&dsound,0) != DS_OK) { MessageBox(ghwnd,"DirectSoundCreate","ERROR",MB_OK); exit(0); } +#endif + if (dsound->SetCooperativeLevel(ghwnd,DSSCL_PRIORITY) != DS_OK) { MessageBox(ghwnd,"SetCooperativeLevel","ERROR",MB_OK); exit(0); } + + //Create primary buffer + dsbdesc.dwSize = sizeof(DSBUFFERDESC); + dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; +#if (USEKENSOUND == 2) + dsbdesc.dwFlags |= DSBCAPS_CTRL3D|DSBCAPS_CTRLVOLUME; +#endif + dsbdesc.dwBufferBytes = 0; //0 for primary + dsbdesc.dwReserved = 0; + dsbdesc.lpwfxFormat = 0; //0 for primary + if (dsound->CreateSoundBuffer(&dsbdesc,&dsprim,0) < 0) + { dsound->Release(); MessageBox(ghwnd,"CreateSoundBuffer (primary) failed","ERROR",MB_OK); exit(0); } + + dsprim->Play(0,0,DSBPLAY_LOOPING); //Force mixer to always be on + +#if (USEKENSOUND == 2) + //Default listener orientation: + // <1,0,0>: right + // <0,1,0>: up + // <0,0,1>: front + //Initialize 3D sound + if (dsprim->QueryInterface(IID_IDirectSound3DListener,(void **)&ds3dlis) != S_OK) + { dsound->Release(); MessageBox(ghwnd,"Query...Listener failed","ERROR",MB_OK); exit(0); } + ds3dlis->SetDistanceFactor(.03,DS3D_DEFERRED); //1 (meters/unit) + ds3dlis->SetRolloffFactor(.03,DS3D_DEFERRED); //1 + ds3dlis->SetDopplerFactor(1,DS3D_DEFERRED); //1 + ds3dlis->SetPosition(0,0,0,DS3D_DEFERRED); //0,0,0 + ds3dlis->SetVelocity(0,0,0,DS3D_DEFERRED); //0,0,0 + ds3dlis->SetOrientation(0,0,1,0,1,0,DS3D_DEFERRED); //0,0,1,0,1,0 + ds3dlis->CommitDeferredSettings(); +#endif + + if (globvolume != 100) dsprim->SetVolume(globvolume); + +#if (USEKENSOUND == 1) + kensoundinit(dsound,44100,2,2); //last line +#endif +} + +#if (USEKENSOUND == 2) + +#define MINSNDLENG 4096 //is 1764 min size? too bad it fails sometimes :/ 1764*25 = 44100 +long loadwav (LPDIRECTSOUNDBUFFER *dabuf, const char *fnam, float freqmul, unsigned long daflags) +{ + WAVEFORMATEX wft; + DSBUFFERDESC bufdesc; + void *w0, *w1; + unsigned long l0, l1, leng; + char tempbuf[12]; + +#ifndef USEKZ + FILE *fil; + if (!(fil = fopen(fnam,"rb"))) return(0); + fread(tempbuf,12,1,fil); + if (*(long *)&tempbuf[0] != 0x46464952) { fclose(fil); return(0); } //RIFF + if (*(long *)&tempbuf[8] != 0x45564157) { fclose(fil); return(0); } //WAVE + for(l1=16;l1;l1--) + { + fread(&tempbuf,8,1,fil); l0 = *(long *)&tempbuf[0]; leng = *(long *)&tempbuf[4]; + if (l0 == 0x61746164) break; //data + if (l0 == 0x20746d66) //fmt + { + fread(&wft,16,1,fil); + //if ((wft.wFormatTag != WAVE_FORMAT_PCM) || (wft.nChannels != 1)) { fclose(fil); return(0); } + if (leng > 16) fseek(fil,(leng-16+1)&~1,SEEK_CUR); + continue; + } + fseek(fil,(leng+1)&~1,SEEK_CUR); + if (feof(fil)) { fclose(fil); return(0); } + } + if (!l1) { fclose(fil); return(0); } +#else + if (!kzopen(fnam)) return(0); + kzread(tempbuf,12); + if (*(long *)&tempbuf[0] != 0x46464952) { kzclose(); return(0); } //RIFF + if (*(long *)&tempbuf[8] != 0x45564157) { kzclose(); return(0); } //WAVE + for(l1=16;l1;l1--) + { + kzread(tempbuf,8); l0 = *(long *)&tempbuf[0]; leng = *(long *)&tempbuf[4]; + if (l0 == 0x61746164) break; //data + if (l0 == 0x20746d66) //fmt + { + kzread(&wft,16); + //if ((wft.wFormatTag != WAVE_FORMAT_PCM) || (wft.nChannels != 1)) { kzclose(); return(0); } + if (leng > 16) kzseek((leng-16+1)&~1,SEEK_CUR); + continue; + } + kzseek((leng+1)&~1,SEEK_CUR); + if (kzeof()) { kzclose(); return(0); } + } + if (!l1) { kzclose(); return(0); } +#endif + + if (*(long *)&freqmul != 0x3f800000) + { + wft.nSamplesPerSec = (long)((float)wft.nSamplesPerSec * freqmul); + wft.nAvgBytesPerSec = wft.nSamplesPerSec * wft.nBlockAlign; + } + wft.cbSize = 0; + + bufdesc.dwSize = sizeof(DSBUFFERDESC); + bufdesc.dwFlags = daflags; + bufdesc.dwBufferBytes = max(leng,MINSNDLENG); + bufdesc.dwReserved = 0; + bufdesc.lpwfxFormat = &wft; + //bufdesc.guid3DAlgorithm = GUID_NULL; +#ifndef USEKZ + if (dsound->CreateSoundBuffer(&bufdesc,dabuf,0) != DS_OK) + { fclose(fil); return(0); } + //write wave data to directsound buffer you just created + if (((*dabuf)->Lock(0,leng,&w0,&l0,&w1,&l1,0)) == DSERR_BUFFERLOST) { fclose(fil); return(0); } + if (w0) fread(w0,l0,1,fil); + if (w1) fread(w1,l1,1,fil); + (*dabuf)->Unlock(w0,l0,w1,l1); + fclose(fil); +#else + if (dsound->CreateSoundBuffer(&bufdesc,dabuf,0) != DS_OK) + { kzclose(); return(0); } + //write wave data to directsound buffer you just created + (*dabuf)->Lock(0,leng,&w0,&l0,&w1,&l1,0); + if (w0) kzread(w0,l0); + if (w1) kzread(w1,l1); + (*dabuf)->Unlock(w0,l0,w1,l1); + kzclose(); +#endif + + //This hack is because DSOUND seems to have problems with very short secondary buffers! + if (leng < MINSNDLENG) + { + if (((*dabuf)->Lock(leng,MINSNDLENG-leng,&w0,&l0,&w1,&l1,0)) == DSERR_BUFFERLOST) return(0); + if (w0) memset(w0,(wft.wBitsPerSample==8)<<7,l0); + if (w1) memset(w1,(wft.wBitsPerSample==8)<<7,l1); + (*dabuf)->Unlock(w0,l0,w1,l1); + } + + return(1); +} + +void setears3d (float iposx, float iposy, float iposz, + float iforx, float ifory, float iforz, + float iheix, float iheiy, float iheiz) +{ + if (!ds3dlis) return; + ds3dlis->SetPosition(iposx,iposy,iposz,DS3D_DEFERRED); + ds3dlis->SetOrientation(iforx,ifory,iforz,iheix,iheiy,iheiz,DS3D_DEFERRED); //0,0,1,0,1,0 + ds3dlis->CommitDeferredSettings(); +} + +long reallyuglyandslowhack4sound () +{ + long i; + unsigned long u; + + sndindex++; + + i = (sndindex&(MAXSOUNDS-1)); + if (ds3dbuf[i]) { ds3dbuf[i]->Release(); ds3dbuf[i] = 0; } + if (dsbuf[i]) { dsbuf[i]->Release(); dsbuf[i] = 0; } + + for(i=0;iGetStatus(&u); + if (!(u&DSBSTATUS_PLAYING)) + { + if (ds3dbuf[i]) { ds3dbuf[i]->Release(); ds3dbuf[i] = 0; } + if (dsbuf[i]) { dsbuf[i]->Release(); dsbuf[i] = 0; } + } + } + return(sndindex&(MAXSOUNDS-1)); +} + +void playsound (const char *filnam, long volperc, float freqmul) +{ + unsigned long u, cnt; + long i; + + if (!dsound) return; + i = reallyuglyandslowhack4sound(); + + if ((!dsound) || ((unsigned long)i >= MAXSOUNDS)) return; + for(cnt=2;cnt;cnt--) + { + if (!dsbuf[i]) if (!loadwav(&dsbuf[i],filnam,freqmul,(((volperc-100)>>31)&DSBCAPS_CTRLVOLUME)|DSBCAPS_STATIC)) return; + dsbuf[i]->GetStatus(&u); if (u&DSBSTATUS_PLAYING) return; + if (volperc < 100) dsbuf[i]->SetVolume(volperc2db100[max(volperc,0)]); + dsbuf[i]->SetCurrentPosition(0); + if (dsbuf[i]->Play(0,0,0) != DSERR_BUFFERLOST) return; + dsbuf[i]->Release(); dsbuf[i] = 0; + } +} + +void playsound (const char *filnam, long volperc, float freqmul, void *pos, long flags) +{ + unsigned long u, cnt; + long i; + + if (!dsound) return; + if (!(flags&1)) { playsound(filnam,volperc,freqmul); return; } + + i = reallyuglyandslowhack4sound(); + + if ((!dsound) || ((unsigned long)i >= MAXSOUNDS)) return; + for(cnt=2;cnt;cnt--) + { + if (!dsbuf[i]) + { + if (!loadwav(&dsbuf[i],filnam,freqmul,(((volperc-100)>>31)&DSBCAPS_CTRLVOLUME)| + DSBCAPS_CTRL3D|DSBCAPS_STATIC|DSBCAPS_MUTE3DATMAXDISTANCE)) return; + if (ds3dbuf[i]) { ds3dbuf[i]->Release(); ds3dbuf[i] = 0; } + dsbuf[i]->QueryInterface(IID_IDirectSound3DBuffer,(void **)&ds3dbuf[i]); + ds3dbuf[i]->SetMode(DS3DMODE_NORMAL,DS3D_DEFERRED); //DS3DMODE_NORMAL + //ds3dbuf[i]->SetMaxDistance(1000000000,DS3D_DEFERRED); //1000000000 + //ds3dbuf[i]->SetMinDistance(1,DS3D_DEFERRED); //1 + ds3dbuf[i]->SetPosition(((point3d *)pos)->x,((point3d *)pos)->y,((point3d *)pos)->z,DS3D_DEFERRED); //0,0,0 + //ds3dbuf[i]->SetVelocity(0,0,0,DS3D_DEFERRED); //0,0,0 + //ds3dbuf[i]->SetConeAngles(0,360,DS3D_DEFERRED); //0,360 + //ds3dbuf[i]->SetConeOrientation(0,0,0,DS3D_DEFERRED); //0,0,0 + //ds3dbuf[i]->SetConeOutsideVolume(DSBVOLUME_MAX,DS3D_DEFERRED); //DSBVOLUME_MAX + ds3dlis->CommitDeferredSettings(); + } + else + { + ds3dbuf[i]->SetPosition(((point3d *)pos)->x,((point3d *)pos)->y,((point3d *)pos)->z,DS3D_IMMEDIATE); + } + dsbuf[i]->GetStatus(&u); if (u&DSBSTATUS_PLAYING) return; + if (volperc < 100) dsbuf[i]->SetVolume(volperc2db100[max(volperc,0)]); + dsbuf[i]->SetCurrentPosition(0); + if (dsbuf[i]->Play(0,0,0) != DSERR_BUFFERLOST) return; + if (ds3dbuf[i]) { ds3dbuf[i]->Release(); ds3dbuf[i] = 0; } + if (dsbuf[i]) { dsbuf[i]->Release(); dsbuf[i] = 0; } + } +} + +void playsoundupdate (void *oposptr, void *nposptr) +{ + //if (!nptr) follow = 0 +} + +#endif +#endif + +//Quitting routines ---------------------------------------------------------- + +long (*catchwmclose)() = 0; +void quitloop () { PostMessage(ghwnd,WM_CLOSE,0,0); } + +void evilquit (const char *str) //Evil because this function makes awful assumptions!!! +{ +#ifndef NODRAW + stopdirectdraw(); + ddflip2gdi(); +#endif + if (str) MessageBox(ghwnd,str,"fatal error!",MB_OK); +#ifndef NOINPUT + uninitmouse(); + uninitkeyboard(); + uninitdirectinput(); +#endif +#ifndef NOSOUND + uninitdirectsound(); +#endif +#ifndef NODRAW + uninitdirectdraw(); +#endif + uninitapp(); + ExitProcess(0); +} + +//GENERAL WINDOWS CODE------------------------------------------------------------------- + +void setalwaysactive (long active) { alwaysactive = active; } + +#ifndef NODRAW +long canrender () { return(ActiveApp); } +#endif + +#ifndef NOINPUT +void setacquire (long mouse, long kbd) +{ + if (mouse_acquire != mouse) + { + if (ActiveApp && gpMouse) { if (mouse) { gpMouse->Acquire(); gbstatus = 0; } else gpMouse->Unacquire(); } + mouse_acquire = mouse; + } + if (kbd_acquire != kbd) + { + if (ActiveApp && gpKeyboard) { if (kbd) { gpKeyboard->Acquire(); shkeystatus = 0; } else gpKeyboard->Unacquire(); } + kbd_acquire = kbd; + } +} +void setmouseout (void (*in)(long,long), long x, long y) +{ + if (fullscreen) return; + setmousein = in; + setacquire(0, kbd_acquire); + + POINT topLeft; + topLeft.x = 0; topLeft.y = 0; + ClientToScreen(ghwnd, &topLeft); + SetCursorPos(topLeft.x + x, topLeft.y + y); +} + + //Use fancy clipper to determine if mouse cursor (x,y) is outside the window + //Note: x,y is relative to top-left corner of ghwnd +long ismouseout (long x, long y) +{ + if (fullscreen) return(0); +#ifndef NO_CLIPPER + //unsigned long siz; + + //ddclip->GetClipList(0,0,&siz); + //if (siz > ddcliprdbytes) + //{ + // ddcliprdbytes = siz; + // ddcliprd = (RGNDATA *)realloc(ddcliprd,siz); + //} +#ifndef NODRAW + if (ddcliprd) + { + POINT abspos; + RECT *r; + long j; + //ddclip->GetClipList(0,ddcliprd,&siz); + + abspos.x = x; abspos.y = y; + ClientToScreen(ghwnd,&abspos); + + r = (RECT *)ddcliprd->Buffer; + for(j=0;j<(long)ddcliprd->rdh.nCount;j++) + { + if ((abspos.x >= r[j].left) && (abspos.x < r[j].right) && + (abspos.y >= r[j].top) && (abspos.y < r[j].bottom)) + return(0); + } + return(1); + } +#endif +#endif + return(((unsigned long)x >= (unsigned long)xres) || ((unsigned long)y >= (unsigned long)yres)); +} + +#endif + +long (CALLBACK *peekwindowproc)(HWND,UINT,WPARAM,LPARAM) = 0; +long CALLBACK WindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + // mouse pos: + static long omx, omy; + long mx, my; + + if (peekwindowproc) { mx = peekwindowproc(hwnd,msg,wParam,lParam); if (mx >= 0) return(mx); } + switch (msg) + { + case WM_SYSCOMMAND: + if ((wParam == SC_KEYMENU) || (wParam == SC_HOTKEY)) return(0); + break; + case WM_ACTIVATEAPP: + ActiveApp = (BOOL)wParam; //!((BOOL)HIWORD(wParam)); + shkeystatus = 0; +#ifndef NOINPUT + gkillbstatus = 1; +#endif + break; + + case WM_ACTIVATE: + //ActiveApp = LOWORD(wParam); //((wParam&65535) != WA_INACTIVE); +#ifndef NOINPUT + if (gpMouse) { if (ActiveApp && mouse_acquire) { gpMouse->Acquire(); gbstatus = 0; } else gpMouse->Unacquire(); } + if (gpKeyboard) { if (ActiveApp && kbd_acquire) { gpKeyboard->Acquire(); shkeystatus = 0; } else gpKeyboard->Unacquire(); } +#endif +#ifndef NODRAW + if ((!fullscreen) && (ActiveApp) && (ddpal) && (ddsurf[0])) + { + if (ddsurf[0]->IsLost() == DDERR_SURFACELOST) ddsurf[0]->Restore(); + ddsurf[0]->SetPalette(ddpal); + updatepalette(0,256); + } + InvalidateRect(hwnd,0,1); +#endif + break; + case WM_PAINT: +#ifndef NODRAW + if (!fullscreen) nextpage(); +#endif + break; + + case WM_SIZE: + gncmdshow = wParam; + if (wParam == SIZE_MAXHIDE) + ActiveApp = 0; + else if (wParam == SIZE_MINIMIZED) + ActiveApp = 0; + else + { + ActiveApp = 1; +#ifndef NODRAW +#ifndef ZOOM_TEST + if ((!fullscreen) && (ddsurf[1])) + { + long oxres = xres, oyres = yres; + xres = LOWORD(lParam); yres = HIWORD(lParam); + + if (ddsurf[1]) { ddsurf[1]->Release(); ddsurf[1] = 0; } + + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + ddsd.dwWidth = xres; + ddsd.dwHeight = yres; + lpdd->CreateSurface(&ddsd,&ddsurf[1],0); + + if (ddrawemulbuf) + { + long i, x, y, ye, pw, pr; + + i = ((colbits+7)>>3)*xres; + if (i < ddrawemulbpl) + { + pw = pr = ((long)ddrawemulbuf); ye = min(yres,oyres); + for(y=1;y>3)+16); + if (!ddrawemulbuf) + { + xres = oxres; yres = oyres; //oops :/ + ddrawemulbuf = realloc(ddrawemulbuf,((xres*yres+7)&~7)*((colbits+7)>>3)+16); + i = ddrawemulbpl; + } + + if (i > ddrawemulbpl) + { + pw = yres*i + ((long)ddrawemulbuf); + pr = yres*ddrawemulbpl + ((long)ddrawemulbuf); + for(y=yres-1;y>=0;y--) + { + pw -= i; pr -= ddrawemulbpl; + for(x=i-1;x>=ddrawemulbpl;x--) *(char *)(pw+x) = 0; + for(;x>=0;x--) *(char *)(pw+x) = *(char *)(pr+x); + } + } + if (yres > oyres) memset((void *)(oyres*i+((long)ddrawemulbuf)),0,(yres-oyres)*i); + + ddrawemulbpl = i; + } + } +#endif +#endif + } +#ifndef NOINPUT + if (gpMouse) { if (ActiveApp && mouse_acquire) { gpMouse->Acquire(); gbstatus = 0; } else gpMouse->Unacquire(); } + if (gpKeyboard) { if (ActiveApp && kbd_acquire) { gpKeyboard->Acquire(); shkeystatus = 0; } else gpKeyboard->Unacquire(); } +#endif + break; + case WM_KEYDOWN: +#ifdef NOINPUT + keystatus[((lParam>>16)&127)+((lParam>>17)&128)] = 1; +#endif + case WM_SYSKEYDOWN: + if ((wParam&0xff) == 0xff) break; //Fixes SHIFT+[ext key] on XP + switch (lParam&0x17f0000) + { + case 0x02a0000: shkeystatus |= (1<<16); break; //0x2a + case 0x0360000: shkeystatus |= (1<<17); break; //0x36 + case 0x01d0000: shkeystatus |= (1<<18); break; //0x1d + case 0x11d0000: shkeystatus |= (1<<19); break; //0x9d + case 0x0380000: shkeystatus |= (1<<20); break; //0x38 + case 0x1380000: shkeystatus |= (1<<21); break; //0xb8 + default: + { + long i = ((keybufw2+1)&(KEYBUFSIZ-1)); + keybuf[keybufw2&(KEYBUFSIZ-1)] = (((lParam>>8)&0x7f00)+((lParam>>9)&0x8000))+shkeystatus; + if (i != keybufr) keybufw2 = i; //prevent fifo overlap + } + } + return(0); + case WM_KEYUP: +#ifdef NOINPUT + keystatus[((lParam>>16)&127)+((lParam>>17)&128)] = 0; +#endif + case WM_SYSKEYUP: + if ((wParam&0xff) == 0xff) break; //Fixes SHIFT+[ext key] on XP + switch (lParam&0x17f0000) + { + case 0x02a0000: shkeystatus &= ~(3<<16); break; //0x2a + case 0x0360000: shkeystatus &= ~(3<<16); break; //0x36 + case 0x01d0000: shkeystatus &= ~(1<<18); break; //0x1d + case 0x11d0000: shkeystatus &= ~(1<<19); break; //0x9d + case 0x0380000: shkeystatus &= ~(1<<20); break; //0x38 + case 0x1380000: shkeystatus &= ~(1<<21); break; //0xb8 + } + return(0); + case WM_CHAR: + if (keybufw2 != keybufr) //stick ASCII code in last FIFO value + keybuf[(keybufw2-1)&(KEYBUFSIZ-1)] |= (wParam&255); + return(0); + case WM_MOUSEWHEEL: + mx = (signed short)HIWORD(wParam); + if (mx > 0) ext_mbstatus[6] = 2; + else if (mx < 0) ext_mbstatus[7] = 2; + ext_mwheel = min(max(ext_mwheel+mx,(unsigned long)(1<<16)-(unsigned long)(1<<31)),(unsigned long)(1<<31)-(unsigned long)(1<<16)); + + break; +#ifndef NOINPUT + case WM_MOUSEMOVE: + mx = LOWORD(lParam); + my = HIWORD(lParam); + if (gpMouse && ActiveApp && setmousein) { + mouse_acquire = 1; + gpMouse->Acquire(); gbstatus = 0; + setmousein(mx, my); + setmousein = NULL; + } + break; +#endif + case WM_LBUTTONDOWN: if (!mouse_acquire) ext_mbstatus[0] = 1|2; break; + case WM_LBUTTONUP: if (!mouse_acquire) ext_mbstatus[0] &= ~2; break; + case WM_RBUTTONDOWN: if (!mouse_acquire) ext_mbstatus[1] = 1|2; break; + case WM_RBUTTONUP: if (!mouse_acquire) ext_mbstatus[1] &= ~2; break; +#ifndef NODRAW + case WM_ERASEBKGND: return(1); //flicker bug? + case WM_NCPAINT: if (fullscreen) return(0); break; //don't redraw window frame - flicker bug? +#endif + case WM_CLOSE: + if (catchwmclose) { if (!catchwmclose()) return(1); } + + //FYI: Application terminates in this order: + //if (keystatus[1]) Post(WM_CLOSE) //Located inside doframe + //WM_CLOSE: uninitdirect* //WARNING: must be before DestroyWindow! + // DestroyWindow! + // Post(WM_DESTROY) + //WM_DESTROY: Post(WM_QUIT) + //WM_QUIT: quitprogram = 1; + //if (quitprogram) exit(); +#ifndef NOINPUT + uninitmouse(); + uninitkeyboard(); + uninitdirectinput(); +#endif +#ifndef NOSOUND + uninitdirectsound(); +#endif +#ifndef NODRAW + uninitdirectdraw(); +#endif + uninitapp(); + break; + case WM_COMMAND: + { + // from a menu + if(HIWORD(wParam) == 0 && MenuFunc != NULL) + { + MenuFunc(LOWORD(wParam), (HANDLE)lParam); + } + break; + } + case WM_DESTROY: + //Does this remove taskbar icon? + UnregisterClass(wc.lpszClassName,ghinst); + PostQuitMessage(0); + return(0); + default: break; + } + return(DefWindowProc(hwnd,msg,wParam,lParam)); +} + +long keyread () +{ + long i; + + if (keybufr == keybufw) return(0); + i = keybuf[keybufr]; keybufr = ((keybufr+1)&(KEYBUFSIZ-1)); +#if 0 //defined(_DEBUG) && !defined(NODRAW) + if (((i>>8)&255) == 0x2e && (i&(3<<18))) { // && (i&(3<<20))) { + debugdirectdraw(); + if (ddrawdebugmode != -1) __asm { int 3 }; + } +#endif + return(i); +} + +void breath () +{ + MSG msg; + while (PeekMessage(&msg,0,0,0,PM_REMOVE)) //&msg,ghwnd, |PM_NOYIELD? + { + if (msg.message == WM_QUIT) { quitprogram = 1; quitparam = msg.wParam; return; } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + keybufw = keybufw2; // to be safe with multithreads + +#ifndef NOSOUND +#if (USEKENSOUND == 1) + ENTERMUTX; + kensoundbreath(MINBREATHREND); + LEAVEMUTX; + umixerbreathe(); +#endif +#endif +} + + //10/20/2004: this code is useless now that quotes are automatically stripped off properly in WinMain() + //Call like this: arg2filename(argv[1],".ksm",curfilename); + //Make sure curfilename length is long enough! +void arg2filename (const char *oarg, const char *ext, char *narg) +{ + long i; + + //Chop off quotes at beginning and end of filename + for(i=strlen(oarg);i>0;i--) + if (oarg[i-1] == '\\') break; + if ((!i) && (oarg[0] == '\"')) i = 1; + strcpy(narg,&oarg[i]); + if (narg[0] == 0) return; + if (narg[strlen(narg)-1] == '\"') narg[strlen(narg)-1] = 0; + strlwr(narg); + if (!strstr(narg,ext)) strcat(narg,ext); +} + +#ifdef __WATCOMC__ + + //Precision: bits 8-9:, Rounding: bits 10-11: + //00 = 24-bit (0) 00 = nearest/even (0) + //01 = reserved (1) 01 = -inf (4) + //10 = 53-bit (2) 10 = inf (8) + //11 = 64-bit (3) 11 = 0 (c) +static long fpuasm[2]; +void fpuinit (long); +#pragma aux fpuinit =\ + "fninit"\ + "fstcw fpuasm"\ + "and byte ptr fpuasm[1], 0f0h"\ + "or byte ptr fpuasm[1], al"\ + "fldcw fpuasm"\ + parm [eax] + +#endif +#ifdef _MSC_VER + + //Precision: bits 8-9:, Rounding: bits 10-11: + //00 = 24-bit (0) 00 = nearest/even (0) + //01 = reserved (1) 01 = -inf (4) + //10 = 53-bit (2) 10 = inf (8) + //11 = 64-bit (3) 11 = 0 (c) +static long fpuasm[2]; +static _inline void fpuinit (long a) +{ + _asm + { + mov eax, a + fninit + fstcw fpuasm + and byte ptr fpuasm[1], 0f0h + or byte ptr fpuasm[1], al + fldcw fpuasm + } +} + +#endif + +#ifndef NO_CONSOLE + int main(int argc, char *argv[]) +#else + int WINAPI WinMain (HINSTANCE hinst, HINSTANCE hpinst, LPSTR cmdline, int ncmdshow) +#endif +{ + long i, j, k, inquote; + + Minidump::Activate(); + MemoryLeakFinder::Activate(); + +#ifndef NO_CONSOLE + HINSTANCE hinst = (HINSTANCE)GetModuleHandle(NULL); + HINSTANCE hpinst = 0; + LPSTR cmdline = ""; + int ncmdshow = SW_SHOW; +#endif + + ghinst = hinst; ghpinst = hpinst; gcmdline = cmdline; gncmdshow = ncmdshow; + + cputype = getcputype(); + if ((cputype&((1<<0)+(1<<4))) != ((1<<0)+(1<<4))) + { MessageBox(0,"Sorry, this program requires FPU&RDTSC support (>=Pentium)",prognam,MB_OK); return(-1); } + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); + + initklock(); +#ifndef NOINPUT + for(i=0;i<256;i++) keystatus[i] = 0; + for(i=0;i<256;i++) ext_keystatus[i] = 0; +#endif + +#ifdef NO_CONSOLE + //Convert Windows command line into ANSI 'C' command line... + int argc; + char *argv[MAX_PATH>>1]; + argv[0] = "exe"; argc = 1; j = inquote = 0; + for(i=0;cmdline[i];i++) + { + k = (((cmdline[i] != ' ') && (cmdline[i] != '\t')) || (inquote)); + if (cmdline[i] == '\"') inquote ^= 1; + if (j < k) { argv[argc++] = &cmdline[i+inquote]; j = inquote+1; continue; } + if ((j) && (!k)) + { + if ((j == 2) && (cmdline[i-1] == '\"')) cmdline[i-1] = 0; + cmdline[i] = 0; j = 0; + } + } + if ((j == 2) && (cmdline[i-1] == '\"')) cmdline[i-1] = 0; + argv[argc] = 0; +#endif + if (initapp(argc,argv) < 0) return(-1); + + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = WindowProc; + wc.cbClsExtra = wc.cbWndExtra = 0; + wc.hInstance = ghinst; + wc.hIcon = LoadIcon(ghinst,IDI_APPLICATION); + wc.hCursor = LoadCursor(0,IDC_ARROW); +#ifndef NODRAW + wc.hbrBackground = 0; +#else +#ifdef _MSC_VER + //wc.hbrBackground = (HBRUSH__ *)GetStockObject(BLACK_BRUSH); + wc.hbrBackground = (struct HBRUSH__ *)GetStockObject(BLACK_BRUSH); +#endif +#ifdef __WATCOMC__ + wc.hbrBackground = GetStockObject(BLACK_BRUSH); +#endif +#endif + wc.lpszMenuName = 0; + wc.lpszClassName = prognam; + RegisterClass(&wc); + + progwndflags = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX; + progwndadd[1] = GetSystemMetrics(SM_CYCAPTION); + if (progresiz) { + progwndflags |= WS_MAXIMIZEBOX|WS_THICKFRAME; + progwndadd[0] = GetSystemMetrics(SM_CXSIZEFRAME)*2; + progwndadd[1] += GetSystemMetrics(SM_CYSIZEFRAME)*2; + } else { + progwndadd[0] = GetSystemMetrics(SM_CXFIXEDFRAME)*2; + progwndadd[1] += GetSystemMetrics(SM_CYFIXEDFRAME)*2; + } + +#ifndef NODRAW + if (fullscreen) + { + if ((ghwnd = CreateWindowEx(WS_EX_TOPMOST,prognam,prognam,WS_POPUP,0,0,GetSystemMetrics(SM_CXSCREEN), + GetSystemMetrics(SM_CYSCREEN),0,0,ghinst,0)) == 0) return(0); + } + else + { +#endif + if (progwndx == 0x80000000) + { + RECT rw; + SystemParametersInfo(SPI_GETWORKAREA,0,&rw,0); + progwndx = ((rw.right -rw.left-(xres+progwndadd[0]))>>1) + rw.left; + progwndy = ((rw.bottom-rw.top -(yres+progwndadd[1]))>>1) + rw.top; + } + if ((ghwnd = CreateWindowEx(0,prognam,prognam,progwndflags, + progwndx,progwndy,xres+progwndadd[0],yres+progwndadd[1],0,0,ghinst,0)) == 0) return(0); +#ifndef NODRAW + } +#endif + + ShowWindow(ghwnd,gncmdshow); +#ifndef NODRAW + if ((!fullscreen) && (gncmdshow == SW_MAXIMIZE)) + { + RECT rw; + SystemParametersInfo(SPI_GETWORKAREA,0,&rw,0); + xres = rw.right -rw.left; + yres = rw.bottom-rw.top; + } +#endif + + //Enable this for smooth start-up, but beware: it halts disk caches! + //HANDLE hProc = GetCurrentProcess(); + //SetPriorityClass(hProc,REALTIME_PRIORITY_CLASS); + +#ifndef NODRAW + if (!initdirectdraw(xres,yres,colbits)) { DestroyWindow(ghwnd); return(0); } +#endif +#if 0 //defined(_DEBUG) && !defined(NODRAW) + debugdirectdraw(); // enable debug mode by default +#endif + +#ifndef NOSOUND +#ifdef DSOUNDINITCOM + coinit = CoInitialize(NULL); +#endif + initdirectsound(); +#endif + + UpdateWindow(ghwnd); + +#ifndef NOINPUT + if (!initdirectinput(ghwnd)) + { + DestroyWindow(ghwnd); +#ifndef NOSOUND + uninitdirectsound(); +#endif +#ifndef NODRAW + uninitdirectdraw(); +#endif + return(0); + } + if (!initkeyboard(ghwnd)) + { + uninitdirectinput(); DestroyWindow(ghwnd); +#ifndef NOSOUND + uninitdirectsound(); +#endif +#ifndef NODRAW + uninitdirectdraw(); +#endif + return(0); + } + if (!initmouse(ghwnd)) + { + uninitkeyboard(); uninitdirectinput(); DestroyWindow(ghwnd); +#ifndef NOSOUND + uninitdirectsound(); +#endif +#ifndef NODRAW + uninitdirectdraw(); +#endif + return(0); + } +#endif + +#if ((USEKENSOUND == 1) && (USETHREADS != 0)) + if (dsound) + { + hmutx = CreateMutex(0,0,0); + _beginthread(kensoundthread,0,0); + } +#endif + + initapp2(); + + breath(); + while (!quitprogram) + { + if (alwaysactive || ActiveApp) { fpuinit(0x2); doframe(); } + else WaitMessage(); + breath(); + } +#if ((USEKENSOUND == 1) && (USETHREADS != 0)) + if (dsound) + { + while (quitprogram != 2) Sleep(USETHREADS); + ENTERMUTX; + CloseHandle(hmutx); + } +#endif +#ifndef NOSOUND +#ifdef DSOUNDINITCOM + if (coinit == S_OK) CoUninitialize(); +#endif +#endif + + MemoryLeakFinder::DumpStatistics(); + + return(quitparam); +} diff --git a/bin/win64/shader.png b/bin/win64/shader.png new file mode 100644 index 0000000..4815bca Binary files /dev/null and b/bin/win64/shader.png differ diff --git a/build/Asura.Runner/Asura.Runner.vcxproj b/build/Asura.Runner/Asura.Runner.vcxproj index 0c18dc5..d145fa3 100644 --- a/build/Asura.Runner/Asura.Runner.vcxproj +++ b/build/Asura.Runner/Asura.Runner.vcxproj @@ -76,6 +76,7 @@ Disabled true true + $(SolutionDir)..\source\external;$(SolutionDir)..\source\modules;%(AdditionalIncludeDirectories) @@ -108,6 +109,7 @@ true true true + $(SolutionDir)..\source\external;$(SolutionDir)..\source\modules;%(AdditionalIncludeDirectories) true @@ -115,6 +117,7 @@ + diff --git a/build/Asura.Runner/Asura.Runner.vcxproj.filters b/build/Asura.Runner/Asura.Runner.vcxproj.filters index 3c6f4fd..ea4223b 100644 --- a/build/Asura.Runner/Asura.Runner.vcxproj.filters +++ b/build/Asura.Runner/Asura.Runner.vcxproj.filters @@ -1,17 +1,6 @@  - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - + \ No newline at end of file diff --git a/build/modules/asura-core/asura-core.vcxproj b/build/modules/asura-core/asura-core.vcxproj index a14c816..68347b5 100644 --- a/build/modules/asura-core/asura-core.vcxproj +++ b/build/modules/asura-core/asura-core.vcxproj @@ -143,18 +143,22 @@ + + + + @@ -163,7 +167,9 @@ + + @@ -194,12 +200,15 @@ + + + @@ -207,6 +216,7 @@ + @@ -215,11 +225,12 @@ + + - diff --git a/build/modules/asura-core/asura-core.vcxproj.filters b/build/modules/asura-core/asura-core.vcxproj.filters index 6c45670..6240784 100644 --- a/build/modules/asura-core/asura-core.vcxproj.filters +++ b/build/modules/asura-core/asura-core.vcxproj.filters @@ -209,6 +209,24 @@ Graphics + + Graphics + + + Graphics + + + Graphics + + + Graphics + + + Input + + + Input + @@ -310,9 +328,6 @@ Input - - Input - Input @@ -365,6 +380,24 @@ Graphics + + Graphics + + + Graphics + + + Graphics + + + Graphics + + + Input + + + Input + diff --git a/build/modules/asura-utils/asura-utils.vcxproj b/build/modules/asura-utils/asura-utils.vcxproj index f314953..40ea6b6 100644 --- a/build/modules/asura-utils/asura-utils.vcxproj +++ b/build/modules/asura-utils/asura-utils.vcxproj @@ -159,6 +159,7 @@ + diff --git a/build/modules/asura-utils/asura-utils.vcxproj.filters b/build/modules/asura-utils/asura-utils.vcxproj.filters index 1305948..c0488cb 100644 --- a/build/modules/asura-utils/asura-utils.vcxproj.filters +++ b/build/modules/asura-utils/asura-utils.vcxproj.filters @@ -195,6 +195,13 @@ + + Math\Rand + + + + Math\Rand + Threads @@ -228,13 +235,7 @@ Threads - - Math\Rand - - - - Math\Rand - + diff --git a/build/tools/bindingGen/obj/Debug/bindingGen.csproj.CoreCompileInputs.cache b/build/tools/bindingGen/obj/Debug/bindingGen.csproj.CoreCompileInputs.cache index c1e0407..93b7e43 100644 --- a/build/tools/bindingGen/obj/Debug/bindingGen.csproj.CoreCompileInputs.cache +++ b/build/tools/bindingGen/obj/Debug/bindingGen.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -534362588ad2d4462c430a54eb5dee7ab94c0164 +76869cb9eeaafde93fc35e764d87dc7f1f272b2f diff --git a/source/Asura.Editor/System/Input.cpp b/source/Asura.Editor/System/Input.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/Asura.Editor/System/Input.h b/source/Asura.Editor/System/Input.h new file mode 100644 index 0000000..682e69f --- /dev/null +++ b/source/Asura.Editor/System/Input.h @@ -0,0 +1,45 @@ +#ifndef _ASRUA_EDITOR_INPUT_H_ +#define _ASRUA_EDITOR_INPUT_H_ + +#include + +#include +#include +#include + +namespace_begin(AsuraEditor) + +// Win32 input entry +class Input : public AEInput::InputDevice +{ +public: + + Input(); + ~Input(); + + bool Open(HWND window); + void Close(void); + + bool GetJoystickNames(std::vector &names); + + bool Activate(bool active); + bool ToggleFullscreen(bool fullscreen, HWND window); + + bool Process(bool discard); + LRESULT OnKey(HWND window, UINT message, WPARAM wParam, LPARAM lParam); + LRESULT OnInput(HWND window, UINT message, WPARAM wParam, LPARAM lParam); + LRESULT OnDeviceChange(LPCWSTR name, bool add); + + static bool ConvertPositionToClientAreaCoord(HWND activeWindow, POINT position, AEMath::Vector2f& newPos); + +private: + + bool UpdateState(); + +}; + +extern Input g_Input; + +namespace_end + +#endif \ No newline at end of file diff --git a/source/Asura.Runner/Main.cpp b/source/Asura.Runner/Main.cpp new file mode 100644 index 0000000..ac91f97 --- /dev/null +++ b/source/Asura.Runner/Main.cpp @@ -0,0 +1,13 @@ +#ifndef _ASURA_RUNNER_MAIN_H_ +#define _ASURA_RUNNER_MAIN_H_ + +#include + +/// SDL +int main(int args, char* argv[]) +{ + + return 0; +} + +#endif \ No newline at end of file diff --git a/source/Asura.Runner/main.cpp b/source/Asura.Runner/main.cpp index 0ce68b6..ac91f97 100644 --- a/source/Asura.Runner/main.cpp +++ b/source/Asura.Runner/main.cpp @@ -1,9 +1,7 @@ -#ifndef __ASURA_RUNNER_MAIN_H__ -#define __ASURA_RUNNER_MAIN_H__ +#ifndef _ASURA_RUNNER_MAIN_H_ +#define _ASURA_RUNNER_MAIN_H_ -#include "runner.h" - -using namespace AsuraRunner; +#include /// SDL int main(int args, char* argv[]) diff --git a/source/Asura.Runner/runner.cpp b/source/Asura.Runner/runner.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/source/Asura.Runner/runner.h b/source/Asura.Runner/runner.h deleted file mode 100644 index 52f4d65..0000000 --- a/source/Asura.Runner/runner.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __ASURA_RUNNER_H__ -#define __ASURA_RUNNER_H__ - -#include - -#include - -namespace AsuraRunner -{ - - class SDLInputDevice : public AEInput::InputDevice - { - public: - - - - }; - -} - -#endif \ No newline at end of file diff --git a/source/modules/asura-box2d/Physics/Body.h b/source/modules/asura-box2d/Physics/Body.h index e5af76a..ecf5bab 100644 --- a/source/modules/asura-box2d/Physics/Body.h +++ b/source/modules/asura-box2d/Physics/Body.h @@ -3,65 +3,62 @@ #include +#include #include -namespace AsuraEngine -{ - namespace Physics - { - - class World; - class Joint; +namespace_begin(AsuraEngine) +namespace_begin(Physics) - enum BodyType - { - BODY_TYPE_INVALID, - BODY_TYPE_STATIC, - BODY_TYPE_DYNAMIC, - BODY_TYPE_KINEMATIC - }; +class World; +class Joint; - class Body - : public AEScripting::Portable - { - public: +enum BodyType +{ + BODY_TYPE_INVALID, + BODY_TYPE_STATIC, + BODY_TYPE_DYNAMIC, + BODY_TYPE_KINEMATIC +}; - private: +class Body : public AEScripting::Portable +{ +public: - friend class Joint; +private: - //----------------------------------------------------------------------------// + friend class Joint; - LUAX_DECL_FACTORY(Body); + //----------------------------------------------------------------------------// - LUAX_DECL_ENUM(BodyType, 1); + LUAX_DECL_FACTORY(Body); - LUAX_DECL_METHOD(_GetType); - LUAX_DECL_METHOD(_GetX); - LUAX_DECL_METHOD(_GetY); - LUAX_DECL_METHOD(_GetAngle); - LUAX_DECL_METHOD(_GetPosition); - LUAX_DECL_METHOD(_GetLinearVelocity); - LUAX_DECL_METHOD(_GetWorldCenter); - LUAX_DECL_METHOD(_GetLocalCenter); - LUAX_DECL_METHOD(_GetAngularVelocity); - LUAX_DECL_METHOD(_GetMass); - LUAX_DECL_METHOD(_GetInertia); - LUAX_DECL_METHOD(_GetMassData); - LUAX_DECL_METHOD(_GetAngularDamping); - LUAX_DECL_METHOD(_GetLinearDamping); - LUAX_DECL_METHOD(_GetGravityScale); - LUAX_DECL_METHOD(_GetGravityScale); + LUAX_DECL_ENUM(BodyType, 1); - //----------------------------------------------------------------------------// + LUAX_DECL_METHOD(_GetType); + LUAX_DECL_METHOD(_GetX); + LUAX_DECL_METHOD(_GetY); + LUAX_DECL_METHOD(_GetAngle); + LUAX_DECL_METHOD(_GetPosition); + LUAX_DECL_METHOD(_GetLinearVelocity); + LUAX_DECL_METHOD(_GetWorldCenter); + LUAX_DECL_METHOD(_GetLocalCenter); + LUAX_DECL_METHOD(_GetAngularVelocity); + LUAX_DECL_METHOD(_GetMass); + LUAX_DECL_METHOD(_GetInertia); + LUAX_DECL_METHOD(_GetMassData); + LUAX_DECL_METHOD(_GetAngularDamping); + LUAX_DECL_METHOD(_GetLinearDamping); + LUAX_DECL_METHOD(_GetGravityScale); + LUAX_DECL_METHOD(_GetGravityScale); - b2Body *body; + //----------------------------------------------------------------------------// - World* mWorld; + b2Body* m_Body; + World* m_World; - }; +}; - } -} +namespace_end +namespace_end #endif \ No newline at end of file diff --git a/source/modules/asura-box2d/Physics/ChainShape.h b/source/modules/asura-box2d/Physics/ChainShape.h index 2ce19fb..9a88263 100644 --- a/source/modules/asura-box2d/Physics/ChainShape.h +++ b/source/modules/asura-box2d/Physics/ChainShape.h @@ -19,7 +19,7 @@ public: private: - b2ChainShape* mShape; + b2ChainShape* m_Shape; }; diff --git a/source/modules/asura-box2d/Physics/Fixture.h b/source/modules/asura-box2d/Physics/Fixture.h index e69de29..a9f0fc7 100644 --- a/source/modules/asura-box2d/Physics/Fixture.h +++ b/source/modules/asura-box2d/Physics/Fixture.h @@ -0,0 +1,17 @@ +#ifndef _ASRUA_ENGINE_FIXTURE_H_ +#define _ASRUA_ENGINE_FIXTURE_H_ + +#include + +namespace_begin(AsuraEngine) +namespace_begin(Physics) + +class Fixture +{ + +}; + +namespace_end +namespace_end + +#endif diff --git a/source/modules/asura-box2d/Physics/World.h b/source/modules/asura-box2d/Physics/World.h index b6d00ca..0419275 100644 --- a/source/modules/asura-box2d/Physics/World.h +++ b/source/modules/asura-box2d/Physics/World.h @@ -1,19 +1,18 @@ #ifndef __ASURA_BOX2D_WORLD_H__ #define __ASURA_BOX2D_WORLD_H__ +#include #include -namespace AsuraEngine -{ - namespace Physics - { +namespace_begin(AsuraEngine) +namespace_begin(Physics) - class World : public AEScripting::Portable - { +class World : public AEScripting::Portable +{ - }; +}; - } -} +namespace_end +namespace_end #endif \ No newline at end of file diff --git a/source/modules/asura-box2d/physics/body.h b/source/modules/asura-box2d/physics/body.h index e5af76a..ecf5bab 100644 --- a/source/modules/asura-box2d/physics/body.h +++ b/source/modules/asura-box2d/physics/body.h @@ -3,65 +3,62 @@ #include +#include #include -namespace AsuraEngine -{ - namespace Physics - { - - class World; - class Joint; +namespace_begin(AsuraEngine) +namespace_begin(Physics) - enum BodyType - { - BODY_TYPE_INVALID, - BODY_TYPE_STATIC, - BODY_TYPE_DYNAMIC, - BODY_TYPE_KINEMATIC - }; +class World; +class Joint; - class Body - : public AEScripting::Portable - { - public: +enum BodyType +{ + BODY_TYPE_INVALID, + BODY_TYPE_STATIC, + BODY_TYPE_DYNAMIC, + BODY_TYPE_KINEMATIC +}; - private: +class Body : public AEScripting::Portable +{ +public: - friend class Joint; +private: - //----------------------------------------------------------------------------// + friend class Joint; - LUAX_DECL_FACTORY(Body); + //----------------------------------------------------------------------------// - LUAX_DECL_ENUM(BodyType, 1); + LUAX_DECL_FACTORY(Body); - LUAX_DECL_METHOD(_GetType); - LUAX_DECL_METHOD(_GetX); - LUAX_DECL_METHOD(_GetY); - LUAX_DECL_METHOD(_GetAngle); - LUAX_DECL_METHOD(_GetPosition); - LUAX_DECL_METHOD(_GetLinearVelocity); - LUAX_DECL_METHOD(_GetWorldCenter); - LUAX_DECL_METHOD(_GetLocalCenter); - LUAX_DECL_METHOD(_GetAngularVelocity); - LUAX_DECL_METHOD(_GetMass); - LUAX_DECL_METHOD(_GetInertia); - LUAX_DECL_METHOD(_GetMassData); - LUAX_DECL_METHOD(_GetAngularDamping); - LUAX_DECL_METHOD(_GetLinearDamping); - LUAX_DECL_METHOD(_GetGravityScale); - LUAX_DECL_METHOD(_GetGravityScale); + LUAX_DECL_ENUM(BodyType, 1); - //----------------------------------------------------------------------------// + LUAX_DECL_METHOD(_GetType); + LUAX_DECL_METHOD(_GetX); + LUAX_DECL_METHOD(_GetY); + LUAX_DECL_METHOD(_GetAngle); + LUAX_DECL_METHOD(_GetPosition); + LUAX_DECL_METHOD(_GetLinearVelocity); + LUAX_DECL_METHOD(_GetWorldCenter); + LUAX_DECL_METHOD(_GetLocalCenter); + LUAX_DECL_METHOD(_GetAngularVelocity); + LUAX_DECL_METHOD(_GetMass); + LUAX_DECL_METHOD(_GetInertia); + LUAX_DECL_METHOD(_GetMassData); + LUAX_DECL_METHOD(_GetAngularDamping); + LUAX_DECL_METHOD(_GetLinearDamping); + LUAX_DECL_METHOD(_GetGravityScale); + LUAX_DECL_METHOD(_GetGravityScale); - b2Body *body; + //----------------------------------------------------------------------------// - World* mWorld; + b2Body* m_Body; + World* m_World; - }; +}; - } -} +namespace_end +namespace_end #endif \ No newline at end of file diff --git a/source/modules/asura-box2d/physics/fixture.h b/source/modules/asura-box2d/physics/fixture.h index e69de29..a9f0fc7 100644 --- a/source/modules/asura-box2d/physics/fixture.h +++ b/source/modules/asura-box2d/physics/fixture.h @@ -0,0 +1,17 @@ +#ifndef _ASRUA_ENGINE_FIXTURE_H_ +#define _ASRUA_ENGINE_FIXTURE_H_ + +#include + +namespace_begin(AsuraEngine) +namespace_begin(Physics) + +class Fixture +{ + +}; + +namespace_end +namespace_end + +#endif diff --git a/source/modules/asura-box2d/physics/world.h b/source/modules/asura-box2d/physics/world.h index b6d00ca..0419275 100644 --- a/source/modules/asura-box2d/physics/world.h +++ b/source/modules/asura-box2d/physics/world.h @@ -1,19 +1,18 @@ #ifndef __ASURA_BOX2D_WORLD_H__ #define __ASURA_BOX2D_WORLD_H__ +#include #include -namespace AsuraEngine -{ - namespace Physics - { +namespace_begin(AsuraEngine) +namespace_begin(Physics) - class World : public AEScripting::Portable - { +class World : public AEScripting::Portable +{ - }; +}; - } -} +namespace_end +namespace_end #endif \ No newline at end of file diff --git a/source/modules/asura-core/Application.h b/source/modules/asura-core/Application.h index ea5faa7..696d125 100644 --- a/source/modules/asura-core/Application.h +++ b/source/modules/asura-core/Application.h @@ -38,40 +38,28 @@ public: virtual ~Application(); - /// - /// ʼǰϵͳ - /// + // ʼǰϵͳ bool InitSubModules(uint flag = ASURA_MODULE_ALL); - /// - /// - /// + // virtual void Run(int argc, char* args[]); - /// - /// ˳runʱĴ - /// + // ˳runʱĴ virtual void OnExit(); protected: - /// - /// moduleapplicationӵmoduleȨ - /// + // moduleapplicationӵmoduleȨ void EnqueueModule(Module* module); private: - /// /// ̵߳lua state handleӦѭСһ˵ֻҪ߳һlua_State̲߳Ҫ̼߳ /// lua̫ʹˡC++дȻעһصһ̴߳lua_Stateעắִк󷢻 /// ̵߳lua_Stateֻ֤һnativeʵ֮һlua_State󶨡 - /// Luax::LuaxVM* m_VM; - /// - /// Asura libsᰴն˳ʼ˳ʱִ˳ - /// + // Asura libsᰴն˳ʼ˳ʱִ˳ std::queue m_Modules; }; diff --git a/source/modules/asura-core/Graphics/DrawInfo.h b/source/modules/asura-core/Graphics/DrawInfo.h index f0e375b..9042f2f 100644 --- a/source/modules/asura-core/Graphics/DrawInfo.h +++ b/source/modules/asura-core/Graphics/DrawInfo.h @@ -6,6 +6,7 @@ namespace_begin(AsuraEngine) namespace_begin(Graphics) +/// struct DrawInfo { diff --git a/source/modules/asura-core/Graphics/DrawUtil.cpp b/source/modules/asura-core/Graphics/DrawUtil.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-core/Graphics/DrawUtil.h b/source/modules/asura-core/Graphics/DrawUtil.h new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-core/Graphics/GPUBuffer.h b/source/modules/asura-core/Graphics/GPUBuffer.h index bb40055..0aa3c29 100644 --- a/source/modules/asura-core/Graphics/GPUBuffer.h +++ b/source/modules/asura-core/Graphics/GPUBuffer.h @@ -31,8 +31,7 @@ enum BufferDataType }; /// -/// VRAM壬ֶ㻺vboebo֣ÿζڴԴϴݡframeworkrenderers -/// +/// VRAM壬ֶ㻺vboebo֣ÿζڴԴϴݡframeworkrenderersй /// ASURA_ABSTRACT class GPUBuffer { @@ -62,10 +61,9 @@ private: GLenum m_Target; GLuint m_Buffer; - /// openglԴ滺岢ûж͵ҪֻglVertexAttribPointerʱָdrawcall ʱݸ - /// ʼַʹbufferȡඥݣԲͬͿԱһbufferСΪ˱ - /// ӿڵļ࣬ڳʼbufferʱָͣڱ͵һ£Բͬ - /// ͷͬbuffer + /// openglԴ滺岢ûж͵ҪֻglVertexAttribPointerʱָdrawcall ʱݸ + /// ʼַʹbufferȡඥݣԲͬͿԱһbufferСΪ˱ֽӿڵļ࣬ + /// ʼbufferʱָͣڱ͵һ£Բͬͷͬbuffer GLenum m_DataType; GLuint m_Usage; diff --git a/source/modules/asura-core/Graphics/GfxDevice.cpp b/source/modules/asura-core/Graphics/GfxDevice.cpp index ef324e3..ea95f54 100644 --- a/source/modules/asura-core/Graphics/GfxDevice.cpp +++ b/source/modules/asura-core/Graphics/GfxDevice.cpp @@ -82,16 +82,6 @@ Color& GfxDevice::GetDrawColor() return state.drawColor; } -Canvas* GfxDevice::GetActiveCanvas() const -{ - return state.canvas; -} - -void GfxDevice::SetActiveCanvas(Canvas* canvas) -{ - state.canvas = canvas; -} - void GfxDevice::SetViewport(const Recti v) { state.viewport = v; @@ -136,16 +126,6 @@ void GfxDevice::DrawArrays(GLenum mode, GLint first, GLsizei count) state.shader->OnUsed(); } -void GfxDevice::SetMatrixMode (MatrixMode mode) -{ - state.matrixMode = mode; -} - -MatrixMode GfxDevice::GetMatrixMode () -{ - return state.matrixMode; -} - void GfxDevice::PushMatrix () { state.matrix[state.matrixMode].Push (); diff --git a/source/modules/asura-core/Graphics/GfxDevice.h b/source/modules/asura-core/Graphics/GfxDevice.h index 1f50b57..02c7392 100644 --- a/source/modules/asura-core/Graphics/GfxDevice.h +++ b/source/modules/asura-core/Graphics/GfxDevice.h @@ -42,47 +42,44 @@ public: static GfxDevice& Get(); - int GetParam(GLParams param); + int GetParam(GLParams param); - bool Init(const AEMath::Recti& viewport); - bool Inited(); + bool Init(const AEMath::Recti& viewport); + bool Inited(); - void SetViewport(const AEMath::Recti viewport); + void SetViewport(const AEMath::Recti viewport); const AEMath::Recti& GetViewport(); - void SetMatrixMode(MatrixMode mode); - MatrixMode GetMatrixMode(); + void PushMatrix(); + void PopMatrix(); - void PushMatrix(); - void PopMatrix(); + void LoadIdentity(); + void Rotate(float angle); + void Translate(float x, float y); + void Scale(float x, float y); + void Ortho(float l, float r, float b, float t, float n, float f); - void LoadIdentity(); - void Rotate(float angle); - void Translate(float x, float y); - void Scale(float x, float y); - void Ortho(float l, float r, float b, float t, float n, float f); + uint GetMatrixDepth(); + uint GetMatrixIndex(); - uint GetMatrixDepth(); - uint GetMatrixIndex(); + void DrawArrays(GLenum mode, GLint first, GLsizei count); AEMath::Matrix44& GetMatrix(MatrixMode mode); AEMath::Matrix44 GetMVPMatrix(); - void SetDrawColor(float r, float g, float b, float a); - Color& GetDrawColor(); - - void SetActiveCanvas(Canvas* = NULL); - Canvas* GetActiveCanvas() const; + void SetDrawColor(float r, float g, float b, float a); + Color& GetDrawColor(); void SetActiveShader(Shader* = NULL); Shader* GetActiveShader() const; - void DrawArrays(GLenum mode, GLint first, GLsizei count); + void WipeError(); + bool HasError(); + GLenum GetError(); - void WipeError(); - bool HasError(); - GLenum GetError(); + GET_SET(MatrixMode, MatrixMode, state.matrixMode); + GET_SET(Canvas*, ActiveCanvas, state.canvas); private: @@ -130,9 +127,14 @@ luaxport: }; -// ȫ GfxDevice extern GfxDevice g_Device; + +#define GL_CALL(x) do { x; /*GLAssert(); */} while(0) + + + + namespace_end namespace_end diff --git a/source/modules/asura-core/Graphics/GraphicsHelper.cpp b/source/modules/asura-core/Graphics/GraphicsHelper.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-core/Graphics/GraphicsHelper.h b/source/modules/asura-core/Graphics/GraphicsHelper.h new file mode 100644 index 0000000..b93756a --- /dev/null +++ b/source/modules/asura-core/Graphics/GraphicsHelper.h @@ -0,0 +1,15 @@ +#ifndef _ASURA_GRAPHICS_HELPER_H_ +#define _ASURA_GRAPHICS_HELPER_H_ + +#include + +namespace_begin(AsuraEngine) +namespace_begin(Graphics) + + + + +namespace_end +namespace_end + +#endif diff --git a/source/modules/asura-core/Graphics/Polygon2D.cpp b/source/modules/asura-core/Graphics/Polygon2D.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-core/Graphics/Polygon2D.h b/source/modules/asura-core/Graphics/Polygon2D.h new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-core/Graphics/VBO.cpp b/source/modules/asura-core/Graphics/VBO.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-core/Graphics/VBO.h b/source/modules/asura-core/Graphics/VBO.h new file mode 100644 index 0000000..80f405f --- /dev/null +++ b/source/modules/asura-core/Graphics/VBO.h @@ -0,0 +1,27 @@ +#ifndef _ASURA_ENGINE_VBO_H_ +#define _ASURA_ENGINE_VBO_H_ + +#include + +namespace_begin(AsuraEngine) +namespace_begin(Graphics) + +struct VertexBufferData +{ + +}; + +struct IndexBufferData +{ + +}; + +class VBO +{ + +}; + +namespace_end +namespace_end + +#endif \ No newline at end of file diff --git a/source/modules/asura-core/Input/InputAxis.cpp b/source/modules/asura-core/Input/InputAxis.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-core/Input/InputAxis.h b/source/modules/asura-core/Input/InputAxis.h new file mode 100644 index 0000000..3052f0b --- /dev/null +++ b/source/modules/asura-core/Input/InputAxis.h @@ -0,0 +1,15 @@ +#ifndef _ASURA_ENGINE_INPUT_AXIS_H_ +#define _ASURA_ENGINE_INPUT_AXIS_H_ + +#include + +namespace_begin(AsuraEngine) +namespace_begin(Input) + +class InputAxis {}; + + +namespace_end +namespace_end + +#endif \ No newline at end of file diff --git a/source/modules/asura-core/Input/InputDevice.cpp b/source/modules/asura-core/Input/InputDevice.cpp index e69de29..0c9c42f 100644 --- a/source/modules/asura-core/Input/InputDevice.cpp +++ b/source/modules/asura-core/Input/InputDevice.cpp @@ -0,0 +1,10 @@ +#include "InputDevice.h" + +namespace_begin(AsuraEngine) +namespace_begin(Input) + + + + +namespace_end +namespace_end \ No newline at end of file diff --git a/source/modules/asura-core/Input/InputDevice.h b/source/modules/asura-core/Input/InputDevice.h index 39f3d37..0ecce99 100644 --- a/source/modules/asura-core/Input/InputDevice.h +++ b/source/modules/asura-core/Input/InputDevice.h @@ -8,29 +8,35 @@ #include "../CoreConfig.h" #include "KeyboardState.h" +#include "MouseState.h" +#include "JoystickState.h" namespace_begin(AsuraEngine) namespace_begin(Input) -/// ͬƽ̨̳ಢʵhandleӿ -ASURA_ABSTRACT class InputDevice : public Singleton +class InputDevice { -protected: +public: - void OnKeyDown(int key); - void OnKeyUp(int key); + InputDevice(); + virtual ~InputDevice(); - void OnMouseMove(const AEMath::Vector2f& position); +protected: - void OnMouseButtonDown(int key); - void OnMouseButtonUp(int key); + virtual bool UpdateState(); - void OnMouseWheel(); + MouseState m_Mouse; + KeyboardState m_Keyboard; + JoystickState m_Joysticks; - void OnInputChar(); +private: + + bool UpdateMousePosition(); }; +//bool ConvertPositionToClientAreaCoord(); + namespace_end namespace_end diff --git a/source/modules/asura-core/Input/InputEvent.cpp b/source/modules/asura-core/Input/InputEvent.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-core/Input/InputEvent.h b/source/modules/asura-core/Input/InputEvent.h new file mode 100644 index 0000000..2c5b84b --- /dev/null +++ b/source/modules/asura-core/Input/InputEvent.h @@ -0,0 +1,21 @@ +#ifndef _ASURA_ENGINE_INPUT_EVENT_H_ +#define _ASURA_ENGINE_INPUT_EVENT_H_ + +#include + +namespace_begin(AsuraEngine) +namespace_begin(Input) + +struct InputEvent +{ + InputEvent(); + ~InputEvent(); + +}; + +//InputEvent ConvertInputEvent(); + +namespace_end +namespace_end + +#endif \ No newline at end of file diff --git a/source/modules/asura-core/Input/InputManager.cpp b/source/modules/asura-core/Input/InputManager.cpp index e69de29..fe49c29 100644 --- a/source/modules/asura-core/Input/InputManager.cpp +++ b/source/modules/asura-core/Input/InputManager.cpp @@ -0,0 +1,124 @@ +#include "InputManager.h" + +namespace_begin(AsuraEngine) +namespace_begin(Input) + +InputManager::InputManager() +{ +} + +InputManager::~InputManager() +{ +} + +void InputManager::Reset() +{ +} + +bool InputManager::GetButton(const std::string& name) +{ +} + +bool InputManager::GetButtonDown(const std::string& name) +{ +} + +bool InputManager::GetButtonUp(const std::string& name) +{ +} + +bool InputManager::HasAxisOrButton(const std::string& name) +{ +} + +float InputManager::GetAxis(const std::string& name) +{ +} + +float InputManager::GetAxisRaw(const std::string& name) +{ +} + +bool InputManager::GetMouseButton(int mouseBut) +{ +} + +bool InputManager::GetMouseButtonState(int mouseBut) +{ +} + +bool InputManager::GetMouseButtonDown(int mouseBut) +{ +} + +bool InputManager::GetMouseButtonUp(int mouseBut) +{ +} + + +bool InputManager::GetKey(int key) +{ +} + +bool InputManager::GetKeyDown(int key) +{ +} + +bool InputManager::GetKeyUp(int key) +{ +} + + +const AEMath::Vector2f& InputManager::GetMouseDelta() +{ +} + +const AEMath::Vector2f& InputManager::GetMousePosition() +{ +} + + +float InputManager::GetJoystickPosition() +{ +} + +void InputManager::setJoystickPosition() +{ +} + + +void InputManager::SetKeyState(int key, bool state) +{ + // This ignores keyRepeats (multiple keydown without a keyup event between) + if (state && !m_CurrentKeyState[key]) + m_ThisFrameKeyDown[key] = true; + if (!state && m_CurrentKeyState[key]) + m_ThisFrameKeyUp[key] = true; + + m_CurrentKeyState[key] = state; +} + +void InputManager::SetMouseDelta(const AEMath::Vector2f& delta) +{ +} + +void InputManager::SetMousePosition(const AEMath::Vector2f& pos) +{ +} + +void InputManager::SetMouseButton(int button, bool enabled) +{ +} + + +void InputManager::ProcessInput() +{ +} + +void InputManager::SendInputEvents() +{ +} + + +namespace_end +namespace_end \ No newline at end of file diff --git a/source/modules/asura-core/Input/InputManager.h b/source/modules/asura-core/Input/InputManager.h index dd11b2f..bbdafd8 100644 --- a/source/modules/asura-core/Input/InputManager.h +++ b/source/modules/asura-core/Input/InputManager.h @@ -1,23 +1,351 @@ -#ifndef __INPUT_MAMANGER_H__ -#define __INPUT_MAMANGER_H__ +#ifndef _ASURA_INPUT_MAMANGER_H_ +#define _ASURA_INPUT_MAMANGER_H_ +#include #include #include #include +#include + +#include +#include + +#include "InputAxis.h" namespace_begin(AsuraEngine) namespace_begin(Input) -/// ߼ class InputManager : public Singleton { -public : +public: + + InputManager(); + ~InputManager(); + + void Reset(); + + bool GetButton(const std::string& name); + bool GetButtonDown(const std::string& name); + bool GetButtonUp(const std::string& name); + bool HasAxisOrButton(const std::string& name); + float GetAxis(const std::string& name); + float GetAxisRaw(const std::string& name); + + bool GetMouseButton(int mouseBut); + bool GetMouseButtonState(int mouseBut); + bool GetMouseButtonDown(int mouseBut); + bool GetMouseButtonUp(int mouseBut); + + bool GetKey(int key); + bool GetKeyDown(int key); + bool GetKeyUp(int key); + + const AEMath::Vector2f& GetMouseDelta(); + const AEMath::Vector2f& GetMousePosition(); + + float GetJoystickPosition(); + void setJoystickPosition(); + + void SetKeyState(int key, bool state); + void SetMouseDelta(const AEMath::Vector2f& delta); + void SetMousePosition(const AEMath::Vector2f& pos); + void SetMouseButton(int button, bool enabled); + + void ProcessInput(); + void SendInputEvents(); + +private: + + dynamic_bitset m_CurrentKeyState; + dynamic_bitset m_ThisFrameKeyDown; + dynamic_bitset m_ThisFrameKeyUp; + + std::vector m_Axis; + + AEMath::Vector2f m_MouseDelta; + AEMath::Vector2f m_MousePos; + bool m_MousePresent; -private : + std::vector> m_JoystickPos; + + std::string m_InputString; + std::string m_CompositionString; + + AEMath::Vector2f m_TextFieldCursorPos; + bool m_TextFieldInput; + + bool m_EatKeyPressOnTextFieldFocus; + int m_IMECompositionMode; + bool m_IMEIsSelected; + + int m_LastJoyNum, m_LastJoyAxis; + bool m_ShouldQuit; + bool m_SimulateMouseWithTouches; }; +// keyboard keys +enum { + /* The keyboard syms have been cleverly chosen to map to ASCII */ + SDLK_UNKNOWN = 0, + SDLK_FIRST = 0, + SDLK_BACKSPACE = 8, + SDLK_TAB = 9, + SDLK_CLEAR = 12, + SDLK_RETURN = 13, + SDLK_PAUSE = 19, + SDLK_ESCAPE = 27, + SDLK_SPACE = 32, + SDLK_EXCLAIM = 33, + SDLK_QUOTEDBL = 34, + SDLK_HASH = 35, + SDLK_DOLLAR = 36, + SDLK_AMPERSAND = 38, + SDLK_QUOTE = 39, + SDLK_LEFTPAREN = 40, + SDLK_RIGHTPAREN = 41, + SDLK_ASTERISK = 42, + SDLK_PLUS = 43, + SDLK_COMMA = 44, + SDLK_MINUS = 45, + SDLK_PERIOD = 46, + SDLK_SLASH = 47, + SDLK_0 = 48, + SDLK_1 = 49, + SDLK_2 = 50, + SDLK_3 = 51, + SDLK_4 = 52, + SDLK_5 = 53, + SDLK_6 = 54, + SDLK_7 = 55, + SDLK_8 = 56, + SDLK_9 = 57, + SDLK_COLON = 58, + SDLK_SEMICOLON = 59, + SDLK_LESS = 60, + SDLK_EQUALS = 61, + SDLK_GREATER = 62, + SDLK_QUESTION = 63, + SDLK_AT = 64, + /* + Skip uppercase letters + */ + SDLK_LEFTBRACKET = 91, + SDLK_BACKSLASH = 92, + SDLK_RIGHTBRACKET = 93, + SDLK_CARET = 94, + SDLK_UNDERSCORE = 95, + SDLK_BACKQUOTE = 96, + SDLK_a = 97, + SDLK_b = 98, + SDLK_c = 99, + SDLK_d = 100, + SDLK_e = 101, + SDLK_f = 102, + SDLK_g = 103, + SDLK_h = 104, + SDLK_i = 105, + SDLK_j = 106, + SDLK_k = 107, + SDLK_l = 108, + SDLK_m = 109, + SDLK_n = 110, + SDLK_o = 111, + SDLK_p = 112, + SDLK_q = 113, + SDLK_r = 114, + SDLK_s = 115, + SDLK_t = 116, + SDLK_u = 117, + SDLK_v = 118, + SDLK_w = 119, + SDLK_x = 120, + SDLK_y = 121, + SDLK_z = 122, + SDLK_DELETE = 127, + /* End of ASCII mapped keysyms */ + + /* International keyboard syms */ + SDLK_WORLD_0 = 160, /* 0xA0 */ + SDLK_WORLD_1 = 161, + SDLK_WORLD_2 = 162, + SDLK_WORLD_3 = 163, + SDLK_WORLD_4 = 164, + SDLK_WORLD_5 = 165, + SDLK_WORLD_6 = 166, + SDLK_WORLD_7 = 167, + SDLK_WORLD_8 = 168, + SDLK_WORLD_9 = 169, + SDLK_WORLD_10 = 170, + SDLK_WORLD_11 = 171, + SDLK_WORLD_12 = 172, + SDLK_WORLD_13 = 173, + SDLK_WORLD_14 = 174, + SDLK_WORLD_15 = 175, + SDLK_WORLD_16 = 176, + SDLK_WORLD_17 = 177, + SDLK_WORLD_18 = 178, + SDLK_WORLD_19 = 179, + SDLK_WORLD_20 = 180, + SDLK_WORLD_21 = 181, + SDLK_WORLD_22 = 182, + SDLK_WORLD_23 = 183, + SDLK_WORLD_24 = 184, + SDLK_WORLD_25 = 185, + SDLK_WORLD_26 = 186, + SDLK_WORLD_27 = 187, + SDLK_WORLD_28 = 188, + SDLK_WORLD_29 = 189, + SDLK_WORLD_30 = 190, + SDLK_WORLD_31 = 191, + SDLK_WORLD_32 = 192, + SDLK_WORLD_33 = 193, + SDLK_WORLD_34 = 194, + SDLK_WORLD_35 = 195, + SDLK_WORLD_36 = 196, + SDLK_WORLD_37 = 197, + SDLK_WORLD_38 = 198, + SDLK_WORLD_39 = 199, + SDLK_WORLD_40 = 200, + SDLK_WORLD_41 = 201, + SDLK_WORLD_42 = 202, + SDLK_WORLD_43 = 203, + SDLK_WORLD_44 = 204, + SDLK_WORLD_45 = 205, + SDLK_WORLD_46 = 206, + SDLK_WORLD_47 = 207, + SDLK_WORLD_48 = 208, + SDLK_WORLD_49 = 209, + SDLK_WORLD_50 = 210, + SDLK_WORLD_51 = 211, + SDLK_WORLD_52 = 212, + SDLK_WORLD_53 = 213, + SDLK_WORLD_54 = 214, + SDLK_WORLD_55 = 215, + SDLK_WORLD_56 = 216, + SDLK_WORLD_57 = 217, + SDLK_WORLD_58 = 218, + SDLK_WORLD_59 = 219, + SDLK_WORLD_60 = 220, + SDLK_WORLD_61 = 221, + SDLK_WORLD_62 = 222, + SDLK_WORLD_63 = 223, + SDLK_WORLD_64 = 224, + SDLK_WORLD_65 = 225, + SDLK_WORLD_66 = 226, + SDLK_WORLD_67 = 227, + SDLK_WORLD_68 = 228, + SDLK_WORLD_69 = 229, + SDLK_WORLD_70 = 230, + SDLK_WORLD_71 = 231, + SDLK_WORLD_72 = 232, + SDLK_WORLD_73 = 233, + SDLK_WORLD_74 = 234, + SDLK_WORLD_75 = 235, + SDLK_WORLD_76 = 236, + SDLK_WORLD_77 = 237, + SDLK_WORLD_78 = 238, + SDLK_WORLD_79 = 239, + SDLK_WORLD_80 = 240, + SDLK_WORLD_81 = 241, + SDLK_WORLD_82 = 242, + SDLK_WORLD_83 = 243, + SDLK_WORLD_84 = 244, + SDLK_WORLD_85 = 245, + SDLK_WORLD_86 = 246, + SDLK_WORLD_87 = 247, + SDLK_WORLD_88 = 248, + SDLK_WORLD_89 = 249, + SDLK_WORLD_90 = 250, + SDLK_WORLD_91 = 251, + SDLK_WORLD_92 = 252, + SDLK_WORLD_93 = 253, + SDLK_WORLD_94 = 254, + SDLK_WORLD_95 = 255, /* 0xFF */ + + /* Numeric keypad */ + SDLK_KP0 = 256, + SDLK_KP1 = 257, + SDLK_KP2 = 258, + SDLK_KP3 = 259, + SDLK_KP4 = 260, + SDLK_KP5 = 261, + SDLK_KP6 = 262, + SDLK_KP7 = 263, + SDLK_KP8 = 264, + SDLK_KP9 = 265, + SDLK_KP_PERIOD = 266, + SDLK_KP_DIVIDE = 267, + SDLK_KP_MULTIPLY = 268, + SDLK_KP_MINUS = 269, + SDLK_KP_PLUS = 270, + SDLK_KP_ENTER = 271, + SDLK_KP_EQUALS = 272, + + /* Arrows + Home/End pad */ + SDLK_UP = 273, + SDLK_DOWN = 274, + SDLK_RIGHT = 275, + SDLK_LEFT = 276, + SDLK_INSERT = 277, + SDLK_HOME = 278, + SDLK_END = 279, + SDLK_PAGEUP = 280, + SDLK_PAGEDOWN = 281, + + /* Function keys */ + SDLK_F1 = 282, + SDLK_F2 = 283, + SDLK_F3 = 284, + SDLK_F4 = 285, + SDLK_F5 = 286, + SDLK_F6 = 287, + SDLK_F7 = 288, + SDLK_F8 = 289, + SDLK_F9 = 290, + SDLK_F10 = 291, + SDLK_F11 = 292, + SDLK_F12 = 293, + SDLK_F13 = 294, + SDLK_F14 = 295, + SDLK_F15 = 296, + + /* Key state modifier keys */ + SDLK_NUMLOCK = 300, + SDLK_CAPSLOCK = 301, + SDLK_SCROLLOCK = 302, + SDLK_RSHIFT = 303, + SDLK_LSHIFT = 304, + SDLK_RCTRL = 305, + SDLK_LCTRL = 306, + SDLK_RALT = 307, + SDLK_LALT = 308, + SDLK_RMETA = 309, + SDLK_LMETA = 310, + SDLK_RGUI = 309, + SDLK_LGUI = 310, + SDLK_LSUPER = 311, /* Left "Windows" key */ + SDLK_RSUPER = 312, /* Right "Windows" key */ + SDLK_MODE = 313, /* "Alt Gr" key */ + SDLK_COMPOSE = 314, /* Multi-key compose key */ + + /* Miscellaneous function keys */ + SDLK_HELP = 315, + SDLK_PRINT = 316, + SDLK_SYSREQ = 317, + SDLK_BREAK = 318, + SDLK_MENU = 319, + SDLK_POWER = 320, /* Power Macintosh power key */ + SDLK_EURO = 321, /* Some european keyboards */ + SDLK_UNDO = 322, /* Atari keyboard has Undo */ + + /* Add any other keys here */ + + SDLK_LAST +}; + + namespace_end namespace_end diff --git a/source/modules/asura-core/Input/JoystickState.h b/source/modules/asura-core/Input/JoystickState.h index e69de29..42d0a79 100644 --- a/source/modules/asura-core/Input/JoystickState.h +++ b/source/modules/asura-core/Input/JoystickState.h @@ -0,0 +1,16 @@ +#ifndef _ASURA_JOYSTICKSTATE_H_ +#define _ASURA_JOYSTICKSTATE_H_ + +#include + +namespace_begin(AsuraEngine) +namespace_begin(Input) + +class JoystickState {}; + + +namespace_end +namespace_end + +#endif + diff --git a/source/modules/asura-core/Input/Keys.h b/source/modules/asura-core/Input/Keys.h deleted file mode 100644 index 8f04dc2..0000000 --- a/source/modules/asura-core/Input/Keys.h +++ /dev/null @@ -1,482 +0,0 @@ - -/** -* Keyboard keys. They are dependent on the current layout of the keyboard. -**/ -enum Key -{ - KEY_UNKNOWN, - - KEY_RETURN, - KEY_ESCAPE, - KEY_BACKSPACE, - KEY_TAB, - KEY_SPACE, - KEY_EXCLAIM, - KEY_QUOTEDBL, - KEY_HASH, - KEY_PERCENT, - KEY_DOLLAR, - KEY_AMPERSAND, - KEY_QUOTE, - KEY_LEFTPAREN, - KEY_RIGHTPAREN, - KEY_ASTERISK, - KEY_PLUS, - KEY_COMMA, - KEY_MINUS, - KEY_PERIOD, - KEY_SLASH, - KEY_0, - KEY_1, - KEY_2, - KEY_3, - KEY_4, - KEY_5, - KEY_6, - KEY_7, - KEY_8, - KEY_9, - KEY_COLON, - KEY_SEMICOLON, - KEY_LESS, - KEY_EQUALS, - KEY_GREATER, - KEY_QUESTION, - KEY_AT, - - KEY_LEFTBRACKET, - KEY_BACKSLASH, - KEY_RIGHTBRACKET, - KEY_CARET, - KEY_UNDERSCORE, - KEY_BACKQUOTE, - KEY_A, - KEY_B, - KEY_C, - KEY_D, - KEY_E, - KEY_F, - KEY_G, - KEY_H, - KEY_I, - KEY_J, - KEY_K, - KEY_L, - KEY_M, - KEY_N, - KEY_O, - KEY_P, - KEY_Q, - KEY_R, - KEY_S, - KEY_T, - KEY_U, - KEY_V, - KEY_W, - KEY_X, - KEY_Y, - KEY_Z, - - KEY_CAPSLOCK, - - KEY_F1, - KEY_F2, - KEY_F3, - KEY_F4, - KEY_F5, - KEY_F6, - KEY_F7, - KEY_F8, - KEY_F9, - KEY_F10, - KEY_F11, - KEY_F12, - - KEY_PRINTSCREEN, - KEY_SCROLLLOCK, - KEY_PAUSE, - KEY_INSERT, - KEY_HOME, - KEY_PAGEUP, - KEY_DELETE, - KEY_END, - KEY_PAGEDOWN, - KEY_RIGHT, - KEY_LEFT, - KEY_DOWN, - KEY_UP, - - KEY_NUMLOCKCLEAR, - KEY_KP_DIVIDE, - KEY_KP_MULTIPLY, - KEY_KP_MINUS, - KEY_KP_PLUS, - KEY_KP_ENTER, - KEY_KP_1, - KEY_KP_2, - KEY_KP_3, - KEY_KP_4, - KEY_KP_5, - KEY_KP_6, - KEY_KP_7, - KEY_KP_8, - KEY_KP_9, - KEY_KP_0, - KEY_KP_PERIOD, - KEY_KP_COMMA, - KEY_KP_EQUALS, - - KEY_APPLICATION, - KEY_POWER, - KEY_F13, - KEY_F14, - KEY_F15, - KEY_F16, - KEY_F17, - KEY_F18, - KEY_F19, - KEY_F20, - KEY_F21, - KEY_F22, - KEY_F23, - KEY_F24, - KEY_EXECUTE, - KEY_HELP, - KEY_MENU, - KEY_SELECT, - KEY_STOP, - KEY_AGAIN, - KEY_UNDO, - KEY_CUT, - KEY_COPY, - KEY_PASTE, - KEY_FIND, - KEY_MUTE, - KEY_VOLUMEUP, - KEY_VOLUMEDOWN, - - KEY_ALTERASE, - KEY_SYSREQ, - KEY_CANCEL, - KEY_CLEAR, - KEY_PRIOR, - KEY_RETURN2, - KEY_SEPARATOR, - KEY_OUT, - KEY_OPER, - KEY_CLEARAGAIN, - - KEY_THOUSANDSSEPARATOR, - KEY_DECIMALSEPARATOR, - KEY_CURRENCYUNIT, - KEY_CURRENCYSUBUNIT, - - KEY_LCTRL, - KEY_LSHIFT, - KEY_LALT, - KEY_LGUI, - KEY_RCTRL, - KEY_RSHIFT, - KEY_RALT, - KEY_RGUI, - - KEY_MODE, - - KEY_AUDIONEXT, - KEY_AUDIOPREV, - KEY_AUDIOSTOP, - KEY_AUDIOPLAY, - KEY_AUDIOMUTE, - KEY_MEDIASELECT, - KEY_WWW, - KEY_MAIL, - KEY_CALCULATOR, - KEY_COMPUTER, - KEY_APP_SEARCH, - KEY_APP_HOME, - KEY_APP_BACK, - KEY_APP_FORWARD, - KEY_APP_STOP, - KEY_APP_REFRESH, - KEY_APP_BOOKMARKS, - - KEY_BRIGHTNESSDOWN, - KEY_BRIGHTNESSUP, - KEY_DISPLAYSWITCH, - KEY_KBDILLUMTOGGLE, - KEY_KBDILLUMDOWN, - KEY_KBDILLUMUP, - KEY_EJECT, - KEY_SLEEP, - - KEY_MAX_ENUM -}; - -/** -* Scancodes represent physical keys independent of the current layout. -* Their names may not match the names of the keys printed on the keyboard. -* Some of them are very esoteric... -**/ -enum Scancode -{ - SCANCODE_UNKNOWN, - - SCANCODE_A, - SCANCODE_B, - SCANCODE_C, - SCANCODE_D, - SCANCODE_E, - SCANCODE_F, - SCANCODE_G, - SCANCODE_H, - SCANCODE_I, - SCANCODE_J, - SCANCODE_K, - SCANCODE_L, - SCANCODE_M, - SCANCODE_N, - SCANCODE_O, - SCANCODE_P, - SCANCODE_Q, - SCANCODE_R, - SCANCODE_S, - SCANCODE_T, - SCANCODE_U, - SCANCODE_V, - SCANCODE_W, - SCANCODE_X, - SCANCODE_Y, - SCANCODE_Z, - - SCANCODE_1, - SCANCODE_2, - SCANCODE_3, - SCANCODE_4, - SCANCODE_5, - SCANCODE_6, - SCANCODE_7, - SCANCODE_8, - SCANCODE_9, - SCANCODE_0, - - SCANCODE_RETURN, - SCANCODE_ESCAPE, - SCANCODE_BACKSPACE, - SCANCODE_TAB, - SCANCODE_SPACE, - - SCANCODE_MINUS, - SCANCODE_EQUALS, - SCANCODE_LEFTBRACKET, - SCANCODE_RIGHTBRACKET, - SCANCODE_BACKSLASH, - SCANCODE_NONUSHASH, - SCANCODE_SEMICOLON, - SCANCODE_APOSTROPHE, - SCANCODE_GRAVE, - SCANCODE_COMMA, - SCANCODE_PERIOD, - SCANCODE_SLASH, - - SCANCODE_CAPSLOCK, - - SCANCODE_F1, - SCANCODE_F2, - SCANCODE_F3, - SCANCODE_F4, - SCANCODE_F5, - SCANCODE_F6, - SCANCODE_F7, - SCANCODE_F8, - SCANCODE_F9, - SCANCODE_F10, - SCANCODE_F11, - SCANCODE_F12, - - SCANCODE_PRINTSCREEN, - SCANCODE_SCROLLLOCK, - SCANCODE_PAUSE, - SCANCODE_INSERT, - SCANCODE_HOME, - SCANCODE_PAGEUP, - SCANCODE_DELETE, - SCANCODE_END, - SCANCODE_PAGEDOWN, - SCANCODE_RIGHT, - SCANCODE_LEFT, - SCANCODE_DOWN, - SCANCODE_UP, - - SCANCODE_NUMLOCKCLEAR, - SCANCODE_KP_DIVIDE, - SCANCODE_KP_MULTIPLY, - SCANCODE_KP_MINUS, - SCANCODE_KP_PLUS, - SCANCODE_KP_ENTER, - SCANCODE_KP_1, - SCANCODE_KP_2, - SCANCODE_KP_3, - SCANCODE_KP_4, - SCANCODE_KP_5, - SCANCODE_KP_6, - SCANCODE_KP_7, - SCANCODE_KP_8, - SCANCODE_KP_9, - SCANCODE_KP_0, - SCANCODE_KP_PERIOD, - - SCANCODE_NONUSBACKSLASH, - SCANCODE_APPLICATION, - SCANCODE_POWER, - SCANCODE_KP_EQUALS, - SCANCODE_F13, - SCANCODE_F14, - SCANCODE_F15, - SCANCODE_F16, - SCANCODE_F17, - SCANCODE_F18, - SCANCODE_F19, - SCANCODE_F20, - SCANCODE_F21, - SCANCODE_F22, - SCANCODE_F23, - SCANCODE_F24, - SCANCODE_EXECUTE, - SCANCODE_HELP, - SCANCODE_MENU, - SCANCODE_SELECT, - SCANCODE_STOP, - SCANCODE_AGAIN, - SCANCODE_UNDO, - SCANCODE_CUT, - SCANCODE_COPY, - SCANCODE_PASTE, - SCANCODE_FIND, - SCANCODE_MUTE, - SCANCODE_VOLUMEUP, - SCANCODE_VOLUMEDOWN, - SCANCODE_KP_COMMA, - SCANCODE_KP_EQUALSAS400, - - SCANCODE_INTERNATIONAL1, - SCANCODE_INTERNATIONAL2, - SCANCODE_INTERNATIONAL3, - SCANCODE_INTERNATIONAL4, - SCANCODE_INTERNATIONAL5, - SCANCODE_INTERNATIONAL6, - SCANCODE_INTERNATIONAL7, - SCANCODE_INTERNATIONAL8, - SCANCODE_INTERNATIONAL9, - SCANCODE_LANG1, - SCANCODE_LANG2, - SCANCODE_LANG3, - SCANCODE_LANG4, - SCANCODE_LANG5, - SCANCODE_LANG6, - SCANCODE_LANG7, - SCANCODE_LANG8, - SCANCODE_LANG9, - - SCANCODE_ALTERASE, - SCANCODE_SYSREQ, - SCANCODE_CANCEL, - SCANCODE_CLEAR, - SCANCODE_PRIOR, - SCANCODE_RETURN2, - SCANCODE_SEPARATOR, - SCANCODE_OUT, - SCANCODE_OPER, - SCANCODE_CLEARAGAIN, - SCANCODE_CRSEL, - SCANCODE_EXSEL, - - SCANCODE_KP_00, - SCANCODE_KP_000, - SCANCODE_THOUSANDSSEPARATOR, - SCANCODE_DECIMALSEPARATOR, - SCANCODE_CURRENCYUNIT, - SCANCODE_CURRENCYSUBUNIT, - SCANCODE_KP_LEFTPAREN, - SCANCODE_KP_RIGHTPAREN, - SCANCODE_KP_LEFTBRACE, - SCANCODE_KP_RIGHTBRACE, - SCANCODE_KP_TAB, - SCANCODE_KP_BACKSPACE, - SCANCODE_KP_A, - SCANCODE_KP_B, - SCANCODE_KP_C, - SCANCODE_KP_D, - SCANCODE_KP_E, - SCANCODE_KP_F, - SCANCODE_KP_XOR, - SCANCODE_KP_POWER, - SCANCODE_KP_PERCENT, - SCANCODE_KP_LESS, - SCANCODE_KP_GREATER, - SCANCODE_KP_AMPERSAND, - SCANCODE_KP_DBLAMPERSAND, - SCANCODE_KP_VERTICALBAR, - SCANCODE_KP_DBLVERTICALBAR, - SCANCODE_KP_COLON, - SCANCODE_KP_HASH, - SCANCODE_KP_SPACE, - SCANCODE_KP_AT, - SCANCODE_KP_EXCLAM, - SCANCODE_KP_MEMSTORE, - SCANCODE_KP_MEMRECALL, - SCANCODE_KP_MEMCLEAR, - SCANCODE_KP_MEMADD, - SCANCODE_KP_MEMSUBTRACT, - SCANCODE_KP_MEMMULTIPLY, - SCANCODE_KP_MEMDIVIDE, - SCANCODE_KP_PLUSMINUS, - SCANCODE_KP_CLEAR, - SCANCODE_KP_CLEARENTRY, - SCANCODE_KP_BINARY, - SCANCODE_KP_OCTAL, - SCANCODE_KP_DECIMAL, - SCANCODE_KP_HEXADECIMAL, - - SCANCODE_LCTRL, - SCANCODE_LSHIFT, - SCANCODE_LALT, - SCANCODE_LGUI, - SCANCODE_RCTRL, - SCANCODE_RSHIFT, - SCANCODE_RALT, - SCANCODE_RGUI, - - SCANCODE_MODE, - - SCANCODE_AUDIONEXT, - SCANCODE_AUDIOPREV, - SCANCODE_AUDIOSTOP, - SCANCODE_AUDIOPLAY, - SCANCODE_AUDIOMUTE, - SCANCODE_MEDIASELECT, - SCANCODE_WWW, - SCANCODE_MAIL, - SCANCODE_CALCULATOR, - SCANCODE_COMPUTER, - SCANCODE_AC_SEARCH, - SCANCODE_AC_HOME, - SCANCODE_AC_BACK, - SCANCODE_AC_FORWARD, - SCANCODE_AC_STOP, - SCANCODE_AC_REFRESH, - SCANCODE_AC_BOOKMARKS, - - SCANCODE_BRIGHTNESSDOWN, - SCANCODE_BRIGHTNESSUP, - SCANCODE_DISPLAYSWITCH, - SCANCODE_KBDILLUMTOGGLE, - SCANCODE_KBDILLUMDOWN, - SCANCODE_KBDILLUMUP, - SCANCODE_EJECT, - SCANCODE_SLEEP, - - SCANCODE_APP1, - SCANCODE_APP2, - - SCANCODE_MAX_ENUM -}; diff --git a/source/modules/asura-core/Input/MouseState.h b/source/modules/asura-core/Input/MouseState.h index e69de29..1192a34 100644 --- a/source/modules/asura-core/Input/MouseState.h +++ b/source/modules/asura-core/Input/MouseState.h @@ -0,0 +1,16 @@ +#ifndef _ASURA_MOUSESTATE_H_ +#define _ASURA_MOUSESTATE_H_ + +#include + +namespace_begin(AsuraEngine) +namespace_begin(Input) + +class MouseState {}; + + +namespace_end +namespace_end + +#endif + diff --git a/source/modules/asura-core/application.h b/source/modules/asura-core/application.h index ea5faa7..696d125 100644 --- a/source/modules/asura-core/application.h +++ b/source/modules/asura-core/application.h @@ -38,40 +38,28 @@ public: virtual ~Application(); - /// - /// ʼǰϵͳ - /// + // ʼǰϵͳ bool InitSubModules(uint flag = ASURA_MODULE_ALL); - /// - /// - /// + // virtual void Run(int argc, char* args[]); - /// - /// ˳runʱĴ - /// + // ˳runʱĴ virtual void OnExit(); protected: - /// - /// moduleapplicationӵmoduleȨ - /// + // moduleapplicationӵmoduleȨ void EnqueueModule(Module* module); private: - /// /// ̵߳lua state handleӦѭСһ˵ֻҪ߳һlua_State̲߳Ҫ̼߳ /// lua̫ʹˡC++дȻעһصһ̴߳lua_Stateעắִк󷢻 /// ̵߳lua_Stateֻ֤һnativeʵ֮һlua_State󶨡 - /// Luax::LuaxVM* m_VM; - /// - /// Asura libsᰴն˳ʼ˳ʱִ˳ - /// + // Asura libsᰴն˳ʼ˳ʱִ˳ std::queue m_Modules; }; diff --git a/source/modules/asura-core/input/keys.h b/source/modules/asura-core/input/keys.h deleted file mode 100644 index 8f04dc2..0000000 --- a/source/modules/asura-core/input/keys.h +++ /dev/null @@ -1,482 +0,0 @@ - -/** -* Keyboard keys. They are dependent on the current layout of the keyboard. -**/ -enum Key -{ - KEY_UNKNOWN, - - KEY_RETURN, - KEY_ESCAPE, - KEY_BACKSPACE, - KEY_TAB, - KEY_SPACE, - KEY_EXCLAIM, - KEY_QUOTEDBL, - KEY_HASH, - KEY_PERCENT, - KEY_DOLLAR, - KEY_AMPERSAND, - KEY_QUOTE, - KEY_LEFTPAREN, - KEY_RIGHTPAREN, - KEY_ASTERISK, - KEY_PLUS, - KEY_COMMA, - KEY_MINUS, - KEY_PERIOD, - KEY_SLASH, - KEY_0, - KEY_1, - KEY_2, - KEY_3, - KEY_4, - KEY_5, - KEY_6, - KEY_7, - KEY_8, - KEY_9, - KEY_COLON, - KEY_SEMICOLON, - KEY_LESS, - KEY_EQUALS, - KEY_GREATER, - KEY_QUESTION, - KEY_AT, - - KEY_LEFTBRACKET, - KEY_BACKSLASH, - KEY_RIGHTBRACKET, - KEY_CARET, - KEY_UNDERSCORE, - KEY_BACKQUOTE, - KEY_A, - KEY_B, - KEY_C, - KEY_D, - KEY_E, - KEY_F, - KEY_G, - KEY_H, - KEY_I, - KEY_J, - KEY_K, - KEY_L, - KEY_M, - KEY_N, - KEY_O, - KEY_P, - KEY_Q, - KEY_R, - KEY_S, - KEY_T, - KEY_U, - KEY_V, - KEY_W, - KEY_X, - KEY_Y, - KEY_Z, - - KEY_CAPSLOCK, - - KEY_F1, - KEY_F2, - KEY_F3, - KEY_F4, - KEY_F5, - KEY_F6, - KEY_F7, - KEY_F8, - KEY_F9, - KEY_F10, - KEY_F11, - KEY_F12, - - KEY_PRINTSCREEN, - KEY_SCROLLLOCK, - KEY_PAUSE, - KEY_INSERT, - KEY_HOME, - KEY_PAGEUP, - KEY_DELETE, - KEY_END, - KEY_PAGEDOWN, - KEY_RIGHT, - KEY_LEFT, - KEY_DOWN, - KEY_UP, - - KEY_NUMLOCKCLEAR, - KEY_KP_DIVIDE, - KEY_KP_MULTIPLY, - KEY_KP_MINUS, - KEY_KP_PLUS, - KEY_KP_ENTER, - KEY_KP_1, - KEY_KP_2, - KEY_KP_3, - KEY_KP_4, - KEY_KP_5, - KEY_KP_6, - KEY_KP_7, - KEY_KP_8, - KEY_KP_9, - KEY_KP_0, - KEY_KP_PERIOD, - KEY_KP_COMMA, - KEY_KP_EQUALS, - - KEY_APPLICATION, - KEY_POWER, - KEY_F13, - KEY_F14, - KEY_F15, - KEY_F16, - KEY_F17, - KEY_F18, - KEY_F19, - KEY_F20, - KEY_F21, - KEY_F22, - KEY_F23, - KEY_F24, - KEY_EXECUTE, - KEY_HELP, - KEY_MENU, - KEY_SELECT, - KEY_STOP, - KEY_AGAIN, - KEY_UNDO, - KEY_CUT, - KEY_COPY, - KEY_PASTE, - KEY_FIND, - KEY_MUTE, - KEY_VOLUMEUP, - KEY_VOLUMEDOWN, - - KEY_ALTERASE, - KEY_SYSREQ, - KEY_CANCEL, - KEY_CLEAR, - KEY_PRIOR, - KEY_RETURN2, - KEY_SEPARATOR, - KEY_OUT, - KEY_OPER, - KEY_CLEARAGAIN, - - KEY_THOUSANDSSEPARATOR, - KEY_DECIMALSEPARATOR, - KEY_CURRENCYUNIT, - KEY_CURRENCYSUBUNIT, - - KEY_LCTRL, - KEY_LSHIFT, - KEY_LALT, - KEY_LGUI, - KEY_RCTRL, - KEY_RSHIFT, - KEY_RALT, - KEY_RGUI, - - KEY_MODE, - - KEY_AUDIONEXT, - KEY_AUDIOPREV, - KEY_AUDIOSTOP, - KEY_AUDIOPLAY, - KEY_AUDIOMUTE, - KEY_MEDIASELECT, - KEY_WWW, - KEY_MAIL, - KEY_CALCULATOR, - KEY_COMPUTER, - KEY_APP_SEARCH, - KEY_APP_HOME, - KEY_APP_BACK, - KEY_APP_FORWARD, - KEY_APP_STOP, - KEY_APP_REFRESH, - KEY_APP_BOOKMARKS, - - KEY_BRIGHTNESSDOWN, - KEY_BRIGHTNESSUP, - KEY_DISPLAYSWITCH, - KEY_KBDILLUMTOGGLE, - KEY_KBDILLUMDOWN, - KEY_KBDILLUMUP, - KEY_EJECT, - KEY_SLEEP, - - KEY_MAX_ENUM -}; - -/** -* Scancodes represent physical keys independent of the current layout. -* Their names may not match the names of the keys printed on the keyboard. -* Some of them are very esoteric... -**/ -enum Scancode -{ - SCANCODE_UNKNOWN, - - SCANCODE_A, - SCANCODE_B, - SCANCODE_C, - SCANCODE_D, - SCANCODE_E, - SCANCODE_F, - SCANCODE_G, - SCANCODE_H, - SCANCODE_I, - SCANCODE_J, - SCANCODE_K, - SCANCODE_L, - SCANCODE_M, - SCANCODE_N, - SCANCODE_O, - SCANCODE_P, - SCANCODE_Q, - SCANCODE_R, - SCANCODE_S, - SCANCODE_T, - SCANCODE_U, - SCANCODE_V, - SCANCODE_W, - SCANCODE_X, - SCANCODE_Y, - SCANCODE_Z, - - SCANCODE_1, - SCANCODE_2, - SCANCODE_3, - SCANCODE_4, - SCANCODE_5, - SCANCODE_6, - SCANCODE_7, - SCANCODE_8, - SCANCODE_9, - SCANCODE_0, - - SCANCODE_RETURN, - SCANCODE_ESCAPE, - SCANCODE_BACKSPACE, - SCANCODE_TAB, - SCANCODE_SPACE, - - SCANCODE_MINUS, - SCANCODE_EQUALS, - SCANCODE_LEFTBRACKET, - SCANCODE_RIGHTBRACKET, - SCANCODE_BACKSLASH, - SCANCODE_NONUSHASH, - SCANCODE_SEMICOLON, - SCANCODE_APOSTROPHE, - SCANCODE_GRAVE, - SCANCODE_COMMA, - SCANCODE_PERIOD, - SCANCODE_SLASH, - - SCANCODE_CAPSLOCK, - - SCANCODE_F1, - SCANCODE_F2, - SCANCODE_F3, - SCANCODE_F4, - SCANCODE_F5, - SCANCODE_F6, - SCANCODE_F7, - SCANCODE_F8, - SCANCODE_F9, - SCANCODE_F10, - SCANCODE_F11, - SCANCODE_F12, - - SCANCODE_PRINTSCREEN, - SCANCODE_SCROLLLOCK, - SCANCODE_PAUSE, - SCANCODE_INSERT, - SCANCODE_HOME, - SCANCODE_PAGEUP, - SCANCODE_DELETE, - SCANCODE_END, - SCANCODE_PAGEDOWN, - SCANCODE_RIGHT, - SCANCODE_LEFT, - SCANCODE_DOWN, - SCANCODE_UP, - - SCANCODE_NUMLOCKCLEAR, - SCANCODE_KP_DIVIDE, - SCANCODE_KP_MULTIPLY, - SCANCODE_KP_MINUS, - SCANCODE_KP_PLUS, - SCANCODE_KP_ENTER, - SCANCODE_KP_1, - SCANCODE_KP_2, - SCANCODE_KP_3, - SCANCODE_KP_4, - SCANCODE_KP_5, - SCANCODE_KP_6, - SCANCODE_KP_7, - SCANCODE_KP_8, - SCANCODE_KP_9, - SCANCODE_KP_0, - SCANCODE_KP_PERIOD, - - SCANCODE_NONUSBACKSLASH, - SCANCODE_APPLICATION, - SCANCODE_POWER, - SCANCODE_KP_EQUALS, - SCANCODE_F13, - SCANCODE_F14, - SCANCODE_F15, - SCANCODE_F16, - SCANCODE_F17, - SCANCODE_F18, - SCANCODE_F19, - SCANCODE_F20, - SCANCODE_F21, - SCANCODE_F22, - SCANCODE_F23, - SCANCODE_F24, - SCANCODE_EXECUTE, - SCANCODE_HELP, - SCANCODE_MENU, - SCANCODE_SELECT, - SCANCODE_STOP, - SCANCODE_AGAIN, - SCANCODE_UNDO, - SCANCODE_CUT, - SCANCODE_COPY, - SCANCODE_PASTE, - SCANCODE_FIND, - SCANCODE_MUTE, - SCANCODE_VOLUMEUP, - SCANCODE_VOLUMEDOWN, - SCANCODE_KP_COMMA, - SCANCODE_KP_EQUALSAS400, - - SCANCODE_INTERNATIONAL1, - SCANCODE_INTERNATIONAL2, - SCANCODE_INTERNATIONAL3, - SCANCODE_INTERNATIONAL4, - SCANCODE_INTERNATIONAL5, - SCANCODE_INTERNATIONAL6, - SCANCODE_INTERNATIONAL7, - SCANCODE_INTERNATIONAL8, - SCANCODE_INTERNATIONAL9, - SCANCODE_LANG1, - SCANCODE_LANG2, - SCANCODE_LANG3, - SCANCODE_LANG4, - SCANCODE_LANG5, - SCANCODE_LANG6, - SCANCODE_LANG7, - SCANCODE_LANG8, - SCANCODE_LANG9, - - SCANCODE_ALTERASE, - SCANCODE_SYSREQ, - SCANCODE_CANCEL, - SCANCODE_CLEAR, - SCANCODE_PRIOR, - SCANCODE_RETURN2, - SCANCODE_SEPARATOR, - SCANCODE_OUT, - SCANCODE_OPER, - SCANCODE_CLEARAGAIN, - SCANCODE_CRSEL, - SCANCODE_EXSEL, - - SCANCODE_KP_00, - SCANCODE_KP_000, - SCANCODE_THOUSANDSSEPARATOR, - SCANCODE_DECIMALSEPARATOR, - SCANCODE_CURRENCYUNIT, - SCANCODE_CURRENCYSUBUNIT, - SCANCODE_KP_LEFTPAREN, - SCANCODE_KP_RIGHTPAREN, - SCANCODE_KP_LEFTBRACE, - SCANCODE_KP_RIGHTBRACE, - SCANCODE_KP_TAB, - SCANCODE_KP_BACKSPACE, - SCANCODE_KP_A, - SCANCODE_KP_B, - SCANCODE_KP_C, - SCANCODE_KP_D, - SCANCODE_KP_E, - SCANCODE_KP_F, - SCANCODE_KP_XOR, - SCANCODE_KP_POWER, - SCANCODE_KP_PERCENT, - SCANCODE_KP_LESS, - SCANCODE_KP_GREATER, - SCANCODE_KP_AMPERSAND, - SCANCODE_KP_DBLAMPERSAND, - SCANCODE_KP_VERTICALBAR, - SCANCODE_KP_DBLVERTICALBAR, - SCANCODE_KP_COLON, - SCANCODE_KP_HASH, - SCANCODE_KP_SPACE, - SCANCODE_KP_AT, - SCANCODE_KP_EXCLAM, - SCANCODE_KP_MEMSTORE, - SCANCODE_KP_MEMRECALL, - SCANCODE_KP_MEMCLEAR, - SCANCODE_KP_MEMADD, - SCANCODE_KP_MEMSUBTRACT, - SCANCODE_KP_MEMMULTIPLY, - SCANCODE_KP_MEMDIVIDE, - SCANCODE_KP_PLUSMINUS, - SCANCODE_KP_CLEAR, - SCANCODE_KP_CLEARENTRY, - SCANCODE_KP_BINARY, - SCANCODE_KP_OCTAL, - SCANCODE_KP_DECIMAL, - SCANCODE_KP_HEXADECIMAL, - - SCANCODE_LCTRL, - SCANCODE_LSHIFT, - SCANCODE_LALT, - SCANCODE_LGUI, - SCANCODE_RCTRL, - SCANCODE_RSHIFT, - SCANCODE_RALT, - SCANCODE_RGUI, - - SCANCODE_MODE, - - SCANCODE_AUDIONEXT, - SCANCODE_AUDIOPREV, - SCANCODE_AUDIOSTOP, - SCANCODE_AUDIOPLAY, - SCANCODE_AUDIOMUTE, - SCANCODE_MEDIASELECT, - SCANCODE_WWW, - SCANCODE_MAIL, - SCANCODE_CALCULATOR, - SCANCODE_COMPUTER, - SCANCODE_AC_SEARCH, - SCANCODE_AC_HOME, - SCANCODE_AC_BACK, - SCANCODE_AC_FORWARD, - SCANCODE_AC_STOP, - SCANCODE_AC_REFRESH, - SCANCODE_AC_BOOKMARKS, - - SCANCODE_BRIGHTNESSDOWN, - SCANCODE_BRIGHTNESSUP, - SCANCODE_DISPLAYSWITCH, - SCANCODE_KBDILLUMTOGGLE, - SCANCODE_KBDILLUMDOWN, - SCANCODE_KBDILLUMUP, - SCANCODE_EJECT, - SCANCODE_SLEEP, - - SCANCODE_APP1, - SCANCODE_APP2, - - SCANCODE_MAX_ENUM -}; diff --git a/source/modules/asura-utils/Classes.h b/source/modules/asura-utils/Classes.h index d92c3d4..b2700f0 100644 --- a/source/modules/asura-utils/Classes.h +++ b/source/modules/asura-utils/Classes.h @@ -1,7 +1,7 @@ #ifndef _ASURAENGINE_CLASSES_H_ #define _ASURAENGINE_CLASSES_H_ -#define GET_SET(TYPE,PROP_NAME,VAR_NAME) void Set##PROP_NAME (TYPE val) { VAR_NAME = val; } const TYPE Get##PROP_NAME () const {return (const TYPE)VAR_NAME; } +#define GET_SET(TYPE,PROP_NAME,VAR_NAME) void Set##PROP_NAME (TYPE val) { VAR_NAME = val; } TYPE Get##PROP_NAME () {return VAR_NAME; } #define namespace_begin(NAMESPACE) namespace NAMESPACE { #define namespace_end } diff --git a/source/modules/asura-utils/Math/Matrix44.h b/source/modules/asura-utils/Math/Matrix44.h index 7b66920..503242f 100644 --- a/source/modules/asura-utils/Math/Matrix44.h +++ b/source/modules/asura-utils/Math/Matrix44.h @@ -1,97 +1,95 @@ #ifndef _ASURA_MATRIX_H_ #define _ASURA_MATRIX_H_ +#include + #include "../Scripting/Portable.hpp" -namespace AsuraEngine -{ - namespace Math - { +namespace_begin(AsuraEngine) +namespace_begin(Math) - /// - /// ҪתõOpenGLglm::mat4 - /// https://blog.csdn.net/candycat1992/article/details/8830894 - /// - class Matrix44 - { - public: +/// ҪתõOpenGLglm::mat4 +/// https://blog.csdn.net/candycat1992/article/details/8830894 +class Matrix44 +{ +public: - static const Matrix44 Identity; + static const Matrix44 Identity; - Matrix44(); + Matrix44(); - Matrix44(const Matrix44& m); + Matrix44(const Matrix44& m); - ~Matrix44(); + ~Matrix44(); - void operator = (const Matrix44& m); + void operator = (const Matrix44& m); - void SetOrtho(float _left, float _right, float _bottom, float _top, float _near, float _far); + void SetOrtho(float _left, float _right, float _bottom, float _top, float _near, float _far); - Matrix44 operator * (const Matrix44 & m) const; + Matrix44 operator * (const Matrix44 & m) const; - void operator *= (const Matrix44 & m); + void operator *= (const Matrix44 & m); - const float* GetElements() const; + const float* GetElements() const; - void SetIdentity(); + void SetIdentity(); - void SetTranslation(float x, float y); + void SetTranslation(float x, float y); - void SetRotation(float r); + void SetRotation(float r); - void SetScale(float sx, float sy); + void SetScale(float sx, float sy); - void SetShear(float kx, float ky); + void SetShear(float kx, float ky); - void SetTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy); + void SetTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy); - void Translate(float x, float y); + void Translate(float x, float y); - void Rotate(float r); + void Rotate(float r); - void Scale(float sx, float sy); + void Scale(float sx, float sy); - void Transform(float x, float y, float angle, float sx, float sy, float ox, float oy); + void Transform(float x, float y, float angle, float sx, float sy, float ox, float oy); - /// - /// Multiplies this Matrix44 with a shear transformation. - /// @param kx Shear along the x-axis. - /// @param ky Shear along the y-axis. - /// - void Shear(float kx, float ky); + /// + /// Multiplies this Matrix44 with a shear transformation. + /// @param kx Shear along the x-axis. + /// @param ky Shear along the y-axis. + /// + void Shear(float kx, float ky); - void Ortho(float left, float right, float bottom, float top, float near, float far); + void Ortho(float left, float right, float bottom, float top, float near, float far); - ///// - ///// Transforms an array of vertices by this Matrix44. The sources and - ///// destination arrays may be the same. - ///// - ///// @param dst Storage for the transformed vertices. - ///// @param src The source vertices. - ///// @param size The number of vertices. - ///// - //void transform(Graphics::Vertex* dst, const Graphics::Vertex * src, int size) const; + ///// + ///// Transforms an array of vertices by this Matrix44. The sources and + ///// destination arrays may be the same. + ///// + ///// @param dst Storage for the transformed vertices. + ///// @param src The source vertices. + ///// @param size The number of vertices. + ///// + //void transform(Graphics::Vertex* dst, const Graphics::Vertex * src, int size) const; - /// - /// ʽ - /// - float Calculate(); + /// + /// ʽ + /// + float Calculate(); - private: +private: - /// - /// | e0 e4 e8 e12 | - /// | e1 e5 e9 e13 | - /// | e2 e6 e10 e14 | - /// | e3 e7 e11 e15 | - /// - float e[16]; + /// + /// | e0 e4 e8 e12 | + /// | e1 e5 e9 e13 | + /// | e2 e6 e10 e14 | + /// | e3 e7 e11 e15 | + /// + float e[16]; - }; +}; - } -} +namespace_end +namespace_end namespace AEMath = AsuraEngine::Math; diff --git a/source/modules/asura-utils/Math/Rand/Rand.h b/source/modules/asura-utils/Math/Rand/Rand.h index efda8db..74b1102 100644 --- a/source/modules/asura-utils/Math/Rand/Rand.h +++ b/source/modules/asura-utils/Math/Rand/Rand.h @@ -25,7 +25,6 @@ Xorshift 32: 20.6 10.7 ms 4 WELL 512: 43.6 55.1 ms 68 */ - // Xorshift 128 implementation // Xorshift paper: http://www.jstatsoft.org/v08/i14/paper // Wikipedia: http://en.wikipedia.org/wiki/Xorshift diff --git a/source/modules/asura-utils/Math/Vector2.hpp b/source/modules/asura-utils/Math/Vector2.hpp index f2405eb..326a57e 100644 --- a/source/modules/asura-utils/Math/Vector2.hpp +++ b/source/modules/asura-utils/Math/Vector2.hpp @@ -1,71 +1,71 @@ #ifndef _ASURA_ENGINE_VECTOR2_H__ #define _ASURA_ENGINE_VECTOR2_H__ -namespace AsuraEngine +#include + +namespace_begin(AsuraEngine) +namespace_begin(Math) + +template +class Vector2 { - namespace Math - { - template - class Vector2 - { - public: - Vector2(); - Vector2(T X, T Y); +public: + Vector2(); + Vector2(T X, T Y); - template - explicit Vector2(const Vector2& vector); + template + explicit Vector2(const Vector2& vector); - void Set(T X, T Y); + void Set(T X, T Y); - T x; ///< X coordinate of the vector - T y; ///< Y coordinate of the vector - }; + T x; ///< X coordinate of the vector + T y; ///< Y coordinate of the vector +}; - template - Vector2 operator -(const Vector2& right); +template +Vector2 operator -(const Vector2& right); - template - Vector2& operator +=(Vector2& left, const Vector2& right); +template +Vector2& operator +=(Vector2& left, const Vector2& right); - template - Vector2& operator -=(Vector2& left, const Vector2& right); +template +Vector2& operator -=(Vector2& left, const Vector2& right); - template - Vector2 operator +(const Vector2& left, const Vector2& right); +template +Vector2 operator +(const Vector2& left, const Vector2& right); - template - Vector2 operator -(const Vector2& left, const Vector2& right); +template +Vector2 operator -(const Vector2& left, const Vector2& right); - template - Vector2 operator *(const Vector2& left, T right); +template +Vector2 operator *(const Vector2& left, T right); - template - Vector2 operator *(T left, const Vector2& right); +template +Vector2 operator *(T left, const Vector2& right); - template - Vector2& operator *=(Vector2& left, T right); +template +Vector2& operator *=(Vector2& left, T right); - template - Vector2 operator /(const Vector2& left, T right); +template +Vector2 operator /(const Vector2& left, T right); - template - Vector2& operator /=(Vector2& left, T right); +template +Vector2& operator /=(Vector2& left, T right); - template - bool operator ==(const Vector2& left, const Vector2& right); +template +bool operator ==(const Vector2& left, const Vector2& right); - template - bool operator !=(const Vector2& left, const Vector2& right); +template +bool operator !=(const Vector2& left, const Vector2& right); #include "Vector2.inc" - // Define the most common types - typedef Vector2 Vector2i; - typedef Vector2 Vector2u; - typedef Vector2 Vector2f; +typedef Vector2 Vector2i; +typedef Vector2 Vector2u; +typedef Vector2 Vector2f; - } -} +namespace_end +namespace_end namespace AEMath = AsuraEngine::Math; diff --git a/source/modules/asura-utils/Math/Vector3.hpp b/source/modules/asura-utils/Math/Vector3.hpp index 8da57cf..c526ace 100644 --- a/source/modules/asura-utils/Math/Vector3.hpp +++ b/source/modules/asura-utils/Math/Vector3.hpp @@ -230,4 +230,6 @@ namespace AsuraEngine } } +namespace AEMath = AsuraEngine::Math; + #endif \ No newline at end of file diff --git a/source/modules/asura-utils/Type.h b/source/modules/asura-utils/Type.h index f7e54c6..318145b 100644 --- a/source/modules/asura-utils/Type.h +++ b/source/modules/asura-utils/Type.h @@ -1,6 +1,7 @@ #ifndef _ASURA_UTILS_TYPE_H_ #define _ASURA_UTILS_TYPE_H_ +#include #include #include @@ -29,6 +30,8 @@ namespace AsuraEngine typedef const char cc8; +#define Assert assert + } // namespace AsuraEngine #endif // _ASURA_CONFIG_H_ \ No newline at end of file diff --git a/source/modules/asura-utils/classes.h b/source/modules/asura-utils/classes.h index d92c3d4..b2700f0 100644 --- a/source/modules/asura-utils/classes.h +++ b/source/modules/asura-utils/classes.h @@ -1,7 +1,7 @@ #ifndef _ASURAENGINE_CLASSES_H_ #define _ASURAENGINE_CLASSES_H_ -#define GET_SET(TYPE,PROP_NAME,VAR_NAME) void Set##PROP_NAME (TYPE val) { VAR_NAME = val; } const TYPE Get##PROP_NAME () const {return (const TYPE)VAR_NAME; } +#define GET_SET(TYPE,PROP_NAME,VAR_NAME) void Set##PROP_NAME (TYPE val) { VAR_NAME = val; } TYPE Get##PROP_NAME () {return VAR_NAME; } #define namespace_begin(NAMESPACE) namespace NAMESPACE { #define namespace_end } diff --git a/source/modules/asura-utils/dynamic_bitset.h b/source/modules/asura-utils/dynamic_bitset.h new file mode 100644 index 0000000..2b04d07 --- /dev/null +++ b/source/modules/asura-utils/dynamic_bitset.h @@ -0,0 +1,1150 @@ +#ifndef DYNAMIC_BITSET_H +#define DYNAMIC_BITSET_H +// (C) Copyright Chuck Allison and Jeremy Siek 2001, 2002. +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all +// copies. This software is provided "as is" without express or +// implied warranty, and with no claim as to its suitability for any +// purpose. + +// With optimizations, bug fixes, and improvements by Gennaro Prota. + +// See http://www.boost.org/libs/dynamic_bitset for documentation. + +// ------------------------------------- +// CHANGE LOG: +// +// - corrected workaround for Dinkum lib's allocate() [GP] +// - changed macro test for old iostreams [GP] +// - removed #include for now. [JGS] +// - Added __GNUC__ to compilers that cannot handle the constructor from basic_string. [JGS] +// - corrected to_block_range [GP] +// - corrected from_block_range [GP] +// - Removed __GNUC__ from compilers that cannot handle the constructor +// from basic_string and added the workaround suggested by GP. [JGS] +// - Removed __BORLANDC__ from the #if around the basic_string +// constructor. Luckily the fix by GP for g++ also fixes Borland. [JGS] + +#include +#include +#include // for memset, memcpy, memcmp, etc. +#include // for std::swap, std::min, std::copy, std::fill +#include // for std::swap, std::min, std::copy, std::fill +#include + +#include "Type.h" + +namespace std +{ + typedef ::size_t size_t; +} +// (C) Copyright Chuck Allison and Jeremy Siek 2001, 2002. +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all +// copies. This software is provided "as is" without express or +// implied warranty, and with no claim as to its suitability for any +// purpose. + +// With optimizations by Gennaro Prota. + +class dynamic_bitset_base +{ + typedef std::size_t size_type; +public: +#if defined(LINUX) && (defined (__LP64__) || defined(_AMD64_)) + typedef unsigned int Block; +#else + typedef unsigned long Block; +#endif + enum { bits_per_block = 8 * sizeof(Block) }; + + dynamic_bitset_base() + : m_bits(0), m_num_bits(0), m_num_blocks(0) { } + + dynamic_bitset_base(size_type num_bits) : + m_num_bits(num_bits), + m_num_blocks(calc_num_blocks(num_bits)) + { + if (m_num_blocks != 0) + { + m_bits = new Block[m_num_blocks]; + memset(m_bits, 0, m_num_blocks * sizeof(Block)); // G.P.S. ask to Jeremy + } + else + m_bits = 0; + } + ~dynamic_bitset_base() { + delete[]m_bits;; + } + + Block* m_bits; + size_type m_num_bits; + size_type m_num_blocks; + + static size_type word(size_type bit) { return bit / bits_per_block; } // [gps] + static size_type offset(size_type bit) { return bit % bits_per_block; } // [gps] + static Block mask1(size_type bit) { return Block(1) << offset(bit); } + static Block mask0(size_type bit) { return ~(Block(1) << offset(bit)); } + static size_type calc_num_blocks(size_type num_bits) + { + return (num_bits + bits_per_block - 1) / bits_per_block; + } +}; + + +// ------- count table implementation -------------- + +typedef unsigned char byte_t; + +template +struct bitcount { + typedef byte_t element_type; + static const byte_t table[]; + +}; +//typedef count table_t; + + +// the table: wrapped in a class template, so +// that it is only instantiated if/when needed +// +template +const byte_t bitcount::table[] = +{ + // Automatically generated by GPTableGen.exe v.1.0 + // +0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, +1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, +1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, +2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, +1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, +2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, +2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, +3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; + + +// ------------------------------------------------------- +template +std::size_t initial_num_blocks(BlockInputIterator first, + BlockInputIterator last) +{ + std::size_t n = 0; + while (first != last) + ++first, ++n; + return n; +} + +class dynamic_bitset : public dynamic_bitset_base +{ +public: + + typedef Block block_type; + typedef std::size_t size_type; + enum { bits_per_block = 8 * sizeof(Block) }; + + // reference to a bit + class reference + { + friend class dynamic_bitset; + dynamic_bitset* bs; + size_type bit; + reference(); // intentionally not implemented + reference(dynamic_bitset& bs_, size_type bit_) : bs(&bs_), bit(bit_) { } + public: + reference& operator=(bool value) // for b[i] = x + { + if (value) + bs->set(bit); + else + bs->reset(bit); + return *this; + } + reference& operator|=(bool value) // for b[i] |= x + { + if (value) + bs->set(bit); + return *this; + } + reference& operator&=(bool value) // for b[i] &= x + { + if (!(value && bs->test(bit))) + bs->reset(bit); + return *this; + } + reference& operator^=(bool value) // for b[i] ^= x + { + bs->set(bit, bs->test(bit) ^ value); + return *this; + } + reference& operator-=(bool value) // for b[i] -= x + { + if (!value) + bs->reset(bit); + return *this; + } + reference& operator=(const reference& j) // for b[i] = b[j] + { + if (j.bs->test(j.bit)) + bs->set(bit); + else + bs->reset(bit); + return *this; + } + reference& operator|=(const reference& j) // for b[i] |= b[j] + { + if (j.bs->test(j.bit)) + bs->set(bit); + return *this; + } + reference& operator&=(const reference& j) // for b[i] &= b[j] + { + if (!(j.bs->test(j.bit) && bs->test(bit))) + bs->reset(bit); + return *this; + } + reference& operator^=(const reference& j) // for b[i] ^= b[j] + { + bs->set(bit, bs->test(bit) ^ j.bs->test(j.bit)); + return *this; + } + reference& operator-=(const reference& j) // for b[i] -= b[j] + { + if (!j.bs->test(j.bit)) + bs->reset(bit); + return *this; + } + bool operator~() const // flips the bit + { + return !bs->test(bit); + } + operator bool() const // for x = b[i] + { + return bs->test(bit); + } + reference& flip() // for b[i].flip(); + { + bs->flip(bit); + return *this; + } + }; + typedef bool const_reference; + + dynamic_bitset(); + explicit + dynamic_bitset(size_type num_bits, unsigned long value = 0); + + // The parenthesis around std::basic_string::npos + // in the code below are to avoid a g++ 3.2 bug and a Borland bug. -JGS + template + explicit + dynamic_bitset(const String& s, + typename String::size_type pos = 0, + typename String::size_type n + = (String::npos)) + : dynamic_bitset_base + (std::min(n, s.size() - pos)) + { + // Locate sub string + Assert(pos > s.length()); + from_string(s, pos, std::min(n, s.size() - pos)); + } + + // The first bit in *first is the least significant bit, and the + // last bit in the block just before *last is the most significant bit. + template + dynamic_bitset(BlockInputIterator first, BlockInputIterator last) + : dynamic_bitset_base + (initial_num_blocks(first, last) + * bits_per_block) + { + if (first != last) { + if (this->m_num_bits == 0) { // dealing with input iterators + this->append(first, last); + } + else { + // dealing with forward iterators, memory has been allocated + for (std::size_t i = 0; first != last; ++first, ++i) + set_block_(i, *first); + } + } + } + + + // copy constructor + dynamic_bitset(const dynamic_bitset& b); + + void swap(dynamic_bitset& b); + + dynamic_bitset& operator=(const dynamic_bitset& b); + + // size changing operations + void resize(size_type num_bits, bool value = false); + void clear(); + void push_back(bool bit); + void append(Block block); + + // This is declared inside the class to avoid compiler bugs. + template + void append(BlockInputIterator first, BlockInputIterator last) + { + if (first != last) { + std::size_t nblocks = initial_num_blocks(first, last); + if (nblocks == 0) { // dealing with input iterators + for (; first != last; ++first) + append(*first); + } + else { // dealing with forward iterators + if (size() % bits_per_block == 0) { + std::size_t old_nblocks = this->m_num_blocks; + resize(size() + nblocks * bits_per_block); + for (std::size_t i = old_nblocks; first != last; ++first) + set_block_(i++, *first); + } + else { + // probably should optimize this, + // but I'm sick of bit twiddling + for (; first != last; ++first) + append(*first); + } + } + } + } + + + // bitset operations + dynamic_bitset& operator&=(const dynamic_bitset& b); + dynamic_bitset& operator|=(const dynamic_bitset& b); + dynamic_bitset& operator^=(const dynamic_bitset& b); + dynamic_bitset& operator-=(const dynamic_bitset& b); + dynamic_bitset& operator<<=(size_type n); + dynamic_bitset& operator>>=(size_type n); + dynamic_bitset operator<<(size_type n) const; + dynamic_bitset operator>>(size_type n) const; + + // basic bit operations + dynamic_bitset& set(size_type n, bool val = true); + dynamic_bitset& set(); + dynamic_bitset& reset(size_type n); + dynamic_bitset& reset(); + dynamic_bitset& flip(size_type n); + dynamic_bitset& flip(); + bool test(size_type n) const; + bool any() const; + bool none() const; + dynamic_bitset operator~() const; + size_type count() const; + + // subscript + reference operator[](size_type pos) { return reference(*this, pos); } + bool operator[](size_type pos) const + { +#if ASURA_EDITOR + if (pos < this->m_num_bits) + return test_(pos); + else + { + //ErrorString("dynamic_bitset.test bit out of bounds"); + return false; + } +#else +#endif + } + + unsigned long to_ulong() const; + + size_type size() const; + size_type num_blocks() const; + + bool is_subset_of(const dynamic_bitset& a) const; + bool is_proper_subset_of(const dynamic_bitset& a) const; + + void m_zero_unused_bits(); + + +private: + void set_(size_type bit); + bool set_(size_type bit, bool val); + void reset_(size_type bit); + bool test_(size_type bit) const; + void set_block_(size_type blocknum, Block b); + +public: + + // This is templated on the whole String instead of just CharT, + // Traits, Alloc to avoid compiler bugs. + template + void from_string(const String& s, typename String::size_type pos, + typename String::size_type rlen) + { + reset(); // bugfix [gps] + size_type const tot = std::min(rlen, s.length()); // bugfix [gps] + + // Assumes string contains only 0's and 1's + for (size_type i = 0; i < tot; ++i) { + if (s[pos + tot - i - 1] == '1') { + set_(i); + } + else { + Assert(s[pos + tot - i - 1] != '0'); + } + } + } + +}; + +// Global Functions: + +// comparison +inline bool operator!=(const dynamic_bitset& a, + const dynamic_bitset& b); + +inline bool operator<=(const dynamic_bitset& a, + const dynamic_bitset& b); + +inline bool operator>(const dynamic_bitset& a, + const dynamic_bitset& b); + +inline bool operator>=(const dynamic_bitset& a, + const dynamic_bitset& b); + +// bitset operations +inline dynamic_bitset +operator&(const dynamic_bitset& b1, + const dynamic_bitset& b2); + +inline dynamic_bitset +operator|(const dynamic_bitset& b1, + const dynamic_bitset& b2); + +inline dynamic_bitset +operator^(const dynamic_bitset& b1, + const dynamic_bitset& b2); + +inline dynamic_bitset +operator-(const dynamic_bitset& b1, + const dynamic_bitset& b2); + + +template +void +to_string(const dynamic_bitset& b, + String& s); + +template +void +to_block_range(const dynamic_bitset& b, + BlockOutputIterator result); + +template +inline void +from_block_range(BlockIterator first, BlockIterator last, + dynamic_bitset& result); + + +//============================================================================= +// dynamic_bitset implementation + + +//----------------------------------------------------------------------------- +// constructors, etc. + +inline dynamic_bitset::dynamic_bitset() + : dynamic_bitset_base(0) { } + +inline dynamic_bitset:: +dynamic_bitset(size_type num_bits, unsigned long value) + : dynamic_bitset_base(num_bits) +{ + const size_type M = std::min(sizeof(unsigned long) * 8, num_bits); + for (size_type i = 0; i < M; ++i, value >>= 1) // [G.P.S.] to be optimized + if (value & 0x1) + set_(i); +} + +// copy constructor +inline dynamic_bitset:: +dynamic_bitset(const dynamic_bitset& b) + : dynamic_bitset_base(b.size()) +{ + memcpy(this->m_bits, b.m_bits, this->m_num_blocks * sizeof(Block)); +} + +inline void dynamic_bitset:: +swap(dynamic_bitset& b) +{ + std::swap(this->m_bits, b.m_bits); + std::swap(this->m_num_bits, b.m_num_bits); + std::swap(this->m_num_blocks, b.m_num_blocks); +} + +inline dynamic_bitset& dynamic_bitset:: +operator=(const dynamic_bitset& b) +{ + dynamic_bitset tmp(b); + this->swap(tmp); + return *this; +} + +//----------------------------------------------------------------------------- +// size changing operations + +inline void dynamic_bitset:: +resize(size_type num_bits, bool value) +{ + if (num_bits == size()) + return; + if (num_bits == 0) + { + this->m_num_bits = 0; + this->m_num_blocks = 0; + delete this->m_bits; + this->m_bits = 0; + return; + } + size_type new_nblocks = this->calc_num_blocks(num_bits); + Block* d = new Block[new_nblocks]; + if (num_bits < size()) { // shrink + std::copy(this->m_bits, this->m_bits + new_nblocks, d); + std::swap(d, this->m_bits); + delete[]d; + } + else { // grow + std::copy(this->m_bits, this->m_bits + this->m_num_blocks, d); + Block val = value ? ~static_cast(0) : static_cast(0); + std::fill(d + this->m_num_blocks, d + new_nblocks, val); + std::swap(d, this->m_bits); + for (std::size_t i = this->m_num_bits; + i < this->m_num_blocks * bits_per_block; ++i) + set_(i, value); + if (d != 0) + delete[]d; + } + this->m_num_bits = num_bits; + this->m_num_blocks = this->calc_num_blocks(num_bits); + m_zero_unused_bits(); +} + +inline void dynamic_bitset:: +clear() +{ + if (this->m_bits != 0) { + delete this->m_bits; + this->m_bits = 0; + this->m_num_bits = 0; + this->m_num_blocks = 0; + } +} + + +inline void dynamic_bitset:: +push_back(bool bit) +{ + this->resize(this->size() + 1); + set_(this->size() - 1, bit); +} + +inline void dynamic_bitset:: +append(Block value) +{ + std::size_t old_size = size(); + resize(old_size + bits_per_block); + if (size() % bits_per_block == 0) + set_block_(this->m_num_blocks - 1, value); + else { + // G.P.S. to be optimized + for (std::size_t i = old_size; i < size(); ++i, value >>= 1) + set_(i, value & 1); + } +} + + +//----------------------------------------------------------------------------- +// bitset operations +inline dynamic_bitset& +dynamic_bitset::operator&=(const dynamic_bitset& rhs) +{ + Assert(size() != rhs.size()); + for (size_type i = 0; i < this->m_num_blocks; ++i) + this->m_bits[i] &= rhs.m_bits[i]; + return *this; +} + +inline dynamic_bitset& +dynamic_bitset::operator|=(const dynamic_bitset& rhs) +{ + Assert(size() != rhs.size()); + for (size_type i = 0; i < this->m_num_blocks; ++i) + this->m_bits[i] |= rhs.m_bits[i]; + m_zero_unused_bits(); + return *this; +} + +inline dynamic_bitset& +dynamic_bitset::operator^=(const dynamic_bitset& rhs) +{ + Assert(size() != rhs.size()); + for (size_type i = 0; i < this->m_num_blocks; ++i) + this->m_bits[i] ^= rhs.m_bits[i]; + m_zero_unused_bits(); + return *this; +} + +inline dynamic_bitset& +dynamic_bitset::operator-=(const dynamic_bitset& rhs) +{ + Assert(size() != rhs.size()); + for (size_type i = 0; i < this->m_num_blocks; ++i) + this->m_bits[i] = this->m_bits[i] & ~rhs.m_bits[i]; + m_zero_unused_bits(); + return *this; +} + +inline dynamic_bitset& +dynamic_bitset::operator<<=(size_type n) +{ + if (n >= this->m_num_bits) + return reset(); + //else + if (n > 0) + { + size_type const last = this->m_num_blocks - 1; // m_num_blocks is >= 1 + size_type const div = n / bits_per_block; // div is <= last + size_type const r = n % bits_per_block; + + // PRE: div != 0 or r != 0 + + if (r != 0) { + + block_type const rs = bits_per_block - r; + + for (size_type i = last - div; i > 0; --i) { + this->m_bits[i + div] = (this->m_bits[i] << r) | (this->m_bits[i - 1] >> rs); + } + this->m_bits[div] = this->m_bits[0] << r; + + } + else { + for (size_type i = last - div; i > 0; --i) { + this->m_bits[i + div] = this->m_bits[i]; + } + this->m_bits[div] = this->m_bits[0]; + } + + + // div blocks are zero filled at the less significant end + std::fill(this->m_bits, this->m_bits + div, static_cast(0)); + + + } + + return *this; + + +} + + + + + + + +// NOTE: this assumes that within a single block bits are +// numbered from right to left. G.P.S. +// +// static Block offset(size_type bit) +// { return bit % bits_per_block; } +// +// +// In the implementation below the 'if (r != 0)' is logically +// unnecessary. It's there as an optimization only: in fact +// for r==0 the first branch becomes the second one with the +// b[last-div] = b[last] >> r; statement that does the work of +// the last iteration. +// +inline +dynamic_bitset & dynamic_bitset::operator>>=(size_type n) { + if (n >= this->m_num_bits) { + return reset(); + } + //else + if (n > 0) { + + size_type const last = this->m_num_blocks - 1; // m_num_blocks is >= 1 + size_type const div = n / bits_per_block; // div is <= last + size_type const r = n % bits_per_block; + + // PRE: div != 0 or r != 0 + + if (r != 0) { + + block_type const ls = bits_per_block - r; + + for (size_type i = div; i < last; ++i) { + this->m_bits[i - div] = (this->m_bits[i] >> r) | (this->m_bits[i + 1] << ls); + } + // r bits go to zero + this->m_bits[last - div] = this->m_bits[last] >> r; + } + + else { + for (size_type i = div; i <= last; ++i) { + this->m_bits[i - div] = this->m_bits[i]; + } + // note the '<=': the last iteration 'absorbs' + // this->m_bits[last-div] = this->m_bits[last] >> 0; + } + + + + // div blocks are zero filled at the most significant end + std::fill(this->m_bits + (this->m_num_blocks - div), this->m_bits + this->m_num_blocks, static_cast(0)); + } + + return *this; +} + + + + + + + +inline dynamic_bitset +dynamic_bitset::operator<<(size_type n) const +{ + dynamic_bitset r(*this); + return r <<= n; +} + +inline dynamic_bitset +dynamic_bitset::operator>>(size_type n) const +{ + dynamic_bitset r(*this); + return r >>= n; +} + + +//----------------------------------------------------------------------------- +// basic bit operations + +inline dynamic_bitset& +dynamic_bitset::set(size_type pos, bool val) +{ + Assert(pos >= this->m_num_bits); + set_(pos, val); + return *this; +} + +inline dynamic_bitset& +dynamic_bitset::set() +{ + if (this->m_num_bits > 0) { + using namespace std; + memset(this->m_bits, ~0u, this->m_num_blocks * sizeof(this->m_bits[0])); + m_zero_unused_bits(); + } + return *this; +} + +inline dynamic_bitset& +dynamic_bitset::reset(size_type pos) +{ + Assert(pos >= this->m_num_bits); + reset_(pos); + return *this; +} + +inline dynamic_bitset& +dynamic_bitset::reset() +{ + if (this->m_num_bits > 0) { + using namespace std; + memset(this->m_bits, 0, this->m_num_blocks * sizeof(this->m_bits[0])); + } + return *this; +} + +inline dynamic_bitset& +dynamic_bitset::flip(size_type pos) +{ + Assert(pos >= this->m_num_bits); + this->m_bits[this->word(pos)] ^= this->mask1(pos); + return *this; +} + +inline dynamic_bitset& +dynamic_bitset::flip() +{ + for (size_type i = 0; i < this->m_num_blocks; ++i) + this->m_bits[i] = ~this->m_bits[i]; + m_zero_unused_bits(); + return *this; +} + +inline bool dynamic_bitset::test(size_type pos) const +{ +#if ASURA_EDITOR + if (pos < this->m_num_bits) + return test_(pos); + else + { + //ErrorString("dynamic_bitset.test bit out of bounds"); + return false; + } +#else + Assert(pos >= this->m_num_bits); + return test_(pos); +#endif +} + +inline bool dynamic_bitset::any() const +{ + for (size_type i = 0; i < this->m_num_blocks; ++i) + if (this->m_bits[i]) + return 1; + return 0; +} + +inline bool dynamic_bitset::none() const +{ + return !any(); +} + +inline dynamic_bitset +dynamic_bitset::operator~() const +{ + dynamic_bitset b(*this); + b.flip(); + return b; +} + + +/* snipped: [gps] + +The following is the straightforward implementation of count(), which +we leave here in a comment for documentation purposes. + +template +typename dynamic_bitset::size_type +dynamic_bitset::count() const +{ + size_type sum = 0; + for (size_type i = 0; i != this->m_num_bits; ++i) + if (test_(i)) + ++sum; + return sum; +} + +The actual algorithm used is based on using a lookup +table. + + + The basic idea of the method is to pick up X bits at a time + from the internal array of blocks and consider those bits as + the binary representation of a number N. Then, to use a table + of 1<::max_bits) and + the internal array of blocks is seen as an array of bytes: if + a byte has exactly 8 bits then it's enough to sum the value + of table[B] for each byte B. Otherwise 8 bits at a time are + 'extracted' from each byte by using another loop. As a further + efficiency consideration note that even if you have, let's say, + 32-bit chars the inner loop will not do 4 (i.e. 32/8) iterations, + unless you have at least one bit set in the highest 8 bits of the + byte. + + Note also that the outmost if/else is not necessary but is there + to help the optimizer (and one of the two branches is always dead + code). + + Aras: hardcoded table to be always max_bits=8. To help not so good compilers. + +*/ + + +inline dynamic_bitset::size_type +dynamic_bitset::count() const +{ + const byte_t * p = reinterpret_cast(this->m_bits); + const byte_t * past_end = p + this->m_num_blocks * sizeof(Block); + + size_type num = 0; + + while (p < past_end) { + num += bitcount<>::table[*p]; + ++p; + } + + return num; +} + + +//----------------------------------------------------------------------------- +// conversions + +// take as ref param instead? +template +void +to_string(const dynamic_bitset& b, + std::basic_string& s) +{ + s.assign(b.size(), '0'); + for (std::size_t i = 0; i < b.size(); ++i) + if (b.test(i)) // [G.P.S.] + s[b.size() - 1 - i] = '1'; +} + + +// Differently from to_string this function dumps out +// every bit of the internal representation (useful +// for debugging purposes) +// +template +void +dump_to_string(const dynamic_bitset& b, + std::basic_string& s) +{ + std::size_t const len = b.m_num_blocks * (dynamic_bitset::bits_per_block); + s.assign(len, '0'); + for (std::size_t i = 0; i != len; ++i) + if (b[i])// could use test_ here, but we have friend issues.-JGS + s[len - 1 - i] = '1'; +} + + + +template +void +to_block_range(const dynamic_bitset& b, + BlockOutputIterator result) +{ + Assert(!(b.size() != 0 || b.num_blocks() == 0)); + std::copy(b.m_bits, b.m_bits + b.m_num_blocks, result); +} + +template +inline void +from_block_range(BlockIterator first, BlockIterator last, + dynamic_bitset& result) +{ + Assert(std::distance(first, last) != result.num_blocks()); + std::copy(first, last, result.m_bits); + result.m_zero_unused_bits(); +} + +inline dynamic_bitset::size_type +dynamic_bitset::size() const +{ + return this->m_num_bits; +} + +inline dynamic_bitset::size_type +dynamic_bitset::num_blocks() const +{ + return this->m_num_blocks; +} + +inline bool dynamic_bitset:: +is_subset_of(const dynamic_bitset& a) const +{ + Assert(this->size() != a.size()); + for (size_type i = 0; i < this->m_num_blocks; ++i) + if (this->m_bits[i] & ~a.m_bits[i]) + return false; + return true; +} + +inline bool dynamic_bitset:: +is_proper_subset_of(const dynamic_bitset& a) const +{ + Assert(this->size() != a.size()); + bool proper = false; + for (size_type i = 0; i < this->m_num_blocks; ++i) { + Block bt = this->m_bits[i], ba = a.m_bits[i]; + if (ba & ~bt) + proper = true; + if (bt & ~ba) + return false; + } + return proper; +} + +//----------------------------------------------------------------------------- +// comparison + +inline bool operator==(const dynamic_bitset& a, + const dynamic_bitset& b) +{ + using namespace std; + return (a.m_num_bits == b.m_num_bits) && + ((a.m_num_bits == 0) || + !memcmp(a.m_bits, b.m_bits, a.m_num_blocks * sizeof(a.m_bits[0]))); +} + +inline bool operator!=(const dynamic_bitset& a, + const dynamic_bitset& b) +{ + return !(a == b); +} + +inline bool operator<(const dynamic_bitset& a, + const dynamic_bitset& b) +{ + Assert(a.size() != b.size()); + typedef dynamic_bitset::size_type size_type; + + if (a.size() == 0) + return false; + + // Since we are storing the most significant bit + // at pos == size() - 1, we need to do the memcmp in reverse. + + // Compare a block at a time + for (size_type i = a.m_num_blocks - 1; i > 0; --i) + if (a.m_bits[i] < b.m_bits[i]) + return true; + else if (a.m_bits[i] > b.m_bits[i]) + return false; + + if (a.m_bits[0] < b.m_bits[0]) + return true; + else + return false; +} + +inline bool operator<=(const dynamic_bitset& a, + const dynamic_bitset& b) +{ + return !(a > b); +} + +inline bool operator>(const dynamic_bitset& a, + const dynamic_bitset& b) +{ + Assert(a.size() != b.size()); + typedef dynamic_bitset::size_type size_type; + + if (a.size() == 0) + return false; + + // Since we are storing the most significant bit + // at pos == size() - 1, we need to do the memcmp in reverse. + + // Compare a block at a time + for (size_type i = a.m_num_blocks - 1; i > 0; --i) + if (a.m_bits[i] < b.m_bits[i]) + return false; + else if (a.m_bits[i] > b.m_bits[i]) + return true; + + if (a.m_bits[0] > b.m_bits[0]) + return true; + else + return false; +} + +inline bool operator>=(const dynamic_bitset& a, + const dynamic_bitset& b) +{ + return !(a < b); +} + +//----------------------------------------------------------------------------- +// bitset operations + +inline dynamic_bitset +operator&(const dynamic_bitset& x, + const dynamic_bitset& y) +{ + dynamic_bitset b(x); + return b &= y; +} + +inline dynamic_bitset +operator|(const dynamic_bitset& x, + const dynamic_bitset& y) +{ + dynamic_bitset b(x); + return b |= y; +} + +inline dynamic_bitset +operator^(const dynamic_bitset& x, + const dynamic_bitset& y) +{ + dynamic_bitset b(x); + return b ^= y; +} + +inline dynamic_bitset +operator-(const dynamic_bitset& x, + const dynamic_bitset& y) +{ + dynamic_bitset b(x); + return b -= y; +} + + +//----------------------------------------------------------------------------- +// private member functions + +inline void dynamic_bitset:: +set_(size_type bit) +{ + this->m_bits[this->word(bit)] |= this->mask1(bit); +} + +inline void dynamic_bitset:: +set_block_(size_type blocknum, Block value) +{ + this->m_bits[blocknum] = value; +} + +inline void dynamic_bitset:: +reset_(size_type b) +{ + this->m_bits[this->word(b)] &= this->mask0(b); +} + +inline bool dynamic_bitset::test_(size_type b) const +{ + return (this->m_bits[this->word(b)] & this->mask1(b)) != static_cast(0); +} + +inline bool dynamic_bitset::set_(size_type n, bool value) +{ + if (value) + set_(n); + else + reset_(n); + return value != static_cast(0); +} + + +// If size() is not a multiple of bits_per_block +// then not all the bits in the last block are used. +// This function resets the unused bits (convenient +// for the implementation of many member functions) +// +inline void dynamic_bitset::m_zero_unused_bits() +{ + Assert(this->m_num_blocks != this->calc_num_blocks(this->m_num_bits)); + + // if != 0 this is the number of bits used in the last block + const size_type used_bits = this->m_num_bits % bits_per_block; + + if (used_bits != 0) + this->m_bits[this->m_num_blocks - 1] &= ~(~static_cast(0) << used_bits); + +} + +#endif diff --git a/source/modules/asura-utils/math/matrix44.h b/source/modules/asura-utils/math/matrix44.h index 7b66920..503242f 100644 --- a/source/modules/asura-utils/math/matrix44.h +++ b/source/modules/asura-utils/math/matrix44.h @@ -1,97 +1,95 @@ #ifndef _ASURA_MATRIX_H_ #define _ASURA_MATRIX_H_ +#include + #include "../Scripting/Portable.hpp" -namespace AsuraEngine -{ - namespace Math - { +namespace_begin(AsuraEngine) +namespace_begin(Math) - /// - /// ҪתõOpenGLglm::mat4 - /// https://blog.csdn.net/candycat1992/article/details/8830894 - /// - class Matrix44 - { - public: +/// ҪתõOpenGLglm::mat4 +/// https://blog.csdn.net/candycat1992/article/details/8830894 +class Matrix44 +{ +public: - static const Matrix44 Identity; + static const Matrix44 Identity; - Matrix44(); + Matrix44(); - Matrix44(const Matrix44& m); + Matrix44(const Matrix44& m); - ~Matrix44(); + ~Matrix44(); - void operator = (const Matrix44& m); + void operator = (const Matrix44& m); - void SetOrtho(float _left, float _right, float _bottom, float _top, float _near, float _far); + void SetOrtho(float _left, float _right, float _bottom, float _top, float _near, float _far); - Matrix44 operator * (const Matrix44 & m) const; + Matrix44 operator * (const Matrix44 & m) const; - void operator *= (const Matrix44 & m); + void operator *= (const Matrix44 & m); - const float* GetElements() const; + const float* GetElements() const; - void SetIdentity(); + void SetIdentity(); - void SetTranslation(float x, float y); + void SetTranslation(float x, float y); - void SetRotation(float r); + void SetRotation(float r); - void SetScale(float sx, float sy); + void SetScale(float sx, float sy); - void SetShear(float kx, float ky); + void SetShear(float kx, float ky); - void SetTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy); + void SetTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy); - void Translate(float x, float y); + void Translate(float x, float y); - void Rotate(float r); + void Rotate(float r); - void Scale(float sx, float sy); + void Scale(float sx, float sy); - void Transform(float x, float y, float angle, float sx, float sy, float ox, float oy); + void Transform(float x, float y, float angle, float sx, float sy, float ox, float oy); - /// - /// Multiplies this Matrix44 with a shear transformation. - /// @param kx Shear along the x-axis. - /// @param ky Shear along the y-axis. - /// - void Shear(float kx, float ky); + /// + /// Multiplies this Matrix44 with a shear transformation. + /// @param kx Shear along the x-axis. + /// @param ky Shear along the y-axis. + /// + void Shear(float kx, float ky); - void Ortho(float left, float right, float bottom, float top, float near, float far); + void Ortho(float left, float right, float bottom, float top, float near, float far); - ///// - ///// Transforms an array of vertices by this Matrix44. The sources and - ///// destination arrays may be the same. - ///// - ///// @param dst Storage for the transformed vertices. - ///// @param src The source vertices. - ///// @param size The number of vertices. - ///// - //void transform(Graphics::Vertex* dst, const Graphics::Vertex * src, int size) const; + ///// + ///// Transforms an array of vertices by this Matrix44. The sources and + ///// destination arrays may be the same. + ///// + ///// @param dst Storage for the transformed vertices. + ///// @param src The source vertices. + ///// @param size The number of vertices. + ///// + //void transform(Graphics::Vertex* dst, const Graphics::Vertex * src, int size) const; - /// - /// ʽ - /// - float Calculate(); + /// + /// ʽ + /// + float Calculate(); - private: +private: - /// - /// | e0 e4 e8 e12 | - /// | e1 e5 e9 e13 | - /// | e2 e6 e10 e14 | - /// | e3 e7 e11 e15 | - /// - float e[16]; + /// + /// | e0 e4 e8 e12 | + /// | e1 e5 e9 e13 | + /// | e2 e6 e10 e14 | + /// | e3 e7 e11 e15 | + /// + float e[16]; - }; +}; - } -} +namespace_end +namespace_end namespace AEMath = AsuraEngine::Math; diff --git a/source/modules/asura-utils/math/vector2.hpp b/source/modules/asura-utils/math/vector2.hpp index f2405eb..326a57e 100644 --- a/source/modules/asura-utils/math/vector2.hpp +++ b/source/modules/asura-utils/math/vector2.hpp @@ -1,71 +1,71 @@ #ifndef _ASURA_ENGINE_VECTOR2_H__ #define _ASURA_ENGINE_VECTOR2_H__ -namespace AsuraEngine +#include + +namespace_begin(AsuraEngine) +namespace_begin(Math) + +template +class Vector2 { - namespace Math - { - template - class Vector2 - { - public: - Vector2(); - Vector2(T X, T Y); +public: + Vector2(); + Vector2(T X, T Y); - template - explicit Vector2(const Vector2& vector); + template + explicit Vector2(const Vector2& vector); - void Set(T X, T Y); + void Set(T X, T Y); - T x; ///< X coordinate of the vector - T y; ///< Y coordinate of the vector - }; + T x; ///< X coordinate of the vector + T y; ///< Y coordinate of the vector +}; - template - Vector2 operator -(const Vector2& right); +template +Vector2 operator -(const Vector2& right); - template - Vector2& operator +=(Vector2& left, const Vector2& right); +template +Vector2& operator +=(Vector2& left, const Vector2& right); - template - Vector2& operator -=(Vector2& left, const Vector2& right); +template +Vector2& operator -=(Vector2& left, const Vector2& right); - template - Vector2 operator +(const Vector2& left, const Vector2& right); +template +Vector2 operator +(const Vector2& left, const Vector2& right); - template - Vector2 operator -(const Vector2& left, const Vector2& right); +template +Vector2 operator -(const Vector2& left, const Vector2& right); - template - Vector2 operator *(const Vector2& left, T right); +template +Vector2 operator *(const Vector2& left, T right); - template - Vector2 operator *(T left, const Vector2& right); +template +Vector2 operator *(T left, const Vector2& right); - template - Vector2& operator *=(Vector2& left, T right); +template +Vector2& operator *=(Vector2& left, T right); - template - Vector2 operator /(const Vector2& left, T right); +template +Vector2 operator /(const Vector2& left, T right); - template - Vector2& operator /=(Vector2& left, T right); +template +Vector2& operator /=(Vector2& left, T right); - template - bool operator ==(const Vector2& left, const Vector2& right); +template +bool operator ==(const Vector2& left, const Vector2& right); - template - bool operator !=(const Vector2& left, const Vector2& right); +template +bool operator !=(const Vector2& left, const Vector2& right); #include "Vector2.inc" - // Define the most common types - typedef Vector2 Vector2i; - typedef Vector2 Vector2u; - typedef Vector2 Vector2f; +typedef Vector2 Vector2i; +typedef Vector2 Vector2u; +typedef Vector2 Vector2f; - } -} +namespace_end +namespace_end namespace AEMath = AsuraEngine::Math; diff --git a/source/modules/asura-utils/math/vector3.hpp b/source/modules/asura-utils/math/vector3.hpp index 8da57cf..c526ace 100644 --- a/source/modules/asura-utils/math/vector3.hpp +++ b/source/modules/asura-utils/math/vector3.hpp @@ -230,4 +230,6 @@ namespace AsuraEngine } } +namespace AEMath = AsuraEngine::Math; + #endif \ No newline at end of file diff --git a/source/modules/asura-utils/type.h b/source/modules/asura-utils/type.h index f7e54c6..318145b 100644 --- a/source/modules/asura-utils/type.h +++ b/source/modules/asura-utils/type.h @@ -1,6 +1,7 @@ #ifndef _ASURA_UTILS_TYPE_H_ #define _ASURA_UTILS_TYPE_H_ +#include #include #include @@ -29,6 +30,8 @@ namespace AsuraEngine typedef const char cc8; +#define Assert assert + } // namespace AsuraEngine #endif // _ASURA_CONFIG_H_ \ No newline at end of file -- cgit v1.1-26-g67d0