diff --git a/ClassicalSharp/Math/Vector3.cs b/ClassicalSharp/Math/Vector3.cs
index 07a7232f6..afa52dd44 100644
--- a/ClassicalSharp/Math/Vector3.cs
+++ b/ClassicalSharp/Math/Vector3.cs
@@ -47,7 +47,7 @@ namespace OpenTK {
public static readonly Vector3 UnitZ = new Vector3(0, 0, 1);
public static readonly Vector3 Zero = new Vector3(0, 0, 0);
- public static readonly Vector3 One = new Vector3(1, 1, 1);
+ public static readonly Vector3 One = new Vector3(1, 1, 1);
public static Vector3 Lerp(Vector3 a, Vector3 b, float blend) {
a.X = blend * (b.X - a.X) + a.X;
diff --git a/src/Animations.c b/src/Animations.c
index 24b2010c3..ce4aa5634 100644
--- a/src/Animations.c
+++ b/src/Animations.c
@@ -4,7 +4,7 @@
#include "Platform.h"
#include "Event.h"
#include "Funcs.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Chat.h"
#include "World.h"
#include "Options.h"
diff --git a/src/AxisLinesRenderer.c b/src/AxisLinesRenderer.c
index 6b90624bb..26056eac8 100644
--- a/src/AxisLinesRenderer.c
+++ b/src/AxisLinesRenderer.c
@@ -1,5 +1,5 @@
#include "AxisLinesRenderer.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Game.h"
#include "GraphicsCommon.h"
#include "SelectionBox.h"
diff --git a/src/Builder.c b/src/Builder.c
index 59f7f2838..bee92cef9 100644
--- a/src/Builder.c
+++ b/src/Builder.c
@@ -5,7 +5,7 @@
#include "Lighting.h"
#include "Platform.h"
#include "MapRenderer.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "ErrorHandler.h"
#include "Drawer.h"
#include "ExtMath.h"
diff --git a/src/Camera.c b/src/Camera.c
index c0e5a2341..ee3e75e97 100644
--- a/src/Camera.c
+++ b/src/Camera.c
@@ -2,7 +2,7 @@
#include "ExtMath.h"
#include "Game.h"
#include "Window.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Funcs.h"
#include "Gui.h"
#include "Entity.h"
diff --git a/src/Chat.c b/src/Chat.c
index f2a9cfa14..0c33708e5 100644
--- a/src/Chat.c
+++ b/src/Chat.c
@@ -9,13 +9,16 @@
#include "Inventory.h"
#include "Entity.h"
#include "Window.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "GraphicsCommon.h"
#include "Funcs.h"
#include "Block.h"
#include "EnvRenderer.h"
#include "GameStructs.h"
+/*########################################################################################################################*
+*-------------------------------------------------------Chat logging------------------------------------------------------*
+*#########################################################################################################################*/
#define CHAT_LOGTIMES_DEF_ELEMS 256
TimeMS Chat_DefaultLogTimes[CHAT_LOGTIMES_DEF_ELEMS];
TimeMS* Chat_LogTimes = Chat_DefaultLogTimes;
@@ -36,12 +39,6 @@ static void Chat_AppendLogTime(void) {
Chat_LogTimes[Chat_LogTimesCount++] = now;
}
-static void ChatLine_Make(struct ChatLine* line, const String* text) {
- String dst = String_ClearedArray(line->Buffer);
- String_AppendString(&dst, text);
- line->Received = DateTime_CurrentUTC_MS();
-}
-
char Chat_LogNameBuffer[STRING_SIZE];
String Chat_LogName = String_FromArray(Chat_LogNameBuffer);
char Chat_LogPathBuffer[FILENAME_SIZE];
@@ -141,6 +138,12 @@ static void Chat_AppendLog(const String* text) {
Chat_LogError2(res, "writing to", &Chat_LogPath);
}
+static void ChatLine_Make(struct ChatLine* line, const String* text) {
+ String dst = String_ClearedArray(line->Buffer);
+ String_AppendString(&dst, text);
+ line->Received = DateTime_CurrentUTC_MS();
+}
+
void Chat_LogError(ReturnCode result, const char* place) {
Chat_Add4("&cError %h when %c", &result, place, NULL, NULL);
}
diff --git a/src/ChunkUpdater.c b/src/ChunkUpdater.c
index f56c021f5..75497361e 100644
--- a/src/ChunkUpdater.c
+++ b/src/ChunkUpdater.c
@@ -4,7 +4,7 @@
#include "ExtMath.h"
#include "Funcs.h"
#include "Game.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Entity.h"
#include "MapRenderer.h"
#include "Platform.h"
diff --git a/src/ClassiCube.vcxproj b/src/ClassiCube.vcxproj
index b30fbace1..eadbf71dc 100644
--- a/src/ClassiCube.vcxproj
+++ b/src/ClassiCube.vcxproj
@@ -241,7 +241,7 @@
-
+
@@ -262,7 +262,6 @@
-
@@ -273,6 +272,7 @@
+
@@ -290,7 +290,6 @@
-
diff --git a/src/ClassiCube.vcxproj.filters b/src/ClassiCube.vcxproj.filters
index 135cae66e..c6ce8366b 100644
--- a/src/ClassiCube.vcxproj.filters
+++ b/src/ClassiCube.vcxproj.filters
@@ -141,9 +141,6 @@
Header Files\Math
-
- Header Files\Graphics
-
Header Files\Graphics
@@ -315,6 +312,9 @@
Header Files\Blocks
+
+ Header Files\Graphics
+
@@ -338,9 +338,6 @@
Source Files\Map
-
- Source Files\Graphics
-
Source Files\2D\Utils
@@ -395,9 +392,6 @@
Source Files\IO
-
- Source Files\Graphics
-
Source Files\Map
@@ -578,5 +572,8 @@
Source Files\Freetype
+
+ Source Files\Graphics
+
\ No newline at end of file
diff --git a/src/D3D9Api.c b/src/D3D9Api.c
deleted file mode 100644
index 11b6736db..000000000
--- a/src/D3D9Api.c
+++ /dev/null
@@ -1,721 +0,0 @@
-#include "GraphicsAPI.h"
-#ifdef CC_BUILD_D3D9
-#include "ErrorHandler.h"
-#include "Platform.h"
-#include "Window.h"
-#include "GraphicsCommon.h"
-#include "Funcs.h"
-#include "Game.h"
-#include "ExtMath.h"
-#include "Bitmap.h"
-#include "Event.h"
-
-//#define D3D_DISABLE_9EX causes compile errors
-#ifdef CC_BUILD_WIN
-#define WIN32_LEAN_AND_MEAN
-#define NOSERVICE
-#define NOMCX
-#define NOIME
-#endif
-#include
-#include
-#include
-
-int Gfx_strideSizes[2] = GFX_STRIDE_SIZES;
-D3DFORMAT d3d9_depthFormats[6] = { D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D16, D3DFMT_D15S1 };
-D3DFORMAT d3d9_viewFormats[4] = { D3DFMT_X8R8G8B8, D3DFMT_R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5 };
-D3DBLEND d3d9_blendFuncs[6] = { D3DBLEND_ZERO, D3DBLEND_ONE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA, D3DBLEND_DESTALPHA, D3DBLEND_INVDESTALPHA };
-D3DCMPFUNC d3d9_compareFuncs[8] = { D3DCMP_ALWAYS, D3DCMP_NOTEQUAL, D3DCMP_NEVER, D3DCMP_LESS, D3DCMP_LESSEQUAL, D3DCMP_EQUAL, D3DCMP_GREATEREQUAL, D3DCMP_GREATER };
-D3DFOGMODE d3d9_modes[3] = { D3DFOG_LINEAR, D3DFOG_EXP, D3DFOG_EXP2 };
-DWORD d3d9_formatMappings[2] = { D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2 };
-
-bool d3d9_vsync;
-IDirect3D9* d3d;
-IDirect3DDevice9* device;
-D3DTRANSFORMSTATETYPE curMatrix;
-DWORD createFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
-D3DFORMAT d3d9_viewFormat, d3d9_depthFormat;
-
-#define D3D9_SetRenderState(state, value, name) \
-ReturnCode res = IDirect3DDevice9_SetRenderState(device, state, value); if (res) ErrorHandler_Fail2(res, name);
-#define D3D9_SetRenderState2(state, value, name) \
-res = IDirect3DDevice9_SetRenderState(device, state, value); if (res) ErrorHandler_Fail2(res, name);
-
-
-/* Forward declarations for these two functions. */
-static void D3D9_SetDefaultRenderStates(void);
-static void D3D9_RestoreRenderStates(void);
-
-static void D3D9_FreeResource(GfxResourceID* resource) {
- if (!resource || *resource == GFX_NULL) return;
- IUnknown* unk = (IUnknown*)(*resource);
- ULONG refCount = unk->lpVtbl->Release(unk);
- *resource = GFX_NULL;
- if (refCount <= 0) return;
-
- uintptr_t addr = (uintptr_t)unk;
- Platform_Log2("D3D9 resource has %i outstanding references! ID 0x%x", &refCount, &addr);
-}
-
-static void D3D9_LoopUntilRetrieved(void) {
- struct ScheduledTask task;
- task.Interval = 1.0f / 60.0f;
- task.Callback = Gfx_LostContextFunction;
-
- while (true) {
- Thread_Sleep(16);
- ReturnCode code = IDirect3DDevice9_TestCooperativeLevel(device);
- if (code == D3DERR_DEVICENOTRESET) return;
-
- task.Callback(&task);
- }
-}
-
-static void D3D9_FindCompatibleFormat(void) {
- int i, count = Array_Elems(d3d9_viewFormats);
- ReturnCode res;
-
- for (i = 0; i < count; i++) {
- d3d9_viewFormat = d3d9_viewFormats[i];
- res = IDirect3D9_CheckDeviceType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3d9_viewFormat, d3d9_viewFormat, true);
- if (!res) break;
-
- if (i == count - 1) {
- ErrorHandler_Fail("Unable to create a back buffer with sufficient precision.");
- }
- }
-
- count = Array_Elems(d3d9_depthFormats);
- for (i = 0; i < count; i++) {
- d3d9_depthFormat = d3d9_depthFormats[i];
- res = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3d9_viewFormat, d3d9_viewFormat, d3d9_depthFormat);
- if (!res) break;
-
- if (i == count - 1) {
- ErrorHandler_Fail("Unable to create a depth buffer with sufficient precision.");
- }
- }
-}
-
-static void D3D9_FillPresentArgs(int width, int height, D3DPRESENT_PARAMETERS* args) {
- args->AutoDepthStencilFormat = d3d9_depthFormat;
- args->BackBufferWidth = width;
- args->BackBufferHeight = height;
- args->BackBufferFormat = d3d9_viewFormat;
- args->BackBufferCount = 1;
- args->EnableAutoDepthStencil = true;
- args->PresentationInterval = d3d9_vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
- args->SwapEffect = D3DSWAPEFFECT_DISCARD;
- args->Windowed = true;
-}
-
-static void D3D9_RecreateDevice(void) {
- D3DPRESENT_PARAMETERS args = { 0 };
- D3D9_FillPresentArgs(Game_Width, Game_Height, &args);
-
- while (IDirect3DDevice9_Reset(device, &args) == D3DERR_DEVICELOST) {
- D3D9_LoopUntilRetrieved();
- }
-
- D3D9_SetDefaultRenderStates();
- D3D9_RestoreRenderStates();
- GfxCommon_RecreateContext();
-}
-
-
-void Gfx_Init(void) {
- Gfx_MinZNear = 0.05f;
- void* winHandle = Window_GetWindowHandle();
- d3d = Direct3DCreate9(D3D_SDK_VERSION);
-
- D3D9_FindCompatibleFormat();
- D3DPRESENT_PARAMETERS args = { 0 };
- D3D9_FillPresentArgs(640, 480, &args);
- ReturnCode res;
-
- /* Try to create a device with as much hardware usage as possible. */
- res = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, winHandle, createFlags, &args, &device);
- if (res) {
- createFlags = D3DCREATE_MIXED_VERTEXPROCESSING;
- res = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, winHandle, createFlags, &args, &device);
- }
- if (res) {
- createFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
- res = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, winHandle, createFlags, &args, &device);
- }
- if (res) ErrorHandler_Fail2(res, "Creating Direct3D9 device");
-
- D3DCAPS9 caps;
- res = IDirect3DDevice9_GetDeviceCaps(device, &caps);
- if (res) ErrorHandler_Fail2(res, "Getting Direct3D9 capabilities");
-
- Gfx_MaxTexWidth = caps.MaxTextureWidth;
- Gfx_MaxTexHeight = caps.MaxTextureHeight;
-
- Gfx_CustomMipmapsLevels = true;
- D3D9_SetDefaultRenderStates();
- GfxCommon_Init();
-}
-
-void Gfx_Free(void) {
- GfxCommon_Free();
- D3D9_FreeResource(&device);
- D3D9_FreeResource(&d3d);
-}
-
-static void D3D9_SetTextureData(IDirect3DTexture9* texture, Bitmap* bmp, int lvl) {
- D3DLOCKED_RECT rect;
- ReturnCode res = IDirect3DTexture9_LockRect(texture, lvl, &rect, NULL, 0);
- if (res) ErrorHandler_Fail2(res, "D3D9_SetTextureData - Lock");
-
- uint32_t size = Bitmap_DataSize(bmp->Width, bmp->Height);
- Mem_Copy(rect.pBits, bmp->Scan0, size);
-
- res = IDirect3DTexture9_UnlockRect(texture, lvl);
- if (res) ErrorHandler_Fail2(res, "D3D9_SetTextureData - Unlock");
-}
-
-static void D3D9_SetTexturePartData(IDirect3DTexture9* texture, int x, int y, Bitmap* bmp, int lvl) {
- RECT part;
- part.left = x; part.right = x + bmp->Width;
- part.top = y; part.bottom = y + bmp->Height;
-
- D3DLOCKED_RECT rect;
- ReturnCode res = IDirect3DTexture9_LockRect(texture, lvl, &rect, &part, 0);
- if (res) ErrorHandler_Fail2(res, "D3D9_SetTexturePartData - Lock");
-
- /* We need to copy scanline by scanline, as generally rect.stride != data.stride */
- uint8_t* src = (uint8_t*)bmp->Scan0;
- uint8_t* dst = (uint8_t*)rect.pBits;
- int yy;
- uint32_t stride = (uint32_t)(bmp->Width) * BITMAP_SIZEOF_PIXEL;
-
- for (yy = 0; yy < bmp->Height; yy++) {
- Mem_Copy(dst, src, stride);
- src += stride;
- dst += rect.Pitch;
- }
-
- res = IDirect3DTexture9_UnlockRect(texture, lvl);
- if (res) ErrorHandler_Fail2(res, "D3D9_SetTexturePartData - Unlock");
-}
-
-static void D3D9_DoMipmaps(IDirect3DTexture9* texture, int x, int y, Bitmap* bmp, bool partial) {
- uint8_t* prev = bmp->Scan0;
- int lvls = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height);
- int lvl, width = bmp->Width, height = bmp->Height;
-
- for (lvl = 1; lvl <= lvls; lvl++) {
- x /= 2; y /= 2;
- if (width > 1) width /= 2;
- if (height > 1) height /= 2;
-
- uint8_t* cur = Mem_Alloc(width * height, BITMAP_SIZEOF_PIXEL, "mipmaps");
- GfxCommon_GenMipmaps(width, height, cur, prev);
-
- Bitmap mipmap;
- Bitmap_Create(&mipmap, width, height, cur);
- if (partial) {
- D3D9_SetTexturePartData(texture, x, y, &mipmap, lvl);
- } else {
- D3D9_SetTextureData(texture, &mipmap, lvl);
- }
-
- if (prev != bmp->Scan0) Mem_Free(prev);
- prev = cur;
- }
- if (prev != bmp->Scan0) Mem_Free(prev);
-}
-
-GfxResourceID Gfx_CreateTexture(Bitmap* bmp, bool managedPool, bool mipmaps) {
- IDirect3DTexture9* tex;
- ReturnCode res;
- int mipmapsLevels = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height);
- int levels = 1 + (mipmaps ? mipmapsLevels : 0);
-
- if (!Math_IsPowOf2(bmp->Width) || !Math_IsPowOf2(bmp->Height)) {
- ErrorHandler_Fail("Textures must have power of two dimensions");
- }
-
- if (managedPool) {
- res = IDirect3DDevice9_CreateTexture(device, bmp->Width, bmp->Height, levels,
- 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex, NULL);
- if (res) ErrorHandler_Fail2(res, "D3D9_CreateTexture");
-
- D3D9_SetTextureData(tex, bmp, 0);
- if (mipmaps) D3D9_DoMipmaps(tex, 0, 0, bmp, false);
- } else {
- IDirect3DTexture9* sys;
- res = IDirect3DDevice9_CreateTexture(device, bmp->Width, bmp->Height, levels,
- 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &sys, NULL);
- if (res) ErrorHandler_Fail2(res, "D3D9_CreateTexture - SystemMem");
-
- D3D9_SetTextureData(sys, bmp, 0);
- if (mipmaps) D3D9_DoMipmaps(sys, 0, 0, bmp, false);
-
- res = IDirect3DDevice9_CreateTexture(device, bmp->Width, bmp->Height, levels,
- 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
- if (res) ErrorHandler_Fail2(res, "D3D9_CreateTexture - GPU");
-
- res = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9*)sys, (IDirect3DBaseTexture9*)tex);
- if (res) ErrorHandler_Fail2(res, "D3D9_CreateTexture - Update");
- D3D9_FreeResource(&sys);
- }
- return tex;
-}
-
-void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, Bitmap* part, bool mipmaps) {
- IDirect3DTexture9* texture = (IDirect3DTexture9*)texId;
- D3D9_SetTexturePartData(texture, x, y, part, 0);
- if (mipmaps) D3D9_DoMipmaps(texture, x, y, part, true);
-}
-
-void Gfx_BindTexture(GfxResourceID texId) {
- ReturnCode res = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9*)texId);
- if (res) ErrorHandler_Fail2(res, "D3D9_BindTexture");
-}
-
-void Gfx_DeleteTexture(GfxResourceID* texId) { D3D9_FreeResource(texId); }
-
-void Gfx_SetTexturing(bool enabled) {
- if (enabled) return;
- ReturnCode res = IDirect3DDevice9_SetTexture(device, 0, NULL);
- if (res) ErrorHandler_Fail2(res, "D3D9_SetTexturing");
-}
-
-void Gfx_EnableMipmaps(void) {
- if (Gfx_Mipmaps) {
- ReturnCode res = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
- if (res) ErrorHandler_Fail2(res, "D3D9_EnableMipmaps");
- }
-}
-
-void Gfx_DisableMipmaps(void) {
- if (Gfx_Mipmaps) {
- ReturnCode res = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
- if (res) ErrorHandler_Fail2(res, "D3D9_DisableMipmaps");
- }
-}
-
-
-bool d3d9_fogEnable = false;
-bool Gfx_GetFog(void) { return d3d9_fogEnable; }
-void Gfx_SetFog(bool enabled) {
- if (d3d9_fogEnable == enabled) return;
- d3d9_fogEnable = enabled;
- if (Gfx_LostContext) return;
- D3D9_SetRenderState(D3DRS_FOGENABLE, (uint32_t)enabled, "D3D9_SetFog");
-}
-
-uint32_t d3d9_fogCol = 0xFF000000; /* black */
-void Gfx_SetFogCol(PackedCol col) {
- if (col.Packed == d3d9_fogCol) return;
- d3d9_fogCol = col.Packed;
- if (Gfx_LostContext) return;
- D3D9_SetRenderState(D3DRS_FOGCOLOR, col.Packed, "D3D9_SetFogColour");
-}
-
-float d3d9_fogDensity = -1.0f;
-void Gfx_SetFogDensity(float value) {
- if (value == d3d9_fogDensity) return;
- d3d9_fogDensity = value;
- if (Gfx_LostContext) return;
- union IntAndFloat raw; raw.f = value;
- D3D9_SetRenderState(D3DRS_FOGDENSITY, raw.u, "D3D9_SetFogDensity");
-}
-
-float d3d9_fogEnd = -1.0f;
-void Gfx_SetFogEnd(float value) {
- if (value == d3d9_fogEnd) return;
- d3d9_fogEnd = value;
- if (Gfx_LostContext) return;
- union IntAndFloat raw; raw.f = value;
- D3D9_SetRenderState(D3DRS_FOGEND, raw.u, "D3D9_SetFogEnd");
-}
-
-D3DFOGMODE d3d9_fogTableMode = D3DFOG_NONE;
-void Gfx_SetFogMode(int fogMode) {
- D3DFOGMODE mode = d3d9_modes[fogMode];
- if (mode == d3d9_fogTableMode) return;
- d3d9_fogTableMode = mode;
- if (Gfx_LostContext) return;
- D3D9_SetRenderState(D3DRS_FOGTABLEMODE, mode, "D3D9_SetFogMode");
-}
-
-
-void Gfx_SetFaceCulling(bool enabled) {
- D3DCULL mode = enabled ? D3DCULL_CW : D3DCULL_NONE;
- D3D9_SetRenderState(D3DRS_CULLMODE, mode, "D3D9_SetFaceCulling");
-}
-
-bool d3d9_alphaTest = false;
-void Gfx_SetAlphaTest(bool enabled) {
- if (d3d9_alphaTest == enabled) return;
-
- d3d9_alphaTest = enabled;
- D3D9_SetRenderState(D3DRS_ALPHATESTENABLE, (uint32_t)enabled, "D3D9_SetAlphaTest");
-}
-
-D3DCMPFUNC d3d9_alphaTestFunc = D3DCMP_ALWAYS;
-int d3d9_alphaTestRef = 0;
-void Gfx_SetAlphaTestFunc(int compareFunc, float refValue) {
- d3d9_alphaTestFunc = d3d9_compareFuncs[compareFunc];
- D3D9_SetRenderState(D3DRS_ALPHAFUNC, d3d9_alphaTestFunc, "D3D9_SetAlphaTest_Func");
- d3d9_alphaTestRef = (int)(refValue * 255);
- D3D9_SetRenderState2(D3DRS_ALPHAREF, d3d9_alphaTestRef, "D3D9_SetAlphaTest_Ref");
-}
-
-bool d3d9_alphaBlend = false;
-void Gfx_SetAlphaBlending(bool enabled) {
- if (d3d9_alphaBlend == enabled) return;
-
- d3d9_alphaBlend = enabled;
- D3D9_SetRenderState(D3DRS_ALPHABLENDENABLE, (uint32_t)enabled, "D3D9_SetAlphaBlending");
-}
-
-D3DBLEND d3d9_srcBlendFunc = D3DBLEND_ONE;
-D3DBLEND d3d9_dstBlendFunc = D3DBLEND_ZERO;
-void Gfx_SetAlphaBlendFunc(int srcBlendFunc, int dstBlendFunc) {
- d3d9_srcBlendFunc = d3d9_blendFuncs[srcBlendFunc];
- D3D9_SetRenderState(D3DRS_SRCBLEND, d3d9_srcBlendFunc, "D3D9_SetAlphaBlendFunc_Src");
- d3d9_dstBlendFunc = d3d9_blendFuncs[dstBlendFunc];
- D3D9_SetRenderState2(D3DRS_DESTBLEND, d3d9_dstBlendFunc, "D3D9_SetAlphaBlendFunc_Dst");
-}
-
-void Gfx_SetAlphaArgBlend(bool enabled) {
- D3DTEXTUREOP op = enabled ? D3DTOP_MODULATE : D3DTOP_SELECTARG1;
- ReturnCode res = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, op);
- if (res) ErrorHandler_Fail2(res, "D3D9_SetAlphaArgBlend");
-}
-
-
-uint32_t d3d9_clearCol = 0xFF000000;
-void Gfx_Clear(void) {
- DWORD flags = D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER;
- ReturnCode res = IDirect3DDevice9_Clear(device, 0, NULL, flags, d3d9_clearCol, 1.0f, 0);
- if (res) ErrorHandler_Fail2(res, "D3D9_Clear");
-}
-
-void Gfx_ClearCol(PackedCol col) {
- d3d9_clearCol = col.Packed;
-}
-
-bool d3d9_depthTest = false;
-void Gfx_SetDepthTest(bool enabled) {
- d3d9_depthTest = enabled;
- D3D9_SetRenderState(D3DRS_ZENABLE, (uint32_t)enabled, "D3D9_SetDepthTest");
-}
-
-D3DCMPFUNC d3d9_depthTestFunc = D3DCMP_LESSEQUAL;
-void Gfx_SetDepthTestFunc(int compareFunc) {
- d3d9_depthTestFunc = d3d9_compareFuncs[compareFunc];
- D3D9_SetRenderState(D3DRS_ZFUNC, d3d9_alphaTestFunc, "D3D9_SetDepthTestFunc");
-}
-
-void Gfx_SetColourWriteMask(bool r, bool g, bool b, bool a) {
- uint32_t channels = (r ? 1u : 0u) | (g ? 2u : 0u) | (b ? 4u : 0u) | (a ? 8u : 0u);
- D3D9_SetRenderState(D3DRS_COLORWRITEENABLE, channels, "D3D9_SetColourWrite");
-}
-
-bool d3d9_depthWrite = false;
-void Gfx_SetDepthWrite(bool enabled) {
- d3d9_depthWrite = enabled;
- D3D9_SetRenderState(D3DRS_ZWRITEENABLE, (uint32_t)enabled, "D3D9_SetDepthWrite");
-}
-
-
-GfxResourceID Gfx_CreateDynamicVb(int vertexFormat, int maxVertices) {
- int size = maxVertices * Gfx_strideSizes[vertexFormat];
- IDirect3DVertexBuffer9* vbuffer;
- ReturnCode res = IDirect3DDevice9_CreateVertexBuffer(device, size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
- d3d9_formatMappings[vertexFormat], D3DPOOL_DEFAULT, &vbuffer, NULL);
- if (res) ErrorHandler_Fail2(res, "D3D9_CreateDynamicVb");
-
- return vbuffer;
-}
-
-static void D3D9_SetVbData(IDirect3DVertexBuffer9* buffer, void* data, int size, const char* lockMsg, const char* unlockMsg, int lockFlags) {
- void* dst = NULL;
- ReturnCode res = IDirect3DVertexBuffer9_Lock(buffer, 0, size, &dst, lockFlags);
- if (res) ErrorHandler_Fail2(res, lockMsg);
-
- Mem_Copy(dst, data, size);
- res = IDirect3DVertexBuffer9_Unlock(buffer);
- if (res) ErrorHandler_Fail2(res, unlockMsg);
-}
-
-GfxResourceID Gfx_CreateVb(void* vertices, int vertexFormat, int count) {
- int size = count * Gfx_strideSizes[vertexFormat];
- IDirect3DVertexBuffer9* vbuffer;
-
- for (;;) {
- ReturnCode res = IDirect3DDevice9_CreateVertexBuffer(device, size, D3DUSAGE_WRITEONLY,
- d3d9_formatMappings[vertexFormat], D3DPOOL_DEFAULT, &vbuffer, NULL);
- if (!res) break;
-
- if (res != D3DERR_OUTOFVIDEOMEMORY) ErrorHandler_Fail2(res, "D3D9_CreateVb");
- Event_RaiseVoid(&GfxEvents_LowVRAMDetected);
- }
-
- D3D9_SetVbData(vbuffer, vertices, size, "D3D9_CreateVb - Lock", "D3D9_CreateVb - Unlock", 0);
- return vbuffer;
-}
-
-static void D3D9_SetIbData(IDirect3DIndexBuffer9* buffer, void* data, int size) {
- void* dst = NULL;
- ReturnCode res = IDirect3DIndexBuffer9_Lock(buffer, 0, size, &dst, 0);
- if (res) ErrorHandler_Fail2(res, "D3D9_CreateIb - Lock");
-
- Mem_Copy(dst, data, size);
- res = IDirect3DIndexBuffer9_Unlock(buffer);
- if (res) ErrorHandler_Fail2(res, "D3D9_CreateIb - Unlock");
-}
-
-GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) {
- int size = indicesCount * 2;
- IDirect3DIndexBuffer9* ibuffer;
- ReturnCode res = IDirect3DDevice9_CreateIndexBuffer(device, size, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ibuffer, NULL);
- if (res) ErrorHandler_Fail2(res, "D3D9_CreateIb");
-
- D3D9_SetIbData(ibuffer, indices, size);
- return ibuffer;
-}
-
-int d3d9_batchStride;
-void Gfx_BindVb(GfxResourceID vb) {
- IDirect3DVertexBuffer9* vbuffer = (IDirect3DVertexBuffer9*)vb;
- ReturnCode res = IDirect3DDevice9_SetStreamSource(device, 0, vbuffer, 0, d3d9_batchStride);
- if (res) ErrorHandler_Fail2(res, "D3D9_BindVb");
-}
-
-void Gfx_BindIb(GfxResourceID ib) {
- IDirect3DIndexBuffer9* ibuffer = (IDirect3DIndexBuffer9*)ib;
- ReturnCode res = IDirect3DDevice9_SetIndices(device, ibuffer);
- if (res) ErrorHandler_Fail2(res, "D3D9_BindIb");
-}
-
-void Gfx_DeleteVb(GfxResourceID* vb) { D3D9_FreeResource(vb); }
-void Gfx_DeleteIb(GfxResourceID* ib) { D3D9_FreeResource(ib); }
-
-int d3d9_batchFormat = -1;
-void Gfx_SetBatchFormat(int format) {
- if (format == d3d9_batchFormat) return;
- d3d9_batchFormat = format;
-
- ReturnCode res = IDirect3DDevice9_SetFVF(device, d3d9_formatMappings[format]);
- if (res) ErrorHandler_Fail2(res, "D3D9_SetBatchFormat");
- d3d9_batchStride = Gfx_strideSizes[format];
-}
-
-void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
- int size = vCount * d3d9_batchStride;
- IDirect3DVertexBuffer9* vbuffer = (IDirect3DVertexBuffer9*)vb;
- D3D9_SetVbData(vbuffer, vertices, size, "D3D9_SetDynamicVbData - Lock", "D3D9_SetDynamicVbData - Unlock", D3DLOCK_DISCARD);
-
- ReturnCode res = IDirect3DDevice9_SetStreamSource(device, 0, vbuffer, 0, d3d9_batchStride);
- if (res) ErrorHandler_Fail2(res, "D3D9_SetDynamicVbData - Bind");
-}
-
-void Gfx_DrawVb_Lines(int verticesCount) {
- ReturnCode res = IDirect3DDevice9_DrawPrimitive(device, D3DPT_LINELIST, 0, verticesCount >> 1);
- if (res) ErrorHandler_Fail2(res, "D3D9_DrawVb_Lines");
-}
-
-void Gfx_DrawVb_IndexedTris(int verticesCount) {
- ReturnCode res = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
- 0, 0, verticesCount, 0, verticesCount >> 1);
- if (res) ErrorHandler_Fail2(res, "D3D9_DrawVb_IndexedTris");
-}
-
-void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
- ReturnCode res = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
- startVertex, 0, verticesCount, 0, verticesCount >> 1);
- if (res) ErrorHandler_Fail2(res, "D3D9_DrawVb_IndexedTris");
-}
-
-void Gfx_DrawIndexedVb_TrisT2fC4b(int verticesCount, int startVertex) {
- ReturnCode res = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
- startVertex, 0, verticesCount, 0, verticesCount >> 1);
- if (res) ErrorHandler_Fail2(res, "D3D9_DrawIndexedVb_TrisT2fC4b");
-}
-
-
-void Gfx_SetMatrixMode(int matrixType) {
- if (matrixType == MATRIX_TYPE_PROJECTION) {
- curMatrix = D3DTS_PROJECTION;
- } else if (matrixType == MATRIX_TYPE_VIEW) {
- curMatrix = D3DTS_VIEW;
- } else if (matrixType == MATRIX_TYPE_TEXTURE) {
- curMatrix = D3DTS_TEXTURE0;
- }
-}
-
-void Gfx_LoadMatrix(struct Matrix* matrix) {
- if (curMatrix == D3DTS_TEXTURE0) {
- matrix->Row2.X = matrix->Row3.X; /* NOTE: this hack fixes the texture movements. */
- IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- }
-
- if (Gfx_LostContext) return;
- ReturnCode res = IDirect3DDevice9_SetTransform(device, curMatrix, matrix);
- if (res) ErrorHandler_Fail2(res, "D3D9_LoadMatrix");
-}
-
-void Gfx_LoadIdentityMatrix(void) {
- if (curMatrix == D3DTS_TEXTURE0) {
- IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
- }
-
- if (Gfx_LostContext) return;
- ReturnCode res = IDirect3DDevice9_SetTransform(device, curMatrix, &Matrix_Identity);
- if (res) ErrorHandler_Fail2(res, "D3D9_LoadIdentityMatrix");
-}
-
-#define d3d9_zN -10000.0f
-#define d3d9_zF 10000.0f
-void Gfx_CalcOrthoMatrix(float width, float height, struct Matrix* matrix) {
- Matrix_OrthographicOffCenter(matrix, 0.0f, width, height, 0.0f, d3d9_zN, d3d9_zF);
- matrix->Row2.Z = 1.0f / (d3d9_zN - d3d9_zF);
- matrix->Row3.Z = d3d9_zN / (d3d9_zN - d3d9_zF);
-}
-void Gfx_CalcPerspectiveMatrix(float fov, float aspect, float zNear, float zFar, struct Matrix* matrix) {
- Matrix_PerspectiveFieldOfView(matrix, fov, aspect, zNear, zFar);
-}
-
-
-ReturnCode Gfx_TakeScreenshot(struct Stream* output, int width, int height) {
- IDirect3DSurface9* backbuffer = NULL;
- IDirect3DSurface9* temp = NULL;
- ReturnCode res;
-
- res = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
- if (res) goto finished;
- res = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &temp, NULL);
- if (res) goto finished; /* TODO: For DX 8 use IDirect3DDevice8::CreateImageSurface */
- res = IDirect3DDevice9_GetRenderTargetData(device, backbuffer, temp);
- if (res) goto finished;
-
- D3DLOCKED_RECT rect;
- res = IDirect3DSurface9_LockRect(temp, &rect, NULL, D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE);
- if (res) goto finished;
- {
- Bitmap bmp; Bitmap_Create(&bmp, width, height, rect.pBits);
- res = Bitmap_EncodePng(&bmp, output);
- if (res) { IDirect3DSurface9_UnlockRect(temp); goto finished; }
- }
- res = IDirect3DSurface9_UnlockRect(temp);
- if (res) goto finished;
-
-finished:
- D3D9_FreeResource(&backbuffer);
- D3D9_FreeResource(&temp);
- return res;
-}
-
-bool Gfx_WarnIfNecessary(void) { return false; }
-
-void Gfx_SetVSync(bool value) {
- if (d3d9_vsync == value) return;
- d3d9_vsync = value;
-
- GfxCommon_LoseContext(" (toggling VSync)");
- D3D9_RecreateDevice();
-}
-
-void Gfx_BeginFrame(void) {
- IDirect3DDevice9_BeginScene(device);
-}
-
-void Gfx_EndFrame(void) {
- IDirect3DDevice9_EndScene(device);
- ReturnCode res = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
- if (!res) return;
- if (res != D3DERR_DEVICELOST) ErrorHandler_Fail2(res, "D3D9_EndFrame");
-
- /* TODO: Make sure this actually works on all graphics cards.*/
- GfxCommon_LoseContext(" (Direct3D9 device lost)");
- D3D9_LoopUntilRetrieved();
- D3D9_RecreateDevice();
-}
-
-const char* D3D9_StrFlags(void) {
- if (createFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) return "Hardware";
- if (createFlags & D3DCREATE_MIXED_VERTEXPROCESSING) return "Mixed";
- if (createFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) return "Software";
- return "(none)";
-}
-
-const char* D3D9_StrFormat(D3DFORMAT format) {
- switch (format) {
- case D3DFMT_D32: return "D32";
- case D3DFMT_D24X8: return "D24X8";
- case D3DFMT_D24S8: return "D24S8";
- case D3DFMT_D24X4S4: return "D24X4S4";
- case D3DFMT_D16: return "D16";
- case D3DFMT_D15S1: return "D15S1";
-
- case D3DFMT_X8R8G8B8: return "X8R8G8B8";
- case D3DFMT_R8G8B8: return "R8G8B8";
- case D3DFMT_R5G6B5: return "R5G6B5";
- case D3DFMT_X1R5G5B5: return "X1R5G5B5";
- }
- return "(unknown)";
-}
-
-float d3d9_totalMem;
-void Gfx_MakeApiInfo(void) {
- D3DADAPTER_IDENTIFIER9 adapter = { 0 };
- IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &adapter);
- d3d9_totalMem = IDirect3DDevice9_GetAvailableTextureMem(device) / (1024.0f * 1024.0f);
-
- String_AppendConst(&Gfx_ApiInfo[0],"-- Using Direct3D9 --");
- String_Format1(&Gfx_ApiInfo[1], "Adapter: %c", adapter.Description);
- String_Format1(&Gfx_ApiInfo[2], "Processing mode: %c", D3D9_StrFlags());
- Gfx_UpdateApiInfo();
- String_Format2(&Gfx_ApiInfo[4], "Max texture size: (%i, %i)", &Gfx_MaxTexWidth, &Gfx_MaxTexHeight);
- String_Format1(&Gfx_ApiInfo[5], "Depth buffer format: %c", D3D9_StrFormat(d3d9_depthFormat));
- String_Format1(&Gfx_ApiInfo[6], "Back buffer format: %c", D3D9_StrFormat(d3d9_viewFormat));
-}
-
-void Gfx_UpdateApiInfo(void) {
- float mem = IDirect3DDevice9_GetAvailableTextureMem(device) / (1024.0f * 1024.0f);
- Gfx_ApiInfo[3].length = 0;
- String_Format2(&Gfx_ApiInfo[3], "Video memory: %f2 MB total, %f2 free", &d3d9_totalMem, &mem);
-}
-
-void Gfx_OnWindowResize(void) {
- GfxCommon_LoseContext(" (resizing window)");
- D3D9_RecreateDevice();
-}
-
-
-static void D3D9_SetDefaultRenderStates(void) {
- Gfx_SetFaceCulling(false);
- d3d9_batchFormat = -1;
- D3D9_SetRenderState(D3DRS_COLORVERTEX, false, "D3D9_ColorVertex");
- D3D9_SetRenderState2(D3DRS_LIGHTING, false, "D3D9_Lighting");
- D3D9_SetRenderState2(D3DRS_SPECULARENABLE, false, "D3D9_SpecularEnable");
- D3D9_SetRenderState2(D3DRS_LOCALVIEWER, false, "D3D9_LocalViewer");
- D3D9_SetRenderState2(D3DRS_DEBUGMONITORTOKEN, false, "D3D9_DebugMonitor");
-}
-
-static void D3D9_RestoreRenderStates(void) {
- union IntAndFloat raw;
- D3D9_SetRenderState(D3DRS_ALPHATESTENABLE, d3d9_alphaTest, "D3D9_AlphaTest");
- D3D9_SetRenderState2(D3DRS_ALPHABLENDENABLE, d3d9_alphaBlend, "D3D9_AlphaBlend");
- D3D9_SetRenderState2(D3DRS_ALPHAFUNC, d3d9_alphaTestFunc, "D3D9_AlphaTestFunc");
- D3D9_SetRenderState2(D3DRS_ALPHAREF, d3d9_alphaTestRef, "D3D9_AlphaRefFunc");
- D3D9_SetRenderState2(D3DRS_SRCBLEND, d3d9_srcBlendFunc, "D3D9_AlphaSrcBlend");
- D3D9_SetRenderState2(D3DRS_DESTBLEND, d3d9_dstBlendFunc, "D3D9_AlphaDstBlend");
- D3D9_SetRenderState2(D3DRS_FOGENABLE, d3d9_fogEnable, "D3D9_Fog");
- D3D9_SetRenderState2(D3DRS_FOGCOLOR, d3d9_fogCol, "D3D9_FogColor");
- raw.f = d3d9_fogDensity;
- D3D9_SetRenderState2(D3DRS_FOGDENSITY, raw.u, "D3D9_FogDensity");
- raw.f = d3d9_fogEnd;
- D3D9_SetRenderState2(D3DRS_FOGEND, raw.u, "D3D9_FogEnd");
- D3D9_SetRenderState2(D3DRS_FOGTABLEMODE, d3d9_fogTableMode, "D3D9_FogMode");
- D3D9_SetRenderState2(D3DRS_ZFUNC, d3d9_depthTestFunc, "D3D9_DepthTestFunc");
- D3D9_SetRenderState2(D3DRS_ZENABLE, d3d9_depthTest, "D3D9_DepthTest");
- D3D9_SetRenderState2(D3DRS_ZWRITEENABLE, d3d9_depthWrite, "D3D9_DepthWrite");
-}
-#endif
diff --git a/src/Drawer2D.c b/src/Drawer2D.c
index 84b042084..f578a1fa4 100644
--- a/src/Drawer2D.c
+++ b/src/Drawer2D.c
@@ -1,5 +1,5 @@
#include "Drawer2D.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Funcs.h"
#include "Platform.h"
#include "ExtMath.h"
diff --git a/src/Entity.c b/src/Entity.c
index c807517ac..9b91aef62 100644
--- a/src/Entity.c
+++ b/src/Entity.c
@@ -8,7 +8,7 @@
#include "Platform.h"
#include "Funcs.h"
#include "ModelCache.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Lighting.h"
#include "Drawer2D.h"
#include "Particle.h"
diff --git a/src/EntityComponents.c b/src/EntityComponents.c
index 10a8d0016..0fe63fd38 100644
--- a/src/EntityComponents.c
+++ b/src/EntityComponents.c
@@ -9,7 +9,7 @@
#include "Camera.h"
#include "Funcs.h"
#include "VertexStructs.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "GraphicsCommon.h"
#include "ModelCache.h"
#include "Physics.h"
diff --git a/src/EnvRenderer.c b/src/EnvRenderer.c
index b2d3bb5cd..c54d2de81 100644
--- a/src/EnvRenderer.c
+++ b/src/EnvRenderer.c
@@ -2,7 +2,7 @@
#include "ExtMath.h"
#include "World.h"
#include "Funcs.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Physics.h"
#include "Block.h"
#include "Platform.h"
diff --git a/src/Game.c b/src/Game.c
index bf03e43cf..a5b6c89dd 100644
--- a/src/Game.c
+++ b/src/Game.c
@@ -3,7 +3,7 @@
#include "World.h"
#include "Lighting.h"
#include "MapRenderer.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Camera.h"
#include "Options.h"
#include "Funcs.h"
diff --git a/src/Graphics.c b/src/Graphics.c
new file mode 100644
index 000000000..809f48826
--- /dev/null
+++ b/src/Graphics.c
@@ -0,0 +1,1315 @@
+#include "Graphics.h"
+#include "ErrorHandler.h"
+#include "Platform.h"
+#include "Window.h"
+#include "GraphicsCommon.h"
+#include "Funcs.h"
+#include "Chat.h"
+#include "Game.h"
+#include "ExtMath.h"
+#include "Bitmap.h"
+#include "Event.h"
+
+int Gfx_strideSizes[2] = { 16, 24 };
+int gfx_batchStride, gfx_batchFormat = -1;
+
+bool gfx_vsync, gfx_fogEnabled;
+bool Gfx_GetFog(void) { return gfx_fogEnabled; }
+
+/*########################################################################################################################*
+*--------------------------------------------------------Direct3D9--------------------------------------------------------*
+*#########################################################################################################################*/
+#ifdef CC_BUILD_D3D9
+//#define D3D_DISABLE_9EX causes compile errors
+#define WIN32_LEAN_AND_MEAN
+#define NOSERVICE
+#define NOMCX
+#define NOIME
+#include
+#include
+#include
+
+D3DCMPFUNC d3d9_compareFuncs[8] = { D3DCMP_ALWAYS, D3DCMP_NOTEQUAL, D3DCMP_NEVER, D3DCMP_LESS, D3DCMP_LESSEQUAL, D3DCMP_EQUAL, D3DCMP_GREATEREQUAL, D3DCMP_GREATER };
+DWORD d3d9_formatMappings[2] = { D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2 };
+
+IDirect3D9* d3d;
+IDirect3DDevice9* device;
+D3DTRANSFORMSTATETYPE curMatrix;
+DWORD createFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
+D3DFORMAT d3d9_viewFormat, d3d9_depthFormat;
+
+#define D3D9_SetRenderState(state, value, name) \
+ReturnCode res = IDirect3DDevice9_SetRenderState(device, state, value); if (res) ErrorHandler_Fail2(res, name);
+#define D3D9_SetRenderState2(state, value, name) \
+res = IDirect3DDevice9_SetRenderState(device, state, value); if (res) ErrorHandler_Fail2(res, name);
+
+static void D3D9_SetDefaultRenderStates(void);
+static void D3D9_RestoreRenderStates(void);
+
+static void D3D9_FreeResource(GfxResourceID* resource) {
+ if (!resource || *resource == GFX_NULL) return;
+ IUnknown* unk = (IUnknown*)(*resource);
+ ULONG refCount = unk->lpVtbl->Release(unk);
+ *resource = GFX_NULL;
+ if (refCount <= 0) return;
+
+ uintptr_t addr = (uintptr_t)unk;
+ Platform_Log2("D3D9 resource has %i outstanding references! ID 0x%x", &refCount, &addr);
+}
+
+static void D3D9_LoopUntilRetrieved(void) {
+ struct ScheduledTask task;
+ task.Interval = 1.0f / 60.0f;
+ task.Callback = Gfx_LostContextFunction;
+
+ while (true) {
+ Thread_Sleep(16);
+ ReturnCode code = IDirect3DDevice9_TestCooperativeLevel(device);
+ if (code == D3DERR_DEVICENOTRESET) return;
+
+ task.Callback(&task);
+ }
+}
+
+static void D3D9_FindCompatibleFormat(void) {
+ static D3DFORMAT depthFormats[6] = { D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D16, D3DFMT_D15S1 };
+ static D3DFORMAT viewFormats[4] = { D3DFMT_X8R8G8B8, D3DFMT_R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5 };
+ ReturnCode res;
+ int i, count = Array_Elems(viewFormats);
+
+ for (i = 0; i < count; i++) {
+ d3d9_viewFormat = viewFormats[i];
+ res = IDirect3D9_CheckDeviceType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3d9_viewFormat, d3d9_viewFormat, true);
+ if (!res) break;
+ }
+ if (i == count) ErrorHandler_Fail("Unable to create a back buffer with sufficient precision.");
+
+ count = Array_Elems(depthFormats);
+ for (i = 0; i < count; i++) {
+ d3d9_depthFormat = depthFormats[i];
+ res = IDirect3D9_CheckDepthStencilMatch(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3d9_viewFormat, d3d9_viewFormat, d3d9_depthFormat);
+ if (!res) break;
+ }
+ if (i == count) ErrorHandler_Fail("Unable to create a depth buffer with sufficient precision.");
+}
+
+static void D3D9_FillPresentArgs(int width, int height, D3DPRESENT_PARAMETERS* args) {
+ args->AutoDepthStencilFormat = d3d9_depthFormat;
+ args->BackBufferWidth = width;
+ args->BackBufferHeight = height;
+ args->BackBufferFormat = d3d9_viewFormat;
+ args->BackBufferCount = 1;
+ args->EnableAutoDepthStencil = true;
+ args->PresentationInterval = gfx_vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
+ args->SwapEffect = D3DSWAPEFFECT_DISCARD;
+ args->Windowed = true;
+}
+
+static void D3D9_RecreateDevice(void) {
+ D3DPRESENT_PARAMETERS args = { 0 };
+ D3D9_FillPresentArgs(Game_Width, Game_Height, &args);
+
+ while (IDirect3DDevice9_Reset(device, &args) == D3DERR_DEVICELOST) {
+ D3D9_LoopUntilRetrieved();
+ }
+
+ D3D9_SetDefaultRenderStates();
+ D3D9_RestoreRenderStates();
+ GfxCommon_RecreateContext();
+}
+
+void Gfx_Init(void) {
+ Gfx_MinZNear = 0.05f;
+ void* winHandle = Window_GetWindowHandle();
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+
+ D3D9_FindCompatibleFormat();
+ D3DPRESENT_PARAMETERS args = { 0 };
+ D3D9_FillPresentArgs(640, 480, &args);
+ ReturnCode res;
+
+ /* Try to create a device with as much hardware usage as possible. */
+ res = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, winHandle, createFlags, &args, &device);
+ if (res) {
+ createFlags = D3DCREATE_MIXED_VERTEXPROCESSING;
+ res = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, winHandle, createFlags, &args, &device);
+ }
+ if (res) {
+ createFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
+ res = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, winHandle, createFlags, &args, &device);
+ }
+ if (res) ErrorHandler_Fail2(res, "Creating Direct3D9 device");
+
+ D3DCAPS9 caps;
+ res = IDirect3DDevice9_GetDeviceCaps(device, &caps);
+ if (res) ErrorHandler_Fail2(res, "Getting Direct3D9 capabilities");
+
+ Gfx_MaxTexWidth = caps.MaxTextureWidth;
+ Gfx_MaxTexHeight = caps.MaxTextureHeight;
+
+ Gfx_CustomMipmapsLevels = true;
+ D3D9_SetDefaultRenderStates();
+ GfxCommon_Init();
+}
+
+void Gfx_Free(void) {
+ GfxCommon_Free();
+ D3D9_FreeResource(&device);
+ D3D9_FreeResource(&d3d);
+}
+
+
+/*########################################################################################################################*
+*---------------------------------------------------------Textures--------------------------------------------------------*
+*#########################################################################################################################*/
+static void D3D9_SetTextureData(IDirect3DTexture9* texture, Bitmap* bmp, int lvl) {
+ D3DLOCKED_RECT rect;
+ ReturnCode res = IDirect3DTexture9_LockRect(texture, lvl, &rect, NULL, 0);
+ if (res) ErrorHandler_Fail2(res, "D3D9_SetTextureData - Lock");
+
+ uint32_t size = Bitmap_DataSize(bmp->Width, bmp->Height);
+ Mem_Copy(rect.pBits, bmp->Scan0, size);
+
+ res = IDirect3DTexture9_UnlockRect(texture, lvl);
+ if (res) ErrorHandler_Fail2(res, "D3D9_SetTextureData - Unlock");
+}
+
+static void D3D9_SetTexturePartData(IDirect3DTexture9* texture, int x, int y, Bitmap* bmp, int lvl) {
+ RECT part;
+ part.left = x; part.right = x + bmp->Width;
+ part.top = y; part.bottom = y + bmp->Height;
+
+ D3DLOCKED_RECT rect;
+ ReturnCode res = IDirect3DTexture9_LockRect(texture, lvl, &rect, &part, 0);
+ if (res) ErrorHandler_Fail2(res, "D3D9_SetTexturePartData - Lock");
+
+ /* We need to copy scanline by scanline, as generally rect.stride != data.stride */
+ uint8_t* src = (uint8_t*)bmp->Scan0;
+ uint8_t* dst = (uint8_t*)rect.pBits;
+ int yy;
+ uint32_t stride = (uint32_t)(bmp->Width) * BITMAP_SIZEOF_PIXEL;
+
+ for (yy = 0; yy < bmp->Height; yy++) {
+ Mem_Copy(dst, src, stride);
+ src += stride;
+ dst += rect.Pitch;
+ }
+
+ res = IDirect3DTexture9_UnlockRect(texture, lvl);
+ if (res) ErrorHandler_Fail2(res, "D3D9_SetTexturePartData - Unlock");
+}
+
+static void D3D9_DoMipmaps(IDirect3DTexture9* texture, int x, int y, Bitmap* bmp, bool partial) {
+ uint8_t* prev = bmp->Scan0;
+ int lvls = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height);
+ int lvl, width = bmp->Width, height = bmp->Height;
+
+ for (lvl = 1; lvl <= lvls; lvl++) {
+ x /= 2; y /= 2;
+ if (width > 1) width /= 2;
+ if (height > 1) height /= 2;
+
+ uint8_t* cur = Mem_Alloc(width * height, BITMAP_SIZEOF_PIXEL, "mipmaps");
+ GfxCommon_GenMipmaps(width, height, cur, prev);
+
+ Bitmap mipmap;
+ Bitmap_Create(&mipmap, width, height, cur);
+ if (partial) {
+ D3D9_SetTexturePartData(texture, x, y, &mipmap, lvl);
+ } else {
+ D3D9_SetTextureData(texture, &mipmap, lvl);
+ }
+
+ if (prev != bmp->Scan0) Mem_Free(prev);
+ prev = cur;
+ }
+ if (prev != bmp->Scan0) Mem_Free(prev);
+}
+
+GfxResourceID Gfx_CreateTexture(Bitmap* bmp, bool managedPool, bool mipmaps) {
+ IDirect3DTexture9* tex;
+ ReturnCode res;
+ int mipmapsLevels = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height);
+ int levels = 1 + (mipmaps ? mipmapsLevels : 0);
+
+ if (!Math_IsPowOf2(bmp->Width) || !Math_IsPowOf2(bmp->Height)) {
+ ErrorHandler_Fail("Textures must have power of two dimensions");
+ }
+
+ if (managedPool) {
+ res = IDirect3DDevice9_CreateTexture(device, bmp->Width, bmp->Height, levels,
+ 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex, NULL);
+ if (res) ErrorHandler_Fail2(res, "D3D9_CreateTexture");
+
+ D3D9_SetTextureData(tex, bmp, 0);
+ if (mipmaps) D3D9_DoMipmaps(tex, 0, 0, bmp, false);
+ } else {
+ IDirect3DTexture9* sys;
+ res = IDirect3DDevice9_CreateTexture(device, bmp->Width, bmp->Height, levels,
+ 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &sys, NULL);
+ if (res) ErrorHandler_Fail2(res, "D3D9_CreateTexture - SystemMem");
+
+ D3D9_SetTextureData(sys, bmp, 0);
+ if (mipmaps) D3D9_DoMipmaps(sys, 0, 0, bmp, false);
+
+ res = IDirect3DDevice9_CreateTexture(device, bmp->Width, bmp->Height, levels,
+ 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
+ if (res) ErrorHandler_Fail2(res, "D3D9_CreateTexture - GPU");
+
+ res = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9*)sys, (IDirect3DBaseTexture9*)tex);
+ if (res) ErrorHandler_Fail2(res, "D3D9_CreateTexture - Update");
+ D3D9_FreeResource(&sys);
+ }
+ return tex;
+}
+
+void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, Bitmap* part, bool mipmaps) {
+ IDirect3DTexture9* texture = (IDirect3DTexture9*)texId;
+ D3D9_SetTexturePartData(texture, x, y, part, 0);
+ if (mipmaps) D3D9_DoMipmaps(texture, x, y, part, true);
+}
+
+void Gfx_BindTexture(GfxResourceID texId) {
+ ReturnCode res = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9*)texId);
+ if (res) ErrorHandler_Fail2(res, "D3D9_BindTexture");
+}
+
+void Gfx_DeleteTexture(GfxResourceID* texId) { D3D9_FreeResource(texId); }
+
+void Gfx_SetTexturing(bool enabled) {
+ if (enabled) return;
+ ReturnCode res = IDirect3DDevice9_SetTexture(device, 0, NULL);
+ if (res) ErrorHandler_Fail2(res, "D3D9_SetTexturing");
+}
+
+void Gfx_EnableMipmaps(void) {
+ if (Gfx_Mipmaps) {
+ ReturnCode res = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+ if (res) ErrorHandler_Fail2(res, "D3D9_EnableMipmaps");
+ }
+}
+
+void Gfx_DisableMipmaps(void) {
+ if (Gfx_Mipmaps) {
+ ReturnCode res = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
+ if (res) ErrorHandler_Fail2(res, "D3D9_DisableMipmaps");
+ }
+}
+
+
+/*########################################################################################################################*
+*-----------------------------------------------------State management----------------------------------------------------*
+*#########################################################################################################################*/
+uint32_t d3d9_fogCol = 0xFF000000; /* black */
+float d3d9_fogDensity = -1.0f, d3d9_fogEnd = -1.0f;
+D3DFOGMODE d3d9_fogMode = D3DFOG_NONE;
+
+bool d3d9_alphaTesting, d3d9_alphaBlending;
+int d3d9_alphaTestRef;
+D3DCMPFUNC d3d9_alphaTestFunc = D3DCMP_ALWAYS;
+D3DBLEND d3d9_srcBlendFunc = D3DBLEND_ONE, d3d9_dstBlendFunc = D3DBLEND_ZERO;
+
+uint32_t d3d9_clearCol = 0xFF000000; /* black */
+bool d3d9_depthTesting, d3d9_depthWriting;
+D3DCMPFUNC d3d9_depthTestFunc = D3DCMP_LESSEQUAL;
+
+void Gfx_SetFaceCulling(bool enabled) {
+ D3DCULL mode = enabled ? D3DCULL_CW : D3DCULL_NONE;
+ D3D9_SetRenderState(D3DRS_CULLMODE, mode, "D3D9_SetFaceCulling");
+}
+
+void Gfx_SetFog(bool enabled) {
+ if (gfx_fogEnabled == enabled) return;
+ gfx_fogEnabled = enabled;
+ if (Gfx_LostContext) return;
+ D3D9_SetRenderState(D3DRS_FOGENABLE, enabled, "D3D9_SetFog");
+}
+
+void Gfx_SetFogCol(PackedCol col) {
+ if (col.Packed == d3d9_fogCol) return;
+ d3d9_fogCol = col.Packed;
+ if (Gfx_LostContext) return;
+ D3D9_SetRenderState(D3DRS_FOGCOLOR, col.Packed, "D3D9_SetFogColour");
+}
+
+void Gfx_SetFogDensity(float value) {
+ if (value == d3d9_fogDensity) return;
+ d3d9_fogDensity = value;
+ if (Gfx_LostContext) return;
+ union IntAndFloat raw; raw.f = value;
+ D3D9_SetRenderState(D3DRS_FOGDENSITY, raw.u, "D3D9_SetFogDensity");
+}
+
+void Gfx_SetFogEnd(float value) {
+ if (value == d3d9_fogEnd) return;
+ d3d9_fogEnd = value;
+ if (Gfx_LostContext) return;
+ union IntAndFloat raw; raw.f = value;
+ D3D9_SetRenderState(D3DRS_FOGEND, raw.u, "D3D9_SetFogEnd");
+}
+
+void Gfx_SetFogMode(int fogMode) {
+ static D3DFOGMODE modes[3] = { D3DFOG_LINEAR, D3DFOG_EXP, D3DFOG_EXP2 };
+ D3DFOGMODE mode = modes[fogMode];
+ if (mode == d3d9_fogMode) return;
+
+ d3d9_fogMode = mode;
+ if (Gfx_LostContext) return;
+ D3D9_SetRenderState(D3DRS_FOGTABLEMODE, mode, "D3D9_SetFogMode");
+}
+
+void Gfx_SetAlphaTest(bool enabled) {
+ if (d3d9_alphaTesting == enabled) return;
+ d3d9_alphaTesting = enabled;
+ D3D9_SetRenderState(D3DRS_ALPHATESTENABLE, enabled, "D3D9_SetAlphaTest");
+}
+
+void Gfx_SetAlphaTestFunc(int compareFunc, float refValue) {
+ d3d9_alphaTestFunc = d3d9_compareFuncs[compareFunc];
+ D3D9_SetRenderState(D3DRS_ALPHAFUNC, d3d9_alphaTestFunc, "D3D9_SetAlphaTest_Func");
+ d3d9_alphaTestRef = (int)(refValue * 255);
+ D3D9_SetRenderState2(D3DRS_ALPHAREF, d3d9_alphaTestRef, "D3D9_SetAlphaTest_Ref");
+}
+
+void Gfx_SetAlphaBlending(bool enabled) {
+ if (d3d9_alphaBlending == enabled) return;
+ d3d9_alphaBlending = enabled;
+ D3D9_SetRenderState(D3DRS_ALPHABLENDENABLE, enabled, "D3D9_SetAlphaBlending");
+}
+
+void Gfx_SetAlphaBlendFunc(int srcBlendFunc, int dstBlendFunc) {
+ static D3DBLEND funcs[6] = { D3DBLEND_ZERO, D3DBLEND_ONE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA, D3DBLEND_DESTALPHA, D3DBLEND_INVDESTALPHA };
+
+ d3d9_srcBlendFunc = funcs[srcBlendFunc];
+ D3D9_SetRenderState(D3DRS_SRCBLEND, d3d9_srcBlendFunc, "D3D9_SetAlphaBlendFunc_Src");
+ d3d9_dstBlendFunc = funcs[dstBlendFunc];
+ D3D9_SetRenderState2(D3DRS_DESTBLEND, d3d9_dstBlendFunc, "D3D9_SetAlphaBlendFunc_Dst");
+}
+
+void Gfx_SetAlphaArgBlend(bool enabled) {
+ D3DTEXTUREOP op = enabled ? D3DTOP_MODULATE : D3DTOP_SELECTARG1;
+ ReturnCode res = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, op);
+ if (res) ErrorHandler_Fail2(res, "D3D9_SetAlphaArgBlend");
+}
+
+void Gfx_ClearCol(PackedCol col) { d3d9_clearCol = col.Packed; }
+void Gfx_SetColourWriteMask(bool r, bool g, bool b, bool a) {
+ DWORD channels = (r ? 1u : 0u) | (g ? 2u : 0u) | (b ? 4u : 0u) | (a ? 8u : 0u);
+ D3D9_SetRenderState(D3DRS_COLORWRITEENABLE, channels, "D3D9_SetColourWrite");
+}
+
+void Gfx_SetDepthTest(bool enabled) {
+ d3d9_depthTesting = enabled;
+ D3D9_SetRenderState(D3DRS_ZENABLE, enabled, "D3D9_SetDepthTest");
+}
+
+void Gfx_SetDepthTestFunc(int compareFunc) {
+ d3d9_depthTestFunc = d3d9_compareFuncs[compareFunc];
+ D3D9_SetRenderState(D3DRS_ZFUNC, d3d9_alphaTestFunc, "D3D9_SetDepthTestFunc");
+}
+
+void Gfx_SetDepthWrite(bool enabled) {
+ d3d9_depthWriting = enabled;
+ D3D9_SetRenderState(D3DRS_ZWRITEENABLE, enabled, "D3D9_SetDepthWrite");
+}
+
+static void D3D9_SetDefaultRenderStates(void) {
+ Gfx_SetFaceCulling(false);
+ gfx_batchFormat = -1;
+ D3D9_SetRenderState(D3DRS_COLORVERTEX, false, "D3D9_ColorVertex");
+ D3D9_SetRenderState2(D3DRS_LIGHTING, false, "D3D9_Lighting");
+ D3D9_SetRenderState2(D3DRS_SPECULARENABLE, false, "D3D9_SpecularEnable");
+ D3D9_SetRenderState2(D3DRS_LOCALVIEWER, false, "D3D9_LocalViewer");
+ D3D9_SetRenderState2(D3DRS_DEBUGMONITORTOKEN, false, "D3D9_DebugMonitor");
+}
+
+static void D3D9_RestoreRenderStates(void) {
+ union IntAndFloat raw;
+ D3D9_SetRenderState(D3DRS_ALPHATESTENABLE, d3d9_alphaTesting, "D3D9_AlphaTest");
+ D3D9_SetRenderState2(D3DRS_ALPHABLENDENABLE, d3d9_alphaBlending, "D3D9_AlphaBlend");
+ D3D9_SetRenderState2(D3DRS_ALPHAFUNC, d3d9_alphaTestFunc, "D3D9_AlphaTestFunc");
+ D3D9_SetRenderState2(D3DRS_ALPHAREF, d3d9_alphaTestRef, "D3D9_AlphaRefFunc");
+ D3D9_SetRenderState2(D3DRS_SRCBLEND, d3d9_srcBlendFunc, "D3D9_AlphaSrcBlend");
+ D3D9_SetRenderState2(D3DRS_DESTBLEND, d3d9_dstBlendFunc, "D3D9_AlphaDstBlend");
+
+ D3D9_SetRenderState2(D3DRS_FOGENABLE, gfx_fogEnabled, "D3D9_Fog");
+ D3D9_SetRenderState2(D3DRS_FOGCOLOR, d3d9_fogCol, "D3D9_FogColor");
+ raw.f = d3d9_fogDensity;
+ D3D9_SetRenderState2(D3DRS_FOGDENSITY, raw.u, "D3D9_FogDensity");
+ raw.f = d3d9_fogEnd;
+ D3D9_SetRenderState2(D3DRS_FOGEND, raw.u, "D3D9_FogEnd");
+ D3D9_SetRenderState2(D3DRS_FOGTABLEMODE, d3d9_fogMode, "D3D9_FogMode");
+
+ D3D9_SetRenderState2(D3DRS_ZFUNC, d3d9_depthTestFunc, "D3D9_DepthTestFunc");
+ D3D9_SetRenderState2(D3DRS_ZENABLE, d3d9_depthTesting, "D3D9_DepthTest");
+ D3D9_SetRenderState2(D3DRS_ZWRITEENABLE, d3d9_depthWriting, "D3D9_DepthWrite");
+}
+
+
+/*########################################################################################################################*
+*---------------------------------------------------Vertex/Index buffers--------------------------------------------------*
+*#########################################################################################################################*/
+GfxResourceID Gfx_CreateDynamicVb(int vertexFormat, int maxVertices) {
+ int size = maxVertices * Gfx_strideSizes[vertexFormat];
+ IDirect3DVertexBuffer9* vbuffer;
+ ReturnCode res = IDirect3DDevice9_CreateVertexBuffer(device, size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
+ d3d9_formatMappings[vertexFormat], D3DPOOL_DEFAULT, &vbuffer, NULL);
+ if (res) ErrorHandler_Fail2(res, "D3D9_CreateDynamicVb");
+
+ return vbuffer;
+}
+
+static void D3D9_SetVbData(IDirect3DVertexBuffer9* buffer, void* data, int size, const char* lockMsg, const char* unlockMsg, int lockFlags) {
+ void* dst = NULL;
+ ReturnCode res = IDirect3DVertexBuffer9_Lock(buffer, 0, size, &dst, lockFlags);
+ if (res) ErrorHandler_Fail2(res, lockMsg);
+
+ Mem_Copy(dst, data, size);
+ res = IDirect3DVertexBuffer9_Unlock(buffer);
+ if (res) ErrorHandler_Fail2(res, unlockMsg);
+}
+
+GfxResourceID Gfx_CreateVb(void* vertices, int vertexFormat, int count) {
+ int size = count * Gfx_strideSizes[vertexFormat];
+ IDirect3DVertexBuffer9* vbuffer;
+
+ for (;;) {
+ ReturnCode res = IDirect3DDevice9_CreateVertexBuffer(device, size, D3DUSAGE_WRITEONLY,
+ d3d9_formatMappings[vertexFormat], D3DPOOL_DEFAULT, &vbuffer, NULL);
+ if (!res) break;
+
+ if (res != D3DERR_OUTOFVIDEOMEMORY) ErrorHandler_Fail2(res, "D3D9_CreateVb");
+ Event_RaiseVoid(&GfxEvents_LowVRAMDetected);
+ }
+
+ D3D9_SetVbData(vbuffer, vertices, size, "D3D9_CreateVb - Lock", "D3D9_CreateVb - Unlock", 0);
+ return vbuffer;
+}
+
+static void D3D9_SetIbData(IDirect3DIndexBuffer9* buffer, void* data, int size) {
+ void* dst = NULL;
+ ReturnCode res = IDirect3DIndexBuffer9_Lock(buffer, 0, size, &dst, 0);
+ if (res) ErrorHandler_Fail2(res, "D3D9_CreateIb - Lock");
+
+ Mem_Copy(dst, data, size);
+ res = IDirect3DIndexBuffer9_Unlock(buffer);
+ if (res) ErrorHandler_Fail2(res, "D3D9_CreateIb - Unlock");
+}
+
+GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) {
+ int size = indicesCount * 2;
+ IDirect3DIndexBuffer9* ibuffer;
+ ReturnCode res = IDirect3DDevice9_CreateIndexBuffer(device, size, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ibuffer, NULL);
+ if (res) ErrorHandler_Fail2(res, "D3D9_CreateIb");
+
+ D3D9_SetIbData(ibuffer, indices, size);
+ return ibuffer;
+}
+
+void Gfx_BindVb(GfxResourceID vb) {
+ IDirect3DVertexBuffer9* vbuffer = (IDirect3DVertexBuffer9*)vb;
+ ReturnCode res = IDirect3DDevice9_SetStreamSource(device, 0, vbuffer, 0, gfx_batchStride);
+ if (res) ErrorHandler_Fail2(res, "D3D9_BindVb");
+}
+
+void Gfx_BindIb(GfxResourceID ib) {
+ IDirect3DIndexBuffer9* ibuffer = (IDirect3DIndexBuffer9*)ib;
+ ReturnCode res = IDirect3DDevice9_SetIndices(device, ibuffer);
+ if (res) ErrorHandler_Fail2(res, "D3D9_BindIb");
+}
+
+void Gfx_DeleteVb(GfxResourceID* vb) { D3D9_FreeResource(vb); }
+void Gfx_DeleteIb(GfxResourceID* ib) { D3D9_FreeResource(ib); }
+
+void Gfx_SetBatchFormat(int format) {
+ if (format == gfx_batchFormat) return;
+ gfx_batchFormat = format;
+
+ ReturnCode res = IDirect3DDevice9_SetFVF(device, d3d9_formatMappings[format]);
+ if (res) ErrorHandler_Fail2(res, "D3D9_SetBatchFormat");
+ gfx_batchStride = Gfx_strideSizes[format];
+}
+
+void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
+ int size = vCount * gfx_batchStride;
+ IDirect3DVertexBuffer9* vbuffer = (IDirect3DVertexBuffer9*)vb;
+ D3D9_SetVbData(vbuffer, vertices, size, "D3D9_SetDynamicVbData - Lock", "D3D9_SetDynamicVbData - Unlock", D3DLOCK_DISCARD);
+
+ ReturnCode res = IDirect3DDevice9_SetStreamSource(device, 0, vbuffer, 0, gfx_batchStride);
+ if (res) ErrorHandler_Fail2(res, "D3D9_SetDynamicVbData - Bind");
+}
+
+void Gfx_DrawVb_Lines(int verticesCount) {
+ ReturnCode res = IDirect3DDevice9_DrawPrimitive(device, D3DPT_LINELIST, 0, verticesCount >> 1);
+ if (res) ErrorHandler_Fail2(res, "D3D9_DrawVb_Lines");
+}
+
+void Gfx_DrawVb_IndexedTris(int verticesCount) {
+ ReturnCode res = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
+ 0, 0, verticesCount, 0, verticesCount >> 1);
+ if (res) ErrorHandler_Fail2(res, "D3D9_DrawVb_IndexedTris");
+}
+
+void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
+ ReturnCode res = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
+ startVertex, 0, verticesCount, 0, verticesCount >> 1);
+ if (res) ErrorHandler_Fail2(res, "D3D9_DrawVb_IndexedTris");
+}
+
+void Gfx_DrawIndexedVb_TrisT2fC4b(int verticesCount, int startVertex) {
+ ReturnCode res = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST,
+ startVertex, 0, verticesCount, 0, verticesCount >> 1);
+ if (res) ErrorHandler_Fail2(res, "D3D9_DrawIndexedVb_TrisT2fC4b");
+}
+
+
+/*########################################################################################################################*
+*---------------------------------------------------------Matrices--------------------------------------------------------*
+*#########################################################################################################################*/
+void Gfx_SetMatrixMode(int matrixType) {
+ if (matrixType == MATRIX_TYPE_PROJECTION) { curMatrix = D3DTS_PROJECTION; }
+ else if (matrixType == MATRIX_TYPE_VIEW) { curMatrix = D3DTS_VIEW; }
+ else if (matrixType == MATRIX_TYPE_TEXTURE) { curMatrix = D3DTS_TEXTURE0; }
+}
+
+void Gfx_LoadMatrix(struct Matrix* matrix) {
+ if (curMatrix == D3DTS_TEXTURE0) {
+ matrix->Row2.X = matrix->Row3.X; /* NOTE: this hack fixes the texture movements. */
+ IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
+ }
+
+ if (Gfx_LostContext) return;
+ ReturnCode res = IDirect3DDevice9_SetTransform(device, curMatrix, matrix);
+ if (res) ErrorHandler_Fail2(res, "D3D9_LoadMatrix");
+}
+
+void Gfx_LoadIdentityMatrix(void) {
+ if (curMatrix == D3DTS_TEXTURE0) {
+ IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
+ }
+
+ if (Gfx_LostContext) return;
+ ReturnCode res = IDirect3DDevice9_SetTransform(device, curMatrix, &Matrix_Identity);
+ if (res) ErrorHandler_Fail2(res, "D3D9_LoadIdentityMatrix");
+}
+
+#define d3d9_zN -10000.0f
+#define d3d9_zF 10000.0f
+void Gfx_CalcOrthoMatrix(float width, float height, struct Matrix* matrix) {
+ Matrix_OrthographicOffCenter(matrix, 0.0f, width, height, 0.0f, d3d9_zN, d3d9_zF);
+ matrix->Row2.Z = 1.0f / (d3d9_zN - d3d9_zF);
+ matrix->Row3.Z = d3d9_zN / (d3d9_zN - d3d9_zF);
+}
+void Gfx_CalcPerspectiveMatrix(float fov, float aspect, float zNear, float zFar, struct Matrix* matrix) {
+ Matrix_PerspectiveFieldOfView(matrix, fov, aspect, zNear, zFar);
+}
+
+
+/*########################################################################################################################*
+*-----------------------------------------------------------Misc----------------------------------------------------------*
+*#########################################################################################################################*/
+ReturnCode Gfx_TakeScreenshot(struct Stream* output, int width, int height) {
+ IDirect3DSurface9* backbuffer = NULL;
+ IDirect3DSurface9* temp = NULL;
+ ReturnCode res;
+
+ res = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
+ if (res) goto finished;
+ res = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &temp, NULL);
+ if (res) goto finished; /* TODO: For DX 8 use IDirect3DDevice8::CreateImageSurface */
+ res = IDirect3DDevice9_GetRenderTargetData(device, backbuffer, temp);
+ if (res) goto finished;
+
+ D3DLOCKED_RECT rect;
+ res = IDirect3DSurface9_LockRect(temp, &rect, NULL, D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE);
+ if (res) goto finished;
+ {
+ Bitmap bmp; Bitmap_Create(&bmp, width, height, rect.pBits);
+ res = Bitmap_EncodePng(&bmp, output);
+ if (res) { IDirect3DSurface9_UnlockRect(temp); goto finished; }
+ }
+ res = IDirect3DSurface9_UnlockRect(temp);
+ if (res) goto finished;
+
+finished:
+ D3D9_FreeResource(&backbuffer);
+ D3D9_FreeResource(&temp);
+ return res;
+}
+
+void Gfx_SetVSync(bool value) {
+ if (gfx_vsync == value) return;
+ gfx_vsync = value;
+
+ GfxCommon_LoseContext(" (toggling VSync)");
+ D3D9_RecreateDevice();
+}
+
+void Gfx_BeginFrame(void) { IDirect3DDevice9_BeginScene(device); }
+void Gfx_Clear(void) {
+ DWORD flags = D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER;
+ ReturnCode res = IDirect3DDevice9_Clear(device, 0, NULL, flags, d3d9_clearCol, 1.0f, 0);
+ if (res) ErrorHandler_Fail2(res, "D3D9_Clear");
+}
+
+void Gfx_EndFrame(void) {
+ IDirect3DDevice9_EndScene(device);
+ ReturnCode res = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ if (!res) return;
+ if (res != D3DERR_DEVICELOST) ErrorHandler_Fail2(res, "D3D9_EndFrame");
+
+ /* TODO: Make sure this actually works on all graphics cards.*/
+ GfxCommon_LoseContext(" (Direct3D9 device lost)");
+ D3D9_LoopUntilRetrieved();
+ D3D9_RecreateDevice();
+}
+
+bool Gfx_WarnIfNecessary(void) { return false; }
+const char* D3D9_StrFlags(void) {
+ if (createFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) return "Hardware";
+ if (createFlags & D3DCREATE_MIXED_VERTEXPROCESSING) return "Mixed";
+ if (createFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) return "Software";
+ return "(none)";
+}
+
+const char* D3D9_StrFormat(D3DFORMAT format) {
+ switch (format) {
+ case D3DFMT_D32: return "D32";
+ case D3DFMT_D24X8: return "D24X8";
+ case D3DFMT_D24S8: return "D24S8";
+ case D3DFMT_D24X4S4: return "D24X4S4";
+ case D3DFMT_D16: return "D16";
+ case D3DFMT_D15S1: return "D15S1";
+
+ case D3DFMT_X8R8G8B8: return "X8R8G8B8";
+ case D3DFMT_R8G8B8: return "R8G8B8";
+ case D3DFMT_R5G6B5: return "R5G6B5";
+ case D3DFMT_X1R5G5B5: return "X1R5G5B5";
+ }
+ return "(unknown)";
+}
+
+float d3d9_totalMem;
+void Gfx_MakeApiInfo(void) {
+ D3DADAPTER_IDENTIFIER9 adapter = { 0 };
+ IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &adapter);
+ d3d9_totalMem = IDirect3DDevice9_GetAvailableTextureMem(device) / (1024.0f * 1024.0f);
+
+ String_AppendConst(&Gfx_ApiInfo[0],"-- Using Direct3D9 --");
+ String_Format1(&Gfx_ApiInfo[1], "Adapter: %c", adapter.Description);
+ String_Format1(&Gfx_ApiInfo[2], "Processing mode: %c", D3D9_StrFlags());
+ Gfx_UpdateApiInfo();
+ String_Format2(&Gfx_ApiInfo[4], "Max texture size: (%i, %i)", &Gfx_MaxTexWidth, &Gfx_MaxTexHeight);
+ String_Format1(&Gfx_ApiInfo[5], "Depth buffer format: %c", D3D9_StrFormat(d3d9_depthFormat));
+ String_Format1(&Gfx_ApiInfo[6], "Back buffer format: %c", D3D9_StrFormat(d3d9_viewFormat));
+}
+
+void Gfx_UpdateApiInfo(void) {
+ float mem = IDirect3DDevice9_GetAvailableTextureMem(device) / (1024.0f * 1024.0f);
+ Gfx_ApiInfo[3].length = 0;
+ String_Format2(&Gfx_ApiInfo[3], "Video memory: %f2 MB total, %f2 free", &d3d9_totalMem, &mem);
+}
+
+void Gfx_OnWindowResize(void) {
+ GfxCommon_LoseContext(" (resizing window)");
+ D3D9_RecreateDevice();
+}
+#endif
+
+
+/*########################################################################################################################*
+*----------------------------------------------------------OpenGL---------------------------------------------------------*
+*#########################################################################################################################*/
+#ifndef CC_BUILD_D3D9
+#ifdef CC_BUILD_WIN
+#define WIN32_LEAN_AND_MEAN
+#define NOSERVICE
+#define NOMCX
+#define NOIME
+#include
+#else
+#define APIENETRY
+#endif
+#include
+
+/* Extensions from later than OpenGL 1.1 */
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_STATIC_DRAW 0x88E4
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_BGRA_EXT 0x80E1
+
+#ifdef CC_BUILD_GL11
+GfxResourceID gl_activeList;
+#define gl_DYNAMICLISTID 1234567891
+void* gl_dynamicListData;
+#else
+typedef void (APIENTRY *FUNC_GLBINDBUFFER) (GLenum target, GLuint buffer);
+typedef void (APIENTRY *FUNC_GLDELETEBUFFERS) (GLsizei n, const GLuint *buffers);
+typedef void (APIENTRY *FUNC_GLGENBUFFERS) (GLsizei n, GLuint *buffers);
+typedef void (APIENTRY *FUNC_GLBUFFERDATA) (GLenum target, const void* size, const void *data, GLenum usage);
+typedef void (APIENTRY *FUNC_GLBUFFERSUBDATA) (GLenum target, const void* offset, const void* size, const void *data);
+FUNC_GLBINDBUFFER glBindBuffer;
+FUNC_GLDELETEBUFFERS glDeleteBuffers;
+FUNC_GLGENBUFFERS glGenBuffers;
+FUNC_GLBUFFERDATA glBufferData;
+FUNC_GLBUFFERSUBDATA glBufferSubData;
+#endif
+
+int gl_compare[8] = { GL_ALWAYS, GL_NOTEQUAL, GL_NEVER, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER };
+typedef void (*GL_SetupVBFunc)(void);
+typedef void (*GL_SetupVBRangeFunc)(int startVertex);
+GL_SetupVBFunc gl_setupVBFunc;
+GL_SetupVBRangeFunc gl_setupVBRangeFunc;
+
+#ifndef CC_BUILD_GL11
+static void GL_CheckVboSupport(void) {
+ String extensions = String_FromReadonly(glGetString(GL_EXTENSIONS));
+ String version = String_FromReadonly(glGetString(GL_VERSION));
+ String vboExt = String_FromConst("GL_ARB_vertex_buffer_object");
+
+ int major = (int)(version.buffer[0] - '0'); /* x.y. (and so forth) */
+ int minor = (int)(version.buffer[2] - '0');
+
+ /* Supported in core since 1.5 */
+ if ((major > 1) || (major == 1 && minor >= 5)) {
+ glBindBuffer = (FUNC_GLBINDBUFFER)GLContext_GetAddress("glBindBuffer");
+ glDeleteBuffers = (FUNC_GLDELETEBUFFERS)GLContext_GetAddress("glDeleteBuffers");
+ glGenBuffers = (FUNC_GLGENBUFFERS)GLContext_GetAddress("glGenBuffers");
+ glBufferData = (FUNC_GLBUFFERDATA)GLContext_GetAddress("glBufferData");
+ glBufferSubData = (FUNC_GLBUFFERSUBDATA)GLContext_GetAddress("glBufferSubData");
+ return;
+ } else if (String_CaselessContains(&extensions, &vboExt)) {
+ glBindBuffer = (FUNC_GLBINDBUFFER)GLContext_GetAddress("glBindBufferARB");
+ glDeleteBuffers = (FUNC_GLDELETEBUFFERS)GLContext_GetAddress("glDeleteBuffersARB");
+ glGenBuffers = (FUNC_GLGENBUFFERS)GLContext_GetAddress("glGenBuffersARB");
+ glBufferData = (FUNC_GLBUFFERDATA)GLContext_GetAddress("glBufferDataARB");
+ glBufferSubData = (FUNC_GLBUFFERSUBDATA)GLContext_GetAddress("glBufferSubDataARB");
+ } else {
+ ErrorHandler_Fail("Only OpenGL 1.1 supported.\r\n\r\n" \
+ "Compile the game with CC_BUILD_GL11, or ask on the classicube forums for it");
+ }
+}
+#endif
+
+void Gfx_Init(void) {
+ Gfx_MinZNear = 0.1f;
+ struct GraphicsMode mode = GraphicsMode_MakeDefault();
+ GLContext_Init(mode);
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &Gfx_MaxTexWidth);
+ Gfx_MaxTexHeight = Gfx_MaxTexWidth;
+
+#ifndef CC_BUILD_GL11
+ Gfx_CustomMipmapsLevels = true;
+ GL_CheckVboSupport();
+#else
+ Gfx_CustomMipmapsLevels = false;
+#endif
+
+ GfxCommon_Init();
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+}
+
+void Gfx_Free(void) {
+ GfxCommon_Free();
+ GLContext_Free();
+}
+
+#define gl_Toggle(cap) if (enabled) { glEnable(cap); } else { glDisable(cap); }
+
+
+/*########################################################################################################################*
+*---------------------------------------------------------Textures--------------------------------------------------------*
+*#########################################################################################################################*/
+static void GL_DoMipmaps(GfxResourceID texId, int x, int y, Bitmap* bmp, bool partial) {
+ uint8_t* prev = bmp->Scan0;
+ int lvls = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height);
+ int lvl, width = bmp->Width, height = bmp->Height;
+
+ for (lvl = 1; lvl <= lvls; lvl++) {
+ x /= 2; y /= 2;
+ if (width > 1) width /= 2;
+ if (height > 1) height /= 2;
+
+ uint8_t* cur = Mem_Alloc(width * height, BITMAP_SIZEOF_PIXEL, "mipmaps");
+ GfxCommon_GenMipmaps(width, height, cur, prev);
+
+ if (partial) {
+ glTexSubImage2D(GL_TEXTURE_2D, lvl, x, y, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, cur);
+ } else {
+ glTexImage2D(GL_TEXTURE_2D, lvl, GL_RGBA, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, cur);
+ }
+
+ if (prev != bmp->Scan0) Mem_Free(prev);
+ prev = cur;
+ }
+ if (prev != bmp->Scan0) Mem_Free(prev);
+}
+
+GfxResourceID Gfx_CreateTexture(Bitmap* bmp, bool managedPool, bool mipmaps) {
+ uint32_t texId;
+ glGenTextures(1, &texId);
+ glBindTexture(GL_TEXTURE_2D, texId);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ if (!Math_IsPowOf2(bmp->Width) || !Math_IsPowOf2(bmp->Height)) {
+ ErrorHandler_Fail("Textures must have power of two dimensions");
+ }
+
+ if (mipmaps) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
+ if (Gfx_CustomMipmapsLevels) {
+ int lvls = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, lvls);
+ }
+ } else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bmp->Width, bmp->Height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, bmp->Scan0);
+
+ if (mipmaps) GL_DoMipmaps(texId, 0, 0, bmp, false);
+ return texId;
+}
+
+void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, Bitmap* part, bool mipmaps) {
+ glBindTexture(GL_TEXTURE_2D, texId);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, part->Width, part->Height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, part->Scan0);
+ if (mipmaps) GL_DoMipmaps(texId, x, y, part, true);
+}
+
+void Gfx_BindTexture(GfxResourceID texId) {
+ glBindTexture(GL_TEXTURE_2D, texId);
+}
+
+void Gfx_DeleteTexture(GfxResourceID* texId) {
+ if (!texId || *texId == GFX_NULL) return;
+ glDeleteTextures(1, texId);
+ *texId = GFX_NULL;
+}
+
+void Gfx_SetTexturing(bool enabled) { gl_Toggle(GL_TEXTURE_2D); }
+void Gfx_EnableMipmaps(void) { }
+void Gfx_DisableMipmaps(void) { }
+
+
+/*########################################################################################################################*
+*-----------------------------------------------------State management----------------------------------------------------*
+*#########################################################################################################################*/
+PackedCol gl_lastFogCol;
+float gl_lastFogEnd = -1, gl_lastFogDensity = -1;
+int gl_lastFogMode = -1;
+
+PackedCol gl_lastClearCol;
+
+void Gfx_SetFog(bool enabled) {
+ gfx_fogEnabled = enabled;
+ gl_Toggle(GL_FOG);
+}
+
+void Gfx_SetFogCol(PackedCol col) {
+ if (PackedCol_Equals(col, gl_lastFogCol)) return;
+ float colRGBA[4] = { col.R / 255.0f, col.G / 255.0f, col.B / 255.0f, col.A / 255.0f };
+ glFogfv(GL_FOG_COLOR, colRGBA);
+ gl_lastFogCol = col;
+}
+
+void Gfx_SetFogDensity(float value) {
+ if (value == gl_lastFogDensity) return;
+ glFogf(GL_FOG_DENSITY, value);
+ gl_lastFogDensity = value;
+}
+
+void Gfx_SetFogEnd(float value) {
+ if (value == gl_lastFogEnd) return;
+ glFogf(GL_FOG_END, value);
+ gl_lastFogEnd = value;
+}
+
+void Gfx_SetFogMode(int mode) {
+ static GLint modes[3] = { GL_LINEAR, GL_EXP, GL_EXP2 };
+ if (mode == gl_lastFogMode) return;
+ glFogi(GL_FOG_MODE, modes[mode]);
+ gl_lastFogMode = mode;
+}
+
+void Gfx_SetFaceCulling(bool enabled) { gl_Toggle(GL_CULL_FACE); }
+void Gfx_SetAlphaTest(bool enabled) { gl_Toggle(GL_ALPHA_TEST); }
+void Gfx_SetAlphaTestFunc(int func, float value) {
+ glAlphaFunc(gl_compare[func], value);
+}
+
+void Gfx_SetAlphaBlending(bool enabled) { gl_Toggle(GL_BLEND); }
+void Gfx_SetAlphaBlendFunc(int srcFunc, int dstFunc) {
+ static GLenum funcs[6] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA };
+ glBlendFunc(funcs[srcFunc], funcs[dstFunc]);
+}
+void Gfx_SetAlphaArgBlend(bool enabled) { }
+
+void Gfx_ClearCol(PackedCol col) {
+ if (PackedCol_Equals(col, gl_lastClearCol)) return;
+ glClearColor(col.R / 255.0f, col.G / 255.0f, col.B / 255.0f, col.A / 255.0f);
+ gl_lastClearCol = col;
+}
+
+void Gfx_SetColourWriteMask(bool r, bool g, bool b, bool a) {
+ glColorMask(r, g, b, a);
+}
+
+void Gfx_SetDepthWrite(bool enabled) {
+ glDepthMask(enabled);
+}
+
+void Gfx_SetDepthTest(bool enabled) { gl_Toggle(GL_DEPTH_TEST); }
+void Gfx_SetDepthTestFunc(int compareFunc) {
+ glDepthFunc(gl_compare[compareFunc]);
+}
+
+
+/*########################################################################################################################*
+*---------------------------------------------------Vertex/Index buffers--------------------------------------------------*
+*#########################################################################################################################*/
+#ifndef CC_BUILD_GL11
+static GfxResourceID GL_GenAndBind(GLenum target) {
+ GfxResourceID id;
+ glGenBuffers(1, &id);
+ glBindBuffer(target, id);
+ return id;
+}
+
+GfxResourceID Gfx_CreateDynamicVb(int vertexFormat, int maxVertices) {
+ GfxResourceID id = GL_GenAndBind(GL_ARRAY_BUFFER);
+ uint32_t sizeInBytes = maxVertices * Gfx_strideSizes[vertexFormat];
+ glBufferData(GL_ARRAY_BUFFER, (void*)sizeInBytes, NULL, GL_DYNAMIC_DRAW);
+ return id;
+}
+
+GfxResourceID Gfx_CreateVb(void* vertices, int vertexFormat, int count) {
+ GfxResourceID id = GL_GenAndBind(GL_ARRAY_BUFFER);
+ uint32_t sizeInBytes = count * Gfx_strideSizes[vertexFormat];
+ glBufferData(GL_ARRAY_BUFFER, (void*)sizeInBytes, vertices, GL_STATIC_DRAW);
+ return id;
+}
+
+GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) {
+ GfxResourceID id = GL_GenAndBind(GL_ELEMENT_ARRAY_BUFFER);
+ uint32_t sizeInBytes = indicesCount * 2;
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, (void*)sizeInBytes, indices, GL_STATIC_DRAW);
+ return id;
+}
+
+void Gfx_BindVb(GfxResourceID vb) { glBindBuffer(GL_ARRAY_BUFFER, vb); }
+void Gfx_BindIb(GfxResourceID ib) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib); }
+
+void Gfx_DeleteVb(GfxResourceID* vb) {
+ if (!vb || *vb == GFX_NULL) return;
+ glDeleteBuffers(1, vb);
+ *vb = GFX_NULL;
+}
+
+void Gfx_DeleteIb(GfxResourceID* ib) {
+ if (!ib || *ib == GFX_NULL) return;
+ glDeleteBuffers(1, ib);
+ *ib = GFX_NULL;
+}
+#else
+GfxResourceID Gfx_CreateDynamicVb(int vertexFormat, int maxVertices) { return gl_DYNAMICLISTID; }
+GfxResourceID Gfx_CreateVb(void* vertices, int vertexFormat, int count) {
+ /* We need to setup client state properly when building the list */
+ int curFormat = gfx_batchFormat;
+ Gfx_SetBatchFormat(vertexFormat);
+ GfxResourceID list = glGenLists(1);
+ glNewList(list, GL_COMPILE);
+ count &= ~0x01; /* Need to get rid of the 1 extra element, see comment in chunk mesh builder for why */
+
+ uint16_t indices[GFX_MAX_INDICES];
+ GfxCommon_MakeIndices(indices, ICOUNT(count));
+
+ int stride = vertexFormat == VERTEX_FORMAT_P3FT2FC4B ? sizeof(VertexP3fT2fC4b) : sizeof(VertexP3fC4b);
+ glVertexPointer(3, GL_FLOAT, stride, vertices);
+ glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)((uint8_t*)vertices + 12));
+ if (vertexFormat == VERTEX_FORMAT_P3FT2FC4B) {
+ glTexCoordPointer(2, GL_FLOAT, stride, (void*)((uint8_t*)vertices + 16));
+ }
+
+ glDrawElements(GL_TRIANGLES, ICOUNT(count), GL_UNSIGNED_SHORT, indices);
+ glEndList();
+ Gfx_SetBatchFormat(curFormat);
+ return list;
+}
+
+GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) { return GFX_NULL; }
+void Gfx_BindVb(GfxResourceID vb) { gl_activeList = vb; }
+void Gfx_BindIb(GfxResourceID ib) { }
+void Gfx_DeleteIb(GfxResourceID* ib) { }
+
+void Gfx_DeleteVb(GfxResourceID* vb) {
+ if (!vb || *vb == GFX_NULL) return;
+ if (*vb != gl_DYNAMICLISTID) glDeleteLists(*vb, 1);
+ *vb = GFX_NULL;
+}
+#endif
+
+void GL_SetupVbPos3fCol4b(void) {
+ glVertexPointer(3, GL_FLOAT, sizeof(VertexP3fC4b), (void*)0);
+ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexP3fC4b), (void*)12);
+}
+
+void GL_SetupVbPos3fTex2fCol4b(void) {
+ glVertexPointer(3, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)0);
+ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexP3fT2fC4b), (void*)12);
+ glTexCoordPointer(2, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)16);
+}
+
+void GL_SetupVbPos3fCol4b_Range(int startVertex) {
+ uint32_t offset = startVertex * (uint32_t)sizeof(VertexP3fC4b);
+ glVertexPointer(3, GL_FLOAT, sizeof(VertexP3fC4b), (void*)(offset));
+ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexP3fC4b), (void*)(offset + 12));
+}
+
+void GL_SetupVbPos3fTex2fCol4b_Range(int startVertex) {
+ uint32_t offset = startVertex * (uint32_t)sizeof(VertexP3fT2fC4b);
+ glVertexPointer(3, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)(offset));
+ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexP3fT2fC4b), (void*)(offset + 12));
+ glTexCoordPointer(2, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)(offset + 16));
+}
+
+void Gfx_SetBatchFormat(int vertexFormat) {
+ if (vertexFormat == gfx_batchFormat) return;
+
+ if (gfx_batchFormat == VERTEX_FORMAT_P3FT2FC4B) {
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+ gfx_batchFormat = vertexFormat;
+ gfx_batchStride = Gfx_strideSizes[vertexFormat];
+
+ if (vertexFormat == VERTEX_FORMAT_P3FT2FC4B) {
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ gl_setupVBFunc = GL_SetupVbPos3fTex2fCol4b;
+ gl_setupVBRangeFunc = GL_SetupVbPos3fTex2fCol4b_Range;
+ } else {
+ gl_setupVBFunc = GL_SetupVbPos3fCol4b;
+ gl_setupVBRangeFunc = GL_SetupVbPos3fCol4b_Range;
+ }
+}
+
+#ifndef CC_BUILD_GL11
+void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
+ glBindBuffer(GL_ARRAY_BUFFER, vb);
+ uint32_t sizeInBytes = vCount * gfx_batchStride;
+ glBufferSubData(GL_ARRAY_BUFFER, NULL, (void*)sizeInBytes, vertices);
+}
+
+void Gfx_DrawVb_Lines(int verticesCount) {
+ gl_setupVBFunc();
+ glDrawArrays(GL_LINES, 0, verticesCount);
+}
+
+void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
+ gl_setupVBRangeFunc(startVertex);
+ glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, NULL);
+}
+
+void Gfx_DrawVb_IndexedTris(int verticesCount) {
+ gl_setupVBFunc();
+ glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, NULL);
+}
+
+void Gfx_DrawIndexedVb_TrisT2fC4b(int verticesCount, int startVertex) {
+ uint32_t offset = startVertex * (uint32_t)sizeof(VertexP3fT2fC4b);
+ glVertexPointer(3, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)(offset));
+ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexP3fT2fC4b), (void*)(offset + 12));
+ glTexCoordPointer(2, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)(offset + 16));
+ glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, NULL);
+}
+#else
+void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
+ gl_activeList = gl_DYNAMICLISTID;
+ gl_dynamicListData = vertices;
+}
+
+static void GL_V16(VertexP3fC4b v) {
+ glColor4ub(v.Col.R, v.Col.G, v.Col.B, v.Col.A);
+ glVertex3f(v.X, v.Y, v.Z);
+}
+
+static void GL_V24(VertexP3fT2fC4b v) {
+ glColor4ub(v.Col.R, v.Col.G, v.Col.B, v.Col.A);
+ glTexCoord2f(v.U, v.V);
+ glVertex3f(v.X, v.Y, v.Z);
+}
+
+static void GL_DrawDynamicTriangles(int verticesCount, int startVertex) {
+ glBegin(GL_TRIANGLES);
+ int i;
+ if (gfx_batchFormat == VERTEX_FORMAT_P3FT2FC4B) {
+ VertexP3fT2fC4b* ptr = (VertexP3fT2fC4b*)gl_dynamicListData;
+ for (i = startVertex; i < startVertex + verticesCount; i += 4) {
+ GL_V24(ptr[i + 0]); GL_V24(ptr[i + 1]); GL_V24(ptr[i + 2]);
+ GL_V24(ptr[i + 2]); GL_V24(ptr[i + 3]); GL_V24(ptr[i + 0]);
+ }
+ } else {
+ VertexP3fC4b* ptr = (VertexP3fC4b*)gl_dynamicListData;
+ for (i = startVertex; i < startVertex + verticesCount; i += 4) {
+ GL_V16(ptr[i + 0]); GL_V16(ptr[i + 1]); GL_V16(ptr[i + 2]);
+ GL_V16(ptr[i + 2]); GL_V16(ptr[i + 3]); GL_V16(ptr[i + 0]);
+ }
+ }
+ glEnd();
+}
+
+void Gfx_DrawVb_Lines(int verticesCount) {
+ glBegin(GL_LINES);
+ int i;
+ if (gfx_batchFormat == VERTEX_FORMAT_P3FT2FC4B) {
+ VertexP3fT2fC4b* ptr = (VertexP3fT2fC4b*)gl_dynamicListData;
+ for (i = 0; i < verticesCount; i += 2) { GL_V24(ptr[i + 0]); GL_V24(ptr[i + 1]); }
+ } else {
+ VertexP3fC4b* ptr = (VertexP3fC4b*)gl_dynamicListData;
+ for (i = 0; i < verticesCount; i += 2) { GL_V16(ptr[i + 0]); GL_V16(ptr[i + 1]); }
+ }
+ glEnd();
+}
+
+void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
+ if (gl_activeList != gl_DYNAMICLISTID) { glCallList(gl_activeList); }
+ else { GL_DrawDynamicTriangles(verticesCount, startVertex); }
+}
+
+void Gfx_DrawVb_IndexedTris(int verticesCount) {
+ if (gl_activeList != gl_DYNAMICLISTID) { glCallList(gl_activeList); }
+ else { GL_DrawDynamicTriangles(verticesCount, 0); }
+}
+
+GfxResourceID gl_lastPartialList;
+void Gfx_DrawIndexedVb_TrisT2fC4b(int verticesCount, int startVertex) {
+ /* TODO: This renders the whole map, bad performance!! FIX FIX */
+ if (gl_activeList == gl_lastPartialList) return;
+ glCallList(gl_activeList);
+ gl_lastPartialList = gl_activeList;
+}
+#endif
+
+
+/*########################################################################################################################*
+*---------------------------------------------------------Matrices--------------------------------------------------------*
+*#########################################################################################################################*/
+int gl_lastMatrixType;
+
+void Gfx_SetMatrixMode(int matrixType) {
+ if (matrixType == gl_lastMatrixType) return;
+ gl_lastMatrixType = matrixType;
+ static GLenum matrixModes[3] = { GL_PROJECTION, GL_MODELVIEW, GL_TEXTURE };
+ glMatrixMode(matrixModes[matrixType]);
+}
+
+void Gfx_LoadMatrix(struct Matrix* matrix) { glLoadMatrixf((float*)matrix); }
+void Gfx_LoadIdentityMatrix(void) { glLoadIdentity(); }
+
+void Gfx_CalcOrthoMatrix(float width, float height, struct Matrix* matrix) {
+ Matrix_OrthographicOffCenter(matrix, 0.0f, width, height, 0.0f, -10000.0f, 10000.0f);
+}
+void Gfx_CalcPerspectiveMatrix(float fov, float aspect, float zNear, float zFar, struct Matrix* matrix) {
+ Matrix_PerspectiveFieldOfView(matrix, fov, aspect, zNear, zFar);
+}
+
+
+/*########################################################################################################################*
+*-----------------------------------------------------------Misc----------------------------------------------------------*
+*#########################################################################################################################*/
+ReturnCode Gfx_TakeScreenshot(struct Stream* output, int width, int height) {
+ Bitmap bmp; Bitmap_Allocate(&bmp, width, height);
+ glReadPixels(0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, bmp.Scan0);
+ uint8_t tmp[PNG_MAX_DIMS * BITMAP_SIZEOF_PIXEL];
+
+ /* flip vertically around y */
+ int x, y;
+ uint32_t stride = (uint32_t)(bmp.Width) * BITMAP_SIZEOF_PIXEL;
+ for (y = 0; y < height / 2; y++) {
+ uint32_t* src = Bitmap_GetRow(&bmp, y);
+ uint32_t* dst = Bitmap_GetRow(&bmp, (height - 1) - y);
+
+ Mem_Copy(tmp, src, stride);
+ Mem_Copy(src, dst, stride);
+ Mem_Copy(dst, tmp, stride);
+ /*for (x = 0; x < bmp.Width; x++) {
+ uint32_t temp = dst[x]; dst[x] = src[x]; src[x] = temp;
+ }*/
+ }
+
+ ReturnCode res = Bitmap_EncodePng(&bmp, output);
+ Mem_Free(bmp.Scan0);
+ return res;
+}
+
+bool nv_mem;
+void Gfx_MakeApiInfo(void) {
+ int depthBits = 0;
+ glGetIntegerv(GL_DEPTH_BITS, &depthBits);
+
+ String_AppendConst(&Gfx_ApiInfo[0],"-- Using OpenGL --");
+ String_Format1(&Gfx_ApiInfo[1], "Vendor: %c", glGetString(GL_VENDOR));
+ String_Format1(&Gfx_ApiInfo[2], "Renderer: %c", glGetString(GL_RENDERER));
+ String_Format1(&Gfx_ApiInfo[3], "GL version: %c", glGetString(GL_VERSION));
+ /* Memory usage goes here */
+ String_Format2(&Gfx_ApiInfo[5], "Max texture size: (%i, %i)", &Gfx_MaxTexWidth, &Gfx_MaxTexHeight);
+ String_Format1(&Gfx_ApiInfo[6], "Depth buffer bits: %i", &depthBits);
+
+ String extensions = String_FromReadonly(glGetString(GL_EXTENSIONS));
+ String memExt = String_FromConst("GL_NVX_gpu_memory_info");
+ nv_mem = String_CaselessContains(&extensions, &memExt);
+}
+
+void Gfx_UpdateApiInfo(void) {
+ if (!nv_mem) return;
+ int totalKb = 0, curKb = 0;
+ glGetIntegerv(0x9048, &totalKb);
+ glGetIntegerv(0x9049, &curKb);
+
+ if (totalKb <= 0 || curKb <= 0) return;
+ Gfx_ApiInfo[4].length = 0;
+ float total = totalKb / 1024.0f, cur = curKb / 1024.0f;
+ String_Format2(&Gfx_ApiInfo[4], "Video memory: %f2 MB total, %f2 free", &total, &cur);
+}
+
+bool Gfx_WarnIfNecessary(void) {
+#ifdef CC_BUILD_GL11
+ Chat_AddRaw("&cYou are using the very outdated OpenGL backend.");
+ Chat_AddRaw("&cAs such you may experience poor performance.");
+ Chat_AddRaw("&cIt is likely you need to install video card drivers.");
+#endif
+
+ String renderer = String_FromReadonly(glGetString(GL_RENDERER));
+ String intel = String_FromConst("Intel");
+ if (!String_ContainsString(&renderer, &intel)) return false;
+
+ Chat_AddRaw("&cIntel graphics cards are known to have issues with the OpenGL build.");
+ Chat_AddRaw("&cVSync may not work, and you may see disappearing clouds and map edges.");
+ Chat_AddRaw("&cFor Windows, try downloading the Direct3D 9 build instead.");
+ return true;
+}
+
+void Gfx_SetVSync(bool value) {
+ if (gfx_vsync == value) return;
+ gfx_vsync = value;
+ GLContext_SetVSync(value);
+}
+
+void Gfx_BeginFrame(void) { }
+void Gfx_Clear(void) {
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+void Gfx_EndFrame(void) {
+ GLContext_SwapBuffers();
+#ifdef CC_BUILD_GL11
+ gl_activeList = NULL;
+#endif
+}
+
+void Gfx_OnWindowResize(void) {
+ glViewport(0, 0, Game_Width, Game_Height);
+}
+#endif
diff --git a/src/GraphicsAPI.h b/src/Graphics.h
similarity index 96%
rename from src/GraphicsAPI.h
rename to src/Graphics.h
index 46d25b412..099ff7a5a 100644
--- a/src/GraphicsAPI.h
+++ b/src/Graphics.h
@@ -38,7 +38,6 @@ struct Matrix Gfx_View, Gfx_Projection;
#define GFX_MAX_INDICES (65536 / 4 * 6)
#define GFX_MAX_VERTICES 65536
-#define GFX_STRIDE_SIZES { 16, 24 }
/* Callback invoked when the current context is lost, and is repeatedly invoked until the context can be retrieved. */
ScheduledTaskCallback Gfx_LostContextFunction;
diff --git a/src/GraphicsCommon.c b/src/GraphicsCommon.c
index e794ecc52..1ced64ece 100644
--- a/src/GraphicsCommon.c
+++ b/src/GraphicsCommon.c
@@ -1,5 +1,5 @@
#include "GraphicsCommon.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Platform.h"
#include "Block.h"
#include "Event.h"
diff --git a/src/Gui.c b/src/Gui.c
index c9a918a01..065e711a6 100644
--- a/src/Gui.c
+++ b/src/Gui.c
@@ -2,7 +2,7 @@
#include "Window.h"
#include "Game.h"
#include "GraphicsCommon.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Event.h"
#include "Drawer2D.h"
#include "ExtMath.h"
diff --git a/src/HeldBlockRenderer.c b/src/HeldBlockRenderer.c
index bed805cca..95c58720b 100644
--- a/src/HeldBlockRenderer.c
+++ b/src/HeldBlockRenderer.c
@@ -2,7 +2,7 @@
#include "Block.h"
#include "Game.h"
#include "Inventory.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "GraphicsCommon.h"
#include "Camera.h"
#include "ModelCache.h"
diff --git a/src/Input.c b/src/Input.c
index 9b981b206..2e53f5a41 100644
--- a/src/Input.c
+++ b/src/Input.c
@@ -7,6 +7,10 @@
#include "Platform.h"
#include "Chat.h"
+
+/*########################################################################################################################*
+*--------------------------------------------------------Key/Mouse--------------------------------------------------------*
+*#########################################################################################################################*/
#define Key_Function_Names \
"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",\
"F11", "F12", "F13", "F14", "F15", "F16", "F17", "F18", "F19", "F20",\
@@ -60,41 +64,32 @@ const char* Key_Names[Key_Count] = {
"XBUTTON1", "XBUTTON2",
};*/
-bool Key_States[Key_Count];
-bool Key_IsPressed(Key key) { return Key_States[key]; }
-
void Key_SetPressed(Key key, bool pressed) {
- if (Key_States[key] != pressed || Key_KeyRepeat) {
- Key_States[key] = pressed;
+ if (Key_Pressed[key] == pressed && !Key_KeyRepeat) return;
+ Key_Pressed[key] = pressed;
- if (pressed) {
- Event_RaiseInt(&KeyEvents_Down, key);
- } else {
- Event_RaiseInt(&KeyEvents_Up, key);
- }
+ if (pressed) {
+ Event_RaiseInt(&KeyEvents_Down, key);
+ } else {
+ Event_RaiseInt(&KeyEvents_Up, key);
}
}
void Key_Clear(void) {
int i;
for (i = 0; i < Key_Count; i++) {
- if (Key_States[i]) Key_SetPressed((Key)i, false);
+ if (Key_Pressed[i]) Key_SetPressed((Key)i, false);
}
}
-
-bool MouseButton_States[MouseButton_Count];
-bool Mouse_IsPressed(MouseButton btn) { return MouseButton_States[btn]; }
-
void Mouse_SetPressed(MouseButton btn, bool pressed) {
- if (MouseButton_States[btn] != pressed) {
- MouseButton_States[btn] = pressed;
+ if (Mouse_Pressed[btn] == pressed) return;
+ Mouse_Pressed[btn] = pressed;
- if (pressed) {
- Event_RaiseInt(&MouseEvents_Down, btn);
- } else {
- Event_RaiseInt(&MouseEvents_Up, btn);
- }
+ if (pressed) {
+ Event_RaiseInt(&MouseEvents_Down, btn);
+ } else {
+ Event_RaiseInt(&MouseEvents_Up, btn);
}
}
@@ -110,6 +105,10 @@ void Mouse_SetPosition(int x, int y) {
Event_RaiseMouseMove(&MouseEvents_Moved, deltaX, deltaY);
}
+
+/*########################################################################################################################*
+*---------------------------------------------------------Keybinds--------------------------------------------------------*
+*#########################################################################################################################*/
Key KeyBind_Keys[KeyBind_Count];
uint8_t KeyBind_Defaults[KeyBind_Count] = {
Key_W, Key_S, Key_A, Key_D,
@@ -136,7 +135,7 @@ const char* KeyBind_Names[KeyBind_Count] = {
Key KeyBind_Get(KeyBind binding) { return KeyBind_Keys[binding]; }
Key KeyBind_GetDefault(KeyBind binding) { return KeyBind_Defaults[binding]; }
-bool KeyBind_IsPressed(KeyBind binding) { return Key_States[KeyBind_Keys[binding]]; }
+bool KeyBind_IsPressed(KeyBind binding) { return Key_Pressed[KeyBind_Keys[binding]]; }
void KeyBind_Load(void) {
int i;
@@ -181,6 +180,9 @@ void KeyBind_Init(void) {
}
+/*########################################################################################################################*
+*---------------------------------------------------------Hotkeys---------------------------------------------------------*
+*#########################################################################################################################*/
uint8_t Hotkeys_LWJGL[256] = {
0, Key_Escape, Key_1, Key_2, Key_3, Key_4, Key_5, Key_6, Key_7, Key_8, Key_9, Key_0, Key_Minus, Key_Plus, Key_BackSpace, Key_Tab,
Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_BracketLeft, Key_BracketRight, Key_Enter, Key_ControlLeft, Key_A, Key_S,
diff --git a/src/Input.h b/src/Input.h
index f86c50aa2..3c56e30fc 100644
--- a/src/Input.h
+++ b/src/Input.h
@@ -71,12 +71,12 @@ are generated for the same key when it is held down for a period of time. Should
bool Key_KeyRepeat;
extern const char* Key_Names[Key_Count];
-#define Key_IsWinPressed() (Key_IsPressed(Key_WinLeft) || Key_IsPressed(Key_WinRight))
-#define Key_IsAltPressed() (Key_IsPressed(Key_AltLeft) || Key_IsPressed(Key_AltRight))
-#define Key_IsControlPressed() (Key_IsPressed(Key_ControlLeft) || Key_IsPressed(Key_ControlRight))
-#define Key_IsShiftPressed() (Key_IsPressed(Key_ShiftLeft) || Key_IsPressed(Key_ShiftRight))
+#define Key_IsWinPressed() (Key_Pressed[Key_WinLeft] || Key_Pressed[Key_WinRight])
+#define Key_IsAltPressed() (Key_Pressed[Key_AltLeft] || Key_Pressed[Key_AltRight])
+#define Key_IsControlPressed() (Key_Pressed[Key_ControlLeft] || Key_Pressed[Key_ControlRight])
+#define Key_IsShiftPressed() (Key_Pressed[Key_ShiftLeft] || Key_Pressed[Key_ShiftRight])
-bool Key_IsPressed(Key key);
+bool Key_Pressed[Key_Count];
void Key_SetPressed(Key key, bool pressed);
void Key_Clear(void);
@@ -89,7 +89,7 @@ typedef enum MouseButton_ {
float Mouse_Wheel;
int Mouse_X, Mouse_Y;
-bool Mouse_IsPressed(MouseButton btn);
+bool Mouse_Pressed[MouseButton_Count];
void Mouse_SetPressed(MouseButton btn, bool pressed);
void Mouse_SetWheel(float wheel);
void Mouse_SetPosition(int x, int y);
diff --git a/src/InputHandler.c b/src/InputHandler.c
index 05abbb1ee..44223328b 100644
--- a/src/InputHandler.c
+++ b/src/InputHandler.c
@@ -26,7 +26,7 @@ TimeMS input_lastClick;
float input_fovIndex = -1.0f;
bool InputHandler_IsMousePressed(MouseButton button) {
- if (Mouse_IsPressed(button)) return true;
+ if (Mouse_Pressed[button]) return true;
/* Key --> mouse mappings */
if (button == MouseButton_Left && KeyBind_IsPressed(KeyBind_MouseLeft)) return true;
diff --git a/src/IsometricDrawer.c b/src/IsometricDrawer.c
index 1ef2663de..fc567b845 100644
--- a/src/IsometricDrawer.c
+++ b/src/IsometricDrawer.c
@@ -1,7 +1,7 @@
#include "IsometricDrawer.h"
#include "Drawer.h"
#include "GraphicsCommon.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "PackedCol.h"
#include "ExtMath.h"
#include "Block.h"
diff --git a/src/MapRenderer.c b/src/MapRenderer.c
index 6c39880a5..022b1d6da 100644
--- a/src/MapRenderer.c
+++ b/src/MapRenderer.c
@@ -1,7 +1,7 @@
#include "MapRenderer.h"
#include "Block.h"
#include "Game.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "EnvRenderer.h"
#include "World.h"
#include "Vectors.h"
diff --git a/src/Menus.c b/src/Menus.c
index c69c1967d..972c7b4cc 100644
--- a/src/Menus.c
+++ b/src/Menus.c
@@ -6,7 +6,7 @@
#include "Platform.h"
#include "Inventory.h"
#include "Drawer2D.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Funcs.h"
#include "TerrainAtlas.h"
#include "ModelCache.h"
diff --git a/src/Model.c b/src/Model.c
index 47f0c7183..6d6f49057 100644
--- a/src/Model.c
+++ b/src/Model.c
@@ -4,7 +4,7 @@
#include "Game.h"
#include "ModelCache.h"
#include "GraphicsCommon.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Entity.h"
#define UV_POS_MASK ((uint16_t)0x7FFF)
diff --git a/src/ModelCache.c b/src/ModelCache.c
index 98975780a..6c9c83e5c 100644
--- a/src/ModelCache.c
+++ b/src/ModelCache.c
@@ -1,5 +1,5 @@
#include "ModelCache.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Game.h"
#include "Event.h"
#include "ExtMath.h"
diff --git a/src/OpenGLApi.c b/src/OpenGLApi.c
deleted file mode 100644
index 4dadc4492..000000000
--- a/src/OpenGLApi.c
+++ /dev/null
@@ -1,616 +0,0 @@
-#include "GraphicsAPI.h"
-#ifndef CC_BUILD_D3D9
-#include "ErrorHandler.h"
-#include "Platform.h"
-#include "Window.h"
-#include "GraphicsCommon.h"
-#include "Funcs.h"
-#include "Chat.h"
-#include "Game.h"
-#include "ExtMath.h"
-#include "Bitmap.h"
-
-#ifdef CC_BUILD_WIN
-#define WIN32_LEAN_AND_MEAN
-#define NOSERVICE
-#define NOMCX
-#define NOIME
-#include
-#else
-#define APIENETRY
-#endif
-#include
-
-/* Extensions from later than OpenGL 1.1 */
-#define GL_TEXTURE_MAX_LEVEL 0x813D
-#define GL_ARRAY_BUFFER 0x8892
-#define GL_ELEMENT_ARRAY_BUFFER 0x8893
-#define GL_STATIC_DRAW 0x88E4
-#define GL_DYNAMIC_DRAW 0x88E8
-#define GL_BGRA_EXT 0x80E1
-
-#ifdef CC_BUILD_GL11
-GfxResourceID gl_activeList;
-#define gl_DYNAMICLISTID 1234567891
-void* gl_dynamicListData;
-#else
-typedef void (APIENTRY *FUNC_GLBINDBUFFER) (GLenum target, GLuint buffer);
-typedef void (APIENTRY *FUNC_GLDELETEBUFFERS) (GLsizei n, const GLuint *buffers);
-typedef void (APIENTRY *FUNC_GLGENBUFFERS) (GLsizei n, GLuint *buffers);
-typedef void (APIENTRY *FUNC_GLBUFFERDATA) (GLenum target, const void* size, const void *data, GLenum usage);
-typedef void (APIENTRY *FUNC_GLBUFFERSUBDATA) (GLenum target, const void* offset, const void* size, const void *data);
-FUNC_GLBINDBUFFER glBindBuffer;
-FUNC_GLDELETEBUFFERS glDeleteBuffers;
-FUNC_GLGENBUFFERS glGenBuffers;
-FUNC_GLBUFFERDATA glBufferData;
-FUNC_GLBUFFERSUBDATA glBufferSubData;
-#endif
-
-int Gfx_strideSizes[2] = GFX_STRIDE_SIZES;
-bool gl_vsync;
-
-int gl_blend[6] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA };
-int gl_compare[8] = { GL_ALWAYS, GL_NOTEQUAL, GL_NEVER, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER };
-int gl_fogModes[3] = { GL_LINEAR, GL_EXP, GL_EXP2 };
-int gl_matrixModes[3] = { GL_PROJECTION, GL_MODELVIEW, GL_TEXTURE };
-
-typedef void (*GL_SetupVBFunc)(void);
-typedef void (*GL_SetupVBRangeFunc)(int startVertex);
-GL_SetupVBFunc gl_setupVBFunc;
-GL_SetupVBRangeFunc gl_setupVBRangeFunc;
-int gl_batchStride, gl_batchFormat = -1;
-
-#ifndef CC_BUILD_GL11
-static void GL_CheckVboSupport(void) {
- String extensions = String_FromReadonly(glGetString(GL_EXTENSIONS));
- String version = String_FromReadonly(glGetString(GL_VERSION));
- String vboExt = String_FromConst("GL_ARB_vertex_buffer_object");
-
- int major = (int)(version.buffer[0] - '0'); /* x.y. (and so forth) */
- int minor = (int)(version.buffer[2] - '0');
-
- /* Supported in core since 1.5 */
- if ((major > 1) || (major == 1 && minor >= 5)) {
- glBindBuffer = (FUNC_GLBINDBUFFER)GLContext_GetAddress("glBindBuffer");
- glDeleteBuffers = (FUNC_GLDELETEBUFFERS)GLContext_GetAddress("glDeleteBuffers");
- glGenBuffers = (FUNC_GLGENBUFFERS)GLContext_GetAddress("glGenBuffers");
- glBufferData = (FUNC_GLBUFFERDATA)GLContext_GetAddress("glBufferData");
- glBufferSubData = (FUNC_GLBUFFERSUBDATA)GLContext_GetAddress("glBufferSubData");
- return;
- } else if (String_CaselessContains(&extensions, &vboExt)) {
- glBindBuffer = (FUNC_GLBINDBUFFER)GLContext_GetAddress("glBindBufferARB");
- glDeleteBuffers = (FUNC_GLDELETEBUFFERS)GLContext_GetAddress("glDeleteBuffersARB");
- glGenBuffers = (FUNC_GLGENBUFFERS)GLContext_GetAddress("glGenBuffersARB");
- glBufferData = (FUNC_GLBUFFERDATA)GLContext_GetAddress("glBufferDataARB");
- glBufferSubData = (FUNC_GLBUFFERSUBDATA)GLContext_GetAddress("glBufferSubDataARB");
- } else {
- ErrorHandler_Fail("Only OpenGL 1.1 supported.\r\n\r\n" \
- "Compile the game with CC_BUILD_GL11, or ask on the classicube forums for it");
- }
-}
-#endif
-
-void Gfx_Init(void) {
- Gfx_MinZNear = 0.1f;
- struct GraphicsMode mode = GraphicsMode_MakeDefault();
- GLContext_Init(mode);
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &Gfx_MaxTexWidth);
- Gfx_MaxTexHeight = Gfx_MaxTexWidth;
-
-#ifndef CC_BUILD_GL11
- Gfx_CustomMipmapsLevels = true;
- GL_CheckVboSupport();
-#else
- Gfx_CustomMipmapsLevels = false;
-#endif
-
- GfxCommon_Init();
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
-}
-
-void Gfx_Free(void) {
- GfxCommon_Free();
- GLContext_Free();
-}
-
-#define gl_Toggle(cap) if (enabled) { glEnable(cap); } else { glDisable(cap); }
-
-static void GL_DoMipmaps(GfxResourceID texId, int x, int y, Bitmap* bmp, bool partial) {
- uint8_t* prev = bmp->Scan0;
- int lvls = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height);
- int lvl, width = bmp->Width, height = bmp->Height;
-
- for (lvl = 1; lvl <= lvls; lvl++) {
- x /= 2; y /= 2;
- if (width > 1) width /= 2;
- if (height > 1) height /= 2;
-
- uint8_t* cur = Mem_Alloc(width * height, BITMAP_SIZEOF_PIXEL, "mipmaps");
- GfxCommon_GenMipmaps(width, height, cur, prev);
-
- if (partial) {
- glTexSubImage2D(GL_TEXTURE_2D, lvl, x, y, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, cur);
- } else {
- glTexImage2D(GL_TEXTURE_2D, lvl, GL_RGBA, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, cur);
- }
-
- if (prev != bmp->Scan0) Mem_Free(prev);
- prev = cur;
- }
- if (prev != bmp->Scan0) Mem_Free(prev);
-}
-
-GfxResourceID Gfx_CreateTexture(Bitmap* bmp, bool managedPool, bool mipmaps) {
- uint32_t texId;
- glGenTextures(1, &texId);
- glBindTexture(GL_TEXTURE_2D, texId);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- if (!Math_IsPowOf2(bmp->Width) || !Math_IsPowOf2(bmp->Height)) {
- ErrorHandler_Fail("Textures must have power of two dimensions");
- }
-
- if (mipmaps) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
- if (Gfx_CustomMipmapsLevels) {
- int lvls = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, lvls);
- }
- } else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- }
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bmp->Width, bmp->Height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, bmp->Scan0);
-
- if (mipmaps) GL_DoMipmaps(texId, 0, 0, bmp, false);
- return texId;
-}
-
-void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, Bitmap* part, bool mipmaps) {
- glBindTexture(GL_TEXTURE_2D, texId);
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, part->Width, part->Height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, part->Scan0);
- if (mipmaps) GL_DoMipmaps(texId, x, y, part, true);
-}
-
-void Gfx_BindTexture(GfxResourceID texId) {
- glBindTexture(GL_TEXTURE_2D, texId);
-}
-
-void Gfx_DeleteTexture(GfxResourceID* texId) {
- if (!texId || *texId == GFX_NULL) return;
- glDeleteTextures(1, texId);
- *texId = GFX_NULL;
-}
-
-void Gfx_SetTexturing(bool enabled) { gl_Toggle(GL_TEXTURE_2D); }
-void Gfx_EnableMipmaps(void) { }
-void Gfx_DisableMipmaps(void) { }
-
-
-bool gl_fogEnable;
-bool Gfx_GetFog(void) { return gl_fogEnable; }
-void Gfx_SetFog(bool enabled) {
- gl_fogEnable = enabled;
- gl_Toggle(GL_FOG);
-}
-
-PackedCol gl_lastFogCol;
-void Gfx_SetFogCol(PackedCol col) {
- if (PackedCol_Equals(col, gl_lastFogCol)) return;
- float colRGBA[4] = { col.R / 255.0f, col.G / 255.0f, col.B / 255.0f, col.A / 255.0f };
- glFogfv(GL_FOG_COLOR, colRGBA);
- gl_lastFogCol = col;
-}
-
-float gl_lastFogEnd = -1, gl_lastFogDensity = -1;
-void Gfx_SetFogDensity(float value) {
- if (value == gl_lastFogDensity) return;
- glFogf(GL_FOG_DENSITY, value);
- gl_lastFogDensity = value;
-}
-
-void Gfx_SetFogEnd(float value) {
- if (value == gl_lastFogEnd) return;
- glFogf(GL_FOG_END, value);
- gl_lastFogEnd = value;
-}
-
-int gl_lastFogMode = -1;
-void Gfx_SetFogMode(int mode) {
- if (mode == gl_lastFogMode) return;
- glFogi(GL_FOG_MODE, gl_fogModes[mode]);
- gl_lastFogMode = mode;
-}
-
-
-void Gfx_SetFaceCulling(bool enabled) { gl_Toggle(GL_CULL_FACE); }
-void Gfx_SetAlphaTest(bool enabled) { gl_Toggle(GL_ALPHA_TEST); }
-void Gfx_SetAlphaTestFunc(int func, float value) {
- glAlphaFunc(gl_compare[func], value);
-}
-
-void Gfx_SetAlphaBlending(bool enabled) { gl_Toggle(GL_BLEND); }
-void Gfx_SetAlphaBlendFunc(int srcFunc, int dstFunc) {
- glBlendFunc(gl_blend[srcFunc], gl_blend[dstFunc]);
-}
-void Gfx_SetAlphaArgBlend(bool enabled) { }
-
-
-void Gfx_Clear(void) {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-}
-
-PackedCol gl_lastClearCol;
-void Gfx_ClearCol(PackedCol col) {
- if (PackedCol_Equals(col, gl_lastClearCol)) return;
- glClearColor(col.R / 255.0f, col.G / 255.0f, col.B / 255.0f, col.A / 255.0f);
- gl_lastClearCol = col;
-}
-
-void Gfx_SetColourWriteMask(bool r, bool g, bool b, bool a) {
- glColorMask(r, g, b, a);
-}
-
-void Gfx_SetDepthWrite(bool enabled) {
- glDepthMask(enabled);
-}
-
-void Gfx_SetDepthTest(bool enabled) { gl_Toggle(GL_DEPTH_TEST); }
-void Gfx_SetDepthTestFunc(int compareFunc) {
- glDepthFunc(gl_compare[compareFunc]);
-}
-
-
-#ifndef CC_BUILD_GL11
-GfxResourceID GL_GenAndBind(GLenum target) {
- GfxResourceID id;
- glGenBuffers(1, &id);
- glBindBuffer(target, id);
- return id;
-}
-#endif
-
-GfxResourceID Gfx_CreateDynamicVb(int vertexFormat, int maxVertices) {
-#ifndef CC_BUILD_GL11
- GfxResourceID id = GL_GenAndBind(GL_ARRAY_BUFFER);
- uint32_t sizeInBytes = maxVertices * Gfx_strideSizes[vertexFormat];
- glBufferData(GL_ARRAY_BUFFER, (void*)sizeInBytes, NULL, GL_DYNAMIC_DRAW);
- return id;
-#else
- return gl_DYNAMICLISTID;
-#endif
-}
-
-#define gl_MAXINDICES ICOUNT(65536)
-GfxResourceID Gfx_CreateVb(void* vertices, int vertexFormat, int count) {
-#ifndef CC_BUILD_GL11
- GfxResourceID id = GL_GenAndBind(GL_ARRAY_BUFFER);
- uint32_t sizeInBytes = count * Gfx_strideSizes[vertexFormat];
- glBufferData(GL_ARRAY_BUFFER, (void*)sizeInBytes, vertices, GL_STATIC_DRAW);
- return id;
-#else
- /* We need to setup client state properly when building the list */
- int curFormat = gl_batchFormat;
- Gfx_SetBatchFormat(vertexFormat);
- GfxResourceID list = glGenLists(1);
- glNewList(list, GL_COMPILE);
- count &= ~0x01; /* Need to get rid of the 1 extra element, see comment in chunk mesh builder for why */
-
- uint16_t indices[GFX_MAX_INDICES];
- GfxCommon_MakeIndices(indices, ICOUNT(count));
-
- int stride = vertexFormat == VERTEX_FORMAT_P3FT2FC4B ? sizeof(VertexP3fT2fC4b) : sizeof(VertexP3fC4b);
- glVertexPointer(3, GL_FLOAT, stride, vertices);
- glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)((uint8_t*)vertices + 12));
- if (vertexFormat == VERTEX_FORMAT_P3FT2FC4B) {
- glTexCoordPointer(2, GL_FLOAT, stride, (void*)((uint8_t*)vertices + 16));
- }
-
- glDrawElements(GL_TRIANGLES, ICOUNT(count), GL_UNSIGNED_SHORT, indices);
- glEndList();
- Gfx_SetBatchFormat(curFormat);
- return list;
-#endif
-}
-
-GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) {
-#ifndef CC_BUILD_GL11
- GfxResourceID id = GL_GenAndBind(GL_ELEMENT_ARRAY_BUFFER);
- uint32_t sizeInBytes = indicesCount * 2;
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, (void*)sizeInBytes, indices, GL_STATIC_DRAW);
- return id;
-#else
- return NULL;
-#endif
-}
-
-void Gfx_BindVb(GfxResourceID vb) {
-#ifndef CC_BUILD_GL11
- glBindBuffer(GL_ARRAY_BUFFER, vb);
-#else
- gl_activeList = vb;
-#endif
-}
-
-void Gfx_BindIb(GfxResourceID ib) {
-#ifndef CC_BUILD_GL11
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib);
-#else
- return;
-#endif
-}
-
-void Gfx_DeleteVb(GfxResourceID* vb) {
- if (!vb || *vb == GFX_NULL) return;
-#ifndef CC_BUILD_GL11
- glDeleteBuffers(1, vb);
-#else
- if (*vb != gl_DYNAMICLISTID) glDeleteLists(*vb, 1);
-#endif
- *vb = GFX_NULL;
-}
-
-void Gfx_DeleteIb(GfxResourceID* ib) {
-#ifndef CC_BUILD_GL11
- if (!ib || *ib == GFX_NULL) return;
- glDeleteBuffers(1, ib);
- *ib = GFX_NULL;
-#else
- return;
-#endif
-}
-
-
-void GL_SetupVbPos3fCol4b(void) {
- glVertexPointer(3, GL_FLOAT, sizeof(VertexP3fC4b), (void*)0);
- glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexP3fC4b), (void*)12);
-}
-
-void GL_SetupVbPos3fTex2fCol4b(void) {
- glVertexPointer(3, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)0);
- glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexP3fT2fC4b), (void*)12);
- glTexCoordPointer(2, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)16);
-}
-
-void GL_SetupVbPos3fCol4b_Range(int startVertex) {
- uint32_t offset = startVertex * (uint32_t)sizeof(VertexP3fC4b);
- glVertexPointer(3, GL_FLOAT, sizeof(VertexP3fC4b), (void*)(offset));
- glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexP3fC4b), (void*)(offset + 12));
-}
-
-void GL_SetupVbPos3fTex2fCol4b_Range(int startVertex) {
- uint32_t offset = startVertex * (uint32_t)sizeof(VertexP3fT2fC4b);
- glVertexPointer(3, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)(offset));
- glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexP3fT2fC4b), (void*)(offset + 12));
- glTexCoordPointer(2, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)(offset + 16));
-}
-
-void Gfx_SetBatchFormat(int vertexFormat) {
- if (vertexFormat == gl_batchFormat) return;
-
- if (gl_batchFormat == VERTEX_FORMAT_P3FT2FC4B) {
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- }
- gl_batchFormat = vertexFormat;
- gl_batchStride = Gfx_strideSizes[vertexFormat];
-
- if (vertexFormat == VERTEX_FORMAT_P3FT2FC4B) {
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- gl_setupVBFunc = GL_SetupVbPos3fTex2fCol4b;
- gl_setupVBRangeFunc = GL_SetupVbPos3fTex2fCol4b_Range;
- } else {
- gl_setupVBFunc = GL_SetupVbPos3fCol4b;
- gl_setupVBRangeFunc = GL_SetupVbPos3fCol4b_Range;
- }
-}
-
-void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
-#ifndef CC_BUILD_GL11
- glBindBuffer(GL_ARRAY_BUFFER, vb);
- uint32_t sizeInBytes = vCount * gl_batchStride;
- glBufferSubData(GL_ARRAY_BUFFER, NULL, (void*)sizeInBytes, vertices);
-#else
- gl_activeList = gl_DYNAMICLISTID;
- gl_dynamicListData = vertices;
-#endif
-}
-
-#ifdef CC_BUILD_GL11
-static void GL_V16(VertexP3fC4b v) {
- glColor4ub(v.Col.R, v.Col.G, v.Col.B, v.Col.A);
- glVertex3f(v.X, v.Y, v.Z);
-}
-
-static void GL_V24(VertexP3fT2fC4b v) {
- glColor4ub(v.Col.R, v.Col.G, v.Col.B, v.Col.A);
- glTexCoord2f(v.U, v.V);
- glVertex3f(v.X, v.Y, v.Z);
-}
-
-static void GL_DrawDynamicTriangles(int verticesCount, int startVertex) {
- glBegin(GL_TRIANGLES);
- int i;
- if (gl_batchFormat == VERTEX_FORMAT_P3FT2FC4B) {
- VertexP3fT2fC4b* ptr = (VertexP3fT2fC4b*)gl_dynamicListData;
- for (i = startVertex; i < startVertex + verticesCount; i += 4) {
- GL_V24(ptr[i + 0]); GL_V24(ptr[i + 1]); GL_V24(ptr[i + 2]);
- GL_V24(ptr[i + 2]); GL_V24(ptr[i + 3]); GL_V24(ptr[i + 0]);
- }
- } else {
- VertexP3fC4b* ptr = (VertexP3fC4b*)gl_dynamicListData;
- for (i = startVertex; i < startVertex + verticesCount; i += 4) {
- GL_V16(ptr[i + 0]); GL_V16(ptr[i + 1]); GL_V16(ptr[i + 2]);
- GL_V16(ptr[i + 2]); GL_V16(ptr[i + 3]); GL_V16(ptr[i + 0]);
- }
- }
- glEnd();
-}
-#endif
-
-void Gfx_DrawVb_Lines(int verticesCount) {
-#ifndef CC_BUILD_GL11
- gl_setupVBFunc();
- glDrawArrays(GL_LINES, 0, verticesCount);
-#else
- glBegin(GL_LINES);
- int i;
- if (gl_batchFormat == VERTEX_FORMAT_P3FT2FC4B) {
- VertexP3fT2fC4b* ptr = (VertexP3fT2fC4b*)gl_dynamicListData;
- for (i = 0; i < verticesCount; i += 2) { GL_V24(ptr[i + 0]); GL_V24(ptr[i + 1]); }
- } else {
- VertexP3fC4b* ptr = (VertexP3fC4b*)gl_dynamicListData;
- for (i = 0; i < verticesCount; i += 2) { GL_V16(ptr[i + 0]); GL_V16(ptr[i + 1]); }
- }
- glEnd();
-#endif
-}
-
-void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
-#ifndef CC_BUILD_GL11
- gl_setupVBRangeFunc(startVertex);
- glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, NULL);
-#else
- if (gl_activeList != gl_DYNAMICLISTID) { glCallList(gl_activeList); }
- else { GL_DrawDynamicTriangles(verticesCount, startVertex); }
-#endif
-}
-
-void Gfx_DrawVb_IndexedTris(int verticesCount) {
-#ifndef CC_BUILD_GL11
- gl_setupVBFunc();
- glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, NULL);
-#else
- if (gl_activeList != gl_DYNAMICLISTID) { glCallList(gl_activeList); }
- else { GL_DrawDynamicTriangles(verticesCount, 0); }
-#endif
-}
-
-GfxResourceID gl_lastPartialList;
-void Gfx_DrawIndexedVb_TrisT2fC4b(int verticesCount, int startVertex) {
-
-#ifndef CC_BUILD_GL11
- uint32_t offset = startVertex * (uint32_t)sizeof(VertexP3fT2fC4b);
- glVertexPointer(3, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)(offset));
- glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexP3fT2fC4b), (void*)(offset + 12));
- glTexCoordPointer(2, GL_FLOAT, sizeof(VertexP3fT2fC4b), (void*)(offset + 16));
- glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, NULL);
-#else
- /* TODO: This renders the whole map, bad performance!! FIX FIX */
- if (gl_activeList != gl_lastPartialList) {
- glCallList(gl_activeList);
- gl_lastPartialList = gl_activeList;
- }
-#endif
-}
-
-
-int gl_lastMatrixType;
-void Gfx_SetMatrixMode(int matrixType) {
- if (matrixType == gl_lastMatrixType) return;
- glMatrixMode(gl_matrixModes[matrixType]);
- gl_lastMatrixType = matrixType;
-}
-
-void Gfx_LoadMatrix(struct Matrix* matrix) { glLoadMatrixf((float*)matrix); }
-void Gfx_LoadIdentityMatrix(void) { glLoadIdentity(); }
-
-void Gfx_CalcOrthoMatrix(float width, float height, struct Matrix* matrix) {
- Matrix_OrthographicOffCenter(matrix, 0.0f, width, height, 0.0f, -10000.0f, 10000.0f);
-}
-void Gfx_CalcPerspectiveMatrix(float fov, float aspect, float zNear, float zFar, struct Matrix* matrix) {
- Matrix_PerspectiveFieldOfView(matrix, fov, aspect, zNear, zFar);
-}
-
-
-ReturnCode Gfx_TakeScreenshot(struct Stream* output, int width, int height) {
- Bitmap bmp; Bitmap_Allocate(&bmp, width, height);
- glReadPixels(0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, bmp.Scan0);
- uint8_t tmp[PNG_MAX_DIMS * BITMAP_SIZEOF_PIXEL];
-
- /* flip vertically around y */
- int x, y;
- uint32_t stride = (uint32_t)(bmp.Width) * BITMAP_SIZEOF_PIXEL;
- for (y = 0; y < height / 2; y++) {
- uint32_t* src = Bitmap_GetRow(&bmp, y);
- uint32_t* dst = Bitmap_GetRow(&bmp, (height - 1) - y);
-
- Mem_Copy(tmp, src, stride);
- Mem_Copy(src, dst, stride);
- Mem_Copy(dst, tmp, stride);
- /*for (x = 0; x < bmp.Width; x++) {
- uint32_t temp = dst[x]; dst[x] = src[x]; src[x] = temp;
- }*/
- }
-
- ReturnCode res = Bitmap_EncodePng(&bmp, output);
- Mem_Free(bmp.Scan0);
- return res;
-}
-
-bool nv_mem;
-void Gfx_MakeApiInfo(void) {
- int depthBits = 0;
- glGetIntegerv(GL_DEPTH_BITS, &depthBits);
-
- String_AppendConst(&Gfx_ApiInfo[0],"-- Using OpenGL --");
- String_Format1(&Gfx_ApiInfo[1], "Vendor: %c", glGetString(GL_VENDOR));
- String_Format1(&Gfx_ApiInfo[2], "Renderer: %c", glGetString(GL_RENDERER));
- String_Format1(&Gfx_ApiInfo[3], "GL version: %c", glGetString(GL_VERSION));
- /* Memory usage goes here */
- String_Format2(&Gfx_ApiInfo[5], "Max texture size: (%i, %i)", &Gfx_MaxTexWidth, &Gfx_MaxTexHeight);
- String_Format1(&Gfx_ApiInfo[6], "Depth buffer bits: %i", &depthBits);
-
- String extensions = String_FromReadonly(glGetString(GL_EXTENSIONS));
- String memExt = String_FromConst("GL_NVX_gpu_memory_info");
- nv_mem = String_CaselessContains(&extensions, &memExt);
-}
-
-void Gfx_UpdateApiInfo(void) {
- if (!nv_mem) return;
- int totalKb = 0, curKb = 0;
- glGetIntegerv(0x9048, &totalKb);
- glGetIntegerv(0x9049, &curKb);
-
- if (totalKb <= 0 || curKb <= 0) return;
- Gfx_ApiInfo[4].length = 0;
- float total = totalKb / 1024.0f, cur = curKb / 1024.0f;
- String_Format2(&Gfx_ApiInfo[4], "Video memory: %f2 MB total, %f2 free", &total, &cur);
-}
-
-bool Gfx_WarnIfNecessary(void) {
-#ifdef CC_BUILD_GL11
- Chat_AddRaw("&cYou are using the very outdated OpenGL backend.");
- Chat_AddRaw("&cAs such you may experience poor performance.");
- Chat_AddRaw("&cIt is likely you need to install video card drivers.");
-#endif
-
- String renderer = String_FromReadonly(glGetString(GL_RENDERER));
- String intel = String_FromConst("Intel");
- if (!String_ContainsString(&renderer, &intel)) return false;
-
- Chat_AddRaw("&cIntel graphics cards are known to have issues with the OpenGL build.");
- Chat_AddRaw("&cVSync may not work, and you may see disappearing clouds and map edges.");
- Chat_AddRaw("&cFor Windows, try downloading the Direct3D 9 build instead.");
- return true;
-}
-
-
-void Gfx_SetVSync(bool value) {
- if (gl_vsync == value) return;
- gl_vsync = value;
- GLContext_SetVSync(value);
-}
-
-void Gfx_BeginFrame(void) { }
-void Gfx_EndFrame(void) {
- GLContext_SwapBuffers();
-#ifdef CC_BUILD_GL11
- gl_activeList = NULL;
-#endif
-}
-
-void Gfx_OnWindowResize(void) {
- glViewport(0, 0, Game_Width, Game_Height);
-}
-#endif
diff --git a/src/Particle.c b/src/Particle.c
index c1d80970c..bfbde6ba7 100644
--- a/src/Particle.c
+++ b/src/Particle.c
@@ -5,7 +5,7 @@
#include "Lighting.h"
#include "Entity.h"
#include "TerrainAtlas.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "GraphicsCommon.h"
#include "Funcs.h"
#include "Game.h"
diff --git a/src/PickedPosRenderer.c b/src/PickedPosRenderer.c
index e8e60b910..757accf88 100644
--- a/src/PickedPosRenderer.c
+++ b/src/PickedPosRenderer.c
@@ -1,7 +1,7 @@
#include "PickedPosRenderer.h"
#include "PackedCol.h"
#include "VertexStructs.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "GraphicsCommon.h"
#include "Game.h"
#include "Event.h"
diff --git a/src/Screens.c b/src/Screens.c
index e12f70d09..61122a430 100644
--- a/src/Screens.c
+++ b/src/Screens.c
@@ -6,7 +6,7 @@
#include "Platform.h"
#include "Inventory.h"
#include "Drawer2D.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Funcs.h"
#include "TerrainAtlas.h"
#include "ModelCache.h"
diff --git a/src/SelectionBox.c b/src/SelectionBox.c
index 0bafb5099..a44486401 100644
--- a/src/SelectionBox.c
+++ b/src/SelectionBox.c
@@ -1,6 +1,6 @@
#include "SelectionBox.h"
#include "ExtMath.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "GraphicsCommon.h"
#include "Event.h"
#include "Funcs.h"
diff --git a/src/String.c b/src/String.c
index 4c2ea7c30..5b13bedb1 100644
--- a/src/String.c
+++ b/src/String.c
@@ -135,7 +135,7 @@ bool String_Append(String* str, char c) {
}
bool String_AppendBool(String* str, bool value) {
- char* text = value ? "True" : "False";
+ const char* text = value ? "True" : "False";
return String_AppendConst(str, text);
}
diff --git a/src/TerrainAtlas.c b/src/TerrainAtlas.c
index 0e24ac61e..6ec8d51da 100644
--- a/src/TerrainAtlas.c
+++ b/src/TerrainAtlas.c
@@ -3,7 +3,7 @@
#include "Block.h"
#include "ExtMath.h"
#include "Funcs.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Platform.h"
void Atlas2D_UpdateState(Bitmap* bmp) {
diff --git a/src/TexturePack.c b/src/TexturePack.c
index 32c15a8b9..2ef288a34 100644
--- a/src/TexturePack.c
+++ b/src/TexturePack.c
@@ -5,7 +5,7 @@
#include "Stream.h"
#include "Bitmap.h"
#include "World.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Event.h"
#include "Game.h"
#include "AsyncDownloader.h"
diff --git a/src/Widgets.c b/src/Widgets.c
index 8a2241a8f..8582e6f6f 100644
--- a/src/Widgets.c
+++ b/src/Widgets.c
@@ -1,5 +1,5 @@
#include "Widgets.h"
-#include "GraphicsAPI.h"
+#include "Graphics.h"
#include "Drawer2D.h"
#include "GraphicsCommon.h"
#include "ExtMath.h"