Remerge oculus-mobile branch with master

This commit is contained in:
mcc 2018-11-02 18:10:08 -04:00
commit 8301bd7dd8
22 changed files with 344 additions and 300 deletions

View File

@ -547,6 +547,7 @@ endif()
# Yay Windows
if(WIN32)
target_sources(lovr PRIVATE src/platform/windows.c)
set_target_properties(lovr PROPERTIES COMPILE_FLAGS "/wd4244")
set_target_properties(lovr PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE")
set_target_properties(lovr PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
@ -572,4 +573,10 @@ if(WIN32)
move_dll(${LOVR_OPENAL})
move_dll(${LOVR_OPENVR})
move_dll(${LOVR_PHYSFS})
elseif(APPLE)
target_sources(lovr PRIVATE src/platform/macos.c)
elseif(EMSCRIPTEN)
target_sources(lovr PRIVATE src/platform/web.c)
elseif(UNIX)
target_sourceS(lovr PRIVATE src/platform/linux.c)
endif()

View File

@ -13,6 +13,7 @@
#include "data/textureData.h"
#include "data/vertexData.h"
#include "filesystem/filesystem.h"
#include "math/transform.h"
#include "util.h"
#define _USE_MATH_DEFINES
#include <math.h>
@ -584,6 +585,12 @@ static int l_lovrGraphicsTransform(lua_State* L) {
return 0;
}
static int l_lovrGraphicsSetProjection(lua_State* L) {
Transform* transform = luax_checktype(L, 1, Transform);
lovrGraphicsSetProjection(transform->matrix);
return 0;
}
// Rendering
static int l_lovrGraphicsClear(lua_State* L) {
@ -1302,6 +1309,7 @@ static const luaL_Reg lovrGraphics[] = {
{ "rotate", l_lovrGraphicsRotate },
{ "scale", l_lovrGraphicsScale },
{ "transform", l_lovrGraphicsTransform },
{ "setProjection", l_lovrGraphicsSetProjection },
// Rendering
{ "clear", l_lovrGraphicsClear },

View File

@ -1,6 +1,5 @@
#include "data/textureData.h"
#include "filesystem/file.h"
#include "lib/dds.h"
#include "lib/stb/stb_image.h"
#include "lib/stb/stb_image_write.h"
#include <stdlib.h>

View File

@ -51,3 +51,190 @@ Color lovrTextureDataGetPixel(TextureData* textureData, int x, int y);
void lovrTextureDataSetPixel(TextureData* textureData, int x, int y, Color color);
bool lovrTextureDataEncode(TextureData* textureData, const char* filename);
void lovrTextureDataDestroy(void* ref);
// DDS structs (modified from ddsparse <https://bitbucket.org/slime73/ddsparse>)
typedef enum DDPF {
DDPF_ALPHAPIXELS = 0x000001,
DDPF_ALPHA = 0x000002,
DDPF_FOURCC = 0x000004,
DDPF_RGB = 0x000040,
DDPF_YUV = 0x000200,
DDPF_LUMINANCE = 0x020000
} DDPF;
typedef enum D3D10ResourceDimension {
D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
D3D10_RESOURCE_DIMENSION_BUFFER = 1,
D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4
} D3D10ResourceDimension;
typedef enum DXGIFormat {
DXGI_FORMAT_UNKNOWN = 0,
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
DXGI_FORMAT_R32G32B32A32_UINT = 3,
DXGI_FORMAT_R32G32B32A32_SINT = 4,
DXGI_FORMAT_R32G32B32_TYPELESS = 5,
DXGI_FORMAT_R32G32B32_FLOAT = 6,
DXGI_FORMAT_R32G32B32_UINT = 7,
DXGI_FORMAT_R32G32B32_SINT = 8,
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
DXGI_FORMAT_R16G16B16A16_UNORM = 11,
DXGI_FORMAT_R16G16B16A16_UINT = 12,
DXGI_FORMAT_R16G16B16A16_SNORM = 13,
DXGI_FORMAT_R16G16B16A16_SINT = 14,
DXGI_FORMAT_R32G32_TYPELESS = 15,
DXGI_FORMAT_R32G32_FLOAT = 16,
DXGI_FORMAT_R32G32_UINT = 17,
DXGI_FORMAT_R32G32_SINT = 18,
DXGI_FORMAT_R32G8X24_TYPELESS = 19,
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
DXGI_FORMAT_R10G10B10A2_UNORM = 24,
DXGI_FORMAT_R10G10B10A2_UINT = 25,
DXGI_FORMAT_R11G11B10_FLOAT = 26,
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
DXGI_FORMAT_R8G8B8A8_UNORM = 28,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
DXGI_FORMAT_R8G8B8A8_UINT = 30,
DXGI_FORMAT_R8G8B8A8_SNORM = 31,
DXGI_FORMAT_R8G8B8A8_SINT = 32,
DXGI_FORMAT_R16G16_TYPELESS = 33,
DXGI_FORMAT_R16G16_FLOAT = 34,
DXGI_FORMAT_R16G16_UNORM = 35,
DXGI_FORMAT_R16G16_UINT = 36,
DXGI_FORMAT_R16G16_SNORM = 37,
DXGI_FORMAT_R16G16_SINT = 38,
DXGI_FORMAT_R32_TYPELESS = 39,
DXGI_FORMAT_D32_FLOAT = 40,
DXGI_FORMAT_R32_FLOAT = 41,
DXGI_FORMAT_R32_UINT = 42,
DXGI_FORMAT_R32_SINT = 43,
DXGI_FORMAT_R24G8_TYPELESS = 44,
DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
DXGI_FORMAT_R8G8_TYPELESS = 48,
DXGI_FORMAT_R8G8_UNORM = 49,
DXGI_FORMAT_R8G8_UINT = 50,
DXGI_FORMAT_R8G8_SNORM = 51,
DXGI_FORMAT_R8G8_SINT = 52,
DXGI_FORMAT_R16_TYPELESS = 53,
DXGI_FORMAT_R16_FLOAT = 54,
DXGI_FORMAT_D16_UNORM = 55,
DXGI_FORMAT_R16_UNORM = 56,
DXGI_FORMAT_R16_UINT = 57,
DXGI_FORMAT_R16_SNORM = 58,
DXGI_FORMAT_R16_SINT = 59,
DXGI_FORMAT_R8_TYPELESS = 60,
DXGI_FORMAT_R8_UNORM = 61,
DXGI_FORMAT_R8_UINT = 62,
DXGI_FORMAT_R8_SNORM = 63,
DXGI_FORMAT_R8_SINT = 64,
DXGI_FORMAT_A8_UNORM = 65,
DXGI_FORMAT_R1_UNORM = 66,
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
DXGI_FORMAT_BC1_TYPELESS = 70,
DXGI_FORMAT_BC1_UNORM = 71,
DXGI_FORMAT_BC1_UNORM_SRGB = 72,
DXGI_FORMAT_BC2_TYPELESS = 73,
DXGI_FORMAT_BC2_UNORM = 74,
DXGI_FORMAT_BC2_UNORM_SRGB = 75,
DXGI_FORMAT_BC3_TYPELESS = 76,
DXGI_FORMAT_BC3_UNORM = 77,
DXGI_FORMAT_BC3_UNORM_SRGB = 78,
DXGI_FORMAT_BC4_TYPELESS = 79,
DXGI_FORMAT_BC4_UNORM = 80,
DXGI_FORMAT_BC4_SNORM = 81,
DXGI_FORMAT_BC5_TYPELESS = 82,
DXGI_FORMAT_BC5_UNORM = 83,
DXGI_FORMAT_BC5_SNORM = 84,
DXGI_FORMAT_B5G6R5_UNORM = 85,
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
DXGI_FORMAT_BC6H_TYPELESS = 94,
DXGI_FORMAT_BC6H_UF16 = 95,
DXGI_FORMAT_BC6H_SF16 = 96,
DXGI_FORMAT_BC7_TYPELESS = 97,
DXGI_FORMAT_BC7_UNORM = 98,
DXGI_FORMAT_BC7_UNORM_SRGB = 99
} DXGIFormat;
typedef struct DDSPixelFormat {
uint32_t size;
uint32_t flags;
uint32_t fourCC;
uint32_t rgbBitCount;
uint32_t rBitMask;
uint32_t gBitMask;
uint32_t bBitMask;
uint32_t aBitMask;
} DDSPixelFormat;
typedef struct DDSHeader {
uint32_t size;
uint32_t flags;
uint32_t height;
uint32_t width;
uint32_t pitchOrLinearSize;
uint32_t depth;
uint32_t mipMapCount;
uint32_t reserved[11];
DDSPixelFormat format;
uint32_t caps1;
uint32_t caps2;
uint32_t caps3;
uint32_t caps4;
uint32_t reserved2;
} DDSHeader;
typedef struct DDSHeader10 {
DXGIFormat dxgiFormat;
D3D10ResourceDimension resourceDimension;
uint32_t miscFlag;
uint32_t arraySize;
uint32_t reserved;
} DDSHeader10;

View File

@ -1,5 +1,6 @@
#include "filesystem/filesystem.h"
#include "filesystem/file.h"
#include "platform.h"
#include "util.h"
#include <physfs.h>
#include <stdio.h>
@ -118,6 +119,10 @@ void lovrFilesystemGetDirectoryItems(const char* path, getDirectoryItemsCallback
PHYSFS_enumerate(path, callback, userdata);
}
int lovrFilesystemGetExecutablePath(char* path, uint32_t size) {
return lovrGetExecutablePath(path, size);
}
const char* lovrFilesystemGetIdentity() {
return state.identity;
}
@ -318,7 +323,10 @@ size_t lovrFilesystemWrite(const char* path, const char* content, size_t size, b
return 0;
}
lovrFileOpen(file, append ? OPEN_APPEND : OPEN_WRITE);
if (lovrFileOpen(file, append ? OPEN_APPEND : OPEN_WRITE)) {
return 0;
}
size_t bytesWritten = lovrFileWrite(file, (void*) content, size);
lovrFileClose(file);
lovrRelease(file);

View File

@ -1,6 +1,7 @@
#include "lib/vec/vec.h"
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#pragma once
@ -26,7 +27,7 @@ void lovrFilesystemDestroy();
int lovrFilesystemCreateDirectory(const char* path);
int lovrFilesystemGetAppdataDirectory(char* dest, unsigned int size);
void lovrFilesystemGetDirectoryItems(const char* path, getDirectoryItemsCallback callback, void* userdata);
#define lovrFilesystemGetExecutablePath lovrGetExecutablePath
int lovrFilesystemGetExecutablePath(char* path, uint32_t size);
const char* lovrFilesystemGetIdentity();
long lovrFilesystemGetLastModified(const char* path);
const char* lovrFilesystemGetRealDirectory(const char* path);

View File

@ -380,6 +380,11 @@ void lovrGraphicsMatrixTransform(mat4 transform) {
mat4_multiply(state.transforms[state.transform], transform);
}
void lovrGraphicsSetProjection(mat4 projection) {
mat4_set(state.camera.projection[0], projection);
mat4_set(state.camera.projection[1], projection);
}
// Rendering
VertexPointer lovrGraphicsGetVertexPointer(uint32_t count) {

View File

@ -206,6 +206,7 @@ void lovrGraphicsTranslate(float x, float y, float z);
void lovrGraphicsRotate(float angle, float ax, float ay, float az);
void lovrGraphicsScale(float x, float y, float z);
void lovrGraphicsMatrixTransform(mat4 transform);
void lovrGraphicsSetProjection(mat4 projection);
// Rendering
VertexPointer lovrGraphicsGetVertexPointer(uint32_t capacity);

View File

@ -144,9 +144,8 @@ static const float* fakeGetBoundsGeometry(int* count) {
}
static void fakeGetPose(float* x, float* y, float* z, float* angle, float* ax, float* ay, float* az) {
*x = state.position[0];
*y = state.position[1];
*z = state.position[2];
*x = *y = *z = 0;
mat4_transform(state.transform, x, y, z);
float q[4];
quat_fromMat4(q, state.transform);
quat_getAngleAxis(q, angle, ax, ay, az);
@ -186,7 +185,6 @@ static void fakeControllerGetPose(Controller* controller, float* x, float* y, fl
*y = 0;
*z = -.75;
mat4_transform(state.transform, x, y, z);
*y += state.offset;
float q[4];
quat_fromMat4(q, state.transform);
@ -223,7 +221,6 @@ static void fakeRenderTo(void (*callback)(void*), void* userdata) {
bool stereo = state.mirrorEye == EYE_BOTH;
Camera camera = { .canvas = NULL, .viewMatrix = { MAT4_IDENTITY }, .stereo = stereo };
mat4_perspective(camera.projection[0], state.clipNear, state.clipFar, 67 * M_PI / 180., (float) width / (1 + stereo) / height);
mat4_translate(camera.viewMatrix[0], 0, state.offset, 0);
mat4_multiply(camera.viewMatrix[0], state.transform);
mat4_invertPose(camera.viewMatrix[0]);
mat4_set(camera.projection[1], camera.projection[0]);
@ -295,6 +292,7 @@ static void fakeUpdate(float dt) {
// Update transform
mat4_identity(state.transform);
mat4_translate(state.transform, 0, state.offset, 0);
mat4_translate(state.transform, state.position[0], state.position[1], state.position[2]);
mat4_rotate(state.transform, state.yaw, 0, 1, 0);
mat4_rotate(state.transform, state.pitch, 1, 0, 0);

View File

@ -21,6 +21,7 @@ typedef struct {
ovrGraphicsLuid luid;
float clipNear;
float clipFar;
float offset;
int lastButtonState;
ovrSizei size;
Canvas* canvas;
@ -103,6 +104,7 @@ static bool oculusInit(float offset, int msaa) {
state.mirrorEye = EYE_BOTH;
state.clipNear = 0.1f;
state.clipFar = 30.f;
state.offset = offset;
vec_init(&state.controllers);
@ -205,7 +207,7 @@ static void oculusGetPose(float* x, float* y, float* z, float* angle, float* ax,
ovrTrackingState *ts = refreshTracking();
ovrVector3f pos = ts->HeadPose.ThePose.Position;
*x = pos.x;
*y = pos.y;
*y = pos.y + state.offset;
*z = pos.z;
ovrQuatf oq = ts->HeadPose.ThePose.Orientation;
float quat[] = { oq.x, oq.y, oq.z, oq.w };
@ -260,7 +262,7 @@ static void oculusControllerGetPose(Controller* controller, float* x, float* y,
ovrTrackingState *ts = refreshTracking();
ovrVector3f pos = ts->HandPoses[controller->id].ThePose.Position;
*x = pos.x;
*y = pos.y;
*y = pos.y + state.offset;
*z = pos.z;
ovrQuatf orient = ts->HandPoses[controller->id].ThePose.Orientation;
float quat[4] = { orient.x, orient.y, orient.z, orient.w };
@ -319,7 +321,6 @@ static ModelData* oculusControllerNewModelData(Controller* controller) {
return NULL;
}
// TODO: need to set up swap chain textures for the eyes and finish view transforms
static void oculusRenderTo(void (*callback)(void*), void* userdata) {
ovrHmdDesc desc = ovr_GetHmdDesc(state.session);
if (!state.canvas) {
@ -378,7 +379,7 @@ static void oculusRenderTo(void (*callback)(void*), void* userdata) {
mat4_identity(transform);
mat4_rotateQuat(transform, orient);
transform[12] = -(transform[0] * pos[0] + transform[4] * pos[1] + transform[8] * pos[2]);
transform[13] = -(transform[1] * pos[0] + transform[5] * pos[1] + transform[9] * pos[2]);
transform[13] = -(transform[1] * pos[0] + transform[5] * pos[1] + transform[9] * pos[2] + state.offset);
transform[14] = -(transform[2] * pos[0] + transform[6] * pos[1] + transform[10] * pos[2]);
ovrMatrix4f projection = ovrMatrix4f_Projection(desc.DefaultEyeFov[eye], state.clipNear, state.clipFar, ovrProjection_ClipRangeOpenGL);
@ -416,10 +417,6 @@ static void oculusRenderTo(void (*callback)(void*), void* userdata) {
ovrLayerHeader* layers = &ld.Header;
ovr_SubmitFrame(state.session, 0, NULL, &layers, 1);
// apparently if this happens we should kill the session and reinit as long as we're getting ovrError_DisplayLost,
// lest oculus get upset should you try to get anything on the store.
// if (!OVR_SUCCESS(result))
// goto Done;
state.needRefreshTracking = true;
state.needRefreshButtons = true;

View File

@ -3,6 +3,7 @@
#include "graphics/canvas.h"
#include "math/mat4.h"
#include "math/quat.h"
#include "platform.h"
#include "util.h"
#include <stdbool.h>
#include <stdio.h>
@ -54,6 +55,7 @@ static void getTransform(unsigned int device, mat4 transform) {
mat4_identity(transform);
} else {
mat4_fromMat34(transform, pose.mDeviceToAbsoluteTracking.m);
transform[13] += state.offset;
}
}
@ -570,7 +572,6 @@ static void openvrRenderTo(void (*callback)(void*), void* userdata) {
for (int i = 0; i < 2; i++) {
EVREye vrEye = (i == 0) ? EVREye_Eye_Left : EVREye_Eye_Right;
mat4_fromMat44(camera.projection[i], state.system->GetProjectionMatrix(vrEye, state.clipNear, state.clipFar).m);
mat4_translate(camera.viewMatrix[i], 0, state.offset, 0);
mat4_multiply(camera.viewMatrix[i], head);
mat4_multiply(camera.viewMatrix[i], mat4_fromMat34(eye, state.system->GetEyeToHeadTransform(vrEye).m));
mat4_invertPose(camera.viewMatrix[i]);

View File

@ -1,191 +0,0 @@
#include <stdint.h>
#include <stddef.h>
#pragma once
// Modified from ddsparse (https://bitbucket.org/slime73/ddsparse)
typedef enum DDPF {
DDPF_ALPHAPIXELS = 0x000001,
DDPF_ALPHA = 0x000002,
DDPF_FOURCC = 0x000004,
DDPF_RGB = 0x000040,
DDPF_YUV = 0x000200,
DDPF_LUMINANCE = 0x020000
} DDPF;
typedef enum D3D10ResourceDimension {
D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
D3D10_RESOURCE_DIMENSION_BUFFER = 1,
D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4
} D3D10ResourceDimension;
typedef enum DXGIFormat {
DXGI_FORMAT_UNKNOWN = 0,
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
DXGI_FORMAT_R32G32B32A32_UINT = 3,
DXGI_FORMAT_R32G32B32A32_SINT = 4,
DXGI_FORMAT_R32G32B32_TYPELESS = 5,
DXGI_FORMAT_R32G32B32_FLOAT = 6,
DXGI_FORMAT_R32G32B32_UINT = 7,
DXGI_FORMAT_R32G32B32_SINT = 8,
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
DXGI_FORMAT_R16G16B16A16_UNORM = 11,
DXGI_FORMAT_R16G16B16A16_UINT = 12,
DXGI_FORMAT_R16G16B16A16_SNORM = 13,
DXGI_FORMAT_R16G16B16A16_SINT = 14,
DXGI_FORMAT_R32G32_TYPELESS = 15,
DXGI_FORMAT_R32G32_FLOAT = 16,
DXGI_FORMAT_R32G32_UINT = 17,
DXGI_FORMAT_R32G32_SINT = 18,
DXGI_FORMAT_R32G8X24_TYPELESS = 19,
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
DXGI_FORMAT_R10G10B10A2_UNORM = 24,
DXGI_FORMAT_R10G10B10A2_UINT = 25,
DXGI_FORMAT_R11G11B10_FLOAT = 26,
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
DXGI_FORMAT_R8G8B8A8_UNORM = 28,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
DXGI_FORMAT_R8G8B8A8_UINT = 30,
DXGI_FORMAT_R8G8B8A8_SNORM = 31,
DXGI_FORMAT_R8G8B8A8_SINT = 32,
DXGI_FORMAT_R16G16_TYPELESS = 33,
DXGI_FORMAT_R16G16_FLOAT = 34,
DXGI_FORMAT_R16G16_UNORM = 35,
DXGI_FORMAT_R16G16_UINT = 36,
DXGI_FORMAT_R16G16_SNORM = 37,
DXGI_FORMAT_R16G16_SINT = 38,
DXGI_FORMAT_R32_TYPELESS = 39,
DXGI_FORMAT_D32_FLOAT = 40,
DXGI_FORMAT_R32_FLOAT = 41,
DXGI_FORMAT_R32_UINT = 42,
DXGI_FORMAT_R32_SINT = 43,
DXGI_FORMAT_R24G8_TYPELESS = 44,
DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
DXGI_FORMAT_R8G8_TYPELESS = 48,
DXGI_FORMAT_R8G8_UNORM = 49,
DXGI_FORMAT_R8G8_UINT = 50,
DXGI_FORMAT_R8G8_SNORM = 51,
DXGI_FORMAT_R8G8_SINT = 52,
DXGI_FORMAT_R16_TYPELESS = 53,
DXGI_FORMAT_R16_FLOAT = 54,
DXGI_FORMAT_D16_UNORM = 55,
DXGI_FORMAT_R16_UNORM = 56,
DXGI_FORMAT_R16_UINT = 57,
DXGI_FORMAT_R16_SNORM = 58,
DXGI_FORMAT_R16_SINT = 59,
DXGI_FORMAT_R8_TYPELESS = 60,
DXGI_FORMAT_R8_UNORM = 61,
DXGI_FORMAT_R8_UINT = 62,
DXGI_FORMAT_R8_SNORM = 63,
DXGI_FORMAT_R8_SINT = 64,
DXGI_FORMAT_A8_UNORM = 65,
DXGI_FORMAT_R1_UNORM = 66,
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
DXGI_FORMAT_BC1_TYPELESS = 70,
DXGI_FORMAT_BC1_UNORM = 71,
DXGI_FORMAT_BC1_UNORM_SRGB = 72,
DXGI_FORMAT_BC2_TYPELESS = 73,
DXGI_FORMAT_BC2_UNORM = 74,
DXGI_FORMAT_BC2_UNORM_SRGB = 75,
DXGI_FORMAT_BC3_TYPELESS = 76,
DXGI_FORMAT_BC3_UNORM = 77,
DXGI_FORMAT_BC3_UNORM_SRGB = 78,
DXGI_FORMAT_BC4_TYPELESS = 79,
DXGI_FORMAT_BC4_UNORM = 80,
DXGI_FORMAT_BC4_SNORM = 81,
DXGI_FORMAT_BC5_TYPELESS = 82,
DXGI_FORMAT_BC5_UNORM = 83,
DXGI_FORMAT_BC5_SNORM = 84,
DXGI_FORMAT_B5G6R5_UNORM = 85,
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
DXGI_FORMAT_BC6H_TYPELESS = 94,
DXGI_FORMAT_BC6H_UF16 = 95,
DXGI_FORMAT_BC6H_SF16 = 96,
DXGI_FORMAT_BC7_TYPELESS = 97,
DXGI_FORMAT_BC7_UNORM = 98,
DXGI_FORMAT_BC7_UNORM_SRGB = 99
} DXGIFormat;
typedef struct DDSPixelFormat {
uint32_t size;
uint32_t flags;
uint32_t fourCC;
uint32_t rgbBitCount;
uint32_t rBitMask;
uint32_t gBitMask;
uint32_t bBitMask;
uint32_t aBitMask;
} DDSPixelFormat;
typedef struct DDSHeader {
uint32_t size;
uint32_t flags;
uint32_t height;
uint32_t width;
uint32_t pitchOrLinearSize;
uint32_t depth;
uint32_t mipMapCount;
uint32_t reserved[11];
DDSPixelFormat format;
uint32_t caps1;
uint32_t caps2;
uint32_t caps3;
uint32_t caps4;
uint32_t reserved2;
} DDSHeader;
typedef struct DDSHeader10 {
DXGIFormat dxgiFormat;
D3D10ResourceDimension resourceDimension;
uint32_t miscFlag;
uint32_t arraySize;
uint32_t reserved;
} DDSHeader10;

View File

@ -5,29 +5,56 @@
#include "lib/glfw.h"
#include "version.h"
#include "luax.h"
#include "platform.h"
#include "util.h"
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
bool lovrRun(int argc, char** argv, int* status);
lua_State* lovrInit(lua_State* L, int argc, char** argv);
void lovrQuit(int status);
#ifndef LOVR_USE_OCULUS_MOBILE
int main(int argc, char** argv) {
if (argc > 1 && (!strcmp(argv[1], "--version") || !strcmp(argv[1], "-v"))) {
printf("LOVR %d.%d.%d (%s)\n", LOVR_VERSION_MAJOR, LOVR_VERSION_MINOR, LOVR_VERSION_PATCH, LOVR_VERSION_ALIAS);
lovrLog("LOVR %d.%d.%d (%s)\n", LOVR_VERSION_MAJOR, LOVR_VERSION_MINOR, LOVR_VERSION_PATCH, LOVR_VERSION_ALIAS);
exit(0);
}
int status;
while (1) {
if (!lovrRun(argc, argv, &status)) {
return status;
bool restart;
do {
lua_State* L = luaL_newstate();
luaL_openlibs(L);
lovrSetErrorCallback((lovrErrorHandler) luax_vthrow, L);
lua_State* T = lovrInit(L, argc, argv);
if (!T) {
return 1;
}
}
#ifdef EMSCRIPTEN
lovrEmscriptenContext context = { L, T, argc, argv };
emscripten_set_main_loop_arg(emscriptenLoop, (void*) &context, 0, 1);
return 0;
#else
while (lua_resume(T, 0) == LUA_YIELD) {
lovrSleep(.001);
}
restart = lua_type(T, -1) == LUA_TSTRING && !strcmp(lua_tostring(T, -1), "restart");
status = lua_tonumber(T, -1);
lua_close(L);
#endif
} while (restart);
glfwTerminate();
return status;
}
#endif
@ -36,24 +63,22 @@ int main(int argc, char** argv) {
#include <emscripten.h>
typedef struct {
lua_State* L;
int ref;
lua_State* T;
int argc;
char** argv;
} lovrEmscriptenContext;
static void emscriptenLoop(void* arg) {
lovrEmscriptenContext* context = arg;
lua_State* L = context->L;
lua_rawgeti(L, LUA_REGISTRYINDEX, context->ref);
if (lua_resume(L, 0) != LUA_YIELD) {
int status = lua_tonumber(L, -1);
bool isRestart = lua_type(L, -1) == LUA_TSTRING && !strcmp(lua_tostring(L, -1), "restart");
if (lua_resume(context->T, 0) != LUA_YIELD) {
bool restart = lua_type(context->T, -1) == LUA_TSTRING && !strcmp(lua_tostring(context->T, -1), "restart");
int status = lua_tonumber(context->T, -1);
lua_close(L);
lua_close(context->L);
emscripten_cancel_main_loop();
if (isRestart) {
lovrRun(context->argc, context->argv, &status);
if (restart) {
main(context->argc, context->argv);
} else {
glfwTerminate();
exit(status);
@ -76,12 +101,7 @@ static void onGlfwError(int code, const char* description) {
lovrThrow(description);
}
bool lovrRun(int argc, char** argv, int* status) {
lua_State* L = luaL_newstate();
luaL_openlibs(L);
lovrSetErrorCallback((lovrErrorHandler) luax_vthrow, L);
lua_State* lovrInit(lua_State* L, int argc, char** argv) {
glfwSetErrorCallback(onGlfwError);
lovrAssert(glfwInit(), "Error initializing GLFW");
glfwSetTime(0);
@ -96,38 +116,18 @@ bool lovrRun(int argc, char** argv, int* status) {
}
lua_setglobal(L, "arg");
luax_registerloader(L, loadSelf, 2);
luax_registerloader(L, loadSelf, 1);
lua_pushcfunction(L, luax_getstack);
if (luaL_loadbuffer(L, (const char*) boot_lua, boot_lua_len, "boot.lua") || lua_pcall(L, 0, 1, -2)) {
fprintf(stderr, "%s\n", lua_tostring(L, -1));
lua_close(L);
*status = 1;
return false;
lovrWarn("%s\n", lua_tostring(L, -1));
return NULL;
}
lua_newthread(L);
lua_State* T = lua_newthread(L);
lua_pushvalue(L, -2);
#ifdef EMSCRIPTEN
lovrEmscriptenContext context = { L, luaL_ref(L, LUA_REGISTRYINDEX), argc, argv };
emscripten_set_main_loop_arg(emscriptenLoop, (void*) &context, 0, 1);
*status = 0;
return false;
#else
while (lua_resume(L, 0) == LUA_YIELD) {
lovrSleep(.001);
}
*status = lua_tonumber(L, -1);
bool restart = lua_type(L, -1) == LUA_TSTRING && !strcmp(lua_tostring(L, -1), "restart");
lua_close(L);
if (!restart) {
glfwTerminate();
}
return restart;
#endif
lua_xmove(L, T, 1);
return T;
}
void lovrQuit(int status) {

12
src/platform.h Normal file
View File

@ -0,0 +1,12 @@
#include <stdint.h>
#pragma once
#include <stdio.h>
#define lovrLog(...) printf(__VA_ARGS__)
#define lovrLogv(...) vprintf(__VA_ARGS__)
#define lovrWarn(...) fprintf(stderr, __VA_ARGS__)
#define lovrWarnv(...) vfprintf(stderr, __VA_ARGS__)
void lovrSleep(double seconds);
int lovrGetExecutablePath(char* dest, uint32_t size);

15
src/platform/linux.c Normal file
View File

@ -0,0 +1,15 @@
#include "platform.h"
#include <unistd.h>
#include <string.h>
void lovrSleep(double seconds) {
usleep((unsigned int) (seconds * 1000000));
}
int lovrGetExecutablePath(char* dest, uint32_t size) {
memset(dest, 0, size);
if (readlink("/proc/self/exe", dest, size) != -1) {
return 0;
}
return 1;
}

11
src/platform/macos.c Normal file
View File

@ -0,0 +1,11 @@
#include "platform.h"
#include <mach-o/dyld.h>
#include <unistd.h>
void lovrSleep(double seconds) {
usleep((unsigned int) (seconds * 1000000));
}
int lovrGetExecutablePath(char* dest, uint32_t size) {
return _NSGetExecutablePath(dest, &size);
}

10
src/platform/web.c Normal file
View File

@ -0,0 +1,10 @@
#include "platform.h"
#include <emscripten.h>
void lovrSleep(double seconds) {
emscripten_sleep((unsigned int) (seconds * 1000));
}
int lovrGetExecutablePath(char* dest, uint32_t size) {
return 1;
}

10
src/platform/windows.c Normal file
View File

@ -0,0 +1,10 @@
#include "platform.h"
#include <Windows.h>
void lovrSleep(double seconds) {
Sleep((unsigned int) (seconds * 1000));
}
int lovrGetExecutablePath(char* dest, uint32_t size) {
return !GetModuleFileName(NULL, dest, size);
}

View File

@ -195,6 +195,8 @@ var LibraryLOVR = {
if (sittingToStanding) {
HEAPF32.set(sittingToStanding, matA >> 2);
Module._mat4_transform(matA, x, y, z);
} else {
HEAPF32[y >> 2] += webvr.offset;
}
} else {
HEAPF32[x >> 2] = HEAPF32[y >> 2] = HEAPF32[z >> 2] = 0;
@ -233,6 +235,8 @@ var LibraryLOVR = {
if (sittingToStanding) {
HEAPF32.set(sittingToStanding, matB >> 2);
Module._mat4_multiply(matA, matB);
} else {
HEAPF32[(matA + 4 * 13) >> 2] += webvr.offset;
}
Module._mat4_translate(matA, pose.position[0], pose.position[1], pose.position[2]);
@ -323,6 +327,7 @@ var LibraryLOVR = {
Module._quat_fromMat4(quat, matA);
Module._quat_getAngleAxis(quat, angle, ax, ay, az);
} else {
HEAPF32[y >> 2] += webvr.offset;
Module._quat_getAngleAxis(quat, angle, ax, ay, az);
}
},

View File

@ -1,6 +1,6 @@
#include "timer/timer.h"
#include "lib/glfw.h"
#include "util.h"
#include "platform.h"
#include <string.h>
static TimerState state;

View File

@ -1,16 +1,6 @@
#include "util.h"
#include "platform.h"
#include <stdlib.h>
#include <stdio.h>
#ifdef _WIN32
#include <Windows.h>
#elif __APPLE__
#include <mach-o/dyld.h>
#include <unistd.h>
#include <dlfcn.h>
#else
#include <unistd.h>
#include <dlfcn.h>
#endif
_Thread_local lovrErrorHandler lovrErrorCallback = NULL;
_Thread_local void* lovrErrorUserdata = NULL;
@ -29,22 +19,14 @@ void lovrThrow(const char* format, ...) {
} else {
va_list args;
va_start(args, format);
fprintf(stderr, "Error: ");
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
lovrWarn("Error: ");
lovrWarnv(format, args);
lovrWarn("\n");
va_end(args);
exit(EXIT_FAILURE);
}
}
void lovrSleep(double seconds) {
#ifdef _WIN32
Sleep((unsigned int)(seconds * 1000));
#else
usleep((unsigned int)(seconds * 1000000));
#endif
}
void* _lovrAlloc(const char* type, size_t size, void (*destructor)(void*)) {
void* object = calloc(1, size);
if (!object) return NULL;
@ -61,26 +43,6 @@ void lovrRelease(void* object) {
if (ref && --ref->count == 0) ref->free(object);
}
int lovrGetExecutablePath(char* dest, uint32_t size) {
#ifdef __APPLE__
if (_NSGetExecutablePath(dest, &size) == 0) {
return 0;
}
#elif _WIN32
return !GetModuleFileName(NULL, dest, size);
#elif EMSCRIPTEN
return 1;
#elif __linux__
memset(dest, 0, size);
if (readlink("/proc/self/exe", dest, size) != -1) {
return 0;
}
#else
#error "This platform is missing an implementation for lovrGetExecutablePath"
#endif
return 1;
}
// https://github.com/starwing/luautf8
size_t utf8_decode(const char *s, const char *e, unsigned *pch) {
unsigned ch;

View File

@ -28,10 +28,8 @@ extern _Thread_local void* lovrErrorUserdata;
void lovrSetErrorCallback(lovrErrorHandler callback, void* context);
void lovrThrow(const char* format, ...);
void lovrSleep(double seconds);
void* _lovrAlloc(const char* type, size_t size, void (*destructor)(void*));
void lovrRetain(void* object);
void lovrRelease(void* object);
int lovrGetExecutablePath(char* dest, uint32_t size);
size_t utf8_decode(const char *s, const char *e, unsigned *pch);
uint32_t nextPo2(uint32_t x);