re-structure

This commit is contained in:
Dennis Eichhorn 2024-07-12 15:26:57 +02:00
parent 0374a0e3fa
commit 9506c2fa9c
134 changed files with 11265 additions and 0 deletions

36
audio/AudioSetting.h Normal file
View File

@ -0,0 +1,36 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_AUDIO_SETTING_H
#define TOS_AUDIO_SETTING_H
#include "../stdlib/Types.h"
#define SOUND_API_DIRECT_SOUND 0
#define SOUND_API_XAUDIO2 1
struct AudioSetting {
uint32 sample_rate;
uint32 sample_size;
uint32 sample_index;
uint32 latency;
int16 volume;
uint32 buffer_size;
// Actual samples inside the buffer
// The buffer could be larger than the data to output
uint32 sample_buffer_size;
int16* buffer;
bool is_playing = false;
byte type = SOUND_API_DIRECT_SOUND;
};
#endif

104
auth/Auth.h Normal file
View File

@ -0,0 +1,104 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_AUTH_H
#define TOS_AUTH_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../lib/curl/include/curl/curl.h"
#include "../utils/MathUtils.h"
#define MAX_AUTH_POST_LENGTH 1024
#define MAX_AUTH_RESPONSE_LENGTH 1024
/**
* Parse response data
*
* @param char* data Response data
* @param size_t size Response size
* @param count count Response count
* @param void* arg Parsed data
*
* @return size_t Parsed data size
*/
size_t write_function(char* data, size_t size, size_t count, void* arg)
{
char* dst = (char *)arg;
size_t length = strlen(dst);
// Ensure we do not exceed the buffer length
size_t available_space = OMS_MIN(MAX_AUTH_RESPONSE_LENGTH, strlen(dst));
if (available_space > 0) {
strncat(dst, data, available_space - 1);
}
dst[available_space - 1] = '\0';
return length;
}
/**
* Get access token from remote source
*
* @param const char* url Access url
* @param char* access_token Url response (hopefully access token)
* @param const char* username Username for authentication
* @param const char* identity_token Identity token (e.g. password)
*
* @return int 0 for failure, > 0 for success
*/
int get_access_token(
const char* url,
char* access_token,
const char* username,
const char* identity_token
)
{
CURL *curl = curl_easy_init();
if (!curl) {
return 0;
}
char post[MAX_AUTH_POST_LENGTH] = {};
char response[MAX_AUTH_RESPONSE_LENGTH] = {};
uint32 http_code = 0;
snprintf(
post,
MAX_AUTH_POST_LENGTH,
"username=%s&identity_token=%s",
username,
identity_token
);
#ifdef _WIN32
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
#endif
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_function);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, response);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post);
CURLcode code = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
curl_easy_cleanup(curl);
if (code == CURLE_OK && http_code == 200) {
strncpy(access_token, response, strlen(response));
return 1;
}
return 0;
}
#endif

73
compression/CRC.h Normal file
View File

@ -0,0 +1,73 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_COMPRESSION_CRC_H
#define TOS_COMPRESSION_CRC_H
#include "../stdlib/Types.h"
uint32 crc_table[256] =
{
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
};
uint32 calculate_crc32_checksum(uint8 *p, uint32 length)
{
uint32 crc = 0xFFFFFFFF;
while (length-- != 0) {
crc = crc_table[((uint8) crc ^ *(p++))] ^ (crc >> 8);
}
// return (~crc); also works
return (crc ^ 0xFFFFFFFF);
}
void fill_crc32_table(uint32 *table){
uint8 index = 0,z;
do {
table[index] = index;
for(z = 8; z; z--) {
table[index] = (table[index] & 1)
? (table[index] >> 1) ^ 0xEDB88320
: table[index] >> 1;
}
} while(++index);
}
#endif

104
compression/LZP.h Normal file
View File

@ -0,0 +1,104 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_COMPRESSION_LZP_H
#define TOS_COMPRESSION_LZP_H
#include <stdio.h>
#include "../stdlib/Types.h"
uint32 encode_lzp(const byte* in, size_t length, byte* out)
{
byte buf[9];
byte table[1 << 16] = {0};
uint16 hash = 0;
int32 i, j;
byte mask, c;
uint32 in_pos = 0, out_pos = 0;
while(true) {
j = 1;
mask = 0;
for (i = 0; i < 8; ++i) {
if (in_pos == length) {
break;
}
c = in[in_pos++];
if (c == table[hash]) {
mask |= 1 << i;
} else {
table[hash] = c;
buf[j++] = c;
}
hash = (hash << 4) ^ c;
}
if (i > 0) {
buf[0] = mask;
for (i = 0; i < j; ++i) {
out[out_pos++] = buf[i];
}
}
if (in_pos == length) {
break;
}
}
return out_pos;
}
uint32 decode_lzp(const byte* in, size_t length, byte* out)
{
byte buf[8];
byte table[1 << 16] = {0};
uint16 hash = 0;
int i, j;
byte mask, c;
uint32 in_pos = 0, out_pos = 0;
while (true) {
j = 0;
if (in_pos == length) {
break;
}
mask = in[in_pos++];
for (i = 0; i < 8; ++i) {
if ((mask & (1 << i)) != 0) {
c = table[hash];
} else {
if (in_pos == length) {
break;
}
c = in[in_pos++];
table[hash] = c;
}
buf[j++] = c;
hash = (hash << 4) ^ c;
}
if (j > 0) {
for (i = 0; i < j; ++i) {
out[out_pos++] = buf[i];
}
}
}
return out_pos;
}
#endif

78
database/Database.h Normal file
View File

@ -0,0 +1,78 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_DATABASE
#define TOS_DATABASE
#include "../stdlib/Types.h"
#include "../lib/sqlite/src/sqlite3.h"
#include "DatabaseType.h"
#include "DatabaseConnection.h"
inline
int db_open_sqlite(DatabaseConnection* con)
{
int rc;
rc = sqlite3_open(con->host, &con->db_sqlite);
if (rc) {
return rc;
}
return 0;
}
inline
int db_open(DatabaseConnection* con)
{
switch (con->type) {
case DB_TYPE_SQLITE: {
return db_open_sqlite(con);
}
case DB_TYPE_MARIA: {
return 0;
}
case DB_TYPE_PSQL: {
return 0;
}
case DB_TYPE_MSSQL: {
return 0;
}
}
return 0;
}
inline
void db_close_sqlite(DatabaseConnection* con)
{
sqlite3_close(con->db_sqlite);
}
inline
void db_close(DatabaseConnection* con)
{
switch (con->type) {
case DB_TYPE_SQLITE: {
db_close_sqlite(con);
return;
}
case DB_TYPE_MARIA: {
return;
}
case DB_TYPE_PSQL: {
return;
}
case DB_TYPE_MSSQL: {
return;
}
}
}
#endif

View File

@ -0,0 +1,29 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_DATABASE_CONNECTION
#define TOS_DATABASE_CONNECTION
#include "../stdlib/Types.h"
#include "../lib/sqlite/src/sqlite3.h"
#include "DatabaseType.h"
struct DatabaseConnection {
union {
sqlite3* db_sqlite;
sqlite3* db_pgsql;
};
DatabaseType type;
uint16 port;
char* host;
char* name; // databse name
};
#endif

19
database/DatabaseType.h Normal file
View File

@ -0,0 +1,19 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_DATABASE_TYPE
#define TOS_DATABASE_TYPE
enum DatabaseType {
DB_TYPE_SQLITE,
DB_TYPE_MARIA,
DB_TYPE_PSQL,
DB_TYPE_MSSQL
};
#endif

1
font/font_characters.txt Normal file
View File

@ -0,0 +1 @@
 ︎☺︎☻︎♥︎♦︎♣︎♠︎•︎◘︎○︎◙︎♂︎♀︎♪︎♫︎☼︎►︎◄︎↕︎‼︎¶︎§︎▬︎↨︎↑︎↓︎→︎←︎∟︎↔︎▲︎▼︎ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{︎¦︎}~︎⌂︎Ç︎ü︎é︎â︎ä︎à︎å︎ç︎ê︎ë︎è︎ï︎î︎ì︎Ä︎Å︎É︎æ︎Æ︎ô︎ö︎ò︎û︎ù︎ÿ︎Ö︎Ü︎¢︎£︎¥︎₧︎ƒ︎á︎í︎ó︎ú︎ñ︎Ñ︎ª︎º︎¿︎⌐︎¬︎½︎¼︎¡︎«︎»︎░︎▒︎▓︎│︎┤︎╡︎╢︎╖︎╕︎╣︎║︎╗︎╝︎╜︎╛︎┐︎└︎┴︎┬︎├︎─︎┼︎╞︎╟︎╚︎╔︎╩︎╦︎╠︎═︎╬︎╧︎╨︎╤︎╥︎╙︎╘︎╒︎╓︎╫︎╪︎┘︎┌︎█︎▄︎▌︎▐︎▀︎α︎ß︎Γ︎π︎Σ︎σ︎µ︎τ︎Φ︎Θ︎Ω︎δ︎∞︎φ︎ε︎∩︎≡︎±︎≥︎≤︎⌠︎⌡︎÷︎≈︎°︎∙︎·︎√︎ⁿ︎²︎■︎□︎

View File

@ -0,0 +1,300 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_GPUAPI_DIRECT3D_UTILS
#define TOS_GPUAPI_DIRECT3D_UTILS
#include <windows.h>
#include <wrl.h>
#include <dxgi1_6.h>
#include "../../lib/directx/d3d12.h"
#include "../../lib/directx/d3dx12.h"
#include "../../stdlib/Types.h"
#define FRAME_COUNT 2
struct Window {
bool is_fullscreen;
int32 width;
int32 height;
char name[32];
int32 x;
int32 y;
HWND hwnd;
// @todo move this out of here to a separate gpuapi struct (same with opengl)
Microsoft::WRL::ComPtr<IDXGISwapChain3> m_swapChain;
Microsoft::WRL::ComPtr<ID3D12Device> device;
Microsoft::WRL::ComPtr<ID3D12Resource> m_renderTargets[FRAME_COUNT];
Microsoft::WRL::ComPtr<ID3D12CommandAllocator> m_commandAllocator;
Microsoft::WRL::ComPtr<ID3D12CommandQueue> m_commandQueue;
Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> m_rtvHeap;
Microsoft::WRL::ComPtr<ID3D12PipelineState> m_pipelineState;
Microsoft::WRL::ComPtr<ID3D12GraphicsCommandList> m_commandList;
Microsoft::WRL::ComPtr<ID3D12Fence> m_fence;
UINT m_rtvDescriptorSize;
UINT m_frameIndex;
HANDLE m_fenceEvent;
UINT64 m_fenceValue;
};
void window_create(Window* window, void* proc)
{
WNDPROC wndproc = (WNDPROC) proc;
WNDCLASSEX wc = {};
HINSTANCE hinstance = GetModuleHandle(0);
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_OWNDC;
wc.lpfnWndProc = wndproc;
wc.hInstance = hinstance;
wc.lpszClassName = (LPCWSTR) window->name;
RegisterClassEx(&wc);
if (window->is_fullscreen) {
window->width = GetSystemMetrics(SM_CXSCREEN);
window->height = GetSystemMetrics(SM_CYSCREEN);
DEVMODE screen_settings;
memset(&screen_settings, 0, sizeof(screen_settings));
screen_settings.dmSize = sizeof(screen_settings);
screen_settings.dmPelsWidth = (unsigned long) window->width;
screen_settings.dmPelsHeight = (unsigned long) window->height;
screen_settings.dmBitsPerPel = 32;
screen_settings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
ChangeDisplaySettings(&screen_settings, CDS_FULLSCREEN);
window->x = 0;
window->y = 0;
}
window->hwnd = CreateWindowEx((DWORD) NULL,
wc.lpszClassName, NULL,
WS_OVERLAPPEDWINDOW,
window->x, window->y,
window->width,
window->height,
NULL, NULL, hinstance, window
);
//SetWindowLongA(window->hwnd, GWL_STYLE, 0);
}
void window_open(const Window* window)
{
ShowWindow(window->hwnd, SW_SHOW);
SetForegroundWindow(window->hwnd);
SetFocus(window->hwnd);
ShowCursor(false);
UpdateWindow(window->hwnd);
}
void window_close(Window* window)
{
CloseWindow(window->hwnd);
}
bool is_directx_12_supported()
{
Microsoft::WRL::ComPtr<IDXGIFactory6> factory;
HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&factory));
if (FAILED(hr)) {
return false;
}
Microsoft::WRL::ComPtr<IDXGIAdapter1> adapter;
for (UINT adapterIndex = 0;
DXGI_ERROR_NOT_FOUND != factory->EnumAdapters1(adapterIndex, &adapter);
++adapterIndex)
{
DXGI_ADAPTER_DESC1 desc;
adapter->GetDesc1(&desc);
// Skip software adapters
if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
continue;
}
try {
if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) {
return true;
}
} catch (...) {
return false;
}
}
return false;
}
void find_hardware_adapter(
IDXGIFactory1* factory,
IDXGIAdapter1** adapter1,
bool use_high_performance_adapter = true
) {
*adapter1 = nullptr;
Microsoft::WRL::ComPtr<IDXGIAdapter1> adapter;
Microsoft::WRL::ComPtr<IDXGIFactory6> factory6;
if (SUCCEEDED(factory->QueryInterface(IID_PPV_ARGS(&factory6)))) {
for (
UINT adapterIndex = 0;
SUCCEEDED(factory6->EnumAdapterByGpuPreference(
adapterIndex,
use_high_performance_adapter == true ? DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE : DXGI_GPU_PREFERENCE_UNSPECIFIED,
IID_PPV_ARGS(&adapter)));
++adapterIndex)
{
DXGI_ADAPTER_DESC1 desc;
adapter->GetDesc1(&desc);
if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
// Don't select the Basic Render Driver adapter.
continue;
}
// Check to see whether the adapter supports Direct3D 12, but don't create the
// actual device yet.
if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) {
break;
}
}
}
if(adapter.Get() == nullptr) {
for (UINT adapterIndex = 0; SUCCEEDED(factory->EnumAdapters1(adapterIndex, &adapter)); ++adapterIndex) {
DXGI_ADAPTER_DESC1 desc;
adapter->GetDesc1(&desc);
if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
// Don't select the Basic Render Driver adapter.
continue;
}
// Check to see whether the adapter supports Direct3D 12, but don't create the
// actual device yet.
if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) {
break;
}
}
}
*adapter1 = adapter.Detach();
}
void load_pipeline(Window* window)
{
uint32 factory_flags = 0;
Microsoft::WRL::ComPtr<IDXGIFactory4> factory;
CreateDXGIFactory2(factory_flags, IID_PPV_ARGS(&factory));
Microsoft::WRL::ComPtr<IDXGIAdapter1> hardware_adapter;
find_hardware_adapter(factory.Get(), &hardware_adapter);
D3D12CreateDevice(
hardware_adapter.Get(),
D3D_FEATURE_LEVEL_11_0,
IID_PPV_ARGS(&window->device)
);
// Describe and create the command queue.
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
window->device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&window->m_commandQueue));
// Describe and create the swap chain.
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
swapChainDesc.BufferCount = FRAME_COUNT;
swapChainDesc.Width = window->width;
swapChainDesc.Height = window->height;
swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapChainDesc.SampleDesc.Count = 1;
Microsoft::WRL::ComPtr<IDXGISwapChain1> swapChain;
factory->CreateSwapChainForHwnd(
window->m_commandQueue.Get(), // Swap chain needs the queue so that it can force a flush on it.
window->hwnd,
&swapChainDesc,
nullptr,
nullptr,
&swapChain
);
// This sample does not support fullscreen transitions.
factory->MakeWindowAssociation(window->hwnd, DXGI_MWA_NO_ALT_ENTER);
swapChain.As(&window->m_swapChain);
window->m_frameIndex = window->m_swapChain->GetCurrentBackBufferIndex();
// Create descriptor heaps.
{
// Describe and create a render target view (RTV) descriptor heap.
D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
rtvHeapDesc.NumDescriptors = FRAME_COUNT;
rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
window->device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&window->m_rtvHeap));
window->m_rtvDescriptorSize = window->device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
}
// Create frame resources.
{
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(window->m_rtvHeap->GetCPUDescriptorHandleForHeapStart());
// Create a RTV for each frame.
for (UINT n = 0; n < FRAME_COUNT; n++)
{
window->m_swapChain->GetBuffer(n, IID_PPV_ARGS(&window->m_renderTargets[n]));
window->device->CreateRenderTargetView(window->m_renderTargets[n].Get(), nullptr, rtvHandle);
rtvHandle.Offset(1, window->m_rtvDescriptorSize);
}
}
window->device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&window->m_commandAllocator));
}
void load_assets(Window* window)
{
// Create the command list.
window->device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, window->m_commandAllocator.Get(), nullptr, IID_PPV_ARGS(&window->m_commandList));
// Command lists are created in the recording state, but there is nothing
// to record yet. The main loop expects it to be closed, so close it now.
window->m_commandList->Close();
// Create synchronization objects.
{
window->device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&window->m_fence));
window->m_fenceValue = 1;
// Create an event handle to use for frame synchronization.
window->m_fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
if (window->m_fenceEvent == nullptr) {
HRESULT_FROM_WIN32(GetLastError());
}
}
}
#endif

319
gpuapi/opengl/UtilsOpengl.h Normal file
View File

@ -0,0 +1,319 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_GPUAPI_OPENGL_UTILS_H
#define TOS_GPUAPI_OPENGL_UTILS_H
#include "../../stdlib/Types.h"
#include "../../utils/RingMemory.h"
#include "../../models/Attrib.h"
#include "../../models/Texture.h"
#include "../../lib/opengl/glew/include/GL/glew.h"
#include "../../lib/opengl/glfw/include/glfw3.h"
#if GLFW_EXPOSE_NATIVE_WIN32
#include "../../lib/opengl/glfw/include/glfw3native.h"
#endif
#ifdef _WIN32
#include <windows.h>
#include "../../platform/win32/UtilsWin32.h"
#endif
struct Window {
bool is_fullscreen;
int32 width;
int32 height;
char name[32];
int32 x;
int32 y;
GLFWwindow* hwnd_lib;
#ifdef _WIN32
HWND hwnd;
#endif
};
inline
void window_create(Window* window, void*)
{
//GLFWmonitor *monitor = glfwGetPrimaryMonitor();
window->hwnd_lib = glfwCreateWindow(
window->width,
window->height,
window->name,
NULL,
NULL
);
glfwSetInputMode(window->hwnd_lib, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwMakeContextCurrent(window->hwnd_lib);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
#if GLFW_EXPOSE_NATIVE_WIN32
window->hwnd = glfwGetWin32Window(window->hwnd_lib);
#endif
}
inline
void window_open(Window* window)
{
glfwMakeContextCurrent(window->hwnd_lib);
glViewport(window->x, window->y, window->width, window->height);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
}
inline
void window_close(Window* window)
{
glfwWindowShouldClose(window->hwnd_lib);
}
inline
uint32 get_texture_data_type(uint32 texture_data_type)
{
switch (texture_data_type) {
case TEXTURE_DATA_TYPE_2D: {
return GL_TEXTURE_2D;
}
case TEXTURE_DATA_TYPE_1D: {
return GL_TEXTURE_1D;
}
case TEXTURE_DATA_TYPE_3D: {
return GL_TEXTURE_3D;
}
case TEXTURE_DATA_TYPE_1D_ARRAY: {
return GL_TEXTURE_1D_ARRAY;
}
case TEXTURE_DATA_TYPE_2D_ARRAY: {
return GL_TEXTURE_2D_ARRAY;
}
case TEXTURE_DATA_TYPE_2D_MULTISAMPLED: {
return GL_TEXTURE_2D_MULTISAMPLE;
}
case TEXTURE_DATA_TYPE_2D_MULTISAMPLED_ARRAY: {
return GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
}
default: {
return GL_TEXTURE_2D;
}
}
}
inline
void prepare_texture(TextureFile* texture, uint32 texture_unit)
{
if (texture->id) {
return;
}
uint32 texture_data_type = get_texture_data_type(texture->texture_data_type);
glGenTextures(1, (GLuint *) &texture->id);
glActiveTexture(GL_TEXTURE0 + texture_unit);
glBindTexture(texture_data_type, (GLuint) texture->id);
}
inline
void load_texture_to_gpu(const TextureFile* texture)
{
uint32 texture_data_type = get_texture_data_type(texture->texture_data_type);
glTexImage2D(
texture_data_type, 0, GL_RGBA,
texture->image.width, texture->image.height,
0, GL_RGBA, GL_UNSIGNED_BYTE,
texture->image.pixels
);
}
GLuint make_shader(GLenum type, const char *source, RingMemory* ring)
{
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &source, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) {
GLint length;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
GLchar *info = (GLchar *) ring_get_memory(ring, length * sizeof(GLchar));
glGetShaderInfoLog(shader, length, NULL, info);
// @todo use global logger
fprintf(stderr, "glCompileShader failed:\n%s\n", info);
}
return shader;
}
GLuint load_shader(GLenum type, const char *path, RingMemory* ring) {
uint64 temp = ring->pos;
// @bug potential bug for shaders > 4 mb
file_body file;
file.content = ring_get_memory(ring, MEGABYTE * 4);
file_read(path, &file);
GLuint result = make_shader(type, (const char *) file.content, ring);
// 4 mb of memory reservation is a lot and since we immediately can dispose of it
// we can also reset our ring memory position
ring->pos = temp;
return result;
}
GLuint make_program(GLuint shader1, GLuint shader2, RingMemory* ring) {
GLuint program = glCreateProgram();
glAttachShader(program, shader1);
glAttachShader(program, shader2);
glLinkProgram(program);
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
GLint length;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
GLchar *info = (GLchar *) ring_get_memory(ring, length * sizeof(GLchar));
glGetProgramInfoLog(program, length, NULL, info);
// @todo use global logger
fprintf(stderr, "glLinkProgram failed: %s\n", info);
}
glDetachShader(program, shader1);
glDetachShader(program, shader2);
glDeleteShader(shader1);
glDeleteShader(shader2);
return program;
}
GLuint load_program(const char *path1, const char *path2, RingMemory* ring) {
GLuint shader1 = load_shader(GL_VERTEX_SHADER, path1, ring);
GLuint shader2 = load_shader(GL_FRAGMENT_SHADER, path2, ring);
GLuint program = make_program(shader1, shader2, ring);
return program;
}
inline
void activate_texture(TextureFile* texture, uint32 texture_unit)
{
}
void draw_triangles_3d(Attrib *attrib, GLuint buffer, int count) {
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glEnableVertexAttribArray(attrib->position);
glEnableVertexAttribArray(attrib->normal);
glEnableVertexAttribArray(attrib->uv);
glVertexAttribPointer(attrib->position, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8, 0);
glVertexAttribPointer(attrib->normal, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8, (GLvoid *)(sizeof(GLfloat) * 3));
glVertexAttribPointer(attrib->uv, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8, (GLvoid *)(sizeof(GLfloat) * 6));
glDrawArrays(GL_TRIANGLES, 0, count);
glDisableVertexAttribArray(attrib->position);
glDisableVertexAttribArray(attrib->normal);
glDisableVertexAttribArray(attrib->uv);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void draw_triangles_2d(Attrib *attrib, GLuint buffer, size_t count) {
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glEnableVertexAttribArray(attrib->position);
glEnableVertexAttribArray(attrib->uv);
glVertexAttribPointer(attrib->position, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, 0);
glVertexAttribPointer(attrib->uv, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, (GLvoid *)(sizeof(GLfloat) * 2));
glDrawArrays(GL_TRIANGLES, 0, (GLsizei) count);
glDisableVertexAttribArray(attrib->position);
glDisableVertexAttribArray(attrib->uv);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
inline
void draw_text(Attrib *attrib, GLuint buffer, size_t length)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
draw_triangles_2d(attrib, buffer, length * 6);
glDisable(GL_BLEND);
}
GLuint gen_text_buffer(float x, float y, float n, const char *text) {
size_t length = strlen(text);
GLfloat *data = NULL; //malloc_faces(4, length); // sizeof(GLfloat) * 6 * 4 * length
for (int i = 0; i < length; i++) {
make_character(data + i * 24, x, y, n / 2, n, text[i]);
x += n;
}
return 0; //gen_faces(4, length, data);
}
inline
void render_text(Attrib *attrib, int justify, float x, float y, float n, const char *text)
{
float matrix[16];
//set_matrix_2d(matrix, g->width, g->height);
glUseProgram(attrib->program);
glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix);
glUniform1i(attrib->sampler, 1);
glUniform1i(attrib->extra1, 0);
size_t length = strlen(text);
x -= n * justify * (length - 1) / 2;
GLuint buffer = gen_text_buffer(x, y, n, text);
draw_text(attrib, buffer, length);
glDeleteBuffers(1, &buffer);
}
inline
int calculate_face_size(int components, int faces)
{
return sizeof(GLfloat) * 6 * components * faces;
}
// generates faces
// data is no longer needed after this
inline
GLuint gpuapi_buffer_generate(int size, GLfloat *data)
{
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
return buffer;
}
inline
void gpuapi_buffer_delete(GLuint buffer)
{
glDeleteBuffers(1, &buffer);
}
#endif

291
image/Bitmap.h Normal file
View File

