move imgui code to folder

This commit is contained in:
Chee Yee
2023-02-22 15:49:27 -08:00
parent 2f7017ad10
commit 1cfeece53f
20 changed files with 716 additions and 7 deletions
+10 -7
View File
@@ -10,9 +10,16 @@ add_definitions(-DCPPHTTPLIB_OPENSSL_SUPPORT)
include_directories(
source
source/pugixml
source/imgui
)
add_executable(ezremote_client
source/imgui/imgui_draw.cpp
source/imgui/imgui_impl_sdl.cpp
source/imgui/imgui_impl_sdlrenderer.cpp
source/imgui/imgui_tables.cpp
source/imgui/imgui_widgets.cpp
source/imgui/imgui.cpp
source/pugixml/pugixml.cpp
source/web/callback.cpp
source/web/fsinfo.cpp
@@ -26,6 +33,8 @@ add_executable(ezremote_client
source/http/iis.cpp
source/http/nginx.cpp
source/http/npxserve.cpp
source/xt_editor/editor.cpp
source/xt_editor/getline.c
source/actions.cpp
source/config.cpp
source/fs.cpp
@@ -43,17 +52,11 @@ add_executable(ezremote_client
source/windows.cpp
source/webdavclient.cpp
source/zip_util.cpp
source/imgui_draw.cpp
source/imgui_impl_sdl.cpp
source/imgui_impl_sdlrenderer.cpp
source/imgui_tables.cpp
source/imgui_widgets.cpp
source/imgui.cpp
)
add_self(ezremote_client)
add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.01" 32 0)
add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.02" 32 0)
target_link_libraries(ezremote_client
c
+40
View File
@@ -0,0 +1,40 @@
#ifndef ARRAY_H
#define ARRAY_H
#define ARRAY_INITIAL_CAPACITY 256
// note: An array whose length can dynamically change at run-time
template <typename T>
struct Array {
T& operator[](int Index) {
return Data[Index];
}
T* Data;
size_t Capacity;
size_t Index;
};
template <typename T>
inline Array<T> array_init(size_t Capacity = ARRAY_INITIAL_CAPACITY) {
Array<T> Result;
Result.Data = (T*)malloc(Capacity * sizeof(T));
Result.Capacity = Capacity;
Result.Index = 0;
return Result;
}
template <typename T>
inline void array_add(Array<T>* _Array, T Value) {
if (_Array->Index >= _Array->Capacity) {
_Array->Capacity *= 2;
_Array->Data = (T*)realloc(_Array->Data, _Array->Capacity * sizeof(T));
}
_Array->Data[_Array->Index] = Value;
_Array->Index++;
}
#endif
+385
View File
@@ -0,0 +1,385 @@
#include "xt_editor/types.h"
#include "xt_editor/editor.h"
struct EditorRow {
char* Chars;
size_t Size;
};
struct EditorState {
int CPosX;
int CPosY;
int Rows;
int Columns;
EditorRow* Row;
int RowCount;
int CharCount;
bool IsFileDirty;
char* FileName;
};
enum CursorStyle_ {
CursorStyle_Block,
CursorStyle_Block_Outline,
CursorStyle_Line,
CursorStyle_Underline,
};
typedef int CursorStyle;
struct EditorConfig {
CursorStyle Style;
bool LineBlink;
};
static EditorState State;
static EditorConfig Config;
static bool IsInitialized = false;
static int TextStart = 7;
static char LeftBuffer[16];
static float BlinkStart = 0;
static float BlinkEnd = 0;
#ifdef BUILD_WIN32
#include "editor_input_win32.cpp"
#else
void Editor_HandleInput()
{};
#endif
void Editor_OpenFile(char* Filename) {
State.FileName = Filename;
State.IsFileDirty = false;
FILE* File = fopen(Filename, "r");
if (!File)
return;
char* Line = 0;
size_t LineCapacity = 0;
ssize_t LineLength;
while ((LineLength = getline(&Line, &LineCapacity, File)) != -1) {
while (LineLength > 0 && (Line[LineLength - 1] == '\n' || Line[LineLength - 1] == '\r')) {
LineLength--;
Editor_AppendRow(Line, LineLength);
State.CharCount += LineLength;
}
}
free(Line);
fclose(File);
}
void Editor_Init() {
State.CPosX = 0;
State.CPosY = 0;
ImVec2 WindowSize = ImGui::GetWindowContentRegionMax();
float FontSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, "#", nullptr, nullptr).x;
ImVec2 CharAdvance = ImVec2(FontSize, ImGui::GetTextLineHeightWithSpacing() * 1.0f);
State.Rows = WindowSize.y / CharAdvance.y;
State.Columns = WindowSize.x / CharAdvance.x;
State.Row = (EditorRow*)malloc(sizeof(EditorRow));
Editor_OpenFile("../src/editor.cpp");
IsInitialized = true;
Config.Style = CursorStyle_Block;
Config.LineBlink = true;
}
// https://en.wikipedia.org/wiki/UTF-8
// We assume that the char is a standalone character (<128) or a leading byte of an UTF-8 code sequence (non-10xxxxxx code)
static int UTF8CharLength(char c) {
if ((c & 0xFE) == 0xFC)
return 6;
if ((c & 0xFC) == 0xF8)
return 5;
if ((c & 0xF8) == 0xF0)
return 4;
else if ((c & 0xF0) == 0xE0)
return 3;
else if ((c & 0xE0) == 0xC0)
return 2;
return 1;
}
int Editor_GetCharacterIndexByCursor(int X, int Y) {
int Index = 0;
int Column = 0;
EditorRow* Line = &State.Row[Y];
if (Line == 0)
return 0;
for (; Index < Line->Size && Column < X;) {
Index += UTF8CharLength(Line->Chars[Index]);
++Column;
}
return Index;
}
void Editor_RenderRows(ImVec2 WindowSize, ImVec2 Pos) {
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImGui::GetStyle().Colors[ImGuiCol_FrameBg]);
//ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
ImGui::BeginChild("Editor", WindowSize, true);
ImGui::PushAllowKeyboardFocus(true);
// Handle input here or else we can't grab the childs input
Editor_HandleInput();
if (State.CPosX < 0)
State.CPosX = 0;
if (State.CPosY < 0)
State.CPosY = 0;
static float FontSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, "#", nullptr, nullptr).x; // Get the size of the tallest char
ImVec2 CharAdvance = ImVec2(FontSize, ImGui::GetTextLineHeightWithSpacing() * 1.0f);
bool Focused = ImGui::IsWindowFocused();
float ScrollX = ImGui::GetScrollX();
float ScrollY = ImGui::GetScrollY();
int LineNum = (int)floor(ScrollY / CharAdvance.y);
int LineMax = Maximum(0, Minimum(State.RowCount - 1, LineNum + (int)floor((ScrollY + WindowSize.y) / CharAdvance.y)));
int ActualTextStart = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, LeftBuffer, nullptr, nullptr).x + TextStart;
ImDrawList* Draw = ImGui::GetWindowDrawList();
while (LineNum <= LineMax) {
ImVec2 LineStartPos = ImVec2(Pos.x, Pos.y + LineNum * CharAdvance.y);
ImVec2 TextPos = ImVec2(LineStartPos.x + ActualTextStart, LineStartPos.y);
snprintf(LeftBuffer, 16, "%*d ", (TextStart - 1), LineNum + 1);
int LineNumWidth = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, LeftBuffer, nullptr, nullptr).x;
Draw->AddText(ImVec2(LineStartPos.x, LineStartPos.y), IM_COL32(255, 255, 255, 255), LeftBuffer);
ImVec2 Start = ImVec2(LineStartPos.x + ScrollX, LineStartPos.y);
ImVec2 End = ImVec2(Start.x + ScrollX + WindowSize.x, Start.y + CharAdvance.y);
Draw->AddRectFilled(Start, End, 0x141414);
Draw->AddRect(Start, End, 0x40808080, 1.0f);
EditorRow* Row = &State.Row[LineNum];
size_t Len = Row->Size;
if (Len > State.Columns) {
Len = State.Columns;
}
if (Config.Style != (CursorStyle_Line))
Draw->AddText(TextPos, IM_COL32(255, 255, 255, 255), Row->Chars);
// Draw the cursor
if (State.CPosY == LineNum && Focused) {
float CursorWidth = CharAdvance.x;
if (Config.Style == CursorStyle_Line || Config.Style == CursorStyle_Underline)
CursorWidth = 1.f;
int Index = Editor_GetCharacterIndexByCursor(State.CPosX, State.CPosY);
int ScaledCurX = (Index * CharAdvance.x);
int ScaledCurY = (State.CPosY * CharAdvance.y);
ImVec2 TextStartPos = ImVec2(Pos.x + ActualTextStart, Pos.y);
ImVec2 CursorStart, CursorEnd;
if (Config.Style == CursorStyle_Underline) { // We are doing underline style
CursorStart = ImVec2(TextStartPos.x + ScaledCurX, ((ScaledCurY + TextStartPos.y + CharAdvance.y) - CursorWidth) - 1);
CursorEnd = ImVec2(TextStartPos.x + ScaledCurX + CharAdvance.x, (ScaledCurY + TextStartPos.y + CharAdvance.y) - 1);
} else {
CursorStart = ImVec2(TextStartPos.x + ScaledCurX, ScaledCurY + TextStartPos.y);
CursorEnd = ImVec2(TextStartPos.x + ScaledCurX + CursorWidth, ScaledCurY + TextStartPos.y + CharAdvance.y);
}
BlinkEnd++;
float Elapsed = (BlinkEnd - BlinkStart);
static int OldCPosX = 0;
static int OldCPosY = 0;
if ((OldCPosX != State.CPosX || OldCPosY != State.CPosY) || Config.LineBlink == false) {
// Constantly render the cursor if we're in motion
(Config.Style == CursorStyle_Block_Outline) ? Draw->AddRect(CursorStart, CursorEnd, 0xffffffff, 1.0f) : Draw->AddRectFilled(CursorStart, CursorEnd, 0xffffffff);
// Draw the char of text at the cursors location in the opposite color
char* Char = (char*)malloc(sizeof(char) * 1);
Char[0] = Row->Chars[Index];
Draw->AddText(CursorStart, IM_COL32(0, 0, 0, 255), Char);
} else {
// Blink the cursor rendering
static float InitStart = 108;
if (Elapsed > InitStart) {
(Config.Style == CursorStyle_Block_Outline) ? Draw->AddRect(CursorStart, CursorEnd, 0xffffffff, 1.0f) : Draw->AddRectFilled(CursorStart, CursorEnd, 0xffffffff);
// Draw the char of text at the cursors location in the opposite color
char* Char = (char*)malloc(sizeof(char) * 1);
Char[0] = Row->Chars[Index];
Draw->AddText(CursorStart, IM_COL32(0, 0, 0, 255), Char);
if (Elapsed > (InitStart + 40))
BlinkStart = BlinkEnd;
}
}
OldCPosX = State.CPosX;
OldCPosY = State.CPosY;
}
// AddRect doesn't allow for a transparent rectangle so we need to write the character again :/
// When we use CursorStyle_Line the original text gets overwritten in a similar way.
if (Config.Style == CursorStyle_Block_Outline || Config.Style == CursorStyle_Line)
Draw->AddText(TextPos, IM_COL32(255, 255, 255, 255), Row->Chars);
{
// DEBUG DRAW: Cursor position and index
int Index = Editor_GetCharacterIndexByCursor(State.CPosX, State.CPosY);
char Temp[64];
sprintf(Temp, "%d, %d, %d", State.CPosX, State.CPosY, Index);
Draw->AddText(ImVec2(Pos.x + 550, Pos.y), IM_COL32(255, 255, 255, 255), Temp);
}
LineNum++;
}
while (LineNum >= LineMax) {
ImVec2 LineStartPos = ImVec2(Pos.x, Pos.y + LineNum * CharAdvance.y);
ImVec2 TextPos = ImVec2(LineStartPos.x + CharAdvance.x * (TextStart + 1), LineStartPos.y);
snprintf(LeftBuffer, 16, "%*s ", (TextStart - 1), "~");
int LineNumWidth = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, LeftBuffer, nullptr, nullptr).x;
Draw->AddText(ImVec2(LineStartPos.x, LineStartPos.y), IM_COL32(255, 255, 255, 255), LeftBuffer);
ImVec2 Start = ImVec2(LineStartPos.x + ScrollX, LineStartPos.y);
ImVec2 End = ImVec2(Start.x + ScrollX + WindowSize.x, Start.y + CharAdvance.y);
Draw->AddRectFilled(Start, End, 0x141414);
Draw->AddRect(Start, End, 0x40808080, 1.0f);
LineNum++;
if (LineNum >= (LineMax)) break; // Impose some limit so that we don't render infinitly
}
ImGui::PopAllowKeyboardFocus();
ImGui::EndChild();
//ImGui::PopStyleVar();
ImGui::PopStyleColor();
ImGui::Text("xt editor -- \"%s\"%s %2s %dL %dC %8s (%d, %d)", State.FileName, (State.IsFileDirty) ? "*" : "", "", State.RowCount, State.CharCount, "", State.CPosX, State.CPosY);
}
void Editor_AppendRow(char* String, size_t Length) {
State.Row = (EditorRow*)realloc(State.Row, sizeof(EditorRow) * (State.RowCount + 1));
int At = State.RowCount;
State.Row[At].Size = Length;
State.Row[At].Chars = (char*)malloc(Length + 1);
memcpy(State.Row[At].Chars, String, Length);
State.Row[At].Chars[Length] = 0;
State.RowCount++;
}
bool StringsMatch(char* A, char* B) {
while (*A && *B) {
if (*A != *B){
return false;
}
++A;
++B;
}
if (*A != *B){
return false;
} else {
return true;
}
}
int StringLength(const char* String) {
int Count = 0;
while (*String++) {
++Count;
}
return Count;
}
char* StringCopy(const char* String) {
char* Result = (char*)malloc(sizeof(char) * (StringLength(String) + 1));
memcpy(Result, String, sizeof(char) * (StringLength(String) + 1));
return Result;
}
void Editor_Render() {
ImGui::Begin("xt Demo Panel", nullptr, ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoScrollbar);
ImGui::SetWindowSize(ImVec2(1280, 720), ImGuiCond_FirstUseEver);
if (!IsInitialized) {
Editor_Init();
}
if (ImGui::BeginMenuBar()) {
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("Quit", "Alt-F4, CTRL-Q")) {
exit(0);
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("View")) {
if (ImGui::MenuItem("Cursor Blink", NULL, &Config.LineBlink)) {
//ImGui::PushItemFlag(ImGuiItemFlags_SelectableDontClosePopup, true);
//ImGui::PopItemFlag();
}
{
const char* Items[] = { "Block", "Block Outline", "Line", "Underline" };
static char* CurrentItem = NULL;
ImGuiComboFlags flags = ImGuiComboFlags_NoArrowButton;
ImGuiStyle& Style = ImGui::GetStyle();
ImGui::Text("Cursor Style");
ImGui::SameLine(0, Style.ItemInnerSpacing.x);
ImGui::PushItemWidth(ImGui::CalcItemWidth() - Style.ItemInnerSpacing.x- ImGui::GetFrameHeight());
if (ImGui::BeginCombo("##custom combo", CurrentItem, ImGuiComboFlags_NoArrowButton)) {
for (int n = 0; n < IM_ARRAYSIZE(Items); n++) {
bool is_selected = (CurrentItem == Items[n]);
if (ImGui::Selectable(Items[n], is_selected)) {
CurrentItem = StringCopy(Items[n]);
if (StringsMatch(CurrentItem, "Block")) {
Config.Style = CursorStyle_Block;
}
else if (StringsMatch(CurrentItem, "Block Outline")) {
Config.Style = CursorStyle_Block_Outline;
}
else if (StringsMatch(CurrentItem, "Line")) {
Config.Style = CursorStyle_Line;
}
else if (StringsMatch(CurrentItem, "Underline")) {
Config.Style = CursorStyle_Underline;
}
}
}
ImGui::EndCombo();
}
ImGui::PopItemWidth();
}
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
ImVec2 WindowSize = ImGui::GetWindowContentRegionMax();
WindowSize.y -= 215;
ImVec2 Pos = ImGui::GetCursorScreenPos();
Editor_RenderRows(WindowSize, Pos);
ImGui::End();
}
+10
View File
@@ -0,0 +1,10 @@
#ifndef EDITOR_H
#define EDITOR_H
#include "imgui.h"
void Editor_Init();
void Editor_AppendRow(char* String, size_t Length);
void Editor_RenderRows(ImVec2 WindowSize, ImVec2 Pos);
void Editor_Render();
#endif
+56
View File
@@ -0,0 +1,56 @@
// getline() is written to POSIX spec so that it can be used on Windows platforms
// This is taken from a stackexchange answer, link has since been lost.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
typedef intptr_t ssize_t;
ssize_t getline(char** lineptr, size_t* n, FILE* stream) {
size_t pos;
int c;
if (lineptr == NULL || stream == NULL || n == NULL) {
errno = EINVAL;
return -1;
}
c = getc(stream);
if (c == EOF) {
return -1;
}
if (*lineptr == NULL) {
*lineptr = (char*)malloc(128);
if (*lineptr == NULL) {
return -1;
}
*n = 128;
}
pos = 0;
while (c != EOF) {
if (pos + 1 >= *n) {
size_t new_size = *n + (*n >> 2);
if (new_size < 128) {
new_size = 128;
}
char* new_ptr = (char*)realloc(*lineptr, new_size);
if (new_ptr == NULL) {
return -1;
}
*n = new_size;
*lineptr = new_ptr;
}
((unsigned char*)(*lineptr))[pos++] = c;
if (c == '\n') {
break;
}
c = getc(stream);
}
(*lineptr)[pos] = '\0';
return pos;
}
+215
View File
@@ -0,0 +1,215 @@
#ifndef TYPES_H
#define TYPES_H
#include <float.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#ifdef BUILD_WIN32 // MSVC
#define API_EXPORT extern "C" __declspec(dllexport)
#define API_IMPORT extern "C" __declspec(dllimport)
#elif BUILD_LINUX | BUILD_MACOS // GCC or Clang
#define API_EXPORT extern "C" __attribute__((visibility("default")))
#define API_IMPORT
#endif
#define global static
typedef unsigned int uint;
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
typedef int32 bool32;
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;
typedef float real32;
typedef double real64;
typedef int8 s8;
typedef int16 s16;
typedef int32 s32;
typedef int64 s64;
typedef bool32 b32;
typedef uint8 u8;
typedef uint16 u16;
typedef uint32 u32;
typedef uint64 u64;
typedef real32 f32;
typedef real64 f64;
typedef uintptr_t umm;
typedef intptr_t smm;
#define S32Min ((s32)0x80000000)
#define S32Max ((s32)0x7fffffff)
#define U16Max 65535
#define U32Max ((u32)-1)
#define U64Max ((u64)-1)
#define F32Max FLT_MAX
#define F32Min -FLT_MAX
#define Minimum(A, B) ((A < B) ? (A) : (B))
#define Maximum(A, B) ((A > B) ? (A) : (B))
#define For(Value) For_e((Value), ArrayCount(Value))
#define For_e(Value, End) For_se((Value), 0, (End))
#define For_se(Value, Start, End) for (int (Value) = (Start); (Value) < (End); ++(Value))
// todo(jax): Should these always be 64-bit?
#define Kilobytes(Value) (((uint64)Value) * 1024LL)
#define Megabytes(Value) (Kilobytes((uint64)Value) * 1024LL)
#define Gigabytes(Value) (Megabytes((uint64)Value) * 1024LL)
#define Terabytes(Value) (Gigabytes((uint64)Value) * 1024LL)
#define ArrayCount(Array) (sizeof(Array) / sizeof((Array)[0]))
// todo(jax): swap, min, max ... macros???
#define AlignPow2(Value, Alignment) ((Value + ((Alignment) - 1)) & ~((Alignment) - 1))
#define Align4(Value) ((Value + 3) & ~3)
#define Align8(Value) ((Value + 7) & ~7)
#define Align16(Value) ((Value + 15) & ~15)
#define Stringize(x) PrimitiveStringize(x)
#define PrimitiveStringize(x) #x
inline b32 IsPow2(u32 Value) {
return ((Value & ~(Value - 1)) == Value);
}
// ANSI Color Codes
#define BLACK "\33[0;30m"
#define RED "\33[0;31m"
#define GREEN "\33[0;32m"
#define YELLOW "\33[0;33m"
#define BLUE "\33[0;34m"
#define MAGENTA "\33[0;35m"
#define CYAN "\33[0;36m"
#define WHITE "\33[0;37m"
#define LIGHT_GRAY "\33[0;37m"
#define DARK_GRAY "\33[1;30m"
#define BOLD_BLACK "\33[1;30m"
#define BOLD_RED "\33[1;31m"
#define BOLD_GREEN "\33[1;32m"
#define BOLD_YELLOW "\33[1;33m"
#define BOLD_BLUE "\33[1;34m"
#define BOLD_MAGENTA "\33[1;35m"
#define BOLD_CYAN "\33[1;36m"
#define BOLD_WHITE "\33[1;37m"
#define RESET "\33[0m"
// note(jax): Platform-independent way to perform an assertion.
// Flat out writes to zero memory to crash the program.
// todo(jax): Create some sort of assert function that creates a message box
// like in previous engines I've worked on!
#if ENGINE_SLOW
#define Assert(Expression) if (!(Expression)) { *(int*)0=0; }
#else
#define Assert(Expression)
#endif
#define InvalidCodePath Assert(!"InvalidCodePath")
// A structure that encapsulates a non-terminated buffer
struct string {
u8* Data;
umm Count;
};
inline u32 SafeTruncateU32(u64 Value) {
// todo(jax): Defines for min/max values
Assert(Value <= 0xFFFFFFFF);
u32 Result = (u32)Value;
return Result;
}
inline u16 SafeTruncateU16(u32 Value) {
// todo(jax): Defines for min/max values
Assert(Value <= 0xFFFF);
u16 Result = (u16)Value;
return Result;
}
inline u8 SafeTruncateU8(u64 Value) {
Assert(Value <= 0xFF);
u8 Result = (u8)Value;
return Result;
}
inline s32 SafeTruncateS32(s64 Value) {
if (Value >> 63) {
b32 IsSafeOperation = !(!(Value >> 32) && 0xffffffff);
if (!IsSafeOperation) {
printf("SafeTruncateS32: Performing unsafe truncation on '%lld'\n", Value);
}
return (s32)Value;
} else {
b32 IsSafeOperation = !((Value >> 32) && 0xffffffff);
if (!IsSafeOperation) {
printf("SafeTruncateS32: Performing unsafe truncation on '%lld'\n", Value);
}
return (s32)Value;
}
}
inline s16 SafeTruncateS16(s32 Value) {
if (Value >> 31) {
b32 IsSafeOperation = !(!(Value >> 16) && 0xffff);
if (!IsSafeOperation) {
printf("SafeTruncateS16: Performing unsafe truncation on '%d'\n", Value);
}
return (s16)Value;
} else {
b32 IsSafeOperation = !((Value >> 16) && 0xffff);
if (!IsSafeOperation) {
printf("SafeTruncateS16: Performing unsafe truncation on '%d'\n", Value);
}
return (s16)Value;
}
}
inline s8 SafeTruncateS8(s16 Value) {
if (Value >> 15) {
b32 IsSafeOperation = !(!(Value >> 8) && 0xff);
if (!IsSafeOperation) {
printf("SafeTruncateS8: Performing unsafe truncation on '%d'\n", Value);
}
return (s8)Value;
} else {
b32 IsSafeOperation = !((Value >> 8) && 0xff);
if (!IsSafeOperation) {
printf("SafeTruncateS8: Performing unsafe truncation on '%d'\n", Value);
}
return (s8)Value;
}
}
//
// note: Scalar operations
//
// todo(jax): These will eventually go into mathlib
inline real32 Square(real32 A) {
real32 Result = A*A;
return Result;
}
inline real32 Lerp(real32 A, real32 t, real32 B){
real32 Result = (1.0f - t)*A + t*B;
return Result;
}
#endif