move imgui code to folder
This commit is contained in:
+10
-7
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user