update
Some checks failed
CI / code-tests: ${{ matrix.os }} / ${{ matrix.platform }} (ubuntu-latest, x64) (push) Has been cancelled
CI / code-tests: ${{ matrix.os }} / ${{ matrix.platform }} (ubuntu-latest, x86) (push) Has been cancelled
CI / general_module_workflow_c (push) Has been cancelled

This commit is contained in:
Dennis Eichhorn 2024-06-08 13:49:05 +02:00
parent e939a3f4a6
commit 4ed50a08bc
38 changed files with 37557 additions and 163 deletions

234
Image/Bitmap.h Normal file
View File

@ -0,0 +1,234 @@
/**
* Jingga
*
* @package Image
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef IMAGE_BITMAP_H
#define IMAGE_BITMAP_H
#include "../Stdlib/Types.h"
namespace Image
{
#define BITMAP_HEADER_SIZE 14
struct BitmapHeader {
byte identifier[2]; // 2 bytes - bitmap identifier
uint32 size; // 4 bytes - size in bytes
byte app_data[4]; // 4 bytes - generated by the image software
uint32 offset; // 4 bytes - defines starting address for pixels
};
#define DIB_BITMAP_TYPE_BITMAPCOREHEADER 12
struct DIB_BITMAPCOREHEADER {
uint32 size;
uint16 width;
uint16 height;
uint16 color_planes;
uint16 bits_per_pixel;
};
#define DIB_BITMAP_TYPE_OS21XBITMAPHEADER DIB_BITMAP_TYPE_BITMAPCOREHEADER
#define DIB_OS21XBITMAPHEADER DIB_BITMAPCOREHEADER
#define DIB_BITMAP_TYPE_OS22XBITMAPHEADER 64
struct DIB_OS22XBITMAPHEADER {
// @todo implement
// They don't use a size as first value? how do I know if this is the correct header?
};
#define DIB_BITMAP_TYPE_BITMAPINFOHEADER 40
struct DIB_BITMAPINFOHEADER {
uint32 size;
int32 width;
int32 height;
uint16 color_planes;
uint16 bits_per_pixel;
uint32 compression_method;
uint32 raw_image_size;
//int32 horizontal_ppm;
//int32 vertical_ppm;
uint32 color_palette;
uint32 important_colors;
};
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_RGB 0x0000
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_RLE8 0x0001
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_RLE4 0x0002
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_BITFIELDS 0x0003
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_JPEG 0x0004
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_PNG 0x0005
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_ALPHABITFIELDS 0x0006
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_CMYK 0x000B
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_CMYKRLE8 0x000C
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_CMYKRLE4 0x000D
#define DIB_BITMAPINFOHEADER_HALFTONING_NONE 0
#define DIB_BITMAPINFOHEADER_HALFTONING_ERROR_DIFFUSION 1
#define DIB_BITMAPINFOHEADER_HALFTONING_PANDA 2
#define DIB_BITMAPINFOHEADER_HALFTONING_SUPER_CIRCLE 3
#define DIB_BITMAP_TYPE_BITMAPV2INFOHEADER 52
struct DIB_BITMAPV2INFOHEADER {
};
#define DIB_BITMAP_TYPE_BITMAPV3INFOHEADER 56
struct DIB_BITMAPV3INFOHEADER {
};
struct CIEXYZ {
int32 ciexyzX;
int32 ciexyzY;
int32 ciexyzZ;
};
struct CIEXYZTRIPLE {
CIEXYZ ciexyzRed;
CIEXYZ ciexyzGreen;
CIEXYZ ciexyzBlue;
};
#define DIB_BITMAP_TYPE_BITMAPV4HEADER 108
struct DIB_BITMAPV4HEADER {
int32 size;
int32 width;
int32 height;
uint16 color_planes;
uint16 bits_per_pixel;
int32 compression_method;
int32 raw_image_size;
//int32 horizontal_ppm;
//int32 vertical_ppm;
uint32 color_palette;
uint32 important_colors;
int32 bV4RedMask;
int32 bV4GreenMask;
int32 bV4BlueMask;
int32 bV4AlphaMask;
int32 bV4CSType;
CIEXYZTRIPLE bV4Endpoints;
int32 bV4GammaRed;
int32 bV4GammaGreen;
int32 bV4GammaBlue;
};
#define DIB_BITMAP_TYPE_BITMAPV5HEADER 124
struct DIB_BITMAPV5HEADER {
int32 size;
int32 width;
int32 height;
uint16 color_planes;
uint16 bits_per_pixel;
int32 compression_method;
int32 raw_image_size;
//int32 horizontal_ppm;
//int32 vertical_ppm;
uint32 color_palette;
uint32 important_colors;
int32 bV5RedMask;
int32 bV5GreenMask;
int32 bV5BlueMask;
int32 bV5AlphaMask;
int32 bV5CSType;
CIEXYZTRIPLE bV5Endpoints;
int32 bV5GammaRed;
int32 bV5GammaGreen;
int32 bV5GammaBlue;
int32 bV5Intent;
int32 bV5ProfileData;
int32 bV5ProfileSize;
int32 bV5Reserved;
};
struct Bitmap {
BitmapHeader header;
byte dib_header_type;
DIB_BITMAPINFOHEADER dib_header; // Despite the different header types we use this one for simplicity
uint32* extra_bit_mask; // 3-4 = 12-16 bytes
byte color_table_size;
byte* color_table;
// Pixels are stored in rows
// Rows are padded in multiples of 4 bytes
byte* pixels;
byte* data;
};
Bitmap generate_bitmap_references(byte* data)
{
Bitmap bitmap = {};
// Fill header
bitmap.header.identifier[0] = *(data + 0);
bitmap.header.identifier[1] = *(data + 1);
bitmap.header.size = *((uint32 *) (data + 2));
bitmap.header.app_data[0] = *(data + 6);
bitmap.header.app_data[1] = *(data + 7);
bitmap.header.app_data[2] = *(data + 8);
bitmap.header.app_data[3] = *(data + 9);
bitmap.header.offset = *((uint32 *) (data + 10));
byte* dib_header_offset = data + BITMAP_HEADER_SIZE;
bitmap.dib_header_type = *dib_header_offset;
byte* color_table_offset = data + BITMAP_HEADER_SIZE + bitmap.dib_header_type;
// Fill DIB header
switch(bitmap.dib_header_type) {
case DIB_BITMAP_TYPE_BITMAPCOREHEADER: {
bitmap.dib_header.size = *((uint32 *) (dib_header_offset));
bitmap.dib_header.width = *((uint16 *) (dib_header_offset + 4));
bitmap.dib_header.height = *((uint16 *) (dib_header_offset + 6));
bitmap.dib_header.color_planes = *((uint16 *) (dib_header_offset + 8));
bitmap.dib_header.bits_per_pixel = *((uint16 *) (dib_header_offset + 10));
bitmap.dib_header.color_palette = 1U << bitmap.dib_header.bits_per_pixel;
} break;
case DIB_BITMAP_TYPE_BITMAPV5HEADER:
case DIB_BITMAP_TYPE_BITMAPV4HEADER:
case DIB_BITMAP_TYPE_BITMAPV3INFOHEADER:
case DIB_BITMAP_TYPE_BITMAPV2INFOHEADER:
case DIB_BITMAP_TYPE_BITMAPINFOHEADER: {
bitmap.dib_header.size = *((uint32 *) (dib_header_offset));
bitmap.dib_header.width = *((int32 *) (dib_header_offset + 4));
bitmap.dib_header.height = *((int32 *) (dib_header_offset + 8));
bitmap.dib_header.color_planes = *((uint16 *) (dib_header_offset + 12));
bitmap.dib_header.bits_per_pixel = *((uint16 *) (dib_header_offset + 14));
bitmap.dib_header.compression_method = *((uint32 *) (dib_header_offset + 16));
bitmap.dib_header.raw_image_size = *((uint32 *) (dib_header_offset + 20));
bitmap.dib_header.color_palette = *((uint32 *) (dib_header_offset + 32));
bitmap.dib_header.important_colors = *((uint32 *) (dib_header_offset + 36));
if (bitmap.dib_header.compression_method == DIB_BITMAPINFOHEADER_COMPRESSION_BI_BITFIELDS) {
// 12 bytes
bitmap.extra_bit_mask = (uint32 *) (dib_header_offset + DIB_BITMAP_TYPE_BITMAPINFOHEADER);
color_table_offset += 12;
} else if (bitmap.dib_header.compression_method == DIB_BITMAPINFOHEADER_COMPRESSION_BI_ALPHABITFIELDS) {
// 16 bytes
bitmap.extra_bit_mask = (uint32 *) (dib_header_offset + DIB_BITMAP_TYPE_BITMAPINFOHEADER);
color_table_offset += 16;
}
} break;
default: {
}
}
// Fill other
bitmap.color_table = color_table_offset;
bitmap.pixels = (byte *) (data + bitmap.header.offset);
bitmap.data = data;
return bitmap;
}
}
#endif

View File

@ -17,18 +17,18 @@ namespace Image::ImageUtils
{
inline float lightnessFromRgb(int r, int g, int b)
{
float vR = r / 255.0;
float vG = g / 255.0;
float vB = b / 255.0;
float vR = (float) r / 255.0f;
float vG = (float) g / 255.0f;
float vB = (float) b / 255.0f;
float lR = vR <= 0.04045 ? vR / 12.92 : pow(((vR + 0.055) / 1.055), 2.4);
float lG = vG <= 0.04045 ? vG / 12.92 : pow(((vG + 0.055) / 1.055), 2.4);
float lB = vB <= 0.04045 ? vB / 12.92 : pow(((vB + 0.055) / 1.055), 2.4);
float lR = vR <= 0.04045 ? vR / 12.92 : powf(((vR + 0.055f) / 1.055f), 2.4f);
float lG = vG <= 0.04045 ? vG / 12.92 : powf(((vG + 0.055f) / 1.055f), 2.4f);
float lB = vB <= 0.04045 ? vB / 12.92 : powf(((vB + 0.055f) / 1.055f), 2.4f);
float y = 0.2126 * lR + 0.7152 * lG + 0.0722 * lB;
float lStar = y <= 216.0 / 24389.0 ? y * 24389.0 / 27.0 : pow(y, (1.0 / 3.0)) * 116.0 - 16.0;
float lStar = y <= 216.0 / 24389.0 ? y * 24389.0 / 27.0 : powf(y, (1.0 / 3.0)) * 116.0 - 16.0;
return lStar / 100.0;
return lStar / 100.0f;
}
} // namespace Image::ImageUtils

0
Image/Png.h Normal file
View File

View File

@ -36,18 +36,18 @@ namespace Image::Skew
float angle = atan2(lines[i][3] - lines[i][1], lines[i][2] - lines[i][0]);
tmpAngles.push_back(angle);
imageOrientation += oms_abs(angle) > OMS_PI / 4 ? 1 : -1;
imageOrientation += OMS_ABS(angle) > OMS_PI / 4 ? 1 : -1;
}
std::vector<float> angles;
for (int i = 0; i < tmpAngles.size(); ++i) {
if (imageOrientation > 0) {
if (oms_deg2rad(90 - maxDegree) < oms_abs(tmpAngles[i]) &&
oms_abs(tmpAngles[i]) < oms_deg2rad(90 + maxDegree)) {
if (OMS_DEG2RAD(90 - maxDegree) < OMS_ABS(tmpAngles[i]) &&
OMS_ABS(tmpAngles[i]) < OMS_DEG2RAD(90 + maxDegree)) {
angles.push_back(tmpAngles[i]);
}
} else {
if (oms_abs(tmpAngles[i]) < oms_deg2rad(maxDegree)) {
if (OMS_ABS(tmpAngles[i]) < OMS_DEG2RAD(maxDegree)) {
angles.push_back(tmpAngles[i]);
}
}
@ -62,7 +62,7 @@ namespace Image::Skew
median += angles[i];
}
float angleDeg = oms_rad2deg(median / angles.size());
float angleDeg = OMS_RAD2DEG(median / angles.size());
cv::Mat orientFix;
if (imageOrientation > 0) {

View File

@ -49,11 +49,11 @@ namespace Image::Thresholding
for (int i = 0; i < dim.width; ++i) {
for (int j = 0; j < dim.height; ++j) {
x1 = oms_max(1, i - s / 2.0);
x2 = oms_min(i + s / 2.0, dim.width - 1);
x1 = OMS_MAX(1, i - s / 2.0);
x2 = OMS_MIN(i + s / 2.0, dim.width - 1);
y1 = oms_max(1, j - s / 2.0);
y2 = oms_min(j + s / 2.0, dim.height - 1);
y1 = OMS_MAX(1, j - s / 2.0);
y2 = OMS_MIN(j + s / 2.0, dim.height - 1);
count = (x2 - x1) * (y2 - y1);
sum = intImg[x2 * y2] - intImg[x2 * (y1 - 1)] - intImg[(x1 - 1) * y2] + intImg[(x1 - 1) * (y1 - 1)];

View File

@ -84,7 +84,7 @@ namespace Input {
PRAWINPUTDEVICELIST pRawInputDeviceList = (PRAWINPUTDEVICELIST) malloc(sizeof(RAWINPUTDEVICELIST) * nDevices);
nDevices = GetRawInputDeviceList(pRawInputDeviceList, &nDevices, sizeof(RAWINPUTDEVICELIST));
nDevices = oms_max(MIN_INPUT_DEVICES, nDevices);
nDevices = OMS_MAX(MIN_INPUT_DEVICES, nDevices);
// We always want at least one empty input device slot
// @todo Change so that we store the actual number of devices
@ -125,33 +125,33 @@ namespace Input {
}
}
RAWINPUTDEVICE rid2[4];
RAWINPUTDEVICE rid[4];
// Mouse
rid2[0].usUsagePage = 0x01; // @todo doesn't work with 0x05 for games?
rid2[0].usUsage = 0x02;
rid2[0].dwFlags = RIDEV_DEVNOTIFY;
rid2[0].hwndTarget = w->hwnd;
rid[0].usUsagePage = 0x01; // @todo doesn't work with 0x05 for games?
rid[0].usUsage = 0x02;
rid[0].dwFlags = RIDEV_DEVNOTIFY;
rid[0].hwndTarget = w->hwnd;
// Joystick
rid2[1].usUsagePage = 0x01; // @todo doesn't work with 0x05 for games?
rid2[1].usUsage = 0x04;
rid2[1].dwFlags = RIDEV_DEVNOTIFY;
rid2[1].hwndTarget = w->hwnd;
rid[1].usUsagePage = 0x01; // @todo doesn't work with 0x05 for games?
rid[1].usUsage = 0x04;
rid[1].dwFlags = RIDEV_DEVNOTIFY;
rid[1].hwndTarget = w->hwnd;
// Gamepad
rid2[2].usUsagePage = 0x01; // @todo doesn't work with 0x05 for games?
rid2[2].usUsage = 0x05;
rid2[2].dwFlags = RIDEV_DEVNOTIFY;
rid2[2].hwndTarget = w->hwnd;
rid[2].usUsagePage = 0x01; // @todo doesn't work with 0x05 for games?
rid[2].usUsage = 0x05;
rid[2].dwFlags = RIDEV_DEVNOTIFY;
rid[2].hwndTarget = w->hwnd;
// Keyboard
rid2[3].usUsagePage = 0x01; // @todo doesn't work with 0x05 for games?
rid2[3].usUsage = 0x06;
rid2[3].dwFlags = RIDEV_DEVNOTIFY;
rid2[3].hwndTarget = w->hwnd;
rid[3].usUsagePage = 0x01; // @todo doesn't work with 0x05 for games?
rid[3].usUsage = 0x06;
rid[3].dwFlags = RIDEV_DEVNOTIFY;
rid[3].hwndTarget = w->hwnd;
if (!RegisterRawInputDevices((PCRAWINPUTDEVICE) rid2, 4, sizeof(RAWINPUTDEVICE))) {
if (!RegisterRawInputDevices((PCRAWINPUTDEVICE) rid, 4, sizeof(RAWINPUTDEVICE))) {
// @todo Log
}

View File

@ -27,6 +27,9 @@ namespace Input {
uint32 id = 0;
bool is_connected = false;
// After handling the state change the game loop should set this to false
bool state_change = false;
bool up = false;
bool down = false;
bool left = false;
@ -51,7 +54,7 @@ namespace Input {
int16 stickr_x = 0;
int16 stickr_y = 0;
bool stick2_press = false;
bool stickr_press = false;
};
// @todo consider to remove some global_persist and defines since we are never calling it somewhere else
@ -103,7 +106,7 @@ namespace Input {
}
}
c = oms_max(MIN_CONTROLLER_DEVICES, c);
c = OMS_MAX(MIN_CONTROLLER_DEVICES, c);
// We always want at least one empty controller slot
// @todo Change so that we store the actual number of devices
@ -162,7 +165,7 @@ namespace Input {
states[controller_index].stickr_x = controller_state.Gamepad.sThumbRX;
states[controller_index].stickr_y = controller_state.Gamepad.sThumbRY;
states[controller_index].stick2_press = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB;
states[controller_index].stickr_press = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB;
++controller_index;
}

0
Logging/Log.h Normal file
View File

View File

@ -0,0 +1,24 @@
#ifndef MATH_MATRIX_FLOAT32_H
#define MATH_MATRIX_FLOAT32_H
#include "../Stdlib/Types.h"
#define LOG_TYPE_STRING 0
#define LOG_TYPE_INT 1
#define LOG_TYPE_BOOL 2
#define LOG_TYPE_REF 3
struct GenericStringLogMessage {
byte datatype = LOG_TYPE_STRING;
uint32 type;
char title[32];
union {
char val_str[128];
int64 val_int;
bool val_bool;
void* val_ref;
};
};
#endif

View File

@ -0,0 +1,125 @@
/**
* Karaka
*
* @package Stdlib
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://jingga.app
* @see https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_collision_detection
*/
#ifndef PHYSICS_COLLISION_DETECTION_H
#define PHYSICS_COLLISION_DETECTION_H
#include "../Stdlib/Intrinsics.h"
#include "../Stdlib/SIMD/SIMD_F32.h"
#include "../Utils/MathUtils.h"
namespace Physics
{
struct CollisionPoint {
union {
struct {
float x;
float y;
float z;
};
float v[3];
};
};
struct CollisionBox {
union {
struct {
float x_min;
float y_min;
float z_min;
float x_max;
float y_max;
float z_max;
};
struct {
float v_min[3];
float v_max[3];
};
};
};
struct CollisionSphere {
union {
struct {
float x;
float y;
float z;
float radius;
};
float v[4];
};
};
/**
* WARNING: Very inefficient, the actual implementation should use SIMD in the context of the actual
* programm. Usually you can group together multiple collision detections and perfom the
* algorithms below on multiple elements at the same time
*/
inline
bool is_point_inside_AABB(CollisionPoint* point, CollisionBox* box)
{
return point->x >= box->x_min
&& point->x <= box->x_max
&& point->y >= box->y_min
&& point->y <= box->y_max
&& point->z >= box->z_min
&& point->z <= box->z_max;
}
inline
bool is_box_box_intersecting(CollisionBox* a, CollisionBox* b)
{
return a->x_min <= b->x_max
&& a->x_max >= b->x_min
&& a->y_min <= b->y_max
&& a->y_max >= b->y_min
&& a->z_min <= b->z_max
&& a->z_max >= b->z_min;
}
inline
bool is_point_inside_sphere(CollisionPoint* point, CollisionSphere* sphere)
{
return Stdlib::Intrinsics::sqrt(
(point->x - sphere->x) * (point->x - sphere->x)
+ (point->y - sphere->y) * (point->y - sphere->y)
+ (point->z - sphere->z) * (point->z - sphere->z)
) <= sphere->radius;
}
inline
bool is_sphere_sphere_intersecting(CollisionSphere* a, CollisionSphere* b)
{
return Stdlib::Intrinsics::sqrt(
(a->x - b->x) * (a->x - b->x)
+ (a->y - b->y) * (a->y - b->y)
+ (a->z - b->z) * (a->z - b->z)
) <= a->radius + b->radius;
}
inline
bool is_sphere_box_intersecting(CollisionSphere* sphere, CollisionBox* box)
{
float x_max = OMS_MAX(box->x_min, OMS_MAX(sphere->x, box->x_max));
float y_max = OMS_MAX(box->y_min, OMS_MAX(sphere->y, box->y_max));
float z_max = OMS_MAX(box->z_min, OMS_MAX(sphere->z, box->z_max));
return Stdlib::Intrinsics::sqrt(
(x_max - sphere->x) * (x_max - sphere->x)
+ (y_max - sphere->y) * (y_max - sphere->y)
+ (z_max - sphere->z) * (z_max - sphere->z)
) <= sphere->radius;
}
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,663 @@
/*************************************************************************
* GLFW 3.4 - www.glfw.org
* A library for OpenGL, window and input
*------------------------------------------------------------------------
* Copyright (c) 2002-2006 Marcus Geelnard
* Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would
* be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
*************************************************************************/
#ifndef _glfw3_native_h_
#define _glfw3_native_h_
#ifdef __cplusplus
extern "C" {
#endif
/*************************************************************************
* Doxygen documentation
*************************************************************************/
/*! @file glfw3native.h
* @brief The header of the native access functions.
*
* This is the header file of the native access functions. See @ref native for
* more information.
*/
/*! @defgroup native Native access
* @brief Functions related to accessing native handles.
*
* **By using the native access functions you assert that you know what you're
* doing and how to fix problems caused by using them. If you don't, you
* shouldn't be using them.**
*
* Before the inclusion of @ref glfw3native.h, you may define zero or more
* window system API macro and zero or more context creation API macros.
*
* The chosen backends must match those the library was compiled for. Failure
* to do this will cause a link-time error.
*
* The available window API macros are:
* * `GLFW_EXPOSE_NATIVE_WIN32`
* * `GLFW_EXPOSE_NATIVE_COCOA`
* * `GLFW_EXPOSE_NATIVE_X11`
* * `GLFW_EXPOSE_NATIVE_WAYLAND`
*
* The available context API macros are:
* * `GLFW_EXPOSE_NATIVE_WGL`
* * `GLFW_EXPOSE_NATIVE_NSGL`
* * `GLFW_EXPOSE_NATIVE_GLX`
* * `GLFW_EXPOSE_NATIVE_EGL`
* * `GLFW_EXPOSE_NATIVE_OSMESA`
*
* These macros select which of the native access functions that are declared
* and which platform-specific headers to include. It is then up your (by
* definition platform-specific) code to handle which of these should be
* defined.
*
* If you do not want the platform-specific headers to be included, define
* `GLFW_NATIVE_INCLUDE_NONE` before including the @ref glfw3native.h header.
*
* @code
* #define GLFW_EXPOSE_NATIVE_WIN32
* #define GLFW_EXPOSE_NATIVE_WGL
* #define GLFW_NATIVE_INCLUDE_NONE
* #include <GLFW/glfw3native.h>
* @endcode
*/
/*************************************************************************
* System headers and types
*************************************************************************/
#if !defined(GLFW_NATIVE_INCLUDE_NONE)
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
/* This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
* example to allow applications to correctly declare a GL_KHR_debug callback)
* but windows.h assumes no one will define APIENTRY before it does
*/
#if defined(GLFW_APIENTRY_DEFINED)
#undef APIENTRY
#undef GLFW_APIENTRY_DEFINED
#endif
#include <windows.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
#if defined(__OBJC__)
#import <Cocoa/Cocoa.h>
#else
#include <ApplicationServices/ApplicationServices.h>
#include <objc/objc.h>
#endif
#endif
#if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
#include <wayland-client.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_WGL)
/* WGL is declared by windows.h */
#endif
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
/* NSGL is declared by Cocoa.h */
#endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
* default it also acts as an OpenGL header
* However, glx.h will include gl.h, which will define it unconditionally
*/
#if defined(GLFW_GLAPIENTRY_DEFINED)
#undef GLAPIENTRY
#undef GLFW_GLAPIENTRY_DEFINED
#endif
#include <GL/glx.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
#include <EGL/egl.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
* default it also acts as an OpenGL header
* However, osmesa.h will include gl.h, which will define it unconditionally
*/
#if defined(GLFW_GLAPIENTRY_DEFINED)
#undef GLAPIENTRY
#undef GLFW_GLAPIENTRY_DEFINED
#endif
#include <GL/osmesa.h>
#endif
#endif /*GLFW_NATIVE_INCLUDE_NONE*/
/*************************************************************************
* Functions
*************************************************************************/
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
/*! @brief Returns the adapter device name of the specified monitor.
*
* @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
* of the specified monitor, or `NULL` if an [error](@ref error_handling)
* occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
/*! @brief Returns the display device name of the specified monitor.
*
* @return The UTF-8 encoded display device name (for example
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
/*! @brief Returns the `HWND` of the specified window.
*
* @return The `HWND` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @remark The `HDC` associated with the window can be queried with the
* [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
* function.
* @code
* HDC dc = GetDC(glfwGetWin32Window(window));
* @endcode
* This DC is private and does not need to be released.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_WGL)
/*! @brief Returns the `HGLRC` of the specified window.
*
* @return The `HGLRC` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT.
*
* @remark The `HDC` associated with the window can be queried with the
* [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
* function.
* @code
* HDC dc = GetDC(glfwGetWin32Window(window));
* @endcode
* This DC is private and does not need to be released.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
*
* @return The `CGDirectDisplayID` of the specified monitor, or
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
/*! @brief Returns the `NSWindow` of the specified window.
*
* @return The `NSWindow` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
/*! @brief Returns the `NSView` of the specified window.
*
* @return The `NSView` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.4.
*
* @ingroup native
*/
GLFWAPI id glfwGetCocoaView(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
/*! @brief Returns the `NSOpenGLContext` of the specified window.
*
* @return The `NSOpenGLContext` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_X11)
/*! @brief Returns the `Display` used by GLFW.
*
* @return The `Display` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI Display* glfwGetX11Display(void);
/*! @brief Returns the `RRCrtc` of the specified monitor.
*
* @return The `RRCrtc` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
/*! @brief Returns the `RROutput` of the specified monitor.
*
* @return The `RROutput` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
/*! @brief Returns the `Window` of the specified window.
*
* @return The `Window` of the specified window, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
/*! @brief Sets the current primary selection to the specified string.
*
* @param[in] string A UTF-8 encoded string.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
*
* @pointer_lifetime The specified string is copied before this function
* returns.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
* @sa glfwGetX11SelectionString
* @sa glfwSetClipboardString
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI void glfwSetX11SelectionString(const char* string);
/*! @brief Returns the contents of the current primary selection as a string.
*
* If the selection is empty or if its contents cannot be converted, `NULL`
* is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated.
*
* @return The contents of the selection as a UTF-8 encoded string, or `NULL`
* if an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
*
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
* should not free it yourself. It is valid until the next call to @ref
* glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the
* library is terminated.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
* @sa glfwSetX11SelectionString
* @sa glfwGetClipboardString
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI const char* glfwGetX11SelectionString(void);
#endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
/*! @brief Returns the `GLXContext` of the specified window.
*
* @return The `GLXContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
/*! @brief Returns the `GLXWindow` of the specified window.
*
* @return The `GLXWindow` of the specified window, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
/*! @brief Returns the `struct wl_display*` used by GLFW.
*
* @return The `struct wl_display*` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
/*! @brief Returns the `struct wl_output*` of the specified monitor.
*
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
/*! @brief Returns the main `struct wl_surface*` of the specified window.
*
* @return The main `struct wl_surface*` of the specified window, or `NULL` if
* an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
/*! @brief Returns the `EGLDisplay` used by GLFW.
*
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark Because EGL is initialized on demand, this function will return
* `EGL_NO_DISPLAY` until the first context has been created via EGL.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
/*! @brief Returns the `EGLContext` of the specified window.
*
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
/*! @brief Returns the `EGLSurface` of the specified window.
*
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
/*! @brief Retrieves the color buffer associated with the specified window.
*
* @param[in] window The window whose color buffer to retrieve.
* @param[out] width Where to store the width of the color buffer, or `NULL`.
* @param[out] height Where to store the height of the color buffer, or `NULL`.
* @param[out] format Where to store the OSMesa pixel format of the color
* buffer, or `NULL`.
* @param[out] buffer Where to store the address of the color buffer, or
* `NULL`.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer);
/*! @brief Retrieves the depth buffer associated with the specified window.
*
* @param[in] window The window whose depth buffer to retrieve.
* @param[out] width Where to store the width of the depth buffer, or `NULL`.
* @param[out] height Where to store the height of the depth buffer, or `NULL`.
* @param[out] bytesPerValue Where to store the number of bytes per depth
* buffer element, or `NULL`.
* @param[out] buffer Where to store the address of the depth buffer, or
* `NULL`.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer);
/*! @brief Returns the `OSMesaContext` of the specified window.
*
* @return The `OSMesaContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window);
#endif
#ifdef __cplusplus
}
#endif
#endif /* _glfw3_native_h_ */

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -12,7 +12,6 @@
#include <dsound.h>
#include <windows.h>
#include <math.h>
#include "../Stdlib/Types.h"
#include "../Utils/MathUtils.h"
@ -25,6 +24,7 @@ namespace Sound {
uint32 sample_rate;
uint32 sample_size;
uint32 sample_index;
uint32 latency;
int16 volume;
@ -35,7 +35,7 @@ namespace Sound {
uint32 sample_buffer_size;
int16* buffer;
bool playing = false;
bool is_playing = false;
byte type = SOUND_API_DIRECT_SOUND;
// Api specific data from here on
@ -78,7 +78,7 @@ namespace Sound {
wf.nBlockAlign = (wf.nChannels * wf.wBitsPerSample) / 8;
wf.nSamplesPerSec = setting->sample_rate;
wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign;
wf.cbSize;
wf.cbSize = 0;
// Create primary buffer
DSBUFFERDESC bufferDesc;
@ -121,8 +121,12 @@ namespace Sound {
inline
void direct_sound_play(DirectSoundSetting* setting)
{
if (!setting->secondary_buffer) {
return;
}
setting->secondary_buffer->Play(0, 0, DSBPLAY_LOOPING);
setting->playing = true;
setting->is_playing = true;
}
inline
@ -157,13 +161,15 @@ namespace Sound {
DWORD bytes_to_lock = (setting->sample_index * setting->sample_size) % setting->buffer_size;
DWORD bytes_to_write = 0;
DWORD target_cursor = (player_cursor + (setting->latency * setting->sample_size)) % setting->buffer_size;
if (bytes_to_lock == player_cursor) {
bytes_to_write = setting->playing ? 0 : setting->buffer_size;
} else if (bytes_to_lock > player_cursor) {
bytes_to_write = setting->is_playing ? 0 : setting->buffer_size;
} else if (bytes_to_lock > target_cursor) {
bytes_to_write = setting->buffer_size - bytes_to_lock;
bytes_to_write += player_cursor;
bytes_to_write += target_cursor;
} else {
bytes_to_write = player_cursor - bytes_to_lock;
bytes_to_write = target_cursor - bytes_to_lock;
}
return bytes_to_write;

View File

@ -12,7 +12,6 @@
#include <xaudio2.h>
#include <windows.h>
#include <math.h>
#include "../Stdlib/Types.h"
#include "../Utils/MathUtils.h"
@ -25,6 +24,7 @@ namespace Sound {
uint32 sample_rate;
uint32 sample_size;
uint32 sample_index;
uint32 latency;
int16 volume;
@ -35,7 +35,7 @@ namespace Sound {
uint32 sample_buffer_size;
int16* buffer;
bool playing = false;
bool is_playing = false;
byte type = SOUND_API_XAUDIO2;
// Api specific data from here on
@ -132,7 +132,7 @@ namespace Sound {
}
setting->source_voice->Start(0, XAUDIO2_COMMIT_NOW);
setting->playing = true;
setting->is_playing = true;
}
inline

View File

@ -12,9 +12,12 @@
#include <immintrin.h>
#include <inttypes.h>
#include <x86intrin.h>
#include <xmmintrin.h>
#ifdef _LINUX
#include <x86intrin.h>
#endif
#include "Types.h"
namespace Stdlib::Intrinsics

View File

@ -10,48 +10,91 @@
#ifndef STDLIB_SIMD_HELPER_H
#define STDLIB_SIMD_HELPER_H
#include <immintrin.h>
#include <stdint.h>
#include <immintrin.h>
#include <xmmintrin.h>
#ifdef _MSC_VER
#include <intrin.h>
#endif
namespace Stdlib::SIMD
{
inline
bool is_sse_supported()
{
uint32_t eax, ebx, ecx, edx;
#ifdef _MSC_VER
int cpuInfo[4] = {-1};
__cpuid(cpuInfo, 1); // CPUID function 1
eax = 1; // CPUID function 1
// Check the SSE feature bit in EDX
return (cpuInfo[3] >> 25) & 1;
#else
uint32_t eax, ebx, ecx, edx;
__asm__ __volatile__("cpuid;" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(eax));
eax = 1; // CPUID function 1
// Check the AVX feature bit in ECX
return (ecx >> 28) & 1;
__asm__ __volatile__("cpuid;" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(eax));
// Check the AVX feature bit in ECX
return (ecx >> 28) & 1;
#endif
}
inline
bool is_avx256_supported()
{
uint32_t eax, ebx, ecx, edx;
#ifdef _MSC_VER
int cpuInfo[4] = {-1};
__cpuid(cpuInfo, 1); // CPUID function 1
eax = 7; // CPUID function 7
ecx = 0; // Sub-function 0
// Check the AVX feature bit in ECX
if ((cpuInfo[2] >> 28) & 1) {
__cpuid(cpuInfo, 7); // CPUID function 7, sub-function 0
// Check the AVX2 feature bit in EBX
return (cpuInfo[1] >> 5) & 1;
}
__asm__ __volatile__("cpuid;" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(eax), "c"(ecx));
return false;
#else
uint32_t eax, ebx, ecx, edx;
// Check the AVX-256 (AVX2) feature bit in EBX
return (ebx >> 5) & 1;
eax = 7; // CPUID function 7
ecx = 0; // Sub-function 0
__asm__ __volatile__("cpuid;" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(eax), "c"(ecx));
// Check the AVX-256 (AVX2) feature bit in EBX
return (ebx >> 5) & 1;
#endif
}
inline
bool is_avx512_supported()
{
uint32_t eax, ebx, ecx, edx;
#ifdef _MSC_VER
int cpuInfo[4] = {-1};
__cpuid(cpuInfo, 1); // CPUID function 1
eax = 7; // CPUID function 7
ecx = 0; // Sub-function 0
// Check the AVX feature bit in ECX
if ((cpuInfo[2] >> 28) & 1) {
__cpuid(cpuInfo, 7); // CPUID function 7, sub-function 0
// Check the AVX-512 feature bit in EBX
return (cpuInfo[1] >> 16) & 1;
}
__asm__ __volatile__("cpuid;" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(eax), "c"(ecx));
return false;
#else
uint32_t eax, ebx, ecx, edx;
// Check the AVX-512 feature bit in EBX
return (ebx >> 16) & 1;
eax = 7; // CPUID function 7
ecx = 0; // Sub-function 0
__asm__ __volatile__("cpuid;" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(eax), "c"(ecx));
// Check the AVX-512 feature bit in EBX
return (ebx >> 16) & 1;
#endif
}
} // namespace Stdlib::SIMD

View File

@ -10,7 +10,6 @@
#ifndef STDLIB_TYPES_H
#define STDLIB_TYPES_H
#include <float.h>
#include <stdint.h>
typedef int8_t int8;
@ -29,6 +28,10 @@ typedef double f64;
typedef unsigned char byte;
#define MAX_BYTE 0xFF
#define MAX_INT16 0xFFFF
#define MAX_INT32 0xFFFFFFFF
#define internal static // only allows local "file" access
#define local_persist static
#define global_persist static
@ -68,7 +71,7 @@ uint16 float_to_f16(float f) {
fraction = 0;
}
f16_bits = sign | (exponent << HALF_FLOAT_EXP_SHIFT) | (fraction & HALF_FLOAT_FRAC_MASK);
f16_bits = (uint16_t) (sign | (exponent << HALF_FLOAT_EXP_SHIFT) | (fraction & HALF_FLOAT_FRAC_MASK));
return f16_bits;
}

View File

@ -1,8 +1,16 @@
#ifndef UI_WINDOW_H
#define UI_WINDOW_H
#ifdef _WIN32
#include <windows.h>
#ifdef OPENGL
#include "../Resources/opengl/glfw/include/glfw3.h"
#ifdef GLFW_EXPOSE_NATIVE_WIN32
#include "../Resources/opengl/glfw/include/glfw3native.h"
#endif
#else
#ifdef _WIN32
#include <windows.h>
#endif
#endif
#include "../Stdlib/Types.h"
@ -12,11 +20,15 @@ namespace UI
struct Window {
int32 width;
int32 height;
char wName[32];
char name[32];
int32 x;
int32 y;
#ifdef OPENGL
GLFWwindow* hwnd_lib;
#endif
#ifdef _WIN32
HWND hwnd;
#endif
@ -24,14 +36,21 @@ namespace UI
void window_open(const Window* window)
{
#ifdef _WIN32
ShowWindow(window->hwnd, SW_SHOW);
UpdateWindow(window->hwnd);
#ifdef OPENGL
return;
#else
#ifdef _WIN32
ShowWindow(window->hwnd, SW_SHOW);
UpdateWindow(window->hwnd);
return;
#endif
#endif
}
void window_create_windows(Window* window, WNDPROC proc)
{
{
#if defined(_WIN32) && !defined(OPENGL)
WNDCLASSEX wc = {};
HINSTANCE hinstance = GetModuleHandle(0);
@ -39,7 +58,7 @@ namespace UI
wc.style = CS_OWNDC;
wc.lpfnWndProc = proc;
wc.hInstance = hinstance;
wc.lpszClassName = (LPCWSTR) window->wName;
wc.lpszClassName = (LPCWSTR) window->name;
RegisterClassEx(&wc);
@ -53,12 +72,50 @@ namespace UI
);
//SetWindowLongA(window->hwnd, GWL_STYLE, 0);
#endif
}
void window_create_opengl(Window* window)
{
#ifdef OPENGL
//GLFWmonitor *monitor = glfwGetPrimaryMonitor();
window->hwnd_lib = glfwCreateWindow(
window->width,
window->height,
window->name,
NULL,
NULL
);
#ifdef GLFW_EXPOSE_NATIVE_WIN32
window->hwnd = glfwGetWin32Window(window->hwnd_lib);
#endif
#endif
}
void window_create(Window* window, void* data)
{
#ifdef OPENGL
window_create_opengl(window);
return;
#else
#ifdef _WIN32
window_create_windows(window, (WNDPROC) data);
return;
#endif
#endif
}
void window_close(Window* window)
{
#ifdef _WIN32
CloseWindow(window->hwnd);
#ifdef OPENGL
glfwWindowShouldClose(window->hwnd_lib);
return;
#else
#ifdef _WIN32
CloseWindow(window->hwnd);
return;
#endif
#endif
}
}

View File

@ -15,74 +15,70 @@
#include <string.h>
#ifdef _WIN32
#include <wchar.h>
#include <windows.h>
#define _chdir chdir
#define _getcwd getcwd
#ifdef _MSC_VER
#include <io.h>
#endif
#else
#include <sys/stat.h>
#include <unistd.h>
#endif
#include "OSWrapper.h"
#include "TestUtils.h"
namespace Utils::FileUtils
{
inline bool file_exists(const char *filename)
inline bool file_exists(const char* filename)
{
#ifdef _WIN32
return access(filename, 0) == 0;
#else
#ifdef _WIN32
#ifdef _MSC_VER
return _access(filename, 0) == 0;
#endif
#else
struct stat buffer;
return stat(filename, &buffer) == 0;
#endif
#endif
}
inline time_t last_modification(const char *filename)
inline void self_path(char* path)
{
#ifdef _WIN32
FILETIME modtime;
HANDLE h;
size_t nameLength = strlen(filename);
wchar_t *wtext = (wchar_t *) calloc(nameLength, sizeof(char));
mbstowcs_s(NULL, wtext, nameLength, filename, nameLength);
LPWSTR pFilename = wtext;
if (!pFilename) {
free(wtext);
return 0;
}
h = CreateFileW(pFilename, GENERIC_READ | FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, 0, NULL);
free(wtext);
free(pFilename);
if (h == INVALID_HANDLE_VALUE) {
return (time_t) 0;
}
if (GetFileTime(h, NULL, NULL, &modtime) == 0) {
return (time_t) 0;
}
unsigned long long seconds = ((unsigned long long) (modtime.dwHighDateTime)) << 32;
seconds |= modtime.dwLowDateTime;
return (seconds - 116444736000000000) / 10000000;
#else
struct stat buffer;
stat(filename, &buffer);
return (time_t) buffer.st_mtim.tv_sec;
#endif
return (time_t) 0;
#ifdef _WIN32
HMODULE dll = GetModuleHandle(NULL);
GetModuleFileNameA(dll, (LPSTR) path, MAX_PATH);
#endif
}
inline const char *file_extension(const char *filename)
inline uint64 last_modification(const char* filename)
{
char *dot = strrchr((char *) filename, '.');
#ifdef _WIN32
FILETIME modified = {};
WIN32_FIND_DATA find_data;
HANDLE fp = FindFirstFileA(filename, (LPWIN32_FIND_DATAA) &find_data);
if(fp != INVALID_HANDLE_VALUE) {
modified = find_data.ftLastWriteTime;
FindClose(fp);
}
ULARGE_INTEGER ull;
ull.LowPart = modified.dwLowDateTime;
ull.HighPart = modified.dwHighDateTime;
return ull.QuadPart;
#else
struct stat buffer;
stat(filename, &buffer);
return (uint64) buffer.st_mtim.tv_sec;
#endif
}
inline const char* file_extension(const char* filename)
{
char* dot = strrchr((char* ) filename, '.');
if (!dot || dot == filename) {
return "";
@ -92,36 +88,146 @@ namespace Utils::FileUtils
}
struct file_body {
char *content;
int size = 0; // doesn't include null termination (same as strlen)
char* content;
uint64 size = 0; // doesn't include null termination (same as strlen)
};
file_body read_file(const char *filename)
inline uint64
file_size(const char* filename)
{
file_body file = {0};
#ifdef _WIN32
HANDLE fp = CreateFileA((LPCSTR) filename,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
FILE *fp = fopen(filename, "rb");
if (!fp) {
return file;
if (fp == INVALID_HANDLE_VALUE) {
return 0;
}
fseek(fp, 0, SEEK_END);
file.size = ftell(fp);
fseek(fp, 0, SEEK_SET);
file.content = (char *) malloc((file.size + 1) * sizeof(char));
if (!file.content) {
fprintf(stderr, "CRITICAL: malloc failed");
return file;
LARGE_INTEGER size;
if (!GetFileSizeEx(fp, &size)) {
CloseHandle(fp);
}
fread(file.content, file.size, 1, fp);
file.content[file.size] = 0;
CloseHandle(fp);
fclose(fp);
return size.QuadPart;
#endif
}
return file;
inline void
file_read(const char* filename, file_body* file)
{
#ifdef _WIN32
HANDLE fp = CreateFileA((LPCSTR) filename,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fp == INVALID_HANDLE_VALUE) {
file->size = 0;
return;
}
LARGE_INTEGER size;
if (!GetFileSizeEx(fp, &size)) {
CloseHandle(fp);
file->content = NULL;
return;
}
DWORD bytes;
ASSERT_SIMPLE(size.QuadPart < MAX_INT32);
if (!ReadFile(fp, file->content, (uint32) size.QuadPart, &bytes, NULL)) {
CloseHandle(fp);
file->content = NULL;
return;
}
CloseHandle(fp);
file->content[bytes] = '\0';
file->size = size.QuadPart;
#endif
}
inline bool
file_write(const char* filename, const file_body* file)
{
#ifdef _WIN32
HANDLE fp = CreateFileA((LPCSTR) filename,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fp == INVALID_HANDLE_VALUE) {
return false;
}
DWORD bytes;
DWORD length = (DWORD) file->size;
ASSERT_SIMPLE(file->size < MAX_INT32);
if (!WriteFile(fp, file->content, length, &bytes, NULL)) {
CloseHandle(fp);
return false;
}
CloseHandle(fp);
#endif
return true;
}
inline void
file_copy(const char* src, const char* dst)
{
#ifdef _WIN32
CopyFileA((LPCSTR) src, (LPCSTR) dst, false);
#endif
}
inline bool
file_append(const char* filename, const file_body* file)
{
#ifdef _WIN32
HANDLE fp = CreateFileA((LPCSTR) filename,
FILE_APPEND_DATA,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fp == INVALID_HANDLE_VALUE) {
return false;
}
DWORD bytes;
DWORD length = (DWORD) file->size;
ASSERT_SIMPLE(file->size < MAX_INT32);
if (!WriteFile(fp, file->content, length, &bytes, NULL)) {
CloseHandle(fp);
return false;
}
CloseHandle(fp);
return true;
#endif
return true;
}
} // namespace Utils::FileUtils

View File

@ -10,15 +10,39 @@
#ifndef UTILS_MATH_UTILS_H
#define UTILS_MATH_UTILS_H
#include <stdio.h>
#include "../Stdlib/Intrinsics.h"
#define OMS_PI 3.14159265358979323846f
#define OMS_PI_OVER_TWO OMS_PI / 2.0f
#define OMS_TWO_PI 2 * OMS_PI
#define oms_max(a, b) ((a) > (b) ? (a) : (b))
#define oms_min(a, b) ((a) > (b) ? (b) : (a))
#define oms_abs(a) ((a) > 0 ? (a) : -(a))
#define oms_deg2rad(angle) ((angle) * OMS_PI / 180.0)
#define oms_rad2deg(angle) ((angle) * 180.0 / OMS_PI)
#define round_to_nearest(a, b) (((a) + ((b) - 1)) & ~((b) - 1))
#define OMS_MAX(a, b) ((a) > (b) ? (a) : (b))
#define OMS_MIN(a, b) ((a) > (b) ? (b) : (a))
#define OMS_ABS(a) ((a) > 0 ? (a) : -(a))
#define OMS_DEG2RAD(angle) ((angle) * OMS_PI / 180.0f)
#define OMS_RAD2DEG(angle) ((angle) * 180.0f / OMS_PI)
#define ROUND_TO_NEAREST(a, b) (((a) + ((b) - 1)) & ~((b) - 1))
// @todo implement table based sine wave + approximation if necessary
// [-PI/2, PI/2]
inline
float sin_approx_pih_pih(float x)
{
return x - (x * x * x / 6.0f);
}
inline
float sinf_approx(float x)
{
x = x - OMS_TWO_PI * Stdlib::Intrinsics::floor((x + OMS_PI) / OMS_TWO_PI);
if (x > OMS_PI_OVER_TWO) {
x = OMS_PI - x;
} else if (x < -OMS_PI_OVER_TWO) {
x = -OMS_PI - x;
}
return x - (x * x * x / 6.0f);
}
#endif

View File

@ -43,7 +43,11 @@ namespace Utils::StringUtils
size_t c = 0;
while (*haystack && c < i + match * (newLength - oldLength)) {
if (strstr(haystack, needle) == haystack) {
strcpy(&result[c], (char *) replace);
#ifdef _WIN32
strcpy_s(&result[c], newLength * sizeof(char), (char *) replace);
#else
strcpy(&result[c], (char *) replace);
#endif
c += newLength;
haystack += oldLength;
@ -130,6 +134,23 @@ namespace Utils::StringUtils
return i;
}
inline void
str_concat(
const char* src1, size_t src1_length,
const char* src2, size_t src2_length,
char* dst
) {
for (size_t i = 0; i < src1_length; ++i) {
*dst++ = *src1++;
}
for (size_t i = 0; i < src2_length; ++i) {
*dst++ = *src2++;
}
*dst++ = '\0';
}
// @todo Implement delim as const char* (also allow \0 length)
inline char *str_combine(const char **str, size_t size, const char delim)
{
@ -150,11 +171,20 @@ namespace Utils::StringUtils
return NULL;
}
strcpy(result, str[0]);
#ifdef _WIN32
strcpy_s(result, (strlen(str[0]) + 1) * sizeof(char), str[0]);
#else
strcpy(result, str[0]);
#endif
for (size_t i = 0; i < size; ++i) {
#ifdef _WIN32
strcat_s(result, total_size, &delim);
strcat_s(result, total_size, str[i]);
#else
strcat(result, &delim);
strcat(result, str[i]);
#endif
}
return result;
@ -194,7 +224,7 @@ namespace Utils::StringUtils
for (j = 1; j <= toSize; ++j) {
dm[i * fromSize + j] = strcmp(from[i - 1], to[j - 1]) == 0
? dm[(i - 1) * fromSize + (j - 1)] + 1
: oms_max(dm[(i - 1) * fromSize + j], dm[i * fromSize + (j - 1)]);
: OMS_MAX(dm[(i - 1) * fromSize + j], dm[i * fromSize + (j - 1)]);
}
}

View File

@ -88,7 +88,7 @@ namespace Test {
#define ASSERT_EQUALS_WITH_DELTA(a, b, delta, t1, t2) \
({ \
if (oms_abs((a) - (b)) <= (delta)) { \
if (OMS_ABS((a) - (b)) <= (delta)) { \
printf("."); \
} else { \
printf("\033[31m[F]\033[0m"); \