@ -0,0 +1,291 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_IMAGE_BITMAP_H
#define TOS_IMAGE_BITMAP_H
#include <stdio.h>
#include <string.h>
#include "../stdlib/Types.h"
#include "../utils/Utils.h"
#include "../utils/EndianUtils.h"
#include "../utils/MathUtils.h"
#include "Image.h"
// See: https://en.wikipedia.org/wiki/BMP_file_format
// IMPORTANT: Remember that we are not using packing for the headers
// Because of that the struct size is different from the actual header size in the file
// This means we have to manually asign the data to the headers
#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;
// Structure:
// 1. pixels stored in rows
// 2. rows are padded in multiples of 4 bytes
// 3. rows start from the bottom (unless the height is negative)
// 4. pixel data is stored in ABGR (graphics libraries usually need BGRA or RGBA)
byte* pixels;
uint32 size;
byte* data;
};
void generate_default_bitmap_references(const file_body* file, Bitmap* bitmap)
{
bitmap->size = file->size;
bitmap->data = file->content;
// Fill header
bitmap->header.identifier[0] = *(file->content + 0);
bitmap->header.identifier[1] = *(file->content + 1);
bitmap->header.size = SWAP_ENDIAN_LITTLE(*((uint32 *) (file->content + 2)));
bitmap->header.app_data[0] = *(file->content + 6);
bitmap->header.app_data[1] = *(file->content + 7);
bitmap->header.app_data[2] = *(file->content + 8);
bitmap->header.app_data[3] = *(file->content + 9);
bitmap->header.offset = SWAP_ENDIAN_LITTLE(*((uint32 *) (file->content + 10)));
byte* dib_header_offset = file->content + BITMAP_HEADER_SIZE;
bitmap->dib_header_type = SWAP_ENDIAN_LITTLE(*((uint32 *) dib_header_offset));
byte* color_table_offset = file->content + BITMAP_HEADER_SIZE + bitmap->dib_header_type;
// Fill DIB header
switch (bitmap->dib_header_type) {
case DIB_BITMAP_TYPE_BITMAPCOREHEADER: {
bitmap->dib_header.size = SWAP_ENDIAN_LITTLE(*((uint32 *) (dib_header_offset)));
bitmap->dib_header.width = SWAP_ENDIAN_LITTLE(*((uint16 *) (dib_header_offset + 4)));
bitmap->dib_header.height = SWAP_ENDIAN_LITTLE(*((uint16 *) (dib_header_offset + 6)));
bitmap->dib_header.color_planes = SWAP_ENDIAN_LITTLE(*((uint16 *) (dib_header_offset + 8)));
bitmap->dib_header.bits_per_pixel = SWAP_ENDIAN_LITTLE(*((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 = SWAP_ENDIAN_LITTLE(*((uint32 *) (dib_header_offset)));
bitmap->dib_header.width = SWAP_ENDIAN_LITTLE(*((int32 *) (dib_header_offset + 4)));
bitmap->dib_header.height = SWAP_ENDIAN_LITTLE(*((int32 *) (dib_header_offset + 8)));
bitmap->dib_header.color_planes = SWAP_ENDIAN_LITTLE(*((uint16 *) (dib_header_offset + 12)));
bitmap->dib_header.bits_per_pixel = SWAP_ENDIAN_LITTLE(*((uint16 *) (dib_header_offset + 14)));
bitmap->dib_header.compression_method = SWAP_ENDIAN_LITTLE(*((uint32 *) (dib_header_offset + 16)));
bitmap->dib_header.raw_image_size = SWAP_ENDIAN_LITTLE(*((uint32 *) (dib_header_offset + 20)));
bitmap->dib_header.color_palette = SWAP_ENDIAN_LITTLE(*((uint32 *) (dib_header_offset + 32)));
bitmap->dib_header.important_colors = SWAP_ENDIAN_LITTLE(*((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 *) (file->content + bitmap->header.offset);
}
void generate_bmp_image(const file_body* src_data, Image* image)
{
Bitmap src = {};
generate_default_bitmap_references(src_data, &src);
image->width = src.dib_header.width;
image->height = src.dib_header.height;
image->length = image->width * image->height;
// rows are 4 bytes multiples in length
uint32 width = ROUND_TO_NEAREST(src.dib_header.width, 4);
uint32 pixel_bytes = src.dib_header.bits_per_pixel / 8;
if (image->order_pixels = IMAGE_PIXEL_ORDER_BGRA) {
memcpy((void *) image->pixels, src.pixels, image->length * pixel_bytes);
return;
}
byte alpha_offset = pixel_bytes == 3 ? 0 : 1;
uint32 row_pos1 = 0;
uint32 row_pos2 = 0;
for (uint32 y = 0; y < src.dib_header.height; ++y) {
for (uint32 x = 0; x < width; ++x) {
if (x >= image->width) {
// we don't care about the padding
continue;
}
row_pos1 = y * width * pixel_bytes;
row_pos2 = (src.dib_header.height - y - 1) * width * pixel_bytes;
// Invert byte order
for (uint32 i = 0; i < pixel_bytes - alpha_offset; ++i) {
image->pixels[row_pos1 + x * pixel_bytes + i] = src.pixels[row_pos2 + x * pixel_bytes + pixel_bytes - alpha_offset - i];
}
// Add alpha channel at end
if (alpha_offset > 0) {
image->pixels[row_pos1 + x * pixel_bytes + 3] = src.pixels[row_pos2 + x * pixel_bytes + pixel_bytes + 3];
}
}
}
}
#endif

32
image/Image.h Normal file
View File

@ -0,0 +1,32 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_IMAGE_H
#define TOS_IMAGE_H
#include "../stdlib/Types.h"
#define IMAGE_PIXEL_ORDER_RGBA 0
#define IMAGE_PIXEL_ORDER_BGRA 1
#define IMAGE_ROW_ORDER_TOP_TO_BOTTOM 0
#define IMAGE_ROW_ORDER_BOTTOM_TO_TOP 1
struct Image {
uint32 width;
uint32 height;
uint32 length;
bool has_alpha;
byte order_pixels; // RGBA vs BGRA
byte order_rows; // top-to-bottom vs bottom-to-top
uint32* pixels;
};
#endif

113
image/Tga.h Normal file
View File

@ -0,0 +1,113 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_IMAGE_TGA_H
#define TOS_IMAGE_TGA_H
#include <string.h>
#include "../stdlib/Types.h"
#include "../utils/Utils.h"
#include "../utils/EndianUtils.h"
#include "Image.h"
// See: https://en.wikipedia.org/wiki/Truevision_TGA
// IMPORTANT: Remember that we are not using packing for the headers
// Because of that the struct size is different from the actual header size in the file
// This means we have to manually asign the data to the headers
// Packed header size
#define TGA_HEADER_SIZE 18
struct TgaHeader {
byte id_length;
byte color_map_type;
byte image_type;
uint16 color_map_index;
uint16 color_map_length;
uint16 color_map_bits;
uint16 x_origin;
uint16 y_origin;
uint16 width;
uint16 height;
byte bits_per_pixel;
byte alpha_bits_per_pixel;
byte horizonal_ordering;
byte vertical_ordering;
};
struct Tga {
TgaHeader header;
byte* pixels;
uint32 size;
byte* data;
};
void generate_default_tga_references(const file_body* file, Tga* tga)
{
tga->header.id_length = file->content[0];
tga->header.color_map_type = file->content[1];
tga->header.image_type = file->content[2];
tga->header.color_map_index = SWAP_ENDIAN_LITTLE(*((uint16 *) (file->content + 3)));
tga->header.color_map_length = SWAP_ENDIAN_LITTLE(*((uint16 *) (file->content + 5)));
tga->header.color_map_bits = file->content[7];
tga->header.width = SWAP_ENDIAN_LITTLE(*((uint16 *) (file->content + 12)));
tga->header.height = SWAP_ENDIAN_LITTLE(*((uint16 *) (file->content + 14)));
tga->header.bits_per_pixel = file->content[16];
tga->header.alpha_bits_per_pixel = file->content[17] & 0x07;
tga->header.horizonal_ordering = file->content[17] & (1 << 4); // 0 = left-to-right
tga->header.vertical_ordering = (file->content[17] & (1 << 5)) == 0 ? 1 : 0; // 0 = top-to-bottom
tga->pixels = file->content + TGA_HEADER_SIZE
+ tga->header.id_length // can be 0
+ tga->header.color_map_length * (tga->header.color_map_bits / 8); // can be 0
}
void generate_tga_image(const file_body* src_data, Image* image)
{
Tga src = {};
generate_default_tga_references(src_data, &src);
image->width = src.header.width;
image->height = src.header.height;
image->length = image->width * image->height;
// @todo also handle bottom-top/top-bottom order here
uint32 pixel_bytes = src.header.bits_per_pixel / 8;
if (image->order_pixels == IMAGE_PIXEL_ORDER_BGRA) {
memcpy((void *) image->pixels, src.pixels, image->length * pixel_bytes);
return;
}
byte alpha_offset = pixel_bytes == 3 ? 0 : 1;
uint32 pixel_rgb_bytes = pixel_bytes - alpha_offset;
uint32 row_pos1;
uint32 row_pos2;
for (uint32 y = 0; y < src.header.height; ++y) {
for (uint32 x = 0; x < src.header.width; ++x) {
row_pos1 = y * image->width * pixel_bytes;
row_pos2 = src.header.vertical_ordering == 0
? y * image->width * pixel_bytes
: (image->height - y - 1) * image->width * pixel_bytes;
for (uint32 i = 0; i < pixel_rgb_bytes; ++i) {
image->pixels[row_pos1 + x * pixel_bytes + i] = src.pixels[row_pos2 + x * pixel_bytes + pixel_rgb_bytes - i];
}
// Add alpha channel at end
if (alpha_offset > 0) {
image->pixels[row_pos1 + x * pixel_bytes + 3] = src.pixels[row_pos2 + x * pixel_bytes + pixel_bytes + 3];
}
}
}
}
#endif

116
input/Input.h Normal file
View File

@ -0,0 +1,116 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_INPUT_H
#define TOS_INPUT_H
#define MAX_KEY_PRESSES 4
#define MIN_INPUT_DEVICES 2
#define INPUT_TYPE_MOUSE 0x01
#define INPUT_TYPE_KEYBOARD 0x02
#define INPUT_TYPE_OTHER 0x03
#define MIN_CONTROLLER_DEVICES 4
#include "../stdlib/Types.h"
#ifdef _WIN32
#include <windows.h>
#endif
struct InputState {
// Device
bool is_connected = false;
char name[256];
byte type = INPUT_TYPE_OTHER;
double time;
#ifdef _WIN32
// @todo maybe replace with id?!
// -> remove _WIN32 section
HANDLE handle_keyboard;
HANDLE handle_mouse;
#endif
// Keyboard
bool key_down = false;
bool key_up = false;
uint16 key = 0;
// After handling the keyboard state change the game loop should set this to false
bool state_change_keyboard = false;
// We only consider up to 4 pressed keys
// Depending on the keyboard you may only be able to detect a limited amount of key presses anyway
uint16 keys_down[MAX_KEY_PRESSES];
// Mouse
// After handling the mouse state change the game loop should set this to false
bool state_change_mouse = false;
uint32 x;
uint32 y;
uint32 x_last;
uint32 y_last;
bool mouse1_down = false;
bool mouse1_up = false;
bool mouse2_down = false;
bool mouse2_up = false;
bool mouse3_down = false;
bool mouse3_up = false;
bool mouse4_down = false;
bool mouse4_up = false;
bool mouse5_down = false;
bool mouse5_up = false;
int16 wheel_delta = 0;
uint32 raw_button = 0;
};
struct ControllerState {
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;
bool right = false;
bool start = false;
bool back = false;
bool shoulder_left = false;
bool shoulder_right = false;
byte trigger_left = 0;
byte trigger_right = 0;
bool button_a = false;
bool button_b = false;
bool button_x = false;
bool button_y = false;
int16 stickl_x = 0;
int16 stickl_y = 0;
bool stickl_press = false;
int16 stickr_x = 0;
int16 stickr_y = 0;
bool stickr_press = false;
};
#endif

19
math/Animation.h Normal file
View File

@ -0,0 +1,19 @@
/**
* Jingga
*
* @package Utils
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MATH_ANIMATION
#define TOS_MATH_ANIMATION
inline
float lerp_approx(float a, float b, float t)
{
return a + t * (b - a);
}
#endif

54
math/PerlinNoise.h Normal file
View File

@ -0,0 +1,54 @@
#include <stdlib.h>
#include <stdio.h>
#include "../stdlib/Intrinsics.h"
#include "Animation.h"
double fade(double t) {
return t * t * t * (t * (t * 6 - 15) + 10);
}
double grad(int hash, double x, double y, double z)
{
int h = hash & 15;
double u = h < 8 ? x : y;
double v = h < 4 ? y : h == 12 || h == 14 ? x : z;
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
}
// permutation = 512 elements
double noise(int* permutation, double x, double y, double z)
{
int X = (int) floor(x) & 255;
int Y = (int) floor(y) & 255;
int Z = (int) floor(z) & 255;
x -= floor(x);
y -= floor(y);
z -= floor(z);
double u = fade(x), v = fade(y), w = fade(z);
int A = permutation[X] + Y;
int AA = permutation[A] + Z;
int AB = permutation[A + 1] + Z;
int B = permutation[X + 1] + Y;
int BA = permutation[B] + Z;
int BB = permutation[B + 1] + Z;
return lerp_approx(
w,
lerp_approx(
v,
lerp_approx(u, grad(permutation[AA], x, y, z), grad(permutation[BA], x - 1, y, z)),
lerp_approx(u, grad(permutation[AB], x, y - 1, z), grad(permutation[BB], x - 1, y - 1, z))
),
lerp_approx(
v,
lerp_approx(u, grad(permutation[AA+1], x, y, z - 1), grad(permutation[BA + 1], x - 1, y, z - 1)),
lerp_approx(u, grad(permutation[AB+1], x, y - 1, z - 1), grad(permutation[BB+1], x - 1, y - 1, z - 1))
)
);
}

294
math/matrix/MatrixFloat32.h Normal file
View File

@ -0,0 +1,294 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MATH_MATRIX_FLOAT32_H
#define TOS_MATH_MATRIX_FLOAT32_H
#include "../../stdlib/Intrinsics.h"
#include "../../utils/MathUtils.h"
void mat3_identity_f32(float* matrix)
{
matrix[0] = 1.0f; matrix[1] = 0.0f; matrix[2] = 0.0f;
matrix[3] = 0.0f; matrix[4] = 1.0f; matrix[5] = 0.0f;
matrix[6] = 0.0f; matrix[7] = 0.0f; matrix[8] = 1.0f;
}
void mat3_identity_f32(__m128* matrix)
{
matrix[0] = _mm_set_ps(1.0f, 0.0f, 0.0f, 0.0f);
matrix[1] = _mm_set_ps(0.0f, 1.0f, 0.0f, 0.0f);
matrix[2] = _mm_set_ps(0.0f, 0.0f, 1.0f, 0.0f);
}
void mat4_identity_f32(float* matrix)
{
matrix[0] = 1.0f; matrix[1] = 0.0f; matrix[2] = 0.0f; matrix[3] = 0.0f;
matrix[4] = 0.0f; matrix[5] = 1.0f; matrix[6] = 0.0f; matrix[7] = 0.0f;
matrix[8] = 0.0f; matrix[9] = 0.0f; matrix[10] = 1.0f; matrix[11] = 0.0f;
matrix[12] = 0.0f; matrix[13] = 0.0f; matrix[14] = 0.0f; matrix[15] = 1.0f;
}
void mat4_identity_f32(__m128* matrix)
{
matrix[0] = _mm_set_ps(1.0f, 0.0f, 0.0f, 0.0f);
matrix[1] = _mm_set_ps(0.0f, 1.0f, 0.0f, 0.0f);
matrix[2] = _mm_set_ps(0.0f, 0.0f, 1.0f, 0.0f);
matrix[3] = _mm_set_ps(0.0f, 0.0f, 0.0f, 1.0f);
}
void mat_translate_f32(float* matrix, float dx, float dy, float dz)
{
matrix[0] = 1; matrix[1] = 0; matrix[2] = 0; matrix[3] = 0;
matrix[4] = 0; matrix[5] = 1; matrix[6] = 0; matrix[7] = 0;
matrix[8] = 0; matrix[9] = 0; matrix[10] = 1; matrix[11] = 0;
matrix[12] = dx; matrix[13] = dy; matrix[14] = dz; matrix[15] = 1;
}
// x, y, z need to be normalized
void mat3_rotate(float* matrix, float x, float y, float z, float angle)
{
float s = sinf_approx(angle);
float c = cosf_approx(angle);
float m = 1 - c;
float mx = m * x;
float my = m * y;
float mz = m * z;
float zs = z * s;
float xs = x * s;
float ys = y * s;
float mxy = mx * y;
float mzx = mz * x;
float myz = my * z;
matrix[0] = mx * x + c;
matrix[1] = mxy - zs;
matrix[2] = mzx + ys;
matrix[3] = 0;
matrix[4] = mxy + zs;
matrix[5] = my * y + c;
matrix[6] = myz - xs;
matrix[7] = 0;
matrix[8] = mzx - ys;
matrix[9] = myz + xs;
matrix[10] = mz * z + c;
matrix[11] = 0;
matrix[12] = 0;
matrix[13] = 0;
matrix[14] = 0;
matrix[15] = 1;
}
void mat3vec3_mult(const float* matrix, const float* vector, float* result)
{
result[0] = matrix[0] * vector[0] + matrix[1] * vector[1] + matrix[2] * vector[2];
result[1] = matrix[3] * vector[0] + matrix[4] * vector[1] + matrix[5] * vector[2];
result[2] = matrix[6] * vector[0] + matrix[7] * vector[1] + matrix[8] * vector[2];
/*
for (int i = 0; i < 3; ++i) {
result[i] = matrix[i * 3 + 0] * vector[0]
+ matrix[i * 3 + 1] * vector[1]
+ matrix[i * 3 + 2] * vector[2];
}
*/
}
void mat3vec3_mult_sse(const float* matrix, const float* vector, float* result)
{
__m128 vec = _mm_loadu_ps(vector);
vec = _mm_insert_ps(vec, _mm_setzero_ps(), 0x30); // vec[3] = 0
for (int i = 0; i < 3; ++i) {
__m128 row = _mm_loadu_ps(&matrix[i * 3]);
row = _mm_insert_ps(row, _mm_setzero_ps(), 0x30); // row[3] = 0
__m128 dot = _mm_dp_ps(row, vec, 0xF1);
result[i] = _mm_cvtss_f32(dot);
}
}
void mat3vec3_mult_sse(const __m128* matrix, const __m128* vector, float* result)
{
for (int i = 0; i < 3; ++i) {
__m128 dot = _mm_dp_ps(matrix[i], *vector, 0xF1);
result[i] = _mm_cvtss_f32(dot);
}
}
void mat3vec3_mult_sse(const __m128* matrix, const __m128* vector, __m128* result)
{
for (int i = 0; i < 4; ++i) {
result[i] = _mm_dp_ps(matrix[i], *vector, 0xF1);
}
}
void mat4vec4_mult(const float* matrix, const float* vector, float* result)
{
result[0] = matrix[0] * vector[0] + matrix[1] * vector[1] + matrix[2] * vector[2] + matrix[3] * vector[3];
result[1] = matrix[4] * vector[0] + matrix[5] * vector[1] + matrix[6] * vector[2] + matrix[7] * vector[3];
result[2] = matrix[8] * vector[0] + matrix[9] * vector[1] + matrix[10] * vector[2] + matrix[11] * vector[3];
result[3] = matrix[12] * vector[0] + matrix[13] * vector[1] + matrix[14] * vector[2] + matrix[15] * vector[3];
/*
for (int i = 0; i < 4; ++i) {
result[i] = matrix[i * 4 + 0] * vector[0]
+ matrix[i * 4 + 1] * vector[1]
+ matrix[i * 4 + 2] * vector[2]
+ matrix[i * 4 + 3] * vector[3];
}
*/
}
void mat4vec4_mult_sse(const float* matrix, const float* vector, float* result)
{
__m128 vec = _mm_loadu_ps(vector);
for (int i = 0; i < 4; ++i) {
__m128 row = _mm_loadu_ps(&matrix[i * 4]);
__m128 dot = _mm_dp_ps(row, vec, 0xF1);
result[i] = _mm_cvtss_f32(dot);
}
}
void mat4vec4_mult_sse(const __m128* matrix, const __m128* vector, float* result)
{
for (int i = 0; i < 4; ++i) {
__m128 dot = _mm_dp_ps(matrix[i], *vector, 0xF1);
result[i] = _mm_cvtss_f32(dot);
}
}
void mat4vec4_mult_sse(const __m128* matrix, const __m128* vector, __m128* result)
{
for (int i = 0; i < 4; ++i) {
result[i] = _mm_dp_ps(matrix[i], *vector, 0xF1);
}
}
// @question Consider to replace with 1d array
void frustum_planes(float planes[6][4], int radius, float *matrix) {
// @todo make this a setting
float znear = 0.125;
float zfar = radius * 32 + 64;
float *m = matrix;
planes[0][0] = m[3] + m[0];
planes[0][1] = m[7] + m[4];
planes[0][2] = m[11] + m[8];
planes[0][3] = m[15] + m[12];
planes[1][0] = m[3] - m[0];
planes[1][1] = m[7] - m[4];
planes[1][2] = m[11] - m[8];
planes[1][3] = m[15] - m[12];
planes[2][0] = m[3] + m[1];
planes[2][1] = m[7] + m[5];
planes[2][2] = m[11] + m[9];
planes[2][3] = m[15] + m[13];
planes[3][0] = m[3] - m[1];
planes[3][1] = m[7] - m[5];
planes[3][2] = m[11] - m[9];
planes[3][3] = m[15] - m[13];
planes[4][0] = znear * m[3] + m[2];
planes[4][1] = znear * m[7] + m[6];
planes[4][2] = znear * m[11] + m[10];
planes[4][3] = znear * m[15] + m[14];
planes[5][0] = zfar * m[3] - m[2];
planes[5][1] = zfar * m[7] - m[6];
planes[5][2] = zfar * m[11] - m[10];
planes[5][3] = zfar * m[15] - m[14];
}
void mat_frustum(
float *matrix, float left, float right, float bottom,
float top, float znear, float zfar)
{
float temp, temp2, temp3, temp4;
temp = 2.0 * znear;
temp2 = right - left;
temp3 = top - bottom;
temp4 = zfar - znear;
matrix[0] = temp / temp2;
matrix[1] = 0.0;
matrix[2] = 0.0;
matrix[3] = 0.0;
matrix[4] = 0.0;
matrix[5] = temp / temp3;
matrix[6] = 0.0;
matrix[7] = 0.0;
matrix[8] = (right + left) / temp2;
matrix[9] = (top + bottom) / temp3;
matrix[10] = (-zfar - znear) / temp4;
matrix[11] = -1.0;
matrix[12] = 0.0;
matrix[13] = 0.0;
matrix[14] = (-temp * zfar) / temp4;
matrix[15] = 0.0;
}
void mat_perspective(
float *matrix, float fov, float aspect,
float znear, float zfar)
{
float ymax, xmax;
ymax = znear * tanf_approx(fov * OMS_PI / 360.0);
xmax = ymax * aspect;
mat_frustum(matrix, -xmax, xmax, -ymax, ymax, znear, zfar);
}
void mat_ortho(
float *matrix,
float left, float right, float bottom, float top, float near, float far)
{
float rl_delta = right - left;
float tb_delta = top - bottom;
float fn_delta = far - near;
matrix[0] = 2 / rl_delta;
matrix[1] = 0;
matrix[2] = 0;
matrix[3] = 0;
matrix[4] = 0;
matrix[5] = 2 / tb_delta;
matrix[6] = 0;
matrix[7] = 0;
matrix[8] = 0;
matrix[9] = 0;
matrix[10] = -2 / fn_delta;
matrix[11] = 0;
matrix[12] = -(right + left) / rl_delta;
matrix[13] = -(top + bottom) / tb_delta;
matrix[14] = -(far + near) / fn_delta;
matrix[15] = 1;
}
#endif

15
math/matrix/MatrixInt32.h Normal file
View File

@ -0,0 +1,15 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MATH_MATRIX_INT32_H
#define TOS_MATH_MATRIX_INT32_H
#include "../../stdlib/Intrinsics.h"
#include "../../utils/MathUtils.h"
#endif

220
math/matrix/MatrixInt64.h Normal file
View File

@ -0,0 +1,220 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MATH_MATRIX_INT64_H
#define TOS_MATH_MATRIX_INT64_H
#include "../../stdlib/Intrinsics.h"
#include "../../utils/MathUtils.h"
#endif
// Remarks: sizes for the second matrix/vector are often implied by the first parameter and the rules for matrix/vector
// multiplication.
// First element is always a matrix of int64_t
/////////////////////////////////
/////////////////////////////////
// Multiplication
/////////////////////////////////
// Array matrix multiplication
/////////////////////////////////
// mult_mat_int32(int64_t **a, size_t ai, size_t aj, int32_t **b)
// mult_mat_int64(int64_t **a, size_t ai, size_t aj, int64_t **b)
// mult_mat_float(int64_t **a, size_t ai, size_t aj, float **b)
// mult_vec_int32(int64_t **a, size_t ai, size_t aj, int32_t *b)
// mult_vec_int64(int64_t **a, size_t ai, size_t aj, int64_t *b)
// mult_vec_float(int64_t **a, size_t ai, size_t aj, float *b)
// mult_scal_int32(int64_t **a, size_t ai, size_t aj, int32_t b)
// mult_scal_int64(int64_t **a, size_t ai, size_t aj, int64_t b)
// mult_scal_float(int64_t **a, size_t ai, size_t aj, float b)
// Modifies the original matrix
// vector 2 matrix multiplication
/////////////////////////////////
// v2_mult_mat_int32(v2 *a, size_t a, int32_t **b)
// v2_mult_mat_int64(v2 *a, size_t a, int64_t **b)
// v2_mult_mat_float(v2 *a, size_t a, float **b)
// v2_mult_mat_v2(v2 *a, size_t a, v2 *b)
// v2_mult_vec_int32(v2 *a, size_t a, int32_t *b)
// v2_mult_vec_int64(v2 *a, size_t a, int64_t *b)
// v2_mult_vec_float(v2 *a, size_t a, float *b)
// v2_mult_vec_v2(v2 *a, size_t a, v2 *b)
// v2_mult_scal_int32(v2 *a, size_t a, int32_t b)
// v2_mult_scal_int64(v2 *a, size_t a, int64_t b)
// v2_mult_scal_float(v2 *a, size_t a, float b)
// vector 3 matrix multiplication
/////////////////////////////////
// v3_mult_mat_int32(v3 *a, size_t a, int32_t **b)
// v3_mult_mat_int64(v3 *a, size_t a, int64_t **b)
// v3_mult_mat_float(v3 *a, size_t a, float **b)
// v3_mult_mat_v3(v3 *a, size_t a, v3 *b)
// v3_mult_vec_int32(v3 *a, size_t a, int32_t *b)
// v3_mult_vec_int64(v3 *a, size_t a, int64_t *b)
// v3_mult_vec_float(v3 *a, size_t a, float *b)
// v3_mult_vec_v3(v3 *a, size_t a, v3 *b)
// v3_mult_scal_int32(v3 *a, size_t a, int32_t b)
// v3_mult_scal_int64(v3 *a, size_t a, int64_t b)
// v3_mult_scal_float(v3 *a, size_t a, float b)
// vector 4 matrix multiplication
/////////////////////////////////
// v4_mult_mat_int32(v4 *a, size_t a, int32_t **b)
// v4_mult_mat_int64(v4 *a, size_t a, int64_t **b)
// v4_mult_mat_float(v4 *a, size_t a, float **b)
// v4_mult_mat_v4(v4 *a, size_t a, v4 *b)
// v4_mult_vec_int32(v4 *a, size_t a, int32_t *b)
// v4_mult_vec_int64(v4 *a, size_t a, int64_t *b)
// v4_mult_vec_float(v4 *a, size_t a, float *b)
// v4_mult_vec_v4(v4 *a, size_t a, v4 *b)
// v4_mult_scal_int32(v4 *a, size_t a, int32_t b)
// v4_mult_scal_int64(v4 *a, size_t a, int64_t b)
// v4_mult_scal_float(v4 *a, size_t a, float b)
/////////////////////////////////
// Addition
/////////////////////////////////
// Array matrix addition
/////////////////////////////////
// add_mat_int32(int64_t **a, size_t ai, size_t aj, int32_t **b)
// add_mat_int64(int64_t **a, size_t ai, size_t aj, int64_t **b)
// add_mat_float(int64_t **a, size_t ai, size_t aj, float **b)
// add_vec_int32(int64_t **a, size_t ai, size_t aj, int32_t *b)
// add_vec_int64(int64_t **a, size_t ai, size_t aj, int64_t *b)
// add_vec_float(int64_t **a, size_t ai, size_t aj, float *b)
// add_scal_int32(int64_t **a, size_t ai, size_t aj, int32_t b)
// add_scal_int64(int64_t **a, size_t ai, size_t aj, int64_t b)
// add_scal_float(int64_t **a, size_t ai, size_t aj, float b)
// vector 2 matrix addition
/////////////////////////////////
// v2_add_mat_int32(v2 *a, size_t a, int32_t **b)
// v2_add_mat_int64(v2 *a, size_t a, int64_t **b)
// v2_add_mat_float(v2 *a, size_t a, float **b)
// v2_add_mat_v2(v2 *a, size_t a, v2 *b)
// v2_add_vec_int32(v2 *a, size_t a, int32_t *b)
// v2_add_vec_int64(v2 *a, size_t a, int64_t *b)
// v2_add_vec_float(v2 *a, size_t a, float *b)
// v2_add_vec_v2(v2 *a, size_t a, v2 *b)
// v2_add_scal_int32(v2 *a, size_t a, int32_t b)
// v2_add_scal_int64(v2 *a, size_t a, int64_t b)
// v2_add_scal_float(v2 *a, size_t a, float b)
// vector 3 matrix addition
/////////////////////////////////
// v3_add_mat_int32(v3 *a, size_t a, int32_t **b)
// v3_add_mat_int64(v3 *a, size_t a, int64_t **b)
// v3_add_mat_float(v3 *a, size_t a, float **b)
// v3_add_mat_v3(v3 *a, size_t a, v3 *b)
// v3_add_vec_int32(v3 *a, size_t a, int32_t *b)
// v3_add_vec_int64(v3 *a, size_t a, int64_t *b)
// v3_add_vec_float(v3 *a, size_t a, float *b)
// v3_add_vec_v3(v3 *a, size_t a, v3 *b)
// v3_add_scal_int32(v3 *a, size_t a, int32_t b)
// v3_add_scal_int64(v3 *a, size_t a, int64_t b)
// v3_add_scal_float(v3 *a, size_t a, float b)
// vector 4 matrix addition
/////////////////////////////////
// v4_add_mat_int32(v4 *a, size_t a, int32_t **b)
// v4_add_mat_int64(v4 *a, size_t a, int64_t **b)
// v4_add_mat_float(v4 *a, size_t a, float **b)
// v4_add_mat_v4(v4 *a, size_t a, v4 *b)
// v4_add_vec_int32(v4 *a, size_t a, int32_t *b)
// v4_add_vec_int64(v4 *a, size_t a, int64_t *b)
// v4_add_vec_float(v4 *a, size_t a, float *b)
// v4_add_vec_v4(v4 *a, size_t a, v4 *b)
// v4_add_scal_int32(v4 *a, size_t a, int32_t b)
// v4_add_scal_int64(v4 *a, size_t a, int64_t b)
// v4_add_scal_float(v4 *a, size_t a, float b)
/////////////////////////////////
// Subtraction
/////////////////////////////////
// Array matrix subtraction
/////////////////////////////////
// sub_mat_int32(int64_t **a, size_t ai, size_t aj, int32_t **b)
// sub_mat_int64(int64_t **a, size_t ai, size_t aj, int64_t **b)
// sub_mat_float(int64_t **a, size_t ai, size_t aj, float **b)
// sub_vec_int32(int64_t **a, size_t ai, size_t aj, int32_t *b)
// sub_vec_int64(int64_t **a, size_t ai, size_t aj, int64_t *b)
// sub_vec_float(int64_t **a, size_t ai, size_t aj, float *b)
// sub_scal_int32(int64_t **a, size_t ai, size_t aj, int32_t b)
// sub_scal_int64(int64_t **a, size_t ai, size_t aj, int64_t b)
// sub_scal_float(int64_t **a, size_t ai, size_t aj, float b)
// vector 2 matrix subtraction
/////////////////////////////////
// v2_sub_mat_int32(v2 *a, size_t a, int32_t **b)
// v2_sub_mat_int64(v2 *a, size_t a, int64_t **b)
// v2_sub_mat_float(v2 *a, size_t a, float **b)
// v2_sub_mat_v2(v2 *a, size_t a, v2 *b)
// v2_sub_vec_int32(v2 *a, size_t a, int32_t *b)
// v2_sub_vec_int64(v2 *a, size_t a, int64_t *b)
// v2_sub_vec_float(v2 *a, size_t a, float *b)
// v2_sub_vec_v2(v2 *a, size_t a, v2 *b)
// v2_sub_scal_int32(v2 *a, size_t a, int32_t b)
// v2_sub_scal_int64(v2 *a, size_t a, int64_t b)
// v2_sub_scal_float(v2 *a, size_t a, float b)
// vector 3 matrix subtraction
/////////////////////////////////
// v3_sub_mat_int32(v3 *a, size_t a, int32_t **b)
// v3_sub_mat_int64(v3 *a, size_t a, int64_t **b)
// v3_sub_mat_float(v3 *a, size_t a, float **b)
// v3_sub_mat_v3(v3 *a, size_t a, v3 *b)
// v3_sub_vec_int32(v3 *a, size_t a, int32_t *b)
// v3_sub_vec_int64(v3 *a, size_t a, int64_t *b)
// v3_sub_vec_float(v3 *a, size_t a, float *b)
// v3_sub_vec_v3(v3 *a, size_t a, v3 *b)
// v3_sub_scal_int32(v3 *a, size_t a, int32_t b)
// v3_sub_scal_int64(v3 *a, size_t a, int64_t b)
// v3_sub_scal_float(v3 *a, size_t a, float b)
// vector 4 matrix subtraction
/////////////////////////////////
// v4_sub_mat_int32(v4 *a, size_t a, int32_t **b)
// v4_sub_mat_int64(v4 *a, size_t a, int64_t **b)
// v4_sub_mat_float(v4 *a, size_t a, float **b)
// v4_sub_mat_v4(v4 *a, size_t a, v4 *b)
// v4_sub_vec_int32(v4 *a, size_t a, int32_t *b)
// v4_sub_vec_int64(v4 *a, size_t a, int64_t *b)
// v4_sub_vec_float(v4 *a, size_t a, float *b)
// v4_sub_vec_v4(v4 *a, size_t a, v4 *b)
// v4_sub_scal_int32(v4 *a, size_t a, int32_t b)
// v4_sub_scal_int64(v4 *a, size_t a, int64_t b)
// v4_sub_scal_float(v4 *a, size_t a, float b)

173
math/matrix/VectorFloat32.h Normal file
View File

@ -0,0 +1,173 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MATH_MATRIX_VECTOR_FLOAT32_H
#define TOS_MATH_MATRIX_VECTOR_FLOAT32_H
#include "../../stdlib/Intrinsics.h"
#include "../../utils/MathUtils.h"
#include "../../stdlib/simd/SIMD_F32.h"
struct v3_f32_4 {
union {
struct {
union {
f32_4 x;
f32_4 r;
};
union {
f32_4 y;
f32_4 g;
};
union {
f32_4 z;
f32_4 b;
};
};
f32_4 v[3];
};
};
struct v3_f32_8 {
union {
struct {
union {
f32_8 x;
f32_8 r;
};
union {
f32_8 y;
f32_8 g;
};
union {
f32_8 z;
f32_8 b;
};
};
f32_8 v[3];
};
};
struct v3_f32_16 {
union {
struct {
union {
f32_16 x;
f32_16 r;
};
union {
f32_16 y;
f32_16 g;
};
union {
f32_16 z;
f32_16 b;
};
};
f32_16 v[3];
};
};
struct v4_f32_4 {
union {
struct {
union {
f32_4 x;
f32_4 r;
};
union {
f32_4 y;
f32_4 g;
};
union {
f32_4 z;
f32_4 b;
};
union {
f32_4 w;
f32_4 a;
};
};
f32_4 v[4];
};
};
struct v4_f32_8 {
union {
struct {
union {
f32_8 x;
f32_8 r;
};
union {
f32_8 y;
f32_8 g;
};
union {
f32_8 z;
f32_8 b;
};
union {
f32_8 w;
f32_8 a;
};
};
f32_8 v[4];
};
};
struct v4_f32_16 {
union {
struct {
union {
f32_16 x;
f32_16 r;
};
union {
f32_16 y;
f32_16 g;
};
union {
f32_16 z;
f32_16 b;
};
union {
f32_16 w;
f32_16 a;
};
};
f32_16 v[4];
};
};
void vec3_normalize_f32(float* x, float* y, float* z)
{
float d = sqrt((*x) * (*x) + (*y) * (*y) + (*z) * (*z));
*x /= d;
*y /= d;
*z /= d;
}
void vec4_normalize_f32(float* x, float* y, float* z, float* w)
{
float d = sqrt((*x) * (*x) + (*y) * (*y) + (*z) * (*z) + (*w) * (*w));
*x /= d;
*y /= d;
*z /= d;
*w /= d;
}
#endif

View File

@ -0,0 +1,16 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MATH_MATRIX_VECTOR_FLOAT64_H
#define TOS_MATH_MATRIX_VECTOR_FLOAT64_H
#include "../../stdlib/Intrinsics.h"
#include "../../utils/MathUtils.h"
#include "../../stdlib/simd/SIMD_F64.h"
#endif

157
math/matrix/VectorInt32.h Normal file
View File

@ -0,0 +1,157 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MATH_MATRIX_VECTOR_INT32_H
#define TOS_MATH_MATRIX_VECTOR_INT32_H
#include <immintrin.h>
#include <xmmintrin.h>
#include "../../stdlib/Intrinsics.h"
#include "../../utils/MathUtils.h"
#include "../../stdlib/simd/SIMD_I32.h"
struct v3_int32_4 {
union {
struct {
union {
int32_4 x;
int32_4 r;
};
union {
int32_4 y;
int32_4 g;
};
union {
int32_4 z;
int32_4 b;
};
};
int32_4 v[3];
};
};
struct v3_int32_8 {
union {
struct {
union {
int32_8 x;
int32_8 r;
};
union {
int32_8 y;
int32_8 g;
};
union {
int32_8 z;
int32_8 b;
};
};
int32_8 v[3];
};
};
struct v3_int32_16 {
union {
struct {
union {
int32_16 x;
int32_16 r;
};
union {
int32_16 y;
int32_16 g;
};
union {
int32_16 z;
int32_16 b;
};
};
int32_16 v[3];
};
};
struct v4_int32_4 {
union {
struct {
union {
int32_4 x;
int32_4 r;
};
union {
int32_4 y;
int32_4 g;
};
union {
int32_4 z;
int32_4 b;
};
union {
int32_4 w;
int32_4 a;
};
};
int32_4 v[4];
};
};
struct v4_int32_8 {
union {
struct {
union {
int32_8 x;
int32_8 r;
};
union {
int32_8 y;
int32_8 g;
};
union {
int32_8 z;
int32_8 b;
};
union {
int32_8 w;
int32_8 a;
};
};
int32_8 v[4];
};
};
struct v4_int32_16 {
union {
struct {
union {
int32_16 x;
int32_16 r;
};
union {
int32_16 y;
int32_16 g;
};
union {
int32_16 z;
int32_16 b;
};
union {
int32_16 w;
int32_16 a;
};
};
int32_16 v[4];
};
};
#endif

157
math/matrix/VectorInt64.h Normal file
View File

@ -0,0 +1,157 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MATH_MATRIX_VECTOR_INT64_H
#define TOS_MATH_MATRIX_VECTOR_INT64_H
#include <immintrin.h>
#include <xmmintrin.h>
#include "../../stdlib/Intrinsics.h"
#include "../../utils/MathUtils.h"
#include "../../stdlib/simd/SIMD_I64.h"
struct v3_int64_2 {
union {
struct {
union {
int64_2 x;
int64_2 r;
};
union {
int64_2 y;
int64_2 g;
};
union {
int64_2 z;
int64_2 b;
};
};
int64_2 v[3];
};
};
struct v3_int64_4 {
union {
struct {
union {
int64_4 x;
int64_4 r;
};
union {
int64_4 y;
int64_4 g;
};
union {
int64_4 z;
int64_4 b;
};
};
int64_4 v[3];
};
};
struct v3_int64_8 {
union {
struct {
union {
int64_8 x;
int64_8 r;
};
union {
int64_8 y;
int64_8 g;
};
union {
int64_8 z;
int64_8 b;
};
};
int64_8 v[3];
};
};
struct v4_int64_2 {
union {
struct {
union {
int64_2 x;
int64_2 r;
};
union {
int64_2 y;
int64_2 g;
};
union {
int64_2 z;
int64_2 b;
};
union {
int64_2 w;
int64_2 a;
};
};
int64_2 v[4];
};
};
struct v4_int64_4 {
union {
struct {
union {
int64_4 x;
int64_4 r;
};
union {
int64_4 y;
int64_4 g;
};
union {
int64_4 z;
int64_4 b;
};
union {
int64_4 w;
int64_4 a;
};
};
int64_4 v[4];
};
};
struct v4_int64_8 {
union {
struct {
union {
int64_8 x;
int64_8 r;
};
union {
int64_8 y;
int64_8 g;
};
union {
int64_8 z;
int64_8 b;
};
union {
int64_8 w;
int64_8 a;
};
};
int64_8 v[4];
};
};
#endif

33
models/Attrib.h Normal file
View File

@ -0,0 +1,33 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_ATTRIB_H
#define TOS_ATTRIB_H
#if OPENGL
#include "../lib/opengl/glew/include/GL/glew.h"
struct Attrib {
GLuint program;
GLuint position;
GLuint normal;
GLuint uv;
GLuint matrix;
GLuint sampler;
GLuint camera;
GLuint timer;
GLuint extra1;
GLuint extra2;
GLuint extra3;
GLuint extra4;
};
#else
struct Attrib {};
#endif
#endif

0
models/Colors.h Normal file
View File

17
models/Obj.h Normal file
View File

@ -0,0 +1,17 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_OBJ_H
#define TOS_MODELS_OBJ_H
#include "../stdlib/Types.h"
struct ObjFile {
};
#endif

17
models/Sound.h Normal file
View File

@ -0,0 +1,17 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_SOUND_H
#define TOS_MODELS_SOUND_H
#include "../stdlib/Types.h"
struct SoundFile {
};
#endif

57
models/Texture.h Normal file
View File

@ -0,0 +1,57 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_TEXTURE_H
#define TOS_MODELS_TEXTURE_H
#define TEXTURE_DATA_TYPE_2D 0
#define TEXTURE_DATA_TYPE_1D 1
#define TEXTURE_DATA_TYPE_3D 2
#define TEXTURE_DATA_TYPE_1D_ARRAY 3
#define TEXTURE_DATA_TYPE_2D_ARRAY 4
#define TEXTURE_DATA_TYPE_2D_MULTISAMPLED 5
#define TEXTURE_DATA_TYPE_2D_MULTISAMPLED_ARRAY 6
#define TEXTURE_WRAP_TYPE_NONE 0
#define TEXTURE_WRAP_TYPE_CLAMP_TO_EDGE 1
#define TEXTURE_WRAP_TYPE_CLAMP_TO_BORDER 2
#define TEXTURE_WRAP_TYPE_REPEAT 3
#define TEXTURE_WRAP_TYPE_MIRRORED_REPEAT 4
#define TEXTURE_WRAP_TYPE_MIRRORED_CLAMP_TO_EDGE 5
#define TEXTURE_MINIFICATION_NONE 0
#define TEXTURE_MINIFICATION_NEAREST 1
#define TEXTURE_MINIFICATION_LINEAR 2
#define TEXTURE_MINIFICATION_NEAREST_MIPMAP_NEAREST 3
#define TEXTURE_MINIFICATION_LINEAR_MIPMAP_NEAREST 4
#define TEXTURE_MINIFICATION_NEAREST_MIPMAP_LINEAR 5
#define TEXTURE_MINIFICATION_LINEAR_MIPMAP_LINEAR 6
#include "../stdlib/Types.h"
#include "../image/Image.h"
#include "Attrib.h"
struct TextureFile {
uint64 id;
byte texture_data_type;
byte texture_wrap_type_s;
byte texture_wrap_type_t;
byte texture_wrap_type_r;
byte texture_minification;
Image image;
#if OPENGL
Attrib attrib;
#endif
};
#endif

51
models/chat/Chat.h Normal file
View File

@ -0,0 +1,51 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_CHAT_H
#define TOS_MODELS_CHAT_H
#include "../../stdlib/Types.h"
#include "ChatLevel.h"
#include "ChatType.h"
#ifndef MAX_CHAR_NAME_LENGTH
#define MAX_CHAR_NAME_LENGTH 32
#endif
#ifndef MAX_MESSAGE_LENGTH
#define MAX_MESSAGE_LENGTH 512
#endif
#ifndef MAX_MESSAGE_HISTORY
#define MAX_MESSAGE_HISTORY 64
#endif
struct ChatMessage {
uint64 id;
unsigned int sender_id;
unsigned int receiver_id;
char sender_name[MAX_CHAR_NAME_LENGTH];
time_t dt;
char message[MAX_MESSAGE_LENGTH];
ChatLevel level;
ChatType type;
};
// Messages are stored in a ring
// -> latest = the newest message
// -> previous message = latest - 1
// -> This makes iterating messages easy since we also know where the chat history memory block starts
struct ChatHistory {
ChatMessage messages[MAX_MESSAGE_HISTORY];
int latest;
};
#endif

20
models/chat/ChatLevel.h Normal file
View File

@ -0,0 +1,20 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_CHAT_LEVEL_H
#define TOS_MODELS_CHAT_LEVEL_H
enum ChatLevel {
CHAT_LEVEL_NORMAL,
CHAT_LEVEL_INFO,
CHAT_LEVEL_IMPORTANT,
CHAT_LEVEL_CRITICAL,
CHAT_LEVEL_DELETED
};
#endif

19
models/chat/ChatStatus.h Normal file
View File

@ -0,0 +1,19 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_CHAT_STATUS_H
#define TOS_MODELS_CHAT_STATUS_H
enum ChatStatus {
CHAT_STATUS_OFFLINE,
CHAT_STATUS_ONLINE,
CHAT_STATUS_HIDDEN,
CHAT_STATUS_DND
};
#endif

20
models/chat/ChatType.h Normal file
View File

@ -0,0 +1,20 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_CHAT_TYPE_H
#define TOS_MODELS_CHAT_TYPE_H
enum ChatType {
CHAT_TYPE_LOCAL,
CHAT_TYPE_GLOBAL,
CHAT_TYPE_PLAYER,
CHAT_TYPE_GROUP,
CHAT_TYPE_GUILD
};
#endif

19
models/item/Equipment.h Normal file
View File

@ -0,0 +1,19 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_EQUIPMENT_H
#define TOS_MODELS_EQUIPMENT_H
#include "../../stdlib/Types.h"
struct Equipment {
byte type;
char* name;
};
#endif

View File

@ -0,0 +1,25 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_EQUIPMENT_TYPE_H
#define TOS_MODELS_EQUIPMENT_TYPE_H
#include "../../stdlib/Types.h"
struct EquipmentType {
byte id;
byte slot;
bool dual;
bool throwing;
bool projectile;
bool damage;
bool armor;
bool supporting;
};
#endif

18
models/item/Item.h Normal file
View File

@ -0,0 +1,18 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_ITEM_H
#define TOS_MODELS_ITEM_H
#include "../../stdlib/Types.h"
struct Item {
uint64 id;
};
#endif

View File

@ -0,0 +1,27 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_ITEM_EQUIPMENT_SLOTS_H
#define TOS_MODELS_ITEM_EQUIPMENT_SLOTS_H
#define EQUIPMENT_SLOT_HEAD 0x01
#define EQUIPMENT_SLOT_NECK 0x02
#define EQUIPMENT_SLOT_BODY 0x03
#define EQUIPMENT_SLOT_BELT 0x04
#define EQUIPMENT_SLOT_PANTS 0x05
#define EQUIPMENT_SLOT_BOOTS 0x06
#define EQUIPMENT_SLOT_RING 0x07
#define EQUIPMENT_SLOT_MAIN_HAND 0x08
#define EQUIPMENT_SLOT_OFF_HAND 0x09
#define EQUIPMENT_SLOT_ARMS 0x0A
#define EQUIPMENT_SLOT_BELT_ATTACHMENT 0x0B
#define EQUIPMENT_SLOT_SHOULDER 0x0C
#define EQUIPMENT_SLOT_BACK 0x0D
#define EQUIPMENT_SLOT_HANDS 0x0E
#endif

View File

@ -0,0 +1,115 @@
#ifndef TOS_MODELS_ITEM_EQUIPMENT_TYPES_H
#define TOS_MODELS_ITEM_EQUIPMENT_TYPES_H
#include "equipment_slots.h"
#include "EquipmentType.h"
#define EQUIPMENT_TYPE_ONE_HANDED_SWORD 0x01
#define EQUIPMENT_TYPE_TWO_HANDED_SWORD 0x02
#define EQUIPMENT_TYPE_HELMET 0x03
#define EQUIPMENT_TYPE_EARING 0x04
#define EQUIPMENT_TYPE_NECKLACE 0x05
#define EQUIPMENT_TYPE_BOOTS 0x06
#define EQUIPMENT_TYPE_STAFF 0x07
#define EQUIPMENT_TYPE_WAND 0x08
#define EQUIPMENT_TYPE_DOLL 0x09
#define EQUIPMENT_TYPE_POLEAXE 0x0A
#define EQUIPMENT_TYPE_SABRE 0x0B
#define EQUIPMENT_TYPE_DAGGER 0x0C
#define EQUIPMENT_TYPE_JAVELIN 0x0D
#define EQUIPMENT_TYPE_QUARTERSTAFF 0x0E
#define EQUIPMENT_TYPE_SPEAR 0x0F
#define EQUIPMENT_TYPE_CLAYMORE 0x10
#define EQUIPMENT_TYPE_DAO 0x11
#define EQUIPMENT_TYPE_CLEAVER 0x12
#define EQUIPMENT_TYPE_BROADSWORD 0x13
#define EQUIPMENT_TYPE_LONGSWORD 0x14
#define EQUIPMENT_TYPE_SCIMITAR 0x15
#define EQUIPMENT_TYPE_RAPIER 0x16
#define EQUIPMENT_TYPE_SICKLE 0x17
#define EQUIPMENT_TYPE_SCYTHE 0x18
#define EQUIPMENT_TYPE_PUNCHING_DAGGER 0x19
#define EQUIPMENT_TYPE_LIGHT_WARHAMMER 0x1A
#define EQUIPMENT_TYPE_LIGHT_MACE 0x1B
#define EQUIPMENT_TYPE_HEAVY_MACE 0x1C
#define EQUIPMENT_TYPE_HEAVY_WARHAMMER 0x1D
#define EQUIPMENT_TYPE_LIGHT_FLAIL 0x1E
#define EQUIPMENT_TYPE_HEAVY_FLAIL 0x1F
#define EQUIPMENT_TYPE_SHURIKAN 0x20
#define EQUIPMENT_TYPE_GLAIVE 0x21
#define EQUIPMENT_TYPE_HALBERD 0x22
#define EQUIPMENT_TYPE_PARTIZAN 0x23
#define EQUIPMENT_TYPE_LONGBOW 0x24
#define EQUIPMENT_TYPE_DOUBLE_BOW 0x25
#define EQUIPMENT_TYPE_BOW 0x27
#define EQUIPMENT_TYPE_RECURVE_BOW 0x28
#define EQUIPMENT_TYPE_CROSSBOW 0x29
#define EQUIPMENT_TYPE_HEAVY_CROSSBOW 0x2A
#define EQUIPMENT_TYPE_WHIP 0x2B
#define EQUIPMENT_TYPE_THROWING_AXE 0x2C
#define EQUIPMENT_TYPE_BLOWGUN 0x2D
#define EQUIPMENT_TYPE_CLUB 0x2E
#define EQUIPMENT_TYPE_GREATCLUB 0x2F
#define EQUIPMENT_TYPE_SLING 0x30
#define EQUIPMENT_TYPE_CHAKRAM 0x31
#define EQUIPMENT_TYPE_TRIDENT 0x32
#define EQUIPMENT_TYPE_THROWING_SPEAR 0x33
#define EQUIPMENT_TYPE_THROWING_KNIVES 0x34
#define EQUIPMENT_TYPE_GRANADE 0x35
#define EQUIPMENT_TYPE_SCRIPTURE 0x36
#define EQUIPMENT_TYPE_BONES 0x37
#define EQUIPMENT_TYPE_MAGIC_CRYSTAL 0x38
#define EQUIPMENT_TYPE_SHIELD 0x39
#define EQUIPMENT_TYPE_QUIVER 0x3D
#define EQUIPMENT_TYPE_PISTOL 0x3E
#define EQUIPMENT_TYPE_SHOTGUN 0x3F
#define EQUIPMENT_TYPE_RIFLE 0x40
#define EQUIPMENT_TYPE_FLASK 0x41
#define EQUIPMENT_TYPE_LIGHT_AXE 0x42
#define EQUIPMENT_TYPE_QUILL 0x43
#define EQUIPMENT_TYPE_PANTS 0x44
#define EQUIPMENT_TYPE_BELT 0x45
#define EQUIPMENT_TYPE_RING 0x46
#define EQUIPMENT_TYPE_ARMS 0x47
#define EQUIPMENT_TYPE_BELT_ATTACHMENT 0x48
#define EQUIPMENT_TYPE_BODY 0x49
#define EQUIPMENT_TYPE_CIRCLET 0x4A
#define EQUIPMENT_TYPE_BRACELET 0x4B
#define EQUIPMENT_TYPE_GADGET 0x4C
#define EQUIPMENT_TYPE_LANTERN 0x4D
#define EQUIPMENT_TYPE_GLASSES 0x4E
#define EQUIPMENT_TYPE_CAPE 0x4F
#define EQUIPMENT_TYPE_POLEARM 0x50
#define EQUIPMENT_TYPE_HEAVY_AXE 0x51
#define EQUIPMENT_TYPE_SCALES 0x52
#define EQUIPMENT_TYPE_PRAYING_BEADS 0x53
#define EQUIPMENT_TYPE_TONFA 0x54
#define EQUIPMENT_TYPE_TETSUBO 0x55
#define EQUIPMENT_TYPE_KAMA 0x56
#define EQUIPMENT_TYPE_SAMURAI_SWORD 0x57
#define EQUIPMENT_TYPE_BOOMERANG 0x58
#define EQUIPMENT_TYPE_SLINGSHOT 0x59
#define EQUIPMENT_TYPE_HARPOON 0x5A
#define EQUIPMENT_TYPE_ORB 0x5B
#define EQUIPMENT_TYPE_RUNESTONE 0x5C
#define EQUIPMENT_TYPE_TALISMAN 0x5D
#define EQUIPMENT_TYPE_GRIMOIRE 0x5E
#define EQUIPMENT_TYPE_SHURIKEN 0x5F
#define EQUIPMENT_TYPE_THROWING_DARTS 0x60
#define EQUIPMENT_TYPE_COCKTAIL 0x61
#define EQUIPMENT_TYPE_FLUTE 0x62
#define EQUIPMENT_TYPE_FAN 0x63
#define EQUIPMENT_TYPE_SCEPTER 0x64
#define EQUIPMENT_TYPE_TAMBOURINE 0x65
#define EQUIPMENT_TYPE_BAGPIPE 0x66
#define EQUIPMENT_TYPE_HARP 0x67
#define EQUIPMENT_TYPE_TROMPET 0x68
#define EQUIPMENT_TYPE_LUTE 0x69
#define EQUIPMENT_TYPE_HORN 0x6A
#define EQUIPMENT_TYPE_BELL 0x6B
#define EQUIPMENT_TYPE_VIOLIN 0x6C
#define EQUIPMENT_TYPE_VIOLIN 0x6D
#define SIZE_EQUIPMENT_TYPE 0x69
#endif

0
models/map.h Normal file
View File

39
models/mob/Mob.cpp Normal file
View File

@ -0,0 +1,39 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_MOB_C
#define TOS_MODELS_MOB_C
#include "../../utils/MathUtils.h"
#include "Mob.h"
#include "MobState.h"
void mob_interpolate(Mob* mob, f32 time)
{
MobState *s1 = &mob->state1;
MobState *s2 = &mob->state2;
float t1 = s2->t - s1->t;
float t2 = time - s2->t;
t1 = OMS_MIN(t1, 1.0f);
t1 = OMS_MAX(t1, 0.1f);
float p = OMS_MIN(t2 / t1, 1.0f);
mob->state.location.x = s1->location.x + (s2->location.x - s1->location.x) * p;
mob->state.location.y = s1->location.y + (s2->location.y - s1->location.y) * p;
mob->state.location.z = s1->location.z + (s2->location.z - s1->location.z) * p;
mob->state.orientation.x = s1->orientation.x + (s2->orientation.x - s1->orientation.x) * p;
mob->state.orientation.y = s1->orientation.y + (s2->orientation.y - s1->orientation.y) * p;
mob->state.orientation.z = s1->orientation.z + (s2->orientation.z - s1->orientation.z) * p;
mob->state.orientation.w = s1->orientation.w + (s2->orientation.w - s1->orientation.w) * p;
}
#endif

34
models/mob/Mob.h Normal file
View File

@ -0,0 +1,34 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_MOB_H
#define TOS_MODELS_MOB_H
#include "../../stdlib/Types.h"
#include "../settings/Settings.h"
#include "../item/Equipment.h"
#include "MobState.h"
struct Mob {
byte category;
byte mclass;
byte level;
byte rank;
unsigned int id;
unsigned int guild_id;
MobState state;
MobState state1;
MobState state2;
};
#endif

73
models/mob/MobAction.h Normal file
View File

@ -0,0 +1,73 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_MOB_ACTION_H
#define TOS_MODELS_MOB_ACTION_H
// @todo Consider to create better ranges
// This would allow easier checks during the game (e.g. can be healed if > X and < Y)
// Checks to consider are:
// - Can be healed
// - Can be attacked
// - Can attack
// - Can escape/teleport/... (-> out of fight)
// - Can cast
// - Can call mount (e.g. not during falling or during fight)
// - ...
// Don't render, ready for garbage collection and re-use
#define MOB_ACTION_INACTIVE 0x00
#define MOB_ACTION_LAG 0x01
#define MOB_ACTION_AAAA 0x02
#define MOB_ACTION_WALK 0x03
#define MOB_ACTION_RUN 0x04
#define MOB_ACTION_SNEAK 0x05
#define MOB_ACTION_CRAWL 0x06
#define MOB_ACTION_CLIMB 0x07
#define MOB_ACTION_SLIDE 0x08
#define MOB_ACTION_JUMP 0x09
#define MOB_ACTION_DUCK 0x0A
#define MOB_ACTION_FALL 0x0B
#define MOB_ACTION_TALK 0x0C
#define MOB_ACTION_ATTACK 0x0D
#define MOB_ACTION_DEFEND 0x0E
#define MOB_ACTION_BLOCK 0x0F
#define MOB_ACTION_DODGE 0x10
#define MOB_ACTION_DIE 0x11
#define MOB_ACTION_DEAD 0x12
#define MOB_ACTION_SWIM 0x13
#define MOB_ACTION_SWIM_HOVER 0x14
#define MOB_ACTION_DIVE 0x15
#define MOB_ACTION_DIVE_HOVER 0x16
#define MOB_ACTION_FLY 0x17
#define MOB_ACTION_FLY_HOVER 0x18
#define MOB_ACTION_STAND 0x19
#define MOB_ACTION_SIT 0x1A
#define MOB_ACTION_LIE 0x1B
#define MOB_ACTION_SPAWN 0x1C
#define MOB_ACTION_TELEPORT 0x1D
#define MOB_ACTION_LOAD 0x1E
#define MOB_ACTION_MINE 0x1F
#define MOB_ACTION_CRAFT 0x20
#define MOB_ACTION_GATHER 0x21
#define MOB_ACTION_FISH 0x22
#define MOB_ACTION_SHOP 0x23
#define MOB_ACTION_EMOTE 0xFF
#endif

0
models/mob/MobCategory.h Normal file
View File

30
models/mob/MobState.h Normal file
View File

@ -0,0 +1,30 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_MOB_STATE_H
#define TOS_MODELS_MOB_STATE_H
#include "../../stdlib/Types.h"
#include "../../stdlib/Mathtypes.h"
#include "MobAction.h"
struct MobState {
v3_f32 location;
v4_f32 orientation;
float t;
// Action performed
// first byte = action category
// last 3 bytes = animation to use
uint32 action = (MOB_ACTION_INACTIVE << 24);
int chunk_id;
};
#endif

6
models/mob/MobStats.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef TOS_MODELS_MOB_STATS_H
#define TOS_MODELS_MOB_STATS_H
#include "../../../stdlib/Types.h"
#endif

15
models/mob/mob_category.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef TOS_MODELS_MOB_CATEGORY_H
#define TOS_MODELS_MOB_CATEGORY_H
#define MOB_CATEGORY_REGULAR 0x01
#define MOB_CATEGORY_CHAMPION 0x02
#define MOB_CATEGORY_BOSS 0x03
#define MOB_CATEGORY_WORLD_BOSS 0x04
#define MOB_CATEGORY_SINGULARITY 0x05
#define MOB_CATEGORY_ANIMAL 0x06
#define MOB_CATEGORY_NPC 0x07
#define MOB_CATEGORY_PLAYER 0x08
#define SIZE_MOB_CATEGORY 0x08
#endif

14
models/mob/mob_list.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef TOS_MODELS_MOB_LIST_H
#define TOS_MODELS_MOB_LIST_H
#define MOB_LIST_COW 0x01
#define MOB_LIST_CHICKEN 0x02
#define MOB_LIST_PIG 0x03
#define MOB_LIST_DOG 0x04
#define MOB_LIST_CAT 0x05
#define MOB_LIST_HORSE 0x06
#define MOB_LIST_CROW 0x07
#define SIZE_MOB_LIST 0x07
#endif

20
models/mob/monster/Drop.h Normal file
View File

@ -0,0 +1,20 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_MOB_DROP_H
#define TOS_MODELS_MOB_DROP_H
#include "../../../stdlib/Types.h"
struct Drop {
uint64 item;
uint32 quantity;
// @todo Add item specifications (e.g. affixes)
};
#endif

View File

@ -0,0 +1,104 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_MOB_LOOT_TABLE_H
#define TOS_MODELS_MOB_LOOT_TABLE_H
#include "../../../stdlib/Types.h"
#include "../../../utils/Utils.h"
#include "../../../utils/MathUtils.h"
#include "Drop.h"
struct LootTable {
// Chance this table becomes effective at all
// Useful to define multiple loot tables for a mob e.g. normal drop + 1 rare guarantueed
float table_chance;
uint64* items;
int table_size;
// If drop chance = -1 -> use default rarity drop chance
float* item_drop_chances;
// How many stacks of that item should be dropped
// Usually only used for consumables
int* item_min_drop_count;
int* item_max_drop_count;
bool item_unique;
// How many "different" items should be dropped
uint32 item_min_count;
uint32 item_max_count;
// How much gold should be dropped
uint32 gold_min_count;
uint32 gold_max_count;
};
// 1. check if table comes into effect
// 2. check if max item drop count is exceeded
void loot_table_drop(const LootTable* table, Drop* drop, uint32 counter = 0)
{
f32 rand = fast_rand_percentage();
if (counter >= table->item_max_count
|| rand > table->table_chance
) {
drop = NULL;
return;
}
f32 range_value = 0;
int i = 0;
for (i = 0; i < table->table_size; ++i) {
range_value += table->item_drop_chances[i];
if (range_value < rand) {
drop->item = table->items[i];
break;
}
}
if (i >= table->table_size) {
drop = NULL;
return;
}
drop->quantity = 1;
if (table->item_max_drop_count[i] > 1) {
rand = fast_rand_percentage();
drop->quantity = OMS_MAX(table->item_min_drop_count[i], (int) ((float) table->item_max_count * rand));
}
}
uint64 loot_table_drop_gold(const LootTable* table)
{
if (table->gold_max_count == 0) {
return 0;
}
f32 rand = fast_rand_percentage();
if (rand > table->table_chance) {
return 0;
}
return OMS_MAX(table->gold_min_count, (uint64) ((f32) table->gold_max_count * rand));
// WARNING: This is mathematically WRONG!
// The expected value of the version above is higher than what you would actually expect
// The correct version would be the one below (although slower)
/*
uint32 r = rand();
if (r > table->table_chance * RAND_MAX) {
return 0;
}
return (r % (table->gold_max_count - table->gold_min_count + 1)) + table->gold_min_count;
*/
}
#endif

View File

@ -0,0 +1,63 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_MOB_MONSTER_H
#define TOS_MODELS_MOB_MONSTER_H
#include "../../../stdlib/Types.h"
#include "../Mob.h"
#include "LootTable.h"
#include "MonsterStats.h"
#if SERVER
struct SMonster {
Mob mob;
SMonsterStats monster_stats;
LootTable loot;
// Data layout
// 12223444
// 1: scale sign
// 2: scale factor (8)
// 3: weight sign
// 4: weight factor (8)
byte custom_size;
// Data layout
// 122222??
// 1: body type (2)
// 2: skin color (32)
byte custom_body;
};
#endif
struct CMonster {
Mob mob;
CMonsterStats monster_stats;
char name[MAX_CHAR_NAME_LENGTH];
char title[MAX_CHAR_TITLE_LENGTH];
// Data layout
// 12223444
// 1: scale sign
// 2: scale factor (8)
// 3: weight sign
// 4: weight factor (8)
byte custom_size;
// Data layout
// 1122222?
// 1: body type (4)
// 2: skin color (32)
byte custom_body;
};
#endif

View File

@ -0,0 +1,22 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_MOB_MONSTER_STATS_H
#define TOS_MODELS_MOB_MONSTER_STATS_H
#include "../../../stdlib/Types.h"
#if SERVER
struct SMonsterStats {
};
#endif
struct CMonsterStats {
};
#endif

View File

@ -0,0 +1,119 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_BACKPACK_H
#define TOS_MODELS_BACKPACK_H
#include "../../../stdlib/Types.h"
#include "../../item/Item.h"
#define MAX_BACKPACK_ITEM_STACK 1024
struct Backpack {
uint32 size;
Item* items;
uint32* quantities;
};
bool backpack_split_items(Backpack* backpack, uint32 index, uint32 quantity)
{
if (quantity > backpack->quantities[index] && quantity > 0) {
return false;
}
// Find empty slot
int32 empty_slot = -1;
for (uint32 i = 0; i < backpack->size; ++i) {
if (backpack->quantities[i] == 0) {
empty_slot = i;
}
}
if (empty_slot < 0) {
return false;
}
memcpy(backpack->items + empty_slot, backpack->items + index, sizeof(Item));
backpack->quantities[empty_slot] = quantity;
return true;
}
void backpack_move_item(Backpack* backpack, uint32 from, uint32 to)
{
if (backpack->quantities[from] == 0) {
return;
}
// Handle item stacking
// @todo only allow stacking for consumables or items that have a stackable flag defined?!
if (backpack->items[to].id == backpack->items[from].id) {
// Only change stack up to MAX_BACKPACK_ITEM_STACK
uint32 stack_change = OMS_MIN(MAX_BACKPACK_ITEM_STACK - backpack->quantities[to], backpack->quantities[from]);
backpack->quantities[to] += stack_change;
backpack->quantities[from] -= stack_change;
return;
}
Item temp_item = {};
memcpy(&temp_item, backpack->items + to, sizeof(Item));
int32 temp_quantity = backpack->quantities[to];
memcpy(backpack->items + to, backpack->items + from, sizeof(Item));
if (temp_quantity == 0) {
backpack->quantities[from] = 0;
return;
}
memcpy(backpack->items + from, &temp_item, sizeof(Item));
backpack->quantities[from] = temp_quantity;
}
inline
int32 backpack_find_empty(const Backpack* backpack)
{
for (uint32 i = 0; i < backpack->size; ++i) {
if (backpack->quantities[i] == 0) {
return i;
}
}
return -1;
}
int32 backpack_add_item(Backpack* backpack, const Item* item, int32 quantities)
{
for (uint32 i = 0; i < backpack->size; ++i) {
if (backpack->quantities[i] == 0) {
// @performance Do We have to memcpy?
// It could be MUCH better to just store pointers in the backpack and have a second unordered backpack
// This would make changing orders much more efficient.
// At the same time how often are we really changing the order?!
memcpy(backpack->items + i, item, sizeof(Item));
backpack->quantities[i] = quantities;
return i;
}
}
return -1;
}
void backpack_remove_item(Backpack* backpack, uint32 index)
{
if (backpack->quantities[index] == 0) {
return;
}
backpack->quantities[index] = 0;
}
#endif

35
models/mob/player/Guild.h Normal file
View File

@ -0,0 +1,35 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_GUILD_H
#define TOS_MODELS_GUILD_H
#include "../../../stdlib/Types.h"
#ifndef MAX_CHAR_NAME_LENGTH
#define MAX_CHAR_NAME_LENGTH 32
#endif
#if SERVER
struct SGuild {
int id = 0;
char name[MAX_CHAR_NAME_LENGTH];
byte rank = 0x00;
};
#endif
// @performance The client should cache the guild names -> avoid sending guild names through network
struct CGuild {
int id = 0;
char name[MAX_CHAR_NAME_LENGTH];
byte rank = 0x00;
};
#endif

View File

@ -0,0 +1,34 @@
void make_player(
float *data,
float x, float y, float z, float rx, float ry)
{
float ao[6][4] = {0};
float light[6][4] = {
{0.8, 0.8, 0.8, 0.8},
{0.8, 0.8, 0.8, 0.8},
{0.8, 0.8, 0.8, 0.8},
{0.8, 0.8, 0.8, 0.8},
{0.8, 0.8, 0.8, 0.8},
{0.8, 0.8, 0.8, 0.8}
};
make_cube_faces(
data, ao, light,
1, 1, 1, 1, 1, 1,
226, 224, 241, 209, 225, 227,
0, 0, 0, 0.4
);
float ma[16];
float mb[16];
mat_identity(ma);
mat_rotate(mb, 0, 1, 0, rx);
mat_multiply(ma, mb, ma);
mat_rotate(mb, cosf(rx), 0, sinf(rx), -ry);
mat_multiply(ma, mb, ma);
mat_apply(data, ma, 36, 3, 10);
mat_translate(mb, x, y, z);
mat_multiply(ma, mb, ma);
mat_apply(data, ma, 36, 0, 10);
}

145
models/mob/player/Player.h Normal file
View File

@ -0,0 +1,145 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_MOB_PLAYER_H
#define TOS_MODELS_MOB_PLAYER_H
#include "../../../stdlib/Types.h"
#include "../../item/Equipment.h"
#include "../Mob.h"
#include "../MobState.h"
#include "../monster/LootTable.h"
#include "Backpack.h"
#include "PlayerStats.h"
#ifndef MAX_CHAR_NAME_LENGTH
#define MAX_CHAR_NAME_LENGTH 32
#endif
#ifndef MAX_CHAR_TITLE_LENGTH
#define MAX_CHAR_TITLE_LENGTH 16
#endif
#if SERVER
struct SPlayer {
Mob mob;
SPlayerStats player_stats;
char name[MAX_CHAR_NAME_LENGTH];
char title[MAX_CHAR_TITLE_LENGTH];
Equipment equipment[14];
PSettings settings;
Backpack* packpack;
// Data layout
// 12223444
// 1: scale sign
// 2: scale factor (8)
// 3: weight sign
// 4: weight factor (8)
byte scale;
byte weight;
// Data layout
// 1122222?
// 1: body type (4)
// 2: skin color (32)
byte body_type;
byte body_color;
// Data layout
// 1-4 race (16)
//
// 5-9 face type (32)
//
// 10-15 hair style (64)
// 16-20 hair color (32)
//
// 21-26 beard style (32)
//
// 27-30 eye style (32)
// 31-35 eye color (32)
//
// 36-40 face scar (32)
// 41-45 body scar (32)
//
// 46-51 tattoo (64)
// 52-56 tattoo color (32)
byte race;
byte face_type;
byte hair_style;
byte hair_color;
byte beard_style;
byte eye_style;
byte eye_color;
byte face_scar;
byte body_scar;
byte tattoo;
byte tattoo_color;
};
#endif
struct CPlayer {
Mob mob;
CPlayerStats player_stats;
char name[MAX_CHAR_NAME_LENGTH];
char title[MAX_CHAR_TITLE_LENGTH];
// Equipment id used for rendering (this could be also the transmog item id)
uint32 equipment[14];
// Equipment transmog data
// 11111222223333344444444455555???
// 1: primary color (32)
// 2: secondary color (32)
// 3: tertiary color (32)
// 4: effect (512)
// 5: effect color (32)
// ?: FREE
uint32 equipmentTransmog[14];
// Data layout
// 12223444
// 1: scale sign
// 2: scale factor (8)
// 3: weight sign
// 4: weight factor (8)
byte custom_size;
// Data layout
// 122222??
// 1: body type (2)
// 2: skin color (32)
byte custom_body;
// Data layout
// 1-4 race (16)
//
// 5-9 face type (32)
//
// 10-15 hair style (64)
// 16-20 hair color (32)
//
// 21-26 beard style (32)
//
// 27-30 eye style (32)
// 31-35 eye color (32)
//
// 36-40 face scar (32)
// 41-45 body scar (32)
//
// 46-51 tattoo (64)
// 52-56 tattoo color (32)
int64 customization;
};
#endif

View File

@ -0,0 +1,349 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_MOB_PLAYER_STATS_H
#define TOS_MODELS_MOB_PLAYER_STATS_H
#include "../../../stdlib/Types.h"
#if SERVER
struct SPlayerStats {
byte stat_str; // strength : effects health + base damage
byte stat_int; // inteligence : effects resource + base demage
byte stat_acc; // accuracy : effects critical chance + base damage + miss chance
byte stat_agi; // agility : effects resource + base damage + dodge change
byte stat_def; // defense : effects resource + base defense + dodge change
byte stat_sta; // stamina : effects health regen + resource regen
// Naming conventions
// : total
// _base : character stats (see stat_ above)
// _equip : character equipment
// _item : other item effects (consumables, e.g. potions)
// _effect : external aoe/skill effect
// _skill : own skill
// Damage types
unsigned int dmg;
unsigned int dmg_base;
unsigned int dmg_equip;
unsigned int dmg_item;
unsigned int dmg_effect;
unsigned int dmg_skill;
unsigned int dmg_pircing;
unsigned int dmg_pircing_base;
unsigned int dmg_pircing_equip;
unsigned int dmg_pircing_item;
unsigned int dmg_pircing_effect;
unsigned int dmg_pircing_skill;
unsigned int dmg_slashing;
unsigned int dmg_slashing_base;
unsigned int dmg_slashing_equip;
unsigned int dmg_slashing_item;
unsigned int dmg_slashing_effect;
unsigned int dmg_slashing_skill;
unsigned int dmg_bludgeoning;
unsigned int dmg_bludgeoning_base;
unsigned int dmg_bludgeoning_equip;
unsigned int dmg_bludgeoning_item;
unsigned int dmg_bludgeoning_effect;
unsigned int dmg_bludgeoning_skill;
unsigned int dmg_fire;
unsigned int dmg_fire_base;
unsigned int dmg_fire_equip;
unsigned int dmg_fire_item;
unsigned int dmg_fire_effect;
unsigned int dmg_fire_skill;
unsigned int dmg_water;
unsigned int dmg_water_base;
unsigned int dmg_water_equip;
unsigned int dmg_water_item;
unsigned int dmg_water_effect;
unsigned int dmg_water_skill;
unsigned int dmg_ice;
unsigned int dmg_ice_base;
unsigned int dmg_ice_equip;
unsigned int dmg_ice_item;
unsigned int dmg_ice_effect;
unsigned int dmg_ice_skill;
unsigned int dmg_earth;
unsigned int dmg_earth_base;
unsigned int dmg_earth_equip;
unsigned int dmg_earth_item;
unsigned int dmg_earth_effect;
unsigned int dmg_earth_skill;
unsigned int dmg_wind;
unsigned int dmg_wind_base;
unsigned int dmg_wind_equip;
unsigned int dmg_wind_item;
unsigned int dmg_wind_effect;
unsigned int dmg_wind_skill;
unsigned int dmg_poison;
unsigned int dmg_poison_base;
unsigned int dmg_poison_equip;
unsigned int dmg_poison_item;
unsigned int dmg_poison_effect;
unsigned int dmg_poison_skill;
unsigned int dmg_lightning;
unsigned int dmg_lightning_base;
unsigned int dmg_lightning_equip;
unsigned int dmg_lightning_item;
unsigned int dmg_lightning_effect;
unsigned int dmg_lightning_skill;
unsigned int dmg_holy;
unsigned int dmg_holy_base;
unsigned int dmg_holy_equip;
unsigned int dmg_holy_item;
unsigned int dmg_holy_effect;
unsigned int dmg_holy_skill;
unsigned int dmg_arcane;
unsigned int dmg_arcane_base;
unsigned int dmg_arcane_equip;
unsigned int dmg_arcane_item;
unsigned int dmg_arcane_effect;
unsigned int dmg_arcane_skill;
unsigned int dmg_corrupted;
unsigned int dmg_corrupted_base;
unsigned int dmg_corrupted_equip;
unsigned int dmg_corrupted_item;
unsigned int dmg_corrupted_effect;
unsigned int dmg_corrupted_skill;
unsigned int dmg_crit;
unsigned int dmg_crit_base;
unsigned int dmg_crit_equip;
unsigned int dmg_crit_item;
unsigned int dmg_crit_effect;
unsigned int dmg_crit_skill;
float dmg_crit_chance;
float dmg_crit_chance_base;
float dmg_crit_chance_equip;
float dmg_crit_chance_item;
float dmg_crit_chance_effect;
float dmg_crit_chance_skill;
// Health & Resource
unsigned int health;
unsigned int health_base;
unsigned int health_equip;
unsigned int health_item;
unsigned int health_effect;
unsigned int health_skill;
unsigned int health_regen;
unsigned int health_regen_base;
unsigned int health_regen_equip;
unsigned int health_regen_item;
unsigned int health_regen_effect;
unsigned int health_regen_skill;
unsigned int resource;
unsigned int resource_base;
unsigned int resource_equip;
unsigned int resource_item;
unsigned int resource_effect;
unsigned int resource_skill;
unsigned int resource_regen;
unsigned int resource_regen_base;
unsigned int resource_regen_equip;
unsigned int resource_regen_item;
unsigned int resource_regen_effect;
unsigned int resource_regen_skill;
// Defense types
// think about it as armor and/or resistence if it helps
unsigned int defense;
unsigned int defense_base;
unsigned int defense_equip;
unsigned int defense_item;
unsigned int defense_effect;
unsigned int defense_skill;
unsigned int defense_pircing;
unsigned int defense_pircing_base;
unsigned int defense_pircing_equip;
unsigned int defense_pircing_item;
unsigned int defense_pircing_effect;
unsigned int defense_pircing_skill;
unsigned int defense_slashing;
unsigned int defense_slashing_base;
unsigned int defense_slashing_equip;
unsigned int defense_slashing_item;
unsigned int defense_slashing_effect;
unsigned int defense_slashing_skill;
unsigned int defense_bludgeoning;
unsigned int defense_bludgeoning_base;
unsigned int defense_bludgeoning_equip;
unsigned int defense_bludgeoning_item;
unsigned int defense_bludgeoning_effect;
unsigned int defense_bludgeoning_skill;
unsigned int defense_fire;
unsigned int defense_fire_base;
unsigned int defense_fire_equip;
unsigned int defense_fire_item;
unsigned int defense_fire_effect;
unsigned int defense_fire_skill;
unsigned int defense_water;
unsigned int defense_water_base;
unsigned int defense_water_equip;
unsigned int defense_water_item;
unsigned int defense_water_effect;
unsigned int defense_water_skill;
unsigned int defense_ice;
unsigned int defense_ice_base;
unsigned int defense_ice_equip;
unsigned int defense_ice_item;
unsigned int defense_ice_effect;
unsigned int defense_ice_skill;
unsigned int defense_earth;
unsigned int defense_earth_base;
unsigned int defense_earth_equip;
unsigned int defense_earth_item;
unsigned int defense_earth_effect;
unsigned int defense_earth_skill;
unsigned int defense_wind;
unsigned int defense_wind_base;
unsigned int defense_wind_equip;
unsigned int defense_wind_item;
unsigned int defense_wind_effect;
unsigned int defense_wind_skill;
unsigned int defense_poison;
unsigned int defense_poison_base;
unsigned int defense_poison_equip;
unsigned int defense_poison_item;
unsigned int defense_poison_effect;
unsigned int defense_poison_skill;
unsigned int defense_lightning;
unsigned int defense_lightning_base;
unsigned int defense_lightning_equip;
unsigned int defense_lightning_item;
unsigned int defense_lightning_effect;
unsigned int defense_lightning_skill;
unsigned int defense_holy;
unsigned int defense_holy_base;
unsigned int defense_holy_equip;
unsigned int defense_holy_item;
unsigned int defense_holy_effect;
unsigned int defense_holy_skill;
unsigned int defense_arcane;
unsigned int defense_arcane_base;
unsigned int defense_arcane_equip;
unsigned int defense_arcane_item;
unsigned int defense_arcane_effect;
unsigned int defense_arcane_skill;
unsigned int defense_corrupted;
unsigned int defense_corrupted_base;
unsigned int defense_corrupted_equip;
unsigned int defense_corrupted_item;
unsigned int defense_corrupted_effect;
unsigned int defense_corrupted_skill;
// Accuracy
float dodge_chance;
float dodge_chance_base;
float dodge_chance_equip;
float dodge_chance_item;
float dodge_chance_effect;
float dodge_chance_skill;
float root_protection;
float root_protection_base;
float root_protection_equip;
float root_protection_item;
float root_protection_effect;
float root_protection_skill;
float miss_chance;
float miss_chance_base;
float miss_chance_equip;
float miss_chance_item;
float miss_chance_effect;
float miss_chance_skill;
// Movement
// Additional speeds may be defined for players
float speed_walk1; // normal/fast
float speed_walk1_base;
float speed_walk1_equip;
float speed_walk1_item;
float speed_walk1_effect;
float speed_walk1_skill;
float speed_walk2; // casual/slow
float speed_swim1; // normal/fast
float speed_swim1_base;
float speed_swim1_equip;
float speed_swim1_item;
float speed_swim1_effect;
float speed_swim1_skill;
float speed_swim2; // casual/slow
float speed_fly1; // normal/fast
float speed_fly1_base;
float speed_fly1_equip;
float speed_fly1_item;
float speed_fly1_effect;
float speed_fly1_skill;
float speed_fly2; // casual/slow
float speed_jump;
float speed_dodge;
float speed_turn;
// Fighting speed
float speed_cast;
float speed_cast_base;
float speed_cast_equip;
float speed_cast_item;
float speed_cast_effect;
float speed_cast_skill;
float speed_attack;
float speed_attack_base;
float speed_attack_equip;
float speed_attack_item;
float speed_attack_effect;
float speed_attack_skill;
};
#endif
struct CPlayerStats {
};
#endif

View File

@ -0,0 +1,53 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_MOB_PLAYER_REPUTATION_H
#define TOS_MODELS_MOB_PLAYER_REPUTATION_H
#include "../../../stdlib/Types.h"
struct Reputation {
// Character trait
int8 bravery;
int8 skill;
int8 wisdom;
int8 goodness;
int8 loyalty;
int8 gratefulness;
int8 persistence;
int8 love;
int8 creativity;
int8 patience;
int8 ambition;
int8 honesty;
int8 empathy;
int8 discretion;
int8 fairness;
int8 kindness;
int8 selflessness;
int8 confidence;
int8 curiousity;
int8 discipline;
int8 flexibility;
int8 humility;
int8 openness;
int8 reliability;
int8 lawfulness;
// Character activity
int8 thief_threat_level;
int8 brawler;
int8 murderer;
int8 trader;
int8 ripoff;
int8 dungeoneer;
int8 raider;
int8 pvpler;
};
#endif

83
models/object/Block.cpp Normal file
View File

@ -0,0 +1,83 @@
void make_cube_faces(
float *data, float ao[6][4], float light[6][4],
int left, int right, int top, int bottom, int front, int back,
int wleft, int wright, int wtop, int wbottom, int wfront, int wback,
float x, float y, float z, float n)
{
static const float positions[6][4][3] = {
{{-1, -1, -1}, {-1, -1, +1}, {-1, +1, -1}, {-1, +1, +1}},
{{+1, -1, -1}, {+1, -1, +1}, {+1, +1, -1}, {+1, +1, +1}},
{{-1, +1, -1}, {-1, +1, +1}, {+1, +1, -1}, {+1, +1, +1}},
{{-1, -1, -1}, {-1, -1, +1}, {+1, -1, -1}, {+1, -1, +1}},
{{-1, -1, -1}, {-1, +1, -1}, {+1, -1, -1}, {+1, +1, -1}},
{{-1, -1, +1}, {-1, +1, +1}, {+1, -1, +1}, {+1, +1, +1}}
};
static const float normals[6][3] = {
{-1, 0, 0},
{+1, 0, 0},
{0, +1, 0},
{0, -1, 0},
{0, 0, -1},
{0, 0, +1}
};
static const float uvs[6][4][2] = {
{{0, 0}, {1, 0}, {0, 1}, {1, 1}},
{{1, 0}, {0, 0}, {1, 1}, {0, 1}},
{{0, 1}, {0, 0}, {1, 1}, {1, 0}},
{{0, 0}, {0, 1}, {1, 0}, {1, 1}},
{{0, 0}, {0, 1}, {1, 0}, {1, 1}},
{{1, 0}, {1, 1}, {0, 0}, {0, 1}}
};
static const float indices[6][6] = {
{0, 3, 2, 0, 1, 3},
{0, 3, 1, 0, 2, 3},
{0, 3, 2, 0, 1, 3},
{0, 3, 1, 0, 2, 3},
{0, 3, 2, 0, 1, 3},
{0, 3, 1, 0, 2, 3}
};
static const float flipped[6][6] = {
{0, 1, 2, 1, 3, 2},
{0, 2, 1, 2, 3, 1},
{0, 1, 2, 1, 3, 2},
{0, 2, 1, 2, 3, 1},
{0, 1, 2, 1, 3, 2},
{0, 2, 1, 2, 3, 1}
};
float *d = data;
float s = 0.0625;
float a = 0 + 1 / 2048.0;
float b = s - 1 / 2048.0;
int faces[6] = {left, right, top, bottom, front, back};
int tiles[6] = {wleft, wright, wtop, wbottom, wfront, wback};
for (int i = 0; i < 6; i++) {
if (faces[i] == 0) {
continue;
}
float du = (tiles[i] % 16) * s;
float dv = (tiles[i] / 16) * s;
int flip = ao[i][0] + ao[i][3] > ao[i][1] + ao[i][2];
for (int v = 0; v < 6; v++) {
int j = flip ? flipped[i][v] : indices[i][v];
*(d++) = x + n * positions[i][j][0];
*(d++) = y + n * positions[i][j][1];
*(d++) = z + n * positions[i][j][2];
*(d++) = normals[i][0];
*(d++) = normals[i][1];
*(d++) = normals[i][2];
*(d++) = du + (uvs[i][j][0] ? b : a);
*(d++) = dv + (uvs[i][j][1] ? b : a);
*(d++) = ao[i][j];
*(d++) = light[i][j];
}
}
}

94
models/object/Block.h Normal file
View File

@ -0,0 +1,94 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_BLOCK_H
#define TOS_MODELS_BLOCK_H
#include "../../stdlib/Types.h"
#include "../../stdlib/SIMD/SIMD_I32.h"
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Block
//
// Blocks are landscape blocks that just get rendered as is
// Blocks are very simple -> fast to render
// WARNING: No other block can be placed at its position!
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Block coordinates are relative to the chunk coordinates
// Block coordinates can also be only grid-based
// Therefore the x,y,z coordinates can be byte datatypes
struct Block {
// 0 - x
// 1 - y
// 2 - z
// 3 - rot1
// 4 - rot2
// 5 - type
int32 v[6];
};
struct BlockDB {
int32 x;
int32 y;
int32 z;
int32 rot1;
int32 rot2;
int32 type;
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// BlockObject
//
// BlockObjectss are any object that fits on the grid.
// BlocksObjects are very simple -> faster to render than other objects.
// WARNING: No other block can be placed at its position!
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Block coordinates are relative to the chunk coordinates
// Block coordinates can also be only grid-based
// Therefore the x,y,z coordinates can be byte datatypes
struct BlockObject {
// 0 - x
// 1 - y
// 2 - z
// 3 - type
// 4 - rotx
// 5 - roty
Stdlib::SIMD::int32_8_simd v;
};
struct BlockObjectDB {
byte x;
byte y;
byte z;
uint32 type;
// first 4 bits = rotation
// 4 possible x rotations
// 4 possible y rotations
// -> 16 possible combinations
// -> 2^4 -> 4 bits
//
// last 4 bits = scale
// -> first bit defines positive or negative scale factor
// -> last 3 bits define scale factor
// -> 2^3 = 8 scale factors
// -> A block can be maximum 9 times its original size or 1/9th of it
// -> note that 0 is the original scale -> 1+8
byte rotation_scale;
};
#endif

55
models/object/Chunk.h Normal file
View File

@ -0,0 +1,55 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_OBJECT_CHUNK_H
#define TOS_MODELS_OBJECT_CHUNK_H
#include "../../stdlib/SIMD/SIMD_I32.h"
#include "../../../stdlib/Types.h"
#include "Block.h"
#include "Object.h"
struct Chunk {
// 0 - x
// 1 - y
// 2 - z
// 3 - size
Stdlib::SIMD::int32_4_simd v;
};
struct ChunkDB {
int x;
int y;
int z;
int size;
};
struct BlockChunk {
Chunk chunk;
// Max size depends on CHUNK_SIZE (= CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE)
Block *entities;
};
struct BlockObjectChunk {
Chunk chunk;
// Max size depends on CHUNK_SIZE (= CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE)
BlockObject *entities;
};
struct ObjectChunk {
Chunk chunk;
// Max size is "unlimited" since multiple objects can be placed at any position
Object *enteties;
};
#endif

37
models/object/Cube.h Normal file
View File

@ -0,0 +1,37 @@
// 6 faces, 4 vertexes, 3 coordinates
positions = {
-1, -1, -1, -1, -1, +1, -1, +1, -1, -1, +1, +1,
+1, -1, -1, +1, -1, +1, +1, +1, -1, +1, +1, +1,
-1, +1, -1, -1, +1, +1, +1, +1, -1, +1, +1, +1,
-1, -1, -1, -1, -1, +1, +1, -1, -1, +1, -1, +1,
-1, -1, -1, -1, +1, -1, +1, -1, -1, +1, +1, -1,
-1, -1, +1, -1, +1, +1, +1, -1, +1, +1, +1, +1
};
// 6 faces 3 coordinates
normals = {
-1, 0, 0,
+1, 0, 0,
0, +1, 0,
0, -1, 0,
0, 0, -1,
0, 0, +1
};
indices = {
0, 3, 2, 0, 1, 3,
0, 3, 1, 0, 2, 3,
0, 3, 2, 0, 1, 3,
0, 3, 1, 0, 2, 3,
0, 3, 2, 0, 1, 3,
0, 3, 1, 0, 2, 3
};
flipped = {
0, 1, 2, 1, 3, 2,
0, 2, 1, 2, 3, 1,
0, 1, 2, 1, 3, 2,
0, 2, 1, 2, 3, 1,
0, 1, 2, 1, 3, 2,
0, 2, 1, 2, 3, 1
};

23
models/object/Object.h Normal file
View File

@ -0,0 +1,23 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_OBJECT_H
#define TOS_MODELS_OBJECT_H
#include "../../../stdlib/Types.h"
// Object coordinates are relative to the chunk coordinates
struct Object {
float x;
float y;
float z;
uint32 type; // defined in object_list
};
#endif

View File

@ -0,0 +1,24 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_Object_TYPE_H
#define TOS_MODELS_Object_TYPE_H
#include "../../config.h"
#include "../../../stdlib/Types.h"
struct ObjectType {
byte id;
byte destructable;
bool climbable;
bool collectable;
bool drops;
bool changable;
};
#endif

279
models/object/object_list.h Normal file
View File

@ -0,0 +1,279 @@
#ifndef TOS_MODELS_OBJECT_LIST_H
#define TOS_MODELS_OBJECT_LIST_H
// (null)
#define OBJ_UNASSIGNED 0x00000000
#define OBJ_ALCHEMY 0x000000CC
#define OBJ_BUCKET 0x000000D8
#define OBJ_CART 0x000000C8
#define OBJ_CHEESE 0x000000DB
#define OBJ_COMPASS 0x000000E3
#define OBJ_DECANTER 0x000000DA
#define OBJ_FORK 0x000000D0
#define OBJ_FURNACE 0x000000CB
#define OBJ_GADGETS 0x000000CD
#define OBJ_GLASS 0x000000D4
#define OBJ_GLASSES 0x000000E4
#define OBJ_GYROSCOPE 0x000000E0
#define OBJ_ICE 0x00000097
#define OBJ_JUG 0x000000D5
#define OBJ_KNIFE 0x000000D2
#define OBJ_LECTERN 0x000000CE
#define OBJ_LOOM 0x000000C9
#define OBJ_MONOCLE 0x000000E5
#define OBJ_NOODLE 0x000000DF
#define OBJ_PITCHER 0x000000D6
#define OBJ_RUSSIAN_EGG 0x000000E6
#define OBJ_SEXTANT 0x000000E2
#define OBJ_SNOW 0x00000096
#define OBJ_SOUP_PLATE 0x000000D3
#define OBJ_SPINNING_MACHINE 0x000000CF
#define OBJ_SPOON 0x000000D1
#define OBJ_STEAK 0x000000DC
#define OBJ_TELESCOPE 0x000000E1
#define OBJ_TRAIN 0x000000CA
#define OBJ_TRAY 0x000000D7
#define OBJ_TURKEY 0x000000DD
#define OBJ_WINE_GLASS 0x000000D9
// Ore
#define OBJ_ORE 0x04000000
#define OBJ_ALUMINUM 0x04000006
#define OBJ_AMBER 0x04000041
#define OBJ_AMETHYST 0x04000040
#define OBJ_BENITOITE 0x0400003C
#define OBJ_BISMUTH 0x04000007
#define OBJ_BLACK_OPAL 0x0400003B
#define OBJ_CLAY 0x040000AD
#define OBJ_COAL 0x04000042
#define OBJ_COBALT 0x04000008
#define OBJ_COBBLESTONE 0x04000052
#define OBJ_COPPER 0x04000009
#define OBJ_DIAMOND 0x04000043
#define OBJ_EARTH 0x04000002
#define OBJ_EMERALD 0x04000044
#define OBJ_FLINTSTONE 0x04000095
#define OBJ_GOLD 0x0400000A
#define OBJ_GRANITE 0x0400004F
#define OBJ_IRON 0x0400000B
#define OBJ_JADEIT 0x0400003F
#define OBJ_LIMESTONE 0x0400004E
#define OBJ_MANGANESE 0x0400000C
#define OBJ_MARBLE 0x04000050
#define OBJ_METEORITE 0x04000047
#define OBJ_NICKEL 0x0400000D
#define OBJ_PHOSPHORUS 0x0400005F
#define OBJ_PLATINUM 0x0400000E
#define OBJ_QUARTZ 0x04000051
#define OBJ_RED_BERYL 0x0400003A
#define OBJ_RED_MEAT 0x04000062
#define OBJ_RUBY 0x04000049
#define OBJ_SALT 0x04000060
#define OBJ_SAND 0x04000001
#define OBJ_SANDSTONE 0x0400005C
#define OBJ_SAPPHIRE 0x04000048
#define OBJ_SILVER 0x0400000F
#define OBJ_STONE 0x04000003
#define OBJ_SULFUR 0x0400005E
#define OBJ_TAAFFEIT 0x0400003E
#define OBJ_TANZANITE 0x0400003D
#define OBJ_TIN 0x040000AE
#define OBJ_TITANIUM 0x04000010
#define OBJ_TUNGSTEN 0x04000011
#define OBJ_VOLCANIC_ROCK 0x040000AC
#define OBJ_WHITE_MEAT 0x04000061
#define OBJ_ZINC 0x040000AF
// Block
#define OBJ_BLOCK 0x05000000
#define OBJ_COLOR_BLOCK_1 0x050000EA
#define OBJ_COLOR_BLOCK_10 0x050000FA
#define OBJ_COLOR_BLOCK_11 0x050000FD
#define OBJ_COLOR_BLOCK_12 0x050000FE
#define OBJ_COLOR_BLOCK_13 0x050000FF
#define OBJ_COLOR_BLOCK_14 0x05000100
#define OBJ_COLOR_BLOCK_15 0x05000101
#define OBJ_COLOR_BLOCK_16 0x05000102
#define OBJ_COLOR_BLOCK_2 0x050000F2
#define OBJ_COLOR_BLOCK_3 0x050000F3
#define OBJ_COLOR_BLOCK_4 0x050000F4
#define OBJ_COLOR_BLOCK_5 0x050000F5
#define OBJ_COLOR_BLOCK_6 0x050000F6
#define OBJ_COLOR_BLOCK_7 0x050000F7
#define OBJ_COLOR_BLOCK_8 0x050000F8
#define OBJ_COLOR_BLOCK_9 0x050000F9
#define OBJ_EARTH_BLOCK 0x050000EB
#define OBJ_GLASS_BLOCK 0x050000ED
#define OBJ_GRANITE_BLOCK 0x05000104
#define OBJ_GRASS_BLOCK 0x050000F1
#define OBJ_GRAVEL_BLOCK 0x05000103
#define OBJ_ICE_BLOCK 0x050000EC
#define OBJ_ICE_COVER 0x050000EF
#define OBJ_LAVA_BLOCK 0x050000FC
#define OBJ_SAND_BLOCK 0x050000E7
#define OBJ_SNOW_BLOCK 0x050000EE
#define OBJ_SNOW_COVER 0x050000F0
#define OBJ_STONE_BLOCK 0x050000E8
#define OBJ_WATER_BLOCK 0x050000FB
#define OBJ_WOOD_BLOCK 0x050000E9
// Herb
#define OBJ_HERB 0x06000000
#define OBJ_ACONITUM 0x0600002D
#define OBJ_ALMONDS 0x0600006B
#define OBJ_ANTHURIUM 0x06000030
#define OBJ_APPLE 0x06000081
#define OBJ_AQUILEGIA 0x06000031
#define OBJ_ARNICA 0x06000024
#define OBJ_ARUM 0x06000032
#define OBJ_ASPARAGUS 0x06000084
#define OBJ_BANANA 0x06000086
#define OBJ_BARLEY 0x0600004C
#define OBJ_BASIL 0x0600008F
#define OBJ_BEAN 0x0600007B
#define OBJ_BETONY 0x0600001D
#define OBJ_BLACK_ANTHURIUM 0x060000A8
#define OBJ_BLACK_BACCARA 0x060000AB
#define OBJ_BLACK_DAHLIA 0x060000A9
#define OBJ_BLACK_MAGIC 0x060000A7
#define OBJ_BLACK_ORCHID 0x060000AA
#define OBJ_BLACKBERRY 0x06000063
#define OBJ_BLACKWATER 0x060000A4
#define OBJ_BLEEDING_HEART 0x06000039
#define OBJ_BLOOD_FLOWER 0x06000019
#define OBJ_BROCCOLI 0x06000079
#define OBJ_BRUGMANSIA 0x06000033
#define OBJ_BUCKWHEAT 0x0600004D
#define OBJ_CABBAGE 0x06000080
#define OBJ_CACAO 0x06000067
#define OBJ_CALADIUM 0x06000034
#define OBJ_CAMELLIA 0x06000094
#define OBJ_CARROT 0x0600007C
#define OBJ_CASHEW 0x0600006C
#define OBJ_CAULIFLOWER 0x0600007A
#define OBJ_CHERRY 0x06000082
#define OBJ_CHESTNUTS 0x0600006A
#define OBJ_CINAMON 0x0600008D
#define OBJ_COCONUT 0x0600006D
#define OBJ_COFFEE 0x06000068
#define OBJ_CONEFLOWER 0x06000021
#define OBJ_CONSOLIDA 0x06000035
#define OBJ_CORN 0x0600004A
#define OBJ_CORPSE_FLOWER 0x0600009B
#define OBJ_COTTON 0x06000028
#define OBJ_CUCUMBER 0x06000075
#define OBJ_DELPHINIUM 0x06000036
#define OBJ_DESERT_ROSE 0x0600002F
#define OBJ_DRAGONFRUIT 0x0600008A
#define OBJ_FIBRE 0x06000046
#define OBJ_FLAME_LILY 0x06000037
#define OBJ_FOXGLOVE 0x0600001C
#define OBJ_GARLIC 0x0600007F
#define OBJ_GHOST_ORCHID 0x0600009D
#define OBJ_GINGER 0x0600008C
#define OBJ_GINGKO 0x06000016
#define OBJ_GRAPES 0x0600008B
#define OBJ_GREEN_ONION 0x06000078
#define OBJ_HAZELNUT 0x0600006E
#define OBJ_HENBANE 0x06000020
#define OBJ_HOLLYHOCK 0x060000A2
#define OBJ_HYACINTH 0x060000A3
#define OBJ_HYDRANGEA 0x060000A0
#define OBJ_IRIS 0x06000038
#define OBJ_JASMINE 0x06000091
#define OBJ_KALE 0x06000085
#define OBJ_LATHYRUS 0x0600002A
#define OBJ_LAVENDER 0x06000014
#define OBJ_LEMON 0x06000098
#define OBJ_LETTUCE 0x06000071
#define OBJ_LILY 0x0600001E
#define OBJ_LINEN 0x06000029
#define OBJ_MACADAMIA 0x0600006F
#define OBJ_MARIGOLD 0x0600001B
#define OBJ_MARSH_MALLOW 0x06000023
#define OBJ_MATCHA 0x06000099
#define OBJ_MIDDLEMIST 0x0600009C
#define OBJ_MIDNIGHT_MYSTIC 0x060000A6
#define OBJ_MIDNIGHT_RUFFLES 0x060000A5
#define OBJ_MUSHROOM 0x06000072
#define OBJ_NIGHTSHADE 0x06000022
#define OBJ_ONION 0x06000077
#define OBJ_ORANGE 0x06000083
#define OBJ_OREGANO 0x0600008E
#define OBJ_PEACH 0x06000088
#define OBJ_PEANUTS 0x06000069
#define OBJ_PEAS 0x06000064
#define OBJ_PECANS 0x06000070
#define OBJ_PEONY 0x0600009E
#define OBJ_PEPERMINT 0x06000092
#define OBJ_PEPPER 0x06000073
#define OBJ_PERIWINKLE 0x0600001A
#define OBJ_PINEAPPLE 0x06000087
#define OBJ_PLATYCODON 0x060000A1
#define OBJ_POTATOS 0x06000065
#define OBJ_PUMPKIN 0x06000076
#define OBJ_RADISH 0x0600007E
#define OBJ_RASPBERRY 0x06000093
#define OBJ_RICE 0x0600004B
#define OBJ_ROSARY_BEAD 0x0600002C
#define OBJ_SAGE 0x06000017
#define OBJ_SENNA 0x0600001F
#define OBJ_SILK 0x06000027
#define OBJ_SOLANUM 0x0600002B
#define OBJ_SPINACH 0x0600007D
#define OBJ_STAR_ANISE 0x06000090
#define OBJ_TOMATO 0x06000074
#define OBJ_TURMERIC 0x06000018
#define OBJ_WALNUT 0x06000066
#define OBJ_WATERMELON 0x06000089
#define OBJ_WELWITSCHIA 0x0600009A
#define OBJ_WHEAT 0x06000045
#define OBJ_WHITE_BANEBERRY 0x0600002E
#define OBJ_WISTERIA 0x0600009F
#define OBJ_YARROW 0x06000025
// Liquid
#define OBJ_LIQUID 0x07000000
#define OBJ_LAVA 0x0700005D
#define OBJ_WATER 0x07000005
// Plant
#define OBJ_PLANT 0x0A000000
#define OBJ_ACACIA_WOOD 0x0A00005B
#define OBJ_ASH_WOOD 0x0A000058
#define OBJ_BAMBOO_WOOD 0x0A000054
#define OBJ_ELM_WOOD 0x0A000057
#define OBJ_MAHOGANY_WOOD 0x0A000059
#define OBJ_OAK_WOOD 0x0A000055
#define OBJ_PINE_WOOD 0x0A000056
#define OBJ_TEAK_WOOD 0x0A00005A
#define OBJ_WALNUT_WOOD 0x0A000053
#define OBJ_WOOD 0x0A000004
// Static Object
#define OBJ_STATIC_OBJECT 0x0B000000
#define OBJ_BAR 0x0B0000BA
#define OBJ_BARREL 0x0B0000BE
#define OBJ_BED 0x0B0000BB
#define OBJ_BOOK 0x0B0000C3
#define OBJ_CHAIR 0x0B0000B6
#define OBJ_CRATE 0x0B0000BF
#define OBJ_DOOR 0x0B0000C4
#define OBJ_FIREPLACE 0x0B0000C1
#define OBJ_IMAGE 0x0B0000B8
#define OBJ_LAMP 0x0B0000B5
#define OBJ_NIGHT_STAND 0x0B0000BC
#define OBJ_OVEN 0x0B0000BD
#define OBJ_PLATE 0x0B0000C0
#define OBJ_POT 0x0B0000C2
#define OBJ_SHELF 0x0B0000B9
#define OBJ_TABLE 0x0B0000B4
#define OBJ_TOOLS 0x0B0000C7
#define OBJ_WALL_ORNAMENTS 0x0B0000C6
#define OBJ_WINDOW 0x0B0000C5
// Static Texture
#define OBJ_STATIC_TEXTURE 0x0D000000
#define OBJ_CARPET 0x0D0000B7
#endif

View File

@ -0,0 +1,27 @@
#ifndef TOS_MODELS_OBJECT_TYPES_H
#define TOS_MODELS_OBJECT_TYPES_H
#define OBJECT_TYPE_LADDER 0x01
#define OBJECT_TYPE_ROPE 0x02
#define OBJECT_TYPE_VINES 0x03
#define OBJECT_TYPE_ORE 0x04
#define OBJECT_TYPE_BLOCK 0x05
#define OBJECT_TYPE_HERB 0x06
#define OBJECT_TYPE_LIQUID 0x07
#define OBJECT_TYPE_PARTICLE 0x08
#define OBJECT_TYPE_FARMING 0x09
#define OBJECT_TYPE_PLANT 0x0A
#define OBJECT_TYPE_STATIC_OBJECT 0x0B
#define OBJECT_TYPE_DYNAMIC_OBJECT 0x0C
#define OBJECT_TYPE_STATIC_TEXTURE 0x0D
#define OBJECT_TYPE_FIXED_LIGHT_SOURCE 0x0E
#define OBJECT_TYPE_DYNAMIC_LIGHT_SOURCE 0x0F
#define OBJECT_TYPE_DYNAMIC_TEXTURE 0x10
#define OBJECT_TYPE_VEHICLE 0x11
#define OBJECT_TYPE_MACHINE 0x12
#define OBJECT_TYPE_MOB 0x13
#define OBJECT_TYPE_FOOD 0x14
#define SIZE_OBJECT_TYPE 0x14
#endif

359
models/settings/Settings.h Normal file
View File

@ -0,0 +1,359 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MODELS_SETTINGS_H
#define TOS_MODELS_SETTINGS_H
#include "../../stdlib/Types.h"
#include "../chat/ChatStatus.h"
#include "setting_types.h"
#if SERVER
struct SSettings {
byte distance_terrain = RENDER_CHUNK_RADIUS;
byte distance_terrain_secondary = RENDER_BLOCK_OBJECT_CHUNK_RADIUS;
byte distance_terrain_tertiary = RENDER_INTERACTIVE_CHUNK_RADIUS;
byte distance_models = RENDER_OBJECT_CHUNK_RADIUS;
byte distance_monster = RENDER_MONSTER_CHUNK_RADIUS;
byte distance_npc = RENDER_NPC_CHUNK_RADIUS;
byte distance_player = RENDER_PAYER_CHUNK_RADIUS;
uint32 player_cache = 8192; // = max active players on a server
uint32 monster_cache = 8192;
uint32 npc_cache = 8192;
uint32 guild_cache = 128;
uint32 message_cache = 1024;
uint32 interpolation_buffer;
byte simd_version;
};
// Player settings that the server needs to know about
struct PSettings {
byte render_distance_models = RENDER_OBJECT_CHUNK_RADIUS;
byte render_distance_monster = RENDER_MONSTER_CHUNK_RADIUS;
byte render_distance_npc = RENDER_NPC_CHUNK_RADIUS;
byte render_distance_player = RENDER_PAYER_CHUNK_RADIUS;
byte chat_status = CHAT_STATUS_OFFLINE;
bool allow_invites = true;
};
#endif
struct CSettings {
char path[MAX_PATH];
bool is_changed = false;
byte simd_version;
byte gpu_api = SETTING_TYPE_GPU_API_NONE;
byte gpu_type = SETTING_TYPE_GPU_MEDIUM;
byte gpu_fps = SETTING_TYPE_UNLIMITED;
byte gpu_aspect_ratio;
byte gpu_resolution;
byte gpu_brightness;
byte gpu_contrast;
byte gpu_gamma;
byte gpu_fov;
byte gpu_sync = SETTING_TYPE_DISABLED;
char editor_hostname[64];
uint16 editor_port;
uint32 gpu_number_of_npc_characters = 128;
uint32 gpu_number_of_player_characters = 512;
uint32 gpu_number_of_monster_characters = 128;
byte gpu_render_distance_terrain = 10;
byte gpu_render_distance_terrain_secondary = 10;
byte gpu_render_distance_terrain_tertiary = 1;
byte gpu_render_distance_models = 1;
byte gpu_render_distance_monster = 3;
byte gpu_render_distance_npc = 3;
byte gpu_render_distance_player = 3;
uint32 player_cache = 512;
uint32 monster_cache = 128;
uint32 npc_cache = 128;
uint32 guild_cache = 128;
uint32 message_cache = 64;
byte gpu_animation_quality;
byte gpu_attack_effect_quality;
byte gpu_shadow_quality;
byte gpu_terrain_quality;
byte gpu_water_quality;
byte gpu_grass_density;
byte gpu_model_quality;
byte gpu_texture_quality;
byte gpu_foliage_distance;
byte gpu_detail_level;
byte gpu_reflection_quality;
byte gpu_refraction_quality;
byte gpu_caustics_quality;
byte gpu_footprint_quality; // mostly used for snow, sand mud
bool gpu_screen_effects; // e.g. water droplets/dust/freezing on screen
byte gpu_memory = 7;
byte cpu_memory = 10;
bool gpu_raytracing = false;
bool gpu_lense_effect = true;
bool gpu_fog_effect = true;
bool gpu_particles_environment = true;
bool gpu_particles_players = true;
bool gpu_particles_monster = true;
bool gpu_particles_ui = true;
bool gpu_particles_skills = true;
bool gpu_particles_weapons = true;
byte gpu_reflection_blur = SETTING_TYPE_DISABLED;
byte gpu_motion_blur = SETTING_TYPE_DISABLED;
byte gpu_blur = SETTING_TYPE_DISABLED;
byte gpu_anti_aliasing = SETTING_TYPE_DISABLED;
byte gpu_sharpening = SETTING_TYPE_DISABLED;
byte gpu_ambient_occlusion = SETTING_TYPE_DISABLED;
bool gpu_depth_of_field = true;
bool gpu_chromatic_aberration = true;
bool gpu_vignetting = true;
bool gpu_light_shafts = true;
bool gpu_camera_shake = false;
byte audio_volume_master = 128;
byte audio_volume_game = 128;
byte audio_volume_environment = 128;
byte audio_volume_music = 128;
byte audio_volume_speech = 128;
uint32 game_window1_dim[2] = {1024, 768};
uint32 game_window1_pos[2];
byte game_window1_mode = SETTING_TYPE_WINDOW_MODE_FULLSCREEN;
byte game_zoom;
byte game_view = SETTING_TYPE_PERSPECTIVE_FIRST;
// General game UI
bool game_crosshair = false;
bool game_healthbar_self = false;
bool game_healthbar_group = false;
bool game_healthbar_players = false;
bool game_healthbar_npc = false;
bool game_healthbar_monsters = false;
bool game_name_monsters = false;
bool game_name_npc = false;
bool game_name_mobs = false;
bool game_show_auras = true;
bool game_show_helmets = true;
uint32 game_interpolation_buffer;
bool game_player_chat = false; // bubble above player
byte game_chat_status = CHAT_STATUS_OFFLINE;
// Extra windows
byte game_window2_type = SETTING_TYPE_DISABLED;
bool game_window2_visible = false;
uint32 game_window2_dim[2] = {1024, 768};
uint32 game_window2_pos[2];
byte game_window3_type = SETTING_TYPE_DISABLED;
bool game_window3_visible = false;
uint32 game_window3_dim[2] = {1024, 768};
uint32 game_window3_pos[2];
byte game_window4_type = SETTING_TYPE_DISABLED;
bool game_window4_visible = false;
uint32 game_window4_dim[2] = {1024, 768};
uint32 game_window4_pos[2];
byte game_window5_type = SETTING_TYPE_DISABLED;
bool game_window5_visible = false;
uint32 game_window5_dim[2] = {1024, 768};
uint32 game_window5_pos[2];
// @todo Consider to allow settings for chat tabs
// define which messags go to which tab
// define custom chat tabs
// UI settings
// Themes
uint32 game_ui_theme = 1;
byte game_ui_size = 128;
uint32 game_item_icon_theme = 1;
uint32 game_menu_theme = 1;
byte game_menu_size = 128;
uint32 game_map_mini_theme = 1;
byte game_map_mini_size = 128;
int32 game_map_mini_pos[2] = { -1, -1 };
uint32 game_quest_theme = 1;
byte game_quest_size = 128;
int32 game_quest_pos[2] = { -1, -1 };
uint32 game_skill_bar_theme = 1;
bool game_skill_bar_animated = false;
byte game_skill_bar_size = 128;
int32 game_skill_bar_pos[2] = { -1, -1 };
uint32 game_health_theme = 1;
bool game_health_animated = false;
byte game_health_size = 128;
int32 game_health_pos[2] = { -1, -1 };
uint32 game_resource_theme = 1;
bool game_resource_animated = false;
byte game_resource_size = 128;
int32 game_resource_pos[2] = { -1, -1 };
uint32 game_party_theme = 1;
bool game_party_animated = false;
byte game_party_size = 128;
int32 game_party_pos[2] = { -1, -1 };
uint32 game_enemy_theme = 1;
bool game_enemy_animated = false;
byte game_enemy_size = 128;
int32 game_enemy_pos[2] = { -1, -1 };
uint32 game_select_info_theme = 1;
byte game_select_info_size = 128;
int32 game_select_info_pos[2] = { -1, -1 };
uint32 game_chat_theme = 1;
byte game_chat_size = 128;
int32 game_chat_pos[2] = { -1, -1 };
// HUD
bool game_show_health_bar_self = false;
bool game_show_health_bar_player = false;
bool game_show_health_bar_monster = false;
bool game_show_health_numbers = false;
bool game_show_resource_numbers = false;
bool game_show_buffs = false;
bool game_show_xp_bar_numbers = true;
bool game_show_name_self = false;
bool game_show_name_player = false;
bool game_show_name_monster = false;
bool game_show_name_npc = false;
bool game_show_title_self = false;
bool game_show_title_other = false;
byte game_minion_visibility_self = 128;
byte game_minion_visibility_player = 128;
bool game_show_dmg_numbers = false;
bool game_show_cooldown_times = false;
bool game_show_dodge = true;
bool game_show_effect_gains = true; // e.g. XP
bool game_minimap_show_merchants = false;
bool game_minimap_show_quest = false;
bool game_minimap_show_dungeons = false;
bool game_minimap_show_names = false;
bool game_show_clock = false;
bool game_map_show_merchants = false;
bool game_map_show_quest = false;
bool game_map_show_dungeons = false;
bool game_map_show_names = false;
bool game_show_subtitles = true;
// Mounts
uint32 game_default_mount = 0;
// Game behavior
bool game_error_audio = true;
bool game_error_text = true;
byte game_default_zoom = 128;
bool game_block_trade = false;
bool game_block_group_invite = false;
bool game_block_guild_invite = false;
bool game_block_chat_invite = false;
bool game_block_friend_invite = false;
bool game_automatically_track_newest_quest = false;
byte game_interact_direction = 0;
byte game_interact_radius = 1;
// Game pad settings
byte stick_left_deadzone = 0;
byte stick_right_deadzone = 0;
byte input_look_speed = 0;
bool input_invert_mouse = false;
bool input_lock_cursor_to_window = true;
bool input_click_to_move = true;
// Hotkey settings
byte hotkeys_movement_up = 0x57; // W
byte hotkeys_movement_down = 0x53; // S
byte hotkeys_movement_left = 0x41; // A
byte hotkeys_movement_right = 0x44; // D
byte hotkeys_cancel_action = 0x44; // X
byte hotkeys_skill_tab_1 = 0x70; // F1
byte hotkeys_skill_tab_2 = 0x71; // F2
byte hotkeys_skill_tab_3 = 0x72; // F3
byte hotkeys_skill_1 = 0x31; // 1
byte hotkeys_skill_2 = 0x32; // 2
byte hotkeys_skill_3 = 0x33; // 3
byte hotkeys_skill_4 = 0x34; // 4
byte hotkeys_skill_5 = 0x35; // 5
byte hotkeys_skill_6 = 0x36; // 6
byte hotkeys_skill_7 = 0x37; // 7
byte hotkeys_skill_8 = 0x38; // 8
byte hotkeys_skill_9 = 0x39; // 9
byte hotkeys_skill_10 = 0x30; // 0
byte hotkeys_interact = 45; // E
byte hotkeys_jump = 0x20; // SPACE
byte hotkeys_dodge = 0x20; // SPACE
byte hotkeys_crouch = 0x14; // CAP
byte hotkeys_walk = 0x11; // CTRL (switches to walking speed, one click only)
byte hotkeys_emote = 0x12; // LEFT_ALT
byte hotkeys_vertical_up = 0x14; // CAPS LOCK
byte hotkeys_vertical_down = 0x10; // SHIFT
byte hotkeys_view_next = 0x09; // TAB
byte hotkeys_view_prv = 0x14; // CAPS LOCK
byte hotkeys_compare_item = 0x11; // CTRL
byte hotkeys_inventory = 0x49; // I
byte hotkeys_character = 0x43; // C
byte hotkeys_skills = 0x53; // S
byte hotkeys_map = 0x4D; // M
byte hotkeys_quest = 0x51; // Q
byte hotkeys_teleport = 0x54; // T
byte hotkeys_attack_move = 0x52; // R
byte hotkeys_force_move = 0x46; // F
byte hotkeys_courser_move = 0x58; // X (move to where courser is)
byte hotkeys_chat = 0x0D; // ENTER
byte hotkeys_hide_ui = 0x48; // H
byte hotkey_zoom_in = 0x21; // Page up (@todo make mouse scroll up)
byte hotkey_zoom_out = 0x22; // page down (@todo make mouse scroll down)
byte hotkey_camera_look = 0x00; // @todo make right mouse hold
byte hotkeys_menu = 0x1B; // ESC
byte hotkeys_window_close = 0x1B; // ESC
};
#endif

View File

View File

View File

View File

View File

@ -0,0 +1,22 @@
gpu_type
gpu_fps
gpu_sync
gpu_number_of_npc_characters
gpu_number_of_player_characters
gpu_number_of_monster_characters
gpu_render_distance_terrain
gpu_render_distance_terrain_secondary
gpu_render_distance_terrain_tertiary
gpu_render_distance_models
gpu_render_distance_monster
gpu_render_distance_npc
gpu_render_distance_player
player_cache
monster_cache
npc_cache
guild_cache
message_cache

View File

@ -0,0 +1,77 @@
#ifndef TOS_MODELS_SETTING_TYPES_H
#define TOS_MODELS_SETTING_TYPES_H
#define SETTING_TYPE_GPU_CUSTOM 0x0
#define SETTING_TYPE_GPU_VLOW 0x1
#define SETTING_TYPE_GPU_LOW 0x2
#define SETTING_TYPE_GPU_MEDIUM 0x3
#define SETTING_TYPE_GPU_HIGH 0x4
#define SETTING_TYPE_GPU_VHIGH 0x5
#define SETTING_TYPE_GPU_ULTRA 0x6
#define SETTING_TYPE_GPU_NEXTGEN 0x7
#define SETTING_TYPE_GPU_API_NONE 0x0
#define SETTING_TYPE_GPU_API_DIRECTX11 0x1
#define SETTING_TYPE_GPU_API_DIRECTX12 0x2
#define SETTING_TYPE_GPU_API_OPENGL 0x3
#define SETTING_TYPE_PERSPECTIVE_FIRST 0x00
#define SETTING_TYPE_PERSPECTIVE_THIRD 0x01
#define SETTING_TYPE_PERSPECTIVE_ISOMETRIC 0x02
#define SETTING_TYPE_ANTI_ALIASING_TAA 0x01
#define SETTING_TYPE_ANTI_ALIASING_SSAA 0x02
#define SETTING_TYPE_ANTI_ALIASING_MSAA 0x03
#define SETTING_TYPE_ANTI_ALIASING_FXAA 0x04
#define SETTING_TYPE_SYNC_V 0x1
#define SETTING_TYPE_SYNC_ADAPTIVE 0x2
#define SETTING_TYPE_SYNC_FAST 0x3
#define SETTING_TYPE_ASPEC_RATIO_4x3 0x00
#define SETTING_TYPE_ASPEC_RATIO_16x9 0x01
#define SETTING_TYPE_ASPEC_RATIO_16x10 0x02
#define SETTING_TYPE_ASPEC_RATIO_21x9 0x03
#define SETTING_TYPE_SCREEN_RESOLUTION_800x600 0x00
#define SETTING_TYPE_SCREEN_RESOLUTION_1024x768 0x01
#define SETTING_TYPE_SCREEN_RESOLUTION_1280x720 0x02
#define SETTING_TYPE_SCREEN_RESOLUTION_1280x800 0x03
#define SETTING_TYPE_SCREEN_RESOLUTION_1280x1024 0x04
#define SETTING_TYPE_SCREEN_RESOLUTION_1360x768 0x05
#define SETTING_TYPE_SCREEN_RESOLUTION_1366x768 0x06
#define SETTING_TYPE_SCREEN_RESOLUTION_1440x900 0x07
#define SETTING_TYPE_SCREEN_RESOLUTION_1536x864 0x08
#define SETTING_TYPE_SCREEN_RESOLUTION_1600x900 0x09
#define SETTING_TYPE_SCREEN_RESOLUTION_1600x1200 0x0A
#define SETTING_TYPE_SCREEN_RESOLUTION_1680x1050 0x0B
#define SETTING_TYPE_SCREEN_RESOLUTION_1920x1080 0x0C
#define SETTING_TYPE_SCREEN_RESOLUTION_1920x1200 0x0D
#define SETTING_TYPE_SCREEN_RESOLUTION_2048x1152 0x0E
#define SETTING_TYPE_SCREEN_RESOLUTION_2048x1536 0x0F
#define SETTING_TYPE_SCREEN_RESOLUTION_2560x1080 0x10
#define SETTING_TYPE_SCREEN_RESOLUTION_2560x1440 0x11
#define SETTING_TYPE_SCREEN_RESOLUTION_2560x1600 0x12
#define SETTING_TYPE_SCREEN_RESOLUTION_3440x1440 0x13
#define SETTING_TYPE_SCREEN_RESOLUTION_3840x2160 0x14
#define SETTING_TYPE_WINDOW_CHAT 0x01
#define SETTING_TYPE_WINDOW_MAP 0x02
#define SETTING_TYPE_WINDOW_RANKING 0x03
#define SETTING_TYPE_WINDOW_SHOP 0x04
#define SETTING_TYPE_WINDOW_STATS 0x05
#define SETTING_TYPE_WINDOW_GROUPS 0x06
#define SETTING_TYPE_WINDOW_PET 0x07 // Pet "tamagochi" window
#define SETTING_TYPE_WINDOW_MODE_FULLSCREEN 0x00
#define SETTING_TYPE_WINDOW_MODE_WINDOWED_FULLSCREEN 0x01
#define SETTING_TYPE_WINDOW_MODE_WINDOWED 0x02
#define SETTING_TYPE_SIMD_128 1
#define SETTING_TYPE_SIMD_256 2
#define SETTING_TYPE_SIMD_512 3
#define SETTING_TYPE_DISABLED 0x00
#define SETTING_TYPE_UNLIMITED 0x00
#endif

84
network/Client.h Normal file
View File

@ -0,0 +1,84 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_NETWORK_CLIENT_H
#define TOS_NETWORK_CLIENT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SocketConnection.h"
#include "../stdlib/Types.h"
#include "../utils/RingMemory.h"
#if _WIN32
#include <winsock2.h>
#include <windows.h>
#define close closesocket
#define sleep Sleep
#else
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#endif
#ifndef MAX_STATIC_NETWORK_PACKET_SIZE
#define MAX_STATIC_NETWORK_PACKET_SIZE 8192
#endif
SOCKET socket_client_udb_connect(const char *hostname, int port, sockaddr_in6 *server_addr) {
addrinfo hints, *res, *p;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;
char port_str[6];
snprintf(port_str, sizeof(port_str), "%d", port);
if (getaddrinfo(hostname, port_str, &hints, &res) != 0) {
return NULL;
}
SOCKET sd = NULL;
for (p = res; p != NULL; p = p->ai_next) {
if ((sd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
continue;
}
memcpy(server_addr, p->ai_addr, p->ai_addrlen);
break;
}
freeaddrinfo(res);
if (p == NULL) {
return NULL;
}
return sd;
}
int socket_client_send(SOCKET sd, char *data, size_t length, sockaddr_in6 *server_addr, socklen_t addr_len) {
int sent_bytes = sendto(sd, data, (int) length, 0, (sockaddr *)server_addr, addr_len);
if (sent_bytes == -1) {
return -1;
}
return 0;
}
int socket_client_disconnect(SOCKET sd)
{
close(sd);
return 0;
}
#endif

8
network/Server.h Normal file
View File

@ -0,0 +1,8 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/

View File

@ -0,0 +1,27 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_NETWORK_SOCKET_CONNECTION_H
#define TOS_NETWORK_SOCKET_CONNECTION_H
#if _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#endif
struct SocketConnection {
SOCKET sd;
sockaddr_in6 server_addr;
socklen_t addr_len;
};
#endif

View File

@ -0,0 +1,103 @@
#ifndef TOS_NETWORK_PACKET_HEADER_H
#define TOS_NETWORK_PACKET_HEADER_H
#include <stdio.h>
#include "../../stdlib/Types.h"
#define HEADER_IPV6_SIZE 40
// Size 40 bytes
struct HeaderIPv6 {
byte data[HEADER_IPV6_SIZE];
};
// Size 42 bytes
struct HeaderIPv6Unpacked {
byte version;
byte traffic_class;
uint32 flow_label;
uint16 length;
byte next_header;
byte hop_limit;
byte src[16];
byte dst[16];
};
inline
void unpack_ipv6_header(const HeaderIPv6* ipv6, HeaderIPv6Unpacked* ipv6_unpacked)
{
ipv6_unpacked->version = (ipv6->data[0] >> 4) & 0x0F;
ipv6_unpacked->traffic_class = ((ipv6->data[0] & 0x0F) << 4) | (ipv6->data[1] >> 4);
ipv6_unpacked->flow_label = ((ipv6->data[1] & 0x0F) << 16) | (ipv6->data[2] << 8) | ipv6->data[3];
ipv6_unpacked->length = (ipv6->data[4] << 8) | ipv6->data[5];
ipv6_unpacked->next_header = ipv6->data[6];
ipv6_unpacked->hop_limit = ipv6->data[7];
memcpy(ipv6_unpacked->src, &ipv6->data[8], 16);
memcpy(ipv6_unpacked->dst, &ipv6->data[24], 16);
}
inline
void pack_ipv6_header(const HeaderIPv6Unpacked* ipv6_unpacked, HeaderIPv6* ipv6)
{
ipv6->data[0] = (ipv6_unpacked->version << 4) | (ipv6_unpacked->traffic_class >> 4);
ipv6->data[1] = (ipv6_unpacked->traffic_class << 4) | ((ipv6_unpacked->flow_label >> 16) & 0x0F);
ipv6->data[1] |= (ipv6_unpacked->flow_label >> 16) & 0x0F;
ipv6->data[2] = (ipv6_unpacked->flow_label >> 8) & 0xFF;
ipv6->data[3] = ipv6_unpacked->flow_label & 0xFF;
ipv6->data[4] = (ipv6_unpacked->length >> 8) & 0xFF;
ipv6->data[5] = ipv6_unpacked->length & 0xFF;
ipv6->data[6] = ipv6_unpacked->next_header;
ipv6->data[7] = ipv6_unpacked->hop_limit;
memcpy(&ipv6->data[8], ipv6_unpacked->src, 16);
memcpy(&ipv6->data[24], ipv6_unpacked->dst, 16);
}
#define HEADER_UDP_SIZE 8
// Size 8 bytes
struct UDPHeaderIPv6 {
byte data[HEADER_UDP_SIZE];
};
// Size 8 bytes
struct UDPHeaderIPv6Unpacked {
uint16 src_port;
uint16 dst_port;
uint16 length;
uint16 checksum;
};
inline
void unpack_udp_header_ipv6(const UDPHeaderIPv6* ipv6, UDPHeaderIPv6Unpacked* udp_unpacked)
{
udp_unpacked->src_port = (ipv6->data[0] << 8) | ipv6->data[1];
udp_unpacked->dst_port = (ipv6->data[2] << 8) | ipv6->data[3];
udp_unpacked->length = (ipv6->data[4] << 8) | ipv6->data[5];
udp_unpacked->checksum = (ipv6->data[6] << 8) | ipv6->data[7];
}
inline
void pack_udp_header_ipv6(const UDPHeaderIPv6Unpacked* udp_unpacked, UDPHeaderIPv6* ipv6)
{
ipv6->data[0] = (udp_unpacked->src_port >> 8) & 0xFF;
ipv6->data[1] = udp_unpacked->src_port & 0xFF;
ipv6->data[2] = (udp_unpacked->dst_port >> 8) & 0xFF;
ipv6->data[3] = udp_unpacked->dst_port & 0xFF;
ipv6->data[4] = (udp_unpacked->length >> 8) & 0xFF;
ipv6->data[5] = udp_unpacked->length & 0xFF;
ipv6->data[6] = (udp_unpacked->checksum >> 8) & 0xFF;
ipv6->data[7] = udp_unpacked->checksum & 0xFF;
}
// Size 7 bytes
struct CustomHeaderUnpacked {
uint16 msg_sequence;
uint16 msg_ack_sequence;
uint16 msg_ack;
byte msg_type;
};
#endif

View File

@ -0,0 +1,83 @@
#ifndef TOS_NETWORK_PACKET_H
#define TOS_NETWORK_PACKET_H
#include <stdio.h>
#include "../../stdlib/Types.h"
#include "../../compression/LZP.h"
#include "PacketHeader.h"
// The message loop is as follows:
// Game Data -> pack data
// Game Message (packed) -> compress data
// Game Message (compressed) -> combine (ipv6 header + udp header + body)
// Packet
// ... Send ...
// ... Receive ...
// Packet -> split (ipv6 header + udp header + body)
// Game Message (compressed) -> decompress data
// Game Message (packed) -> unpack data
// Game Data
// Game messages
// Type 1: Snapshot = absolute state
// Type 2: Delta = relative data to previous data
// Can be usually much smaller data size, since deltas are usually small
struct UDPPacketIPv6 {
byte* data;
};
struct UDPMessageIPv6 {
HeaderIPv6Unpacked header_ipv6;
UDPHeaderIPv6Unpacked header_udp;
CustomHeaderUnpacked header_custom;
size_t length;
byte* data;
};
/**
* WARNING: This requires the original message to remain in memory since we are only referencing the data
*/
inline
void udp_packet_to_message(const UDPPacketIPv6* packet, UDPMessageIPv6* message)
{
unpack_ipv6_header((const HeaderIPv6*) packet->data, &message->header_ipv6);
unpack_udp_header_ipv6((const UDPHeaderIPv6*) (packet->data + HEADER_IPV6_SIZE), &message->header_udp);
message->data = (byte *) (packet->data + HEADER_IPV6_SIZE + HEADER_UDP_SIZE);
// @todo transform packet data to appropriate packet type
}
/**
* The original message can be deleted since the data is copied over
*/
inline
void message_to_udp_packet(const UDPMessageIPv6* message, UDPPacketIPv6* packet)
{
pack_ipv6_header(&message->header_ipv6, (HeaderIPv6 *) packet);
packet->data = packet->data + HEADER_IPV6_SIZE;
pack_udp_header_ipv6(&message->header_udp, (UDPHeaderIPv6 *) packet);
packet->data = packet->data - HEADER_IPV6_SIZE;
memcpy(packet->data + HEADER_IPV6_SIZE + HEADER_UDP_SIZE, message->data, message->length);
}
inline
void decompress_data(UDPMessageIPv6* message, byte* decompress_buffer)
{
decode_lzp(message->data, message->length, decompress_buffer);
message->data = decompress_buffer;
}
inline
void compress_data(UDPMessageIPv6* message, byte* compressed_buffer)
{
encode_lzp(message->data, message->length, compressed_buffer);
message->data = compressed_buffer;
}
#endif

View File

@ -0,0 +1,24 @@
#ifndef TOS_NETWORK_PACKET_CHAT_MESSAGE_H
#define TOS_NETWORK_PACKET_CHAT_MESSAGE_H
#include <stdio.h>
#include "../../../stdlib/Types.h"
#include "../../../config.h"
struct ChatMessagePacket {
byte* data; // fixed 8+2+?
};
struct ChatMessagePacketUnpacked {
uint32 from;
uint32 to;
byte type; // 2^3 Global, Player, Group, Guild, Local
byte level; // 2^2 Normal, info (grey), important (yellow), critical (red)
uint16 length; // 2^9
char* message; // Max Length: MAX_MESSAGE_LENGTH
};
#endif

View File

@ -0,0 +1,39 @@
#ifndef TOS_NETWORK_PACKET_MOB_INFO_H
#define TOS_NETWORK_PACKET_MOB_INFO_H
#include <stdio.h>
#include "../../../stdlib/Types.h"
struct MobInfoPacketSnapshot {
byte* data;
};
struct MobInfoPacketSnapshotUnpacked {
uint32 mob_id;
byte mob_type;
uint32 chunk;
byte level; // 2^7
byte health; // 2^7
byte resource; // 2^7
byte xp;
// Data layout
// 12223444
// 1: scale sign
// 2: scale factor (8)
// 3: weight sign
// 4: weight factor (8)
byte custom_size;
// Data layout
// 1122222?
// 1: body type (4)
// 2: skin color (32)
byte custom_body;
uint64 time;
};
#endif

View File

@ -0,0 +1,52 @@
#ifndef TOS_NETWORK_PACKET_MOB_STATE_H
#define TOS_NETWORK_PACKET_MOB_STATE_H
#include <stdio.h>
#include "../../../stdlib/Types.h"
struct MobStatePacketSnapshot {
byte* data;
};
struct MobStatePacketSnapshotUnpacked {
uint32 mob_id;
byte mob_type;
uint32 chunk;
f16 x;
f16 y;
f16 z;
f16 roll;
f16 pitch;
f16 yaw;
uint32 state_flag;
uint64 time;
};
struct MobStatePacketDelta {
byte* data;
};
struct MobStatePacketDeltaUnpacked {
uint32 mob_id;
byte mob_type;
uint32 chunk;
f16 x;
f16 y;
f16 z;
f16 roll;
f16 pitch;
f16 yaw;
uint32 state_flag;
uint64 time;
};
#endif

View File

@ -0,0 +1,85 @@
#ifndef TOS_NETWORK_PACKET_MOB_PLAYER_INFO_H
#define TOS_NETWORK_PACKET_MOB_PLAYER_INFO_H
#include <stdio.h>
#include "../../../../stdlib/Types.h"
#include "../../../../config.h"
struct PlayerInfoPacketSnapshot {
byte* data;
};
// 32+32+256+128+8+8+7+7+7+7+56+406+448+64=184bytes
struct PlayerInfoPacketSnapshotUnpacked {
uint32 mob_id;
uint32 chunk;
byte name[MAX_CHAR_NAME_LENGTH];
byte title[MAX_CHAR_TITLE_LENGTH];
byte xp;
// Data layout
// 12223444
// 1: scale sign
// 2: scale factor (8)
// 3: weight sign
// 4: weight factor (8)
byte scale;
byte weight;
byte level; // 2^7
byte health; // 2^7
byte resource; // 2^7
// Data layout 2^7
// 1122222?
// 1: body type (4)
// 2: skin color (32)
byte body_type;
byte body_color;
// Data layout
// 1-4 race (16)
//
// 5-9 face type (32)
//
// 10-15 hair style (64)
// 16-20 hair color (32)
//
// 21-26 beard style (32)
//
// 27-30 eye style (32)
// 31-35 eye color (32)
//
// 36-40 face scar (32)
// 41-45 body scar (32)
//
// 46-51 tattoo (64)
// 52-56 tattoo color (32)
byte race;
byte face_type;
byte hair_style;
byte hair_color;
byte beard_style;
byte eye_style;
byte eye_color;
byte face_scar;
byte body_scar;
byte tattoo;
byte tattoo_color;
// Equipment transmog data
// 11111222223333344444444455555???
// 1: primary color (32)
// 2: secondary color (32)
// 3: tertiary color (32)
// 4: effect (512)
// 5: effect color (32)
// ?: FREE
uint32 equipmentTransmog[14];
uint32 equipment[14];
uint64 time;
};
#endif

View File

@ -0,0 +1,12 @@
#ifndef TOS_NETWORK_PACKAGE_PLAYER_STATE_H
#define TOS_NETWORK_PACKAGE_PLAYER_STATE_H
#include "../../../stdlib/Types.h"
struct SPlayerState {
};
struct CPlayerState {
};
#endif

View File

@ -0,0 +1,88 @@
#ifndef TOS_NETWORK_PACKET_TYPES_H
#define TOS_NETWORK_PACKET_TYPES_H
#define PACKET_TYPE_AUTH 0
#define SUB_PACKET_TYPE_AUTH_LOGIN 0
#define SUB_PACKET_TYPE_AUTH_LOADIN 1
#define SUB_PACKET_TYPE_AUTH_LOADOUT 2
#define SUB_PACKET_TYPE_AUTH_LOGOUT 3
#define PACKET_TYPE_MOB_STATE_SNAPSHOT 1
#define PACKET_TYPE_MOB_STATE_DELTA 2
#define PACKET_TYPE_MOB_STATE_POSITION_SNAPSHOT 3
#define PACKET_TYPE_MOB_STATE_POSITION_DELTA 4
#define PACKET_TYPE_MOB_STATE_ACTION_SNAPSHOT 5
#define PACKET_TYPE_MOB_STATE_ACTION_DELTA 6
#define PACKET_TYPE_MOB_LOOKS 7
#define PACKET_TYPE_CHAT_MSG 8
#define PACKET_TYPE_CHAT_ACTION 9
#define SUB_PACKET_TYPE_CHAT_FRIENDS_LOAD 1
#define SUB_PACKET_TYPE_CHAT_FRIENDS_ADD 2
#define SUB_PACKET_TYPE_CHAT_FRIENDS_REMOVE 3
#define SUB_PACKET_TYPE_CHAT_BLOCKED_LOAD 4
#define SUB_PACKET_TYPE_CHAT_BLOCKED_ADD 5
#define SUB_PACKET_TYPE_CHAT_BLOCKED_REMOVE 6
#define SUB_PACKET_TYPE_CHAT_FIND 7 // no data = list all
#define PACKET_TYPE_GUILD 10
#define SUB_PACKET_TYPE_GUILD_INVITE 0
#define SUB_PACKET_TYPE_GUILD_REQUEST 1
#define SUB_PACKET_TYPE_GUILD_JOIN 2
#define SUB_PACKET_TYPE_GUILD_LEAVE 3
#define SUB_PACKET_TYPE_GUILD_KICK 4
#define SUB_PACKET_TYPE_GUILD_FIND 5 // no data = list all
#define SUB_PACKET_TYPE_GUILD_LOAD_PUBLIC 6
#define SUB_PACKET_TYPE_GUILD_LOAD_PRIVATE 7
#define SUB_PACKET_TYPE_GUILD_LOAD_MEMBERS 8
#define SUB_PACKET_TYPE_GUILD_ACTION_CREATE 9
#define SUB_PACKET_TYPE_GUILD_ACTION_DELETE 10
#define SUB_PACKET_TYPE_GUILD_ACTION_PERMISSION 11 // Change permission of member
#define SUB_PACKET_TYPE_GUILD_ACTION_RENAME 12
#define SUB_PACKET_TYPE_GUILD_ACTION_DESCRIPTION 13
#define SUB_PACKET_TYPE_GUILD_ACTION_DESIGN 14
#define SUB_PACKET_TYPE_GUILD_ACTION_BANNER 15
// @todo guild hall actions (buy/sell/add furniture/...)
#define PACKET_TYPE_SHOP 11
#define SUB_PACKET_TYPE_SHOP_FIND 0
#define SUB_PACKET_TYPE_SHOP_SELL 1
#define SUB_PACKET_TYPE_SHOP_BUY 2
#define SUB_PACKET_TYPE_SHOP_BID 3
#define SUB_PACKET_TYPE_SHOP_CANCEL 4
#define PACKET_TYPE_SHOP 12
#define SUB_PACKET_TYPE_SHOP_FIND 0
#define SUB_PACKET_TYPE_SHOP_SELL 1
#define SUB_PACKET_TYPE_SHOP_BUY 2
#define SUB_PACKET_TYPE_SHOP_BID 3
#define SUB_PACKET_TYPE_SHOP_CANCEL 4
#define PACKET_TYPE_GROUP 13
#define SUB_PACKET_TYPE_GROUP_INVITE 0
#define SUB_PACKET_TYPE_GROUP_JOIN 1
#define SUB_PACKET_TYPE_GROUP_LEAVE 2
#define SUB_PACKET_TYPE_GROUP_KICK 3
#define SUB_PACKET_TYPE_GROUP_FIND 4
#define PACKET_TYPE_INTERACT 14
#define PACKET_TYPE_MOB_ITEM 15
#define SUB_PACKET_TYPE_MOB_ITEM_PICKUP 0
#define SUB_PACKET_TYPE_MOB_ITEM_USE 1
#define SUB_PACKET_TYPE_MOB_ITEM_EQUIP 2
#define SUB_PACKET_TYPE_MOB_ITEM_DROP 3
#define SUB_PACKET_TYPE_MOB_ITEM_MOVE 4
#define PACKET_TYPE_GM_ACTION 16
#define SUB_PACKET_TYPE_GM_ACTION_MOVE 0 // moves any type of mob to any location
#define SUB_PACKET_TYPE_GM_ACTION_KILL 1
#define SUB_PACKET_TYPE_GM_ACTION_SPAWN 2
#define SUB_PACKET_TYPE_GM_ACTION_KICK 3
#define SUB_PACKET_TYPE_GM_ACTION_BAN 4
#define SUB_PACKET_TYPE_GM_ACTION_CHAT_REMOVE 5
#define SUB_PACKET_TYPE_GM_ACTION_AWARD_QUEST 6
#define SUB_PACKET_TYPE_GM_ACTION_RESET_QUEST 7
#endif

View File

@ -0,0 +1,54 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_UTILS_LINUX_H
#define TOS_UTILS_LINUX_H
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/stat.h>
#include <unistd.h>
#include "../../stdlib/Types.h"
#include "../../utils/Utils.h"
#include "../../utils/TestUtils.h"
inline uint64 last_modification(const char* filename)
{
struct stat buffer;
stat(filename, &buffer);
return (uint64) buffer.st_mtime.tv_sec;
}
inline void
file_read(const char* filename, file_body* file)
{
FILE *fp = fopen(filename, "rb");
fseek(fp, 0, SEEK_END);
file->size = ftell(fp);
rewind(fp);
fread(file->content, 1, file->size, fp);
fclose(fp);
}
inline
void strncpy_s(char *dest, size_t destsz, const char *src, size_t count) {
size_t i;
for (i = 0; i < count && i < destsz - 1 && src[i] != '\0'; ++i) {
dest[i] = src[i];
}
dest[i] = '\0';
}
#endif

369
platform/win32/UtilsWin32.h Normal file
View File

@ -0,0 +1,369 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_UTILS_WIN32_H
#define TOS_UTILS_WIN32_H
#include <windows.h>
#ifdef _MSC_VER
#include <io.h>
#endif
#include "../../stdlib/Types.h"
#include "../../utils/Utils.h"
#include "../../utils/TestUtils.h"
#define strtok_r strtok_s
inline uint64
file_size(const char* filename)
{
HANDLE fp = CreateFileA((LPCSTR) filename,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fp == INVALID_HANDLE_VALUE) {
return 0;
}
LARGE_INTEGER size;
if (!GetFileSizeEx(fp, &size)) {
CloseHandle(fp);
}
CloseHandle(fp);
return size.QuadPart;
}
inline void
file_read(const char* filename, file_body* file)
{
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;
}
inline uint64
file_read_struct(const char* filename, void* file, uint32 size)
{
HANDLE fp = CreateFileA((LPCSTR) filename,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fp == INVALID_HANDLE_VALUE) {
return 0;
}
LARGE_INTEGER fsize;
if (!GetFileSizeEx(fp, &fsize)) {
CloseHandle(fp);
return 0;
}
DWORD read;
ASSERT_SIMPLE(fsize.QuadPart > size);
if (!ReadFile(fp, file, (uint32) size, &read, NULL)) {
CloseHandle(fp);
return 0;
}
CloseHandle(fp);
return read;
}
inline bool
file_write(const char* filename, const file_body* file)
{
HANDLE fp = CreateFileA((LPCSTR) filename,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fp == INVALID_HANDLE_VALUE) {
return false;
}
DWORD written;
DWORD length = (DWORD) file->size;
ASSERT_SIMPLE(file->size < MAX_INT32);
if (!WriteFile(fp, file->content, length, &written, NULL)) {
CloseHandle(fp);
return false;
}
CloseHandle(fp);
return true;
}
inline bool
file_write_struct(const char* filename, const void* file, uint32 size)
{
HANDLE fp = CreateFileA((LPCSTR) filename,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fp == INVALID_HANDLE_VALUE) {
return false;
}
DWORD written;
ASSERT_SIMPLE(size < MAX_INT32);
if (!WriteFile(fp, file, size, &written, NULL)) {
CloseHandle(fp);
return false;
}
CloseHandle(fp);
return true;
}
inline void
file_copy(const char* src, const char* dst)
{
CopyFileA((LPCSTR) src, (LPCSTR) dst, false);
}
inline
HANDLE get_append_handle(const char* filename)
{
HANDLE fp = CreateFileA((LPCSTR) filename,
FILE_APPEND_DATA,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fp == INVALID_HANDLE_VALUE) {
return NULL;
}
return fp;
}
inline bool
file_append(const char* filename, const char* file)
{
HANDLE fp = CreateFileA((LPCSTR) filename,
FILE_APPEND_DATA,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fp == INVALID_HANDLE_VALUE) {
return false;
}
DWORD written;
DWORD length = (DWORD) strlen(file); // @question WHY is WriteFile not supporting larger data?
ASSERT_SIMPLE(length < MAX_INT32);
if (!WriteFile(fp, file, length, &written, NULL)) {
CloseHandle(fp);
return false;
}
CloseHandle(fp);
return true;
}
inline bool
file_append(HANDLE fp, const char* file)
{
if (fp == INVALID_HANDLE_VALUE) {
return false;
}
DWORD written;
DWORD length = (DWORD) strlen(file); // @question WHY is WriteFile not supporting larger data?
ASSERT_SIMPLE(length < MAX_INT32);
if (!WriteFile(fp, file, length, &written, NULL)) {
CloseHandle(fp);
return false;
}
CloseHandle(fp);
return true;
}
inline bool
file_append(const char* filename, const file_body* file)
{
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;
}
inline uint64 last_modified(const char* filename)
{
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;
}
inline void self_path(char* path)
{
//HMODULE dll = GetModuleHandle(NULL);
GetModuleFileNameA(NULL, (LPSTR) path, MAX_PATH);
}
void log_to_file(LogPool* logs, HANDLE fp)
{
// we don't log an empty log pool
if (logs->pos == 0) {
return;
}
char *offset = logs->memory;
for (uint32 i = 0; i < logs->pos * MAX_LOG_LENGTH + MAX_LOG_LENGTH; ++i) {
if (*offset == '\0') {
*offset = '\n';
// @performance would it make sense to jump to the next log message
// we know that after \0 until the end of this log message everything is 0
}
++offset;
}
logs->memory[logs->count * MAX_LOG_LENGTH - 1] = '\0';
file_append(fp, logs->memory);
// reset log position to start of memory pool
logs->pos = 0;
}
// snprintf(logs->memory + logs->pos * MAX_LOG_LENGTH, MAX_LOG_LENGTH, "My text %s", str1);
// log(log, NULL);
void log(LogPool* logs, HANDLE fp = NULL)
{
// Zero memory after \0 until end of THIS log message
// Older log messages that are coming after are retained
// Older log messages can come after this log message due to the ring memory
char *offset = logs->memory + logs->pos * MAX_LOG_LENGTH;
bool ended = false;
for (uint32 i = 0; i < MAX_LOG_LENGTH; ++i) {
if (ended) {
*offset = 0;
++offset;
continue;
}
if (*offset == '\0') {
ended = true;
}
++offset;
}
++logs->pos;
// write log pool to file
if (logs->pos >= logs->count) {
if (fp != NULL) {
log_to_file(logs, fp);
}
// reset log position to start of memory pool
logs->pos = 0;
}
}
#if (LOG_LEVEL == 0)
// Don't perform any logging at log level 0
#define LOG(logs, fp)
#define LOG_TO_FILE(logs, fp)
#else
#define LOG(logs, fp) log(logs, fp);
#define LOG_TO_FILE(logs, fp) log_to_file(logs, fp);
#endif
#endif

View File

@ -0,0 +1,86 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_UTILS_WINDOWS_H
#define TOS_UTILS_WINDOWS_H
#include <windows.h>
#include "../../stdlib/Types.h"
struct Window {
bool is_fullscreen;
int32 width;
int32 height;
char name[32];
int32 x;
int32 y;
HWND hwnd;
};
void window_create(Window* window, void* proc)
{
WNDPROC wndproc = (WNDPROC) proc;
WNDCLASSEX wc = {};
HINSTANCE hinstance = GetModuleHandle(0);
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_OWNDC;
wc.lpfnWndProc = wndproc;
wc.hInstance = hinstance;
wc.lpszClassName = (LPCWSTR) window->name;
RegisterClassEx(&wc);
if (window->is_fullscreen) {
window->width = GetSystemMetrics(SM_CXSCREEN);
window->height = GetSystemMetrics(SM_CYSCREEN);
DEVMODE screen_settings;
memset(&screen_settings, 0, sizeof(screen_settings));
screen_settings.dmSize = sizeof(screen_settings);
screen_settings.dmPelsWidth = (unsigned long) window->width;
screen_settings.dmPelsHeight = (unsigned long) window->height;
screen_settings.dmBitsPerPel = 32;
screen_settings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
ChangeDisplaySettings(&screen_settings, CDS_FULLSCREEN);
window->x = 0;
window->y = 0;
}
window->hwnd = CreateWindowEx((DWORD) NULL,
wc.lpszClassName, NULL,
WS_OVERLAPPEDWINDOW,
window->x, window->y,
window->width,
window->height,
NULL, NULL, hinstance, window
);
//SetWindowLongA(window->hwnd, GWL_STYLE, 0);
}
void window_open(const Window* window)
{
ShowWindow(window->hwnd, SW_SHOW);
SetForegroundWindow(window->hwnd);
SetFocus(window->hwnd);
ShowCursor(false);
UpdateWindow(window->hwnd);
}
void window_close(Window* window)
{
CloseWindow(window->hwnd);
}
#endif

View File

@ -0,0 +1,202 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_SOUND_DIRECT_SOUND_H
#define TOS_SOUND_DIRECT_SOUND_H
#include <dsound.h>
#include <windows.h>
#include "../../../stdlib/Types.h"
#include "../../../audio/AudioSetting.h"
#include "../../../utils/MathUtils.h"
struct DirectSoundSetting {
LPDIRECTSOUND8 direct_sound;
LPDIRECTSOUNDBUFFER primary_buffer;
LPDIRECTSOUNDBUFFER secondary_buffer;
};
// BEGIN: Dynamically load DirectSound
typedef HRESULT WINAPI audio_create(LPCGUID, LPDIRECTSOUND8*, LPUNKNOWN);
HRESULT WINAPI DirectSoundCreate8Stub(LPCGUID, LPDIRECTSOUND8*, LPUNKNOWN) {
return 0;
}
// END: Dynamically load DirectSound
void audio_load(HWND hwnd, AudioSetting* setting, DirectSoundSetting* api_setting) {
HMODULE lib = LoadLibraryExA((LPCSTR) "dsound.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!lib) {
// @todo Log
return;
}
audio_create* DirectSoundCreate8 = (audio_create *) GetProcAddress(lib, "DirectSoundCreate8");
if (!DirectSoundCreate8 || !SUCCEEDED(DirectSoundCreate8(0, &api_setting->direct_sound, 0))) {
// @todo Log
return;
}
if(!SUCCEEDED(api_setting->direct_sound->SetCooperativeLevel(hwnd, DSSCL_PRIORITY))) {
// @todo Log
return;
}
WAVEFORMATEX wf = {};
wf.wFormatTag = WAVE_FORMAT_PCM;
wf.nChannels = 2;
wf.wBitsPerSample = 16;
wf.nBlockAlign = (wf.nChannels * wf.wBitsPerSample) / 8;
wf.nSamplesPerSec = setting->sample_rate;
wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign;
wf.cbSize = 0;
// Create primary buffer
DSBUFFERDESC bufferDesc;
ZeroMemory(&bufferDesc, sizeof(DSBUFFERDESC));
bufferDesc.dwSize = sizeof(DSBUFFERDESC);
bufferDesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
if(!SUCCEEDED(api_setting->direct_sound->CreateSoundBuffer(&bufferDesc, &api_setting->primary_buffer, 0))) {
// @todo Log
return;
}
if (!SUCCEEDED(api_setting->primary_buffer->SetFormat(&wf))) {
// @todo Log
return;
}
setting->buffer_size = setting->sample_rate * setting->sample_size;
setting->buffer = (int16 *) calloc(setting->sample_rate, setting->sample_size);
// Create secondary buffer
DSBUFFERDESC bufferDesc2;
ZeroMemory(&bufferDesc2, sizeof(DSBUFFERDESC));
bufferDesc2.dwSize = sizeof(DSBUFFERDESC);
bufferDesc2.dwFlags = 0;
bufferDesc2.dwBufferBytes = setting->buffer_size;
bufferDesc2.lpwfxFormat = &wf;
if(!SUCCEEDED(api_setting->direct_sound->CreateSoundBuffer(&bufferDesc2, &api_setting->secondary_buffer, 0))) {
// @todo Log
return;
}
}
inline
void audio_play(AudioSetting* setting, DirectSoundSetting* api_setting)
{
if (!api_setting->secondary_buffer) {
return;
}
api_setting->secondary_buffer->Play(0, 0, DSBPLAY_LOOPING);
setting->is_playing = true;
}
inline
void audio_free(AudioSetting* setting, DirectSoundSetting* api_setting)
{
if (api_setting->direct_sound) {
api_setting->direct_sound->Release();
}
if (api_setting->primary_buffer) {
api_setting->primary_buffer->Release();
}
if (api_setting->secondary_buffer) {
api_setting->secondary_buffer->Release();
}
}
/**
* Calculates the samples in bytes to generate for the buffer
*/
inline
uint32 audio_buffer_fillable(const AudioSetting* setting, const DirectSoundSetting* api_setting)
{
DWORD player_cursor;
DWORD write_cursor;
if (!SUCCEEDED(api_setting->secondary_buffer->GetCurrentPosition(&player_cursor, &write_cursor))) {
// @todo Log
return 0;
}
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->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 += target_cursor;
} else {
bytes_to_write = target_cursor - bytes_to_lock;
}
return bytes_to_write;
}
inline
void audio_play_buffer(AudioSetting* setting, DirectSoundSetting* api_setting, uint32 bytes_to_write)
{
if (bytes_to_write == 0) {
return;
}
void *region1;
DWORD region1_size;
void *region2;
DWORD region2_size;
DWORD bytes_to_lock = (setting->sample_index * setting->sample_size) % setting->buffer_size;
api_setting->secondary_buffer->Lock(
bytes_to_lock, bytes_to_write,
&region1, &region1_size,
&region2, &region2_size,
0
);
// @question Do we even need to use memcpy? Can't we use the buffer directly?
// Probably depends on what lock actually does to region1/region2
// Of course we would than need some mechanism to check when we can write into the buffer
// See XAudio2 for this, we would probably need a second buffer as well
memcpy(
(void *) region1,
(void *) setting->buffer,
region1_size
);
if (region2_size > 0) {
memcpy(
(void *) region2,
(void *) (setting->buffer + region1_size),
region2_size
);
}
api_setting->secondary_buffer->Unlock(region1, region1_size, region2, region2_size);
setting->sample_index += bytes_to_write / setting->sample_size;
setting->sample_buffer_size = 0;
}
#endif

View File

@ -0,0 +1,196 @@
/**
* Jingga
*
* @package Stdlib
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_SOUND_XAUDIO2_H
#define TOS_SOUND_XAUDIO2_H
#include <xaudio2.h>
#include <windows.h>
#include "../../../stdlib/Types.h"
#include "../../../audio/AudioSetting.h"
#include "../../../utils/MathUtils.h"
struct XAudio2Setting {
IXAudio2* xaudio2;
IXAudio2SourceVoice* source_voice;
IXAudio2MasteringVoice* mastering_voice;
XAUDIO2_BUFFER internal_buffer[2];
};
// BEGIN: Dynamically load XAudio2
typedef HRESULT WINAPI audio_create(IXAudio2**, UINT32, XAUDIO2_PROCESSOR);
HRESULT WINAPI XAudio2CreateStub(IXAudio2**, UINT32, XAUDIO2_PROCESSOR) {
return 0;
}
// END: Dynamically load XAudio2
void audio_load(HWND hwnd, AudioSetting* setting, XAudio2Setting* api_setting) {
HMODULE lib = LoadLibraryExA((LPCSTR) "xaudio2_9.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!lib) {
// @todo Log
lib = LoadLibraryExA((LPCSTR) "xaudio2_8.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
}
if (!lib) {
// @todo Log
return;
}
audio_create* XAudio2Create = (audio_create *) GetProcAddress(lib, "XAudio2Create");
if (!XAudio2Create || !SUCCEEDED(XAudio2Create(&api_setting->xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR))) {
// @todo Log
return;
}
if (!SUCCEEDED(api_setting->xaudio2->CreateMasteringVoice(
&api_setting->mastering_voice,
XAUDIO2_DEFAULT_CHANNELS,
setting->sample_rate,
0,
NULL
))) {
// @todo Log
return;
}
WAVEFORMATEX wf = {};
wf.wFormatTag = WAVE_FORMAT_PCM;
wf.nChannels = 2;
wf.wBitsPerSample = (uint16) ((setting->sample_size * 8) / wf.nChannels); // = sample_size per channel
wf.nBlockAlign = (wf.nChannels * wf.wBitsPerSample) / 8; // = sample_szie
wf.nSamplesPerSec = setting->sample_rate;
wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign; // = buffer_size
wf.cbSize = 0;
if (!SUCCEEDED(api_setting->xaudio2->CreateSourceVoice(&api_setting->source_voice, &wf))) {
// @todo Log
return;
}
setting->buffer_size = setting->sample_rate * setting->sample_size;
setting->buffer = (int16 *) calloc(setting->sample_rate, setting->sample_size);
// @question Consider to move to the heap?
api_setting->internal_buffer[0].Flags = 0;
api_setting->internal_buffer[0].AudioBytes = setting->buffer_size;
api_setting->internal_buffer[0].pAudioData = (byte *) malloc(setting->buffer_size * sizeof(byte));
api_setting->internal_buffer[0].PlayBegin = 0;
api_setting->internal_buffer[0].PlayLength = 0;
api_setting->internal_buffer[0].LoopBegin = 0;
api_setting->internal_buffer[0].LoopLength = 0;
api_setting->internal_buffer[0].LoopCount = 0;
api_setting->internal_buffer[0].pContext = NULL;
api_setting->internal_buffer[1].Flags = 0;
api_setting->internal_buffer[1].AudioBytes = setting->buffer_size;
api_setting->internal_buffer[1].pAudioData = (byte *) malloc(setting->buffer_size * sizeof(byte));
api_setting->internal_buffer[1].PlayBegin = 0;
api_setting->internal_buffer[1].PlayLength = 0;
api_setting->internal_buffer[1].LoopBegin = 0;
api_setting->internal_buffer[1].LoopLength = 0;
api_setting->internal_buffer[1].LoopCount = 0;
api_setting->internal_buffer[1].pContext = NULL;
setting->sample_index = 0;
}
inline
void audio_play(AudioSetting* setting, XAudio2Setting* api_setting) {
if (!api_setting->source_voice) {
// @todo Log
return;
}
api_setting->source_voice->Start(0, XAUDIO2_COMMIT_NOW);
setting->is_playing = true;
}
inline
void audio_free(AudioSetting* setting, XAudio2Setting* api_setting)
{
if (api_setting->internal_buffer[0].pAudioData) {
free((void *) api_setting->internal_buffer[0].pAudioData);
}
if (api_setting->internal_buffer[1].pAudioData) {
free((void *) api_setting->internal_buffer[1].pAudioData);
}
if (setting->buffer) {
free((void *) setting->buffer);
}
if (api_setting->source_voice) {
api_setting->source_voice->DestroyVoice();
}
if (api_setting->mastering_voice) {
api_setting->mastering_voice->DestroyVoice();
}
if (api_setting->xaudio2) {
api_setting->xaudio2->Release();
}
}
/**
* Calculates the samples to generate for the buffer
*
* For XAudio2 we currently always fill the entire buffer size.
* For other audio APIs we maybe have to do something else
*/
inline
uint32 audio_buffer_fillable(const AudioSetting* setting, const XAudio2Setting* api_setting)
{
if (!api_setting->source_voice) {
// @todo Log
return 0;
}
XAUDIO2_VOICE_STATE state;
api_setting->source_voice->GetState(&state);
if (state.BuffersQueued > 1) {
return 0;
}
return setting->buffer_size;
}
inline
void audio_play_buffer(AudioSetting* setting, XAudio2Setting* api_setting, uint32 bytes_to_write) {
if (!api_setting->source_voice) {
// @todo Log
return;
}
if (bytes_to_write == 0) {
return;
}
memcpy(
(void *) api_setting->internal_buffer[setting->sample_index].pAudioData,
setting->buffer,
bytes_to_write
);
if (!SUCCEEDED(api_setting->source_voice->SubmitSourceBuffer(&api_setting->internal_buffer[setting->sample_index]))) {
// @todo Log
return;
}
setting->sample_index = (setting->sample_index + 1) % 2;
setting->sample_buffer_size = 0;
}
#endif

View File

@ -0,0 +1,188 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_INPUT_RAW_H
#define TOS_INPUT_RAW_H
#include <windows.h>
#include "../../../stdlib/Types.h"
#include "../../../input/Input.h"
#include "../../../utils/TestUtils.h"
#include "../../../utils/MathUtils.h"
InputState* init_input(HWND hwnd)
{
uint32 nDevices;
GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST));
PRAWINPUTDEVICELIST pRawInputDeviceList = (PRAWINPUTDEVICELIST) malloc(sizeof(RAWINPUTDEVICELIST) * nDevices);
nDevices = GetRawInputDeviceList(pRawInputDeviceList, &nDevices, sizeof(RAWINPUTDEVICELIST));
// We always want at least one empty input device slot
// @todo Change so that we store the actual number of devices
InputState *inputs = (InputState *) calloc((nDevices + 1), sizeof(InputState));
if (nDevices == 0) {
free(pRawInputDeviceList);
return inputs;
}
uint32 cb_size = 256;
for (uint32 i = 0; i < nDevices; ++i) {
GetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, inputs[i].name, &cb_size);
cb_size = sizeof(RID_DEVICE_INFO);
RID_DEVICE_INFO rdi;
GetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICEINFO, &rdi, &cb_size);
switch (rdi.dwType) {
case RIM_TYPEMOUSE: {
inputs[i].handle_mouse = pRawInputDeviceList[i].hDevice;
inputs[i].is_connected = true;
inputs[i].type = INPUT_TYPE_MOUSE;
} break;
case RIM_TYPEKEYBOARD: {
inputs[i].handle_keyboard = pRawInputDeviceList[i].hDevice;
inputs[i].is_connected = true;
inputs[i].type = INPUT_TYPE_KEYBOARD;
} break;
case RIM_TYPEHID: {
inputs[i].type = INPUT_TYPE_OTHER;
} break;
default: {
}
}
}
RAWINPUTDEVICE rid[4];
// Mouse
rid[0].usUsagePage = 0x01; // @todo doesn't work with 0x05 for games?
rid[0].usUsage = 0x02;
rid[0].dwFlags = RIDEV_DEVNOTIFY;
rid[0].hwndTarget = hwnd;
// Joystick
rid[1].usUsagePage = 0x01; // @todo doesn't work with 0x05 for games?
rid[1].usUsage = 0x04;
rid[1].dwFlags = RIDEV_DEVNOTIFY;
rid[1].hwndTarget = hwnd;
// Gamepad
rid[2].usUsagePage = 0x01; // @todo doesn't work with 0x05 for games?
rid[2].usUsage = 0x05;
rid[2].dwFlags = RIDEV_DEVNOTIFY;
rid[2].hwndTarget = hwnd;
// Keyboard
rid[3].usUsagePage = 0x01; // @todo doesn't work with 0x05 for games?
rid[3].usUsage = 0x06;
rid[3].dwFlags = RIDEV_DEVNOTIFY;
rid[3].hwndTarget = hwnd;
if (!RegisterRawInputDevices((PCRAWINPUTDEVICE) rid, 4, sizeof(RAWINPUTDEVICE))) {
// @todo Log
}
// free(rid);
free(pRawInputDeviceList);
return inputs;
}
void handle_input(LPARAM lParam, InputState* states)
{
uint32 db_size;
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &db_size, sizeof(RAWINPUTHEADER));
// @todo pull out, we only need to register this memory once
// Maybe even put it into the general memory pool
LPBYTE lpb = (BYTE *) malloc(db_size * sizeof(BYTE));
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &db_size, sizeof(RAWINPUTHEADER));
RAWINPUT* raw = (RAWINPUT*) lpb;
uint32 i = 0;
if (raw->header.dwType == RIM_TYPEMOUSE) {
// @todo Change so we can directly access the correct state (maybe map handle address to index?)
while (states[i].is_connected && states[i].handle_mouse != raw->header.hDevice) {++i;}
if (!states[i].is_connected) {
return;
}
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawmouse
if (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) {
RECT rect;
if (raw->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) {
rect.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
rect.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
rect.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
rect.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
} else {
rect.left = 0;
rect.top = 0;
rect.right = GetSystemMetrics(SM_CXSCREEN);
rect.bottom = GetSystemMetrics(SM_CYSCREEN);
}
states[i].x_last = states[i].x;
states[i].y_last = states[i].y;
states[i].x = MulDiv(raw->data.mouse.lLastX, rect.right, 65535) + rect.left;
states[i].y = MulDiv(raw->data.mouse.lLastY, rect.bottom, 65535) + rect.top;
states[i].state_change_mouse = true;
} else if (raw->data.mouse.lLastX != 0 || raw->data.mouse.lLastY != 0) {
states[i].x_last = states[i].x;
states[i].y_last = states[i].y;
states[i].x = states[i].x + raw->data.mouse.lLastX;
states[i].y = states[i].y + raw->data.mouse.lLastY;
states[i].state_change_mouse = true;
}
} else if (raw->header.dwType == RIM_TYPEKEYBOARD) {
// @todo Change so we can directly access the correct state (maybe map handle address to index?)
while (states[i].is_connected && states[i].handle_keyboard != raw->header.hDevice) {++i;}
if (!states[i].is_connected) {
return;
}
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawkeyboard
RAWKEYBOARD rawKB = raw->data.keyboard;
states[i].key = raw->data.keyboard.MakeCode;
states[i].key_up = raw->data.keyboard.Flags & RI_KEY_BREAK;
states[i].key_down = raw->data.keyboard.Flags & RI_KEY_MAKE;
if (states[i].key_down) {
for (int j = 0; j < MAX_KEY_PRESSES; ++j) {
if (states[i].keys_down[j] == NULL) {
states[i].keys_down[j] = states[i].key;
}
}
} else if (states[i].key_up) {
for (int j = 0; j < MAX_KEY_PRESSES; ++j) {
if (states[i].keys_down[j] == states[i].key) {
states[i].keys_down[j] = NULL;
}
}
}
states[i].state_change_keyboard = true;
}
}
#endif

View File

@ -0,0 +1,131 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_INPUT_XINPUT_H
#define TOS_INPUT_XINPUT_H
#include <XInput.h>
#include <windows.h>
#include "../../../input/Input.h"
#include "../../../stdlib/Types.h"
#include "../../../utils/MathUtils.h"
// @todo consider to remove some global_persist and defines since we are never calling it somewhere else
// BEGIN: Dynamically load XInput
typedef DWORD WINAPI x_input_get_state(DWORD, XINPUT_STATE*);
DWORD WINAPI XInputGetStateStub(DWORD, XINPUT_STATE*) {
return 0;
}
global_persist x_input_get_state* XInputGetState_ = XInputGetStateStub;
#define XInputGetState XInputGetState_
typedef DWORD WINAPI x_input_set_state(DWORD, XINPUT_VIBRATION*);
DWORD WINAPI XInputSetStateStub(DWORD, XINPUT_VIBRATION*) {
return 0;
}
global_persist x_input_set_state* XInputSetState_ = XInputSetStateStub;
#define XInputSetState XInputSetState_
void xinput_load() {
HMODULE lib = LoadLibraryExA((LPCSTR) "xinput1_4.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
if(!lib) {
// @todo Log
lib = LoadLibraryExA((LPCSTR) "xinput1_3.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
}
if (!lib) {
// @todo Log
return;
}
XInputGetState = (x_input_get_state *) GetProcAddress(lib, "XInputGetState");
XInputSetState = (x_input_set_state *) GetProcAddress(lib, "XInputSetState");
if (!XInputGetState || !XInputSetState) {
// @todo Log
return;
}
}
// END: Dynamically load XInput
ControllerState* init_controllers()
{
uint32 c = 0;
for (uint32 controller_index = 0; controller_index < XUSER_MAX_COUNT; ++controller_index) {
XINPUT_STATE controller_state;
if (XInputGetState(controller_index, &controller_state) == ERROR_SUCCESS) {
++c;
}
}
// We always want at least one empty controller slot
// @todo Change so that we store the actual number of devices
ControllerState *controllers = (ControllerState *) calloc((c + 1), sizeof(ControllerState));
if (c == 0) {
return controllers;
}
c = 0;
for (uint32 controller_index = 0; controller_index < XUSER_MAX_COUNT; ++controller_index) {
XINPUT_STATE controller_state;
if (XInputGetState(controller_index, &controller_state) == ERROR_SUCCESS) {
++c;
controllers[c].id = controller_index;
controllers[c].is_connected = true;
}
}
return controllers;
}
void handle_controller_input(ControllerState* states)
{
uint32 controller_index = 0;
while(states[controller_index].is_connected) {
XINPUT_STATE controller_state;
if (XInputGetState(controller_index, &controller_state) != ERROR_SUCCESS) {
++controller_index;
continue;
}
states[controller_index].up = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP;
states[controller_index].down = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN;
states[controller_index].left = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT;
states[controller_index].right = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT;
states[controller_index].start = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_START;
states[controller_index].back = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK;
states[controller_index].shoulder_left = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER;
states[controller_index].shoulder_right = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER;
states[controller_index].trigger_left = controller_state.Gamepad.bLeftTrigger;
states[controller_index].trigger_right = controller_state.Gamepad.bRightTrigger;
states[controller_index].button_a = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_A;
states[controller_index].button_b = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_B;
states[controller_index].button_x = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_X;
states[controller_index].button_y = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_Y;
states[controller_index].stickl_x = controller_state.Gamepad.sThumbLX;
states[controller_index].stickl_y = controller_state.Gamepad.sThumbLY;
states[controller_index].stickl_press = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB;
states[controller_index].stickr_x = controller_state.Gamepad.sThumbRX;
states[controller_index].stickr_y = controller_state.Gamepad.sThumbRY;
states[controller_index].stickr_press = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB;
++controller_index;
}
}
#endif

0
render/liquid.cpp Normal file
View File

0
render/mob.cpp Normal file
View File

0
render/object.cpp Normal file
View File

0
render/sky.cpp Normal file
View File

0
render/text.cpp Normal file
View File

View File

View File

@ -0,0 +1,13 @@
#include "helper.hlsli"
varying vec3 position;
uniform sampler2D water;
const vec3 underwaterColor = vec3(0.4, 0.9, 1.0);
void main() {
gl_FragColor = vec4(getSphereColor(position), 1.0);
vec4 info = texture2D(water, position.xz * 0.5 + 0.5);
if (position.y < info.r) {
gl_FragColor.rgb *= underwaterColor * 1.2;
}
}

View File

@ -0,0 +1,8 @@
varying vec3 position;
float poolHeight = 1.0;
void main() {
position = gl_Vertex.xyz;
position.y = ((1.0 - position.y) * (7.0 / 12.0) - 1.0) * poolHeight;
gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0);
}

View File

@ -0,0 +1,130 @@
const float IOR_AIR = 1.0;
const float IOR_WATER = 1.333;
float poolHeight = 1.0;
uniform vec3 light;
uniform vec3 sphereCenter;
uniform float sphereRadius;
uniform sampler2D tiles;
uniform sampler2D causticTex;
uniform sampler2D water;
vec2 intersectCube(vec3 origin, vec3 ray, vec3 cubeMin, vec3 cubeMax) {
vec3 tMin = (cubeMin - origin) / ray;
vec3 tMax = (cubeMax - origin) / ray;
vec3 t1 = min(tMin, tMax);
vec3 t2 = max(tMin, tMax);
float tNear = max(max(t1.x, t1.y), t1.z);
float tFar = min(min(t2.x, t2.y), t2.z);
return vec2(tNear, tFar);
}
float intersectSphere(vec3 origin, vec3 ray, vec3 sphereCenter, float sphereRadius) {
vec3 toSphere = origin - sphereCenter;
float a = dot(ray, ray);
float b = 2.0 * dot(toSphere, ray);
float c = dot(toSphere, toSphere) - sphereRadius * sphereRadius;
float discriminant = b * b - 4.0 * a * c;
if (discriminant > 0.0) {
float t = (-b - sqrt(discriminant)) / (2.0 * a);
if (t > 0.0) {
return t;
}
}
return 1.0e6;
}
uniform sampler2D causticTex;
vec3 getSphereColor(vec3 point) {
vec3 color = vec3(0.5);
/* ambient occlusion with walls */
color *= 1.0 - 0.9 / pow((1.0 + sphereRadius - abs(point.x)) / sphereRadius, 3.0);
color *= 1.0 - 0.9 / pow((1.0 + sphereRadius - abs(point.z)) / sphereRadius, 3.0);
color *= 1.0 - 0.9 / pow((point.y + 1.0 + sphereRadius) / sphereRadius, 3.0);
/* caustics */
vec3 sphereNormal = (point - sphereCenter) / sphereRadius;
vec3 refractedLight = refract(-light, vec3(0.0, 1.0, 0.0), IOR_AIR / IOR_WATER);
float diffuse = max(0.0, dot(-refractedLight, sphereNormal)) * 0.5;
vec4 info = texture2D(water, point.xz * 0.5 + 0.5);
if (point.y < info.r) {
vec4 caustic = texture2D(causticTex, 0.75 * (point.xz - point.y * refractedLight.xz / refractedLight.y) * 0.5 + 0.5);
diffuse *= caustic.r * 4.0;
}
color += diffuse;
return color;
}
uniform sampler2D tiles;
vec3 getWallColor(vec3 point) {
float scale = 0.5;
vec3 wallColor;
vec3 normal;
if (abs(point.x) > 0.999) {
wallColor = texture2D(tiles, point.yz * 0.5 + vec2(1.0, 0.5)).rgb;
normal = vec3(-point.x, 0.0, 0.0);
} else if (abs(point.z) > 0.999) {
wallColor = texture2D(tiles, point.yx * 0.5 + vec2(1.0, 0.5)).rgb;
normal = vec3(0.0, 0.0, -point.z);
} else {
wallColor = texture2D(tiles, point.xz * 0.5 + 0.5).rgb;
normal = vec3(0.0, 1.0, 0.0);
}
scale /= length(point); /* pool ambient occlusion */
scale *= 1.0 - 0.9 / pow(length(point - sphereCenter) / sphereRadius, 4.0); /* sphere ambient occlusion */
/* caustics */
vec3 refractedLight = -refract(-light, vec3(0.0, 1.0, 0.0), IOR_AIR / IOR_WATER);
float diffuse = max(0.0, dot(refractedLight, normal));
vec4 info = texture2D(water, point.xz * 0.5 + 0.5);
if (point.y < info.r) {
vec4 caustic = texture2D(causticTex, 0.75 * (point.xz - point.y * refractedLight.xz / refractedLight.y) * 0.5 + 0.5);
scale += diffuse * caustic.r * 2.0 * caustic.g;
} else {
/* shadow for the rim of the pool */
vec2 t = intersectCube(point, refractedLight, vec3(-1.0, -poolHeight, -1.0), vec3(1.0, 2.0, 1.0));
diffuse *= 1.0 / (1.0 + exp(-200.0 / (1.0 + 10.0 * (t.y - t.x)) * (point.y + refractedLight.y * t.y - 2.0 / 12.0)));
scale += diffuse * 0.5;
}
return wallColor * scale;
}
uniform samplerCube sky;
vec3 getSurfaceRayColor(vec3 origin, vec3 ray, vec3 waterColor) {
vec3 color;
float q = intersectSphere(origin, ray, sphereCenter, sphereRadius);
if (q < 1.0e6) {
color = getSphereColor(origin + ray * q);
} else if (ray.y < 0.0) {
vec2 t = intersectCube(origin, ray, vec3(-1.0, -poolHeight, -1.0), vec3(1.0, 2.0, 1.0));
color = getWallColor(origin + ray * t.y);
} else {
vec2 t = intersectCube(origin, ray, vec3(-1.0, -poolHeight, -1.0), vec3(1.0, 2.0, 1.0));
vec3 hit = origin + ray * t.y;
if (hit.y < 2.0 / 12.0) {
color = getWallColor(hit);
} else {
color = textureCube(sky, ray).rgb;
color += vec3(pow(max(0.0, dot(light, ray)), 5000.0)) * vec3(10.0, 8.0, 6.0);
}
}
if (ray.y < 0.0) {
color *= waterColor;
}
return color;
}

View File

@ -0,0 +1,12 @@
varying vec3 position;
const vec3 underwaterColor = vec3(0.4, 0.9, 1.0);
uniform sampler2D water;
void main() {
gl_FragColor = vec4(getSphereColor(position), 1.0);
vec4 info = texture2D(water, position.xz * 0.5 + 0.5);
if (position.y < info.r) {
gl_FragColor.rgb *= underwaterColor * 1.2;
}
}

View File

@ -0,0 +1,8 @@
uniform vec3 sphereCenter;
uniform float sphereRadius;
varying vec3 position;
void main() {
position = sphereCenter + gl_Vertex.xyz * sphereRadius;
gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0);
}

Some files were not shown because too many files have changed in this diff Show More