Compare commits
3 Commits
master
...
in-progres
Author | SHA1 | Date | |
---|---|---|---|
d3d8421110 | |||
404ec22e57 | |||
79b6e83147 |
26
README.md
26
README.md
@ -129,15 +129,23 @@ A list of layers in the codebase and their associated namespaces are below:
|
|||||||
- `base` (no namespace): Universal, codebase-wide constructs. It contains
|
- `base` (no namespace): Universal, codebase-wide constructs. It contains
|
||||||
strings, math, memory allocators, threading, and logging.
|
strings, math, memory allocators, threading, and logging.
|
||||||
It depends on no other codebase layers.
|
It depends on no other codebase layers.
|
||||||
- `es/core` (`ES_`): Short for Engine Subsystem. Implements the
|
|
||||||
- `es/gfx` (`ES_`): Engine Subsystem graphical frontend. Builds on top of
|
- `ef/core` (`EF_`): The scanner engine's non-graphical frontend. It implements
|
||||||
`es/core` to provide graphical features such as windows, panels, and all
|
interfacing with the scanner over usb, colour space settings, and all intricate
|
||||||
interfaces needed for using the scanner. It is the main user of `os/gfx`.
|
details that have to do with the software working with the scanner.
|
||||||
- `os/core` (`OS_`): An abstraction layer that provides core, non-graphical
|
- `ef/gfx` (`EF_`): The scanner engine`s graphical frontend. It provides all
|
||||||
functionality from the operating sytem under a general use abstraction API.
|
graphical features, including windows, panels, and all other various interfaces
|
||||||
This is implemented per supported operating system.
|
needed by the engine to function.
|
||||||
- `os/gfx` (`OS_`): This layer builds on top of `os/core`, it provides
|
|
||||||
graphical operating functionalities under a general use abstraction API.
|
- `render` (`R_`): An abstraction layer providing an abstract API for rendering using
|
||||||
|
various GPU APIs under a common interface. This layer does not implement a high level
|
||||||
|
API for drawing, it is strictly for minimal abstractions on a needed basis. Higher
|
||||||
|
level drawing features are implemented in the `draw` layer
|
||||||
|
|
||||||
|
- `draw` (`D_`): Implements a high level graphics drawing API for the scanning engine.
|
||||||
|
It uses the underlying `render` abstraction API. It provides a high-level API for various
|
||||||
|
draw commands, but takes care to bath them together.
|
||||||
|
|
||||||
- `ui` (`UI_`): For building graphical user interfaces. Provides a core
|
- `ui` (`UI_`): For building graphical user interfaces. Provides a core
|
||||||
immediate mode hierarchical user interface data structure building API, and
|
immediate mode hierarchical user interface data structure building API, and
|
||||||
has helper layers for building higher level widgets.
|
has helper layers for building higher level widgets.
|
@ -44,6 +44,10 @@
|
|||||||
#define BUILD_DEBUG 1
|
#define BUILD_DEBUG 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BUILD_ENTRY_DEFINING_UNIT)
|
||||||
|
#define BUILD_ENTRY_DEFINING_UNIT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(BUILD_VERSION_MAJOR)
|
#if !defined(BUILD_VERSION_MAJOR)
|
||||||
#define BUILD_VERSION_MAJOR 0
|
#define BUILD_VERSION_MAJOR 0
|
||||||
#endif
|
#endif
|
||||||
|
6
src/base/base_core.c
Normal file
6
src/base/base_core.c
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// Safe Casts
|
||||||
|
internal u16 safe_cast_u16(u32 x) {
|
||||||
|
// Assert
|
||||||
|
u16 result = (u16)x;
|
||||||
|
return result;
|
||||||
|
}
|
@ -134,6 +134,9 @@ global const u32 bit30 = (1 << 29);
|
|||||||
global const u32 bit31 = (1 << 30);
|
global const u32 bit31 = (1 << 30);
|
||||||
global const u32 bit32 = (1 << 31);
|
global const u32 bit32 = (1 << 31);
|
||||||
|
|
||||||
|
// Safe Casts
|
||||||
|
internal u16 safe_cast_u16(u32 x);
|
||||||
|
|
||||||
// Misc helpers
|
// Misc helpers
|
||||||
// NOTE(tijani): Divides total size of array by size of one element in the array gives
|
// NOTE(tijani): Divides total size of array by size of one element in the array gives
|
||||||
// the number of elements in the array.
|
// the number of elements in the array.
|
||||||
|
@ -1 +1,12 @@
|
|||||||
internal void main_thread_entry_point(void) { ThreadNameF("[main thread]"); }
|
internal void main_thread_base_entry_point(void) {
|
||||||
|
ThreadNameF("[main thread]");
|
||||||
|
|
||||||
|
#if defined(OS_GFX_H)
|
||||||
|
os_gfx_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GFX_H)
|
||||||
|
gfx_init(update_and_render);
|
||||||
|
#endif
|
||||||
|
entry_point();
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#ifndef BASE_ENTRY_POINT_H
|
#ifndef BASE_ENTRY_POINT_H
|
||||||
#define BASE_ENTRY_POINT_H
|
#define BASE_ENTRY_POINT_H
|
||||||
|
|
||||||
internal void main_thread_entry_point(void);
|
internal void main_thread_base_entry_point(void);
|
||||||
|
|
||||||
#endif // BASE_ENTRY_POINT_H
|
#endif // BASE_ENTRY_POINT_H
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
|
#include "base_core.c"
|
||||||
#include "base_arena.c"
|
#include "base_arena.c"
|
||||||
#include "base_strings.c"
|
#include "base_strings.c"
|
||||||
#include "base_markup.c"
|
#include "base_markup.c"
|
||||||
#include "base_threading_context.c"
|
#include "base_threading_context.c"
|
||||||
|
#include "base_entry_point.c"
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#include "base_strings.h"
|
#include "base_strings.h"
|
||||||
#include "base_markup.h"
|
#include "base_markup.h"
|
||||||
#include "base_threading_context.h"
|
#include "base_threading_context.h"
|
||||||
|
#include "base_entry_point.h"
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
#endif // BASE_INC_H
|
#endif // BASE_INC_H
|
||||||
|
38
src/base/base_math.h
Normal file
38
src/base/base_math.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef BASE_MATH_H
|
||||||
|
#define BASE_MATH_H
|
||||||
|
|
||||||
|
// Vector Types
|
||||||
|
typedef Vec2F32 Vec2F32;
|
||||||
|
union Vec2F32 {
|
||||||
|
struct {
|
||||||
|
f32 x;
|
||||||
|
f32 y;
|
||||||
|
};
|
||||||
|
f32 v[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Range Types
|
||||||
|
// Range 2 (forms a rectangle)
|
||||||
|
typedef union Rng2F32 Rng2F32;
|
||||||
|
union Rng2F32 {
|
||||||
|
struct {
|
||||||
|
Vec2F32 min;
|
||||||
|
Vec2F32 Max;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct {
|
||||||
|
Vec2F32 pos0;
|
||||||
|
Vec2F32 pos1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct {
|
||||||
|
f32 x0;
|
||||||
|
f32 y0;
|
||||||
|
|
||||||
|
f32 x1;
|
||||||
|
f32 y1;
|
||||||
|
};
|
||||||
|
Vec2F32 v[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BASE_MATH_H
|
46
src/ef/gfx/ef_gfx.c
Normal file
46
src/ef/gfx/ef_gfx.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
// Window State functions
|
||||||
|
internal EF_Window *ef_window_open(Vec2F32 size, OS_Handle preferred_monitor) {
|
||||||
|
EF_Window *window = ef_gfx_state->free_window;
|
||||||
|
if (window != 0) {
|
||||||
|
SLLStackPop(ef_gfx_state->free_window);
|
||||||
|
u64 gen = window->gen;
|
||||||
|
MemoryZeroStruct(window);
|
||||||
|
window->gen = gen;
|
||||||
|
} else {
|
||||||
|
window = push_array(ef_gfx_state->arena, EF_Window, 1);
|
||||||
|
}
|
||||||
|
window->gen += 1;
|
||||||
|
window->arena = arena_alloc();
|
||||||
|
|
||||||
|
{
|
||||||
|
String8 title = str8_lit_comp(BUILD_TITLE_STRING_LITERAL);
|
||||||
|
window->os = os_window_open(size, OS_WindowFlag_CustomBorder, title);
|
||||||
|
}
|
||||||
|
window->last_dpi = os_dpi_fram_window(window->os);
|
||||||
|
|
||||||
|
// NOTE(tijani): Setting preferred monitor, not important
|
||||||
|
// OS_Handle zero_monitor = {0};
|
||||||
|
// if(!os_handle_match(zero_monitor, preferred_window)){
|
||||||
|
// os_set_window
|
||||||
|
// }
|
||||||
|
|
||||||
|
os_window_equip_repaint(window->os, ef_gfx_state->repaint_hook, window);
|
||||||
|
DLLPushBack(ef_gfx_state->first_winow, ef_gfx_state->last_window, window);
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
internal EF_Window *ef_window_from_os_handle(OS_Handle os) {}
|
||||||
|
internal void df_window_update_and_render(Arena *arena, EF_Window *window_state) {}
|
||||||
|
|
||||||
|
// Main layer top level calls
|
||||||
|
internal void ef_gfx_init(OS_WindowRepaintFunctionType *window_repaint_entry_point) {
|
||||||
|
// Begin profiling
|
||||||
|
Arena *arena = arena_alloc();
|
||||||
|
ef_gfx_state = push_array(arena, EF_GfxState, 1);
|
||||||
|
ef_gfx_state->arena = arena;
|
||||||
|
ef_gfx_state->num_frame_requested = 2;
|
||||||
|
ef_gfx_state->repaint_hook = window_repaint_entry_point;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void ef_gfx_begin_frame(Arena *arena) {}
|
||||||
|
internal void ef_gfx_end_frame(void) {}
|
84
src/ef/gfx/ef_gfx.h
Normal file
84
src/ef/gfx/ef_gfx.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#ifndef EF_GFX_H
|
||||||
|
#define EF_GFX_H
|
||||||
|
|
||||||
|
// Per-Window State
|
||||||
|
typedef struct EF_Window EF_Window;
|
||||||
|
struct EF_Window {
|
||||||
|
// Links and metadata
|
||||||
|
EF_Window *next;
|
||||||
|
EF_Window *previous;
|
||||||
|
u64 gen;
|
||||||
|
u64 frames_alive;
|
||||||
|
// EF_ConfigSource config_source;
|
||||||
|
|
||||||
|
// Top level info & handles
|
||||||
|
Arena *arena;
|
||||||
|
OS_Handle os;
|
||||||
|
// R_handle render; // not needed for now, will revisit
|
||||||
|
// UI_State *ui_state; // not needed for now, will revisit
|
||||||
|
f32 last_dpi;
|
||||||
|
|
||||||
|
// config / settings
|
||||||
|
|
||||||
|
// view state delta histor
|
||||||
|
|
||||||
|
// menu bar state
|
||||||
|
|
||||||
|
// tab context menu state
|
||||||
|
|
||||||
|
// error state
|
||||||
|
|
||||||
|
// panel state
|
||||||
|
|
||||||
|
// per-frame drawing state
|
||||||
|
};
|
||||||
|
|
||||||
|
// Graphical state
|
||||||
|
typedef struct EF_GfxState EF_GfxState;
|
||||||
|
struct EF_GfxState {
|
||||||
|
Arena *arena;
|
||||||
|
|
||||||
|
// frame request state
|
||||||
|
u64 num_frames_requested;
|
||||||
|
|
||||||
|
// history cache
|
||||||
|
|
||||||
|
// key map table NOTE(tijani): ??
|
||||||
|
|
||||||
|
// confirmation popup state
|
||||||
|
|
||||||
|
// windows
|
||||||
|
OS_WindowRepaintFunctionType *repaint_hook;
|
||||||
|
EF_Window *first_window;
|
||||||
|
EF_Window *last_window;
|
||||||
|
EF_Window *free_window;
|
||||||
|
u64 window_count;
|
||||||
|
b32 last_window_queued_save;
|
||||||
|
|
||||||
|
// view state
|
||||||
|
|
||||||
|
// drag/drop satte machine
|
||||||
|
|
||||||
|
// rich hove info
|
||||||
|
|
||||||
|
// running theme state
|
||||||
|
|
||||||
|
// global setting
|
||||||
|
|
||||||
|
// icon texture
|
||||||
|
};
|
||||||
|
|
||||||
|
// Globals
|
||||||
|
global EF_GfxState *ef_gfx_satet = 0;
|
||||||
|
|
||||||
|
// Window State functions
|
||||||
|
internal EF_Window *ef_window_open(Vec2F32 size, OS_Handle preferred_monitor);
|
||||||
|
internal EF_Window *ef_window_from_os_handle(OS_Handle os);
|
||||||
|
internal void df_window_update_and_render(Arena *arena, EF_Window *window_state);
|
||||||
|
|
||||||
|
// Main layer top level calls
|
||||||
|
internal void ef_gfx_init(OS_WindowRepaintFunctionType *window_repaint_entry_point);
|
||||||
|
internal void ef_gfx_begin_frame(Arena *arena);
|
||||||
|
internal void ef_gfx_end_frame(void);
|
||||||
|
|
||||||
|
#endif // EF_GFX_H
|
28
src/goff/goff.c
Normal file
28
src/goff/goff.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
internal void update_and_render(OS_Handle repaint_window_handle) {
|
||||||
|
// Profiling start
|
||||||
|
Temp scratch = scratch_begin(0, 0);
|
||||||
|
|
||||||
|
// Get events from OS
|
||||||
|
OS_EventList events = {0};
|
||||||
|
if (os_handle_match(repaint_window_handle, os_handle_zero())) {
|
||||||
|
events = os_get_events(scratch.arena, gfx_state->num_frames_requested == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// begin frames
|
||||||
|
{ gfx_begin_frame(scratch.arena); }
|
||||||
|
|
||||||
|
// Update and render
|
||||||
|
{}
|
||||||
|
|
||||||
|
// End frondend frame
|
||||||
|
{ gfx_end_frame(); }
|
||||||
|
|
||||||
|
// Submit rendering to all windows
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Show windows after first frame
|
||||||
|
{}
|
||||||
|
|
||||||
|
scratch_end(scratch);
|
||||||
|
// Profiling end
|
||||||
|
}
|
8
src/goff/goff.h
Normal file
8
src/goff/goff.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef GOFF_H
|
||||||
|
#define GOFF_H
|
||||||
|
|
||||||
|
// Frontend entry point
|
||||||
|
|
||||||
|
internal void update_and_render(OS_HANDLE repaint_window);
|
||||||
|
|
||||||
|
#endif // GOFF_H
|
@ -10,4 +10,36 @@
|
|||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
u64 main(int argc, char **argv) { return 0; }
|
// Build Options
|
||||||
|
// #define BUILD_VERSION_MAJOR 0
|
||||||
|
// #define BUILD_VERSION_MINOR 1
|
||||||
|
// #define BUILD_VERSION_PATCH 0
|
||||||
|
// #define BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA"
|
||||||
|
// #define BUILD_TITLE "Goff Film Scanner"
|
||||||
|
// #define OS_GRAPHICAL 1
|
||||||
|
|
||||||
|
// Entry Point
|
||||||
|
|
||||||
|
internal void entry_point() {
|
||||||
|
Temp scratch = scratch_begin(0, 0);
|
||||||
|
|
||||||
|
// Setup layers
|
||||||
|
{ gfx_init(); }
|
||||||
|
|
||||||
|
// Main application loop
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
|
||||||
|
// Update and render frame here
|
||||||
|
OS_Handle repaint_window = {0};
|
||||||
|
update_and_render(repaint_window);
|
||||||
|
|
||||||
|
// Quit
|
||||||
|
// if (gfx_state->first_window == 0) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scratch_end(scratch);
|
||||||
|
}
|
||||||
|
0
src/os/core/os_core.c
Normal file
0
src/os/core/os_core.c
Normal file
@ -11,6 +11,12 @@ struct OS_SystemInfo {
|
|||||||
String8 machine_name;
|
String8 machine_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Handle types
|
||||||
|
typedef struct OS_Handle OS_Handle;
|
||||||
|
struct OS_Handle {
|
||||||
|
u64 l_u64[1];
|
||||||
|
};
|
||||||
|
|
||||||
// Process Information
|
// Process Information
|
||||||
typedef struct OS_ProcessInfo OS_ProcessInfo;
|
typedef struct OS_ProcessInfo OS_ProcessInfo;
|
||||||
struct OS_ProcessInfo {
|
struct OS_ProcessInfo {
|
||||||
@ -45,4 +51,14 @@ internal void os_set_thread_name(String8 name);
|
|||||||
|
|
||||||
// %os_hooks(implemented per-os) Aborting
|
// %os_hooks(implemented per-os) Aborting
|
||||||
internal void os_abort(s32 exit_code);
|
internal void os_abort(s32 exit_code);
|
||||||
|
|
||||||
|
// %os_hooks(implemented per-os) Entry Points
|
||||||
|
// os_core defines a low level entry point if BUILD_ENTRY_DEFINING_UNIT is
|
||||||
|
// defined to 1. This will call into the standard cocdebase program entry point
|
||||||
|
// called "entry_point"
|
||||||
|
|
||||||
|
#if BUILD_ENTRY_DEFINING_UNIT
|
||||||
|
internal void entry_point(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // OS_CORE_H
|
#endif // OS_CORE_H
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
// compatibility with older versions of windows where the modern WIN32
|
// compatibility with older versions of windows where the modern WIN32
|
||||||
// SetThreadDescription function is not available and use old ways.
|
// SetThreadDescription function is not available and use old ways.
|
||||||
// This way it can be done dynamically at runtime without any hiccups.
|
// This way it can be done dynamically at runtime without any hiccups.
|
||||||
typedef HRESULT W32_SetThreadDescription(HANDLE hThread, PCWSTR lpThreadDescription);
|
typedef HRESULT W32_SetThreadDescription_Type(HANDLE hThread, PCWSTR lpThreadDescription);
|
||||||
global W32_SetThreadDescription *w32_SetThreadDescription_func = 0;
|
global W32_SetThreadDescription_Type *w32_SetThreadDescription_func = 0;
|
||||||
|
|
||||||
// %os_hooks(implemented per-os) System and process info
|
// %os_hooks(implemented per-os) System and process info
|
||||||
internal OS_SystemInfo *os_get_system_info(void) { return &os_w32_state.system_info; }
|
internal OS_SystemInfo *os_get_system_info(void) { return &os_w32_state.system_info; }
|
||||||
@ -46,7 +46,7 @@ internal b32 os_commit_large(void *ptr, u64 size) { return -1; }
|
|||||||
|
|
||||||
// %os_hooks(implemented per-os) Threads
|
// %os_hooks(implemented per-os) Threads
|
||||||
internal u32 os_thread_id(void) {
|
internal u32 os_thread_id(void) {
|
||||||
u32 id = GetCurrentThreadID();
|
u32 id = GetCurrentThreadId();
|
||||||
return (id);
|
return (id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,3 +90,41 @@ internal void os_set_thread_name(String8 name) {
|
|||||||
|
|
||||||
// %os_hooks(implemented per-os) Aborting
|
// %os_hooks(implemented per-os) Aborting
|
||||||
internal void os_abort(s32 exit_code) { ExitProcess(exit_code); }
|
internal void os_abort(s32 exit_code) { ExitProcess(exit_code); }
|
||||||
|
|
||||||
|
internal void w32_entry_point_caller() {
|
||||||
|
// OS layer initialization
|
||||||
|
{
|
||||||
|
// dynamically load windows functions, not guaranteed on all SDKs
|
||||||
|
{
|
||||||
|
HMODULE module = LoadLibraryA("kernel32.dll");
|
||||||
|
w32_SetThreadDescription_func = (W32_SetThreadDescription_Type *)GetProcAddress(module, "SetThreadDescription");
|
||||||
|
FreeLibrary(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable large pages if possible
|
||||||
|
{
|
||||||
|
HANDLE token;
|
||||||
|
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) {
|
||||||
|
LUID luid;
|
||||||
|
if (LookupPrivilegeValue(0, SE_LOCK_MEMORY_NAME, &luid)) {
|
||||||
|
TOKEN_PRIVILEGES priv;
|
||||||
|
priv.PrivilegeCount = 1;
|
||||||
|
priv.Privileges[0].Luid = luid;
|
||||||
|
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||||
|
AdjustTokenPrivileges(token, 0, &priv, sizeof(priv), 0, 0);
|
||||||
|
}
|
||||||
|
CloseHandle(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get system info
|
||||||
|
}
|
||||||
|
|
||||||
|
// call into the actual entry point
|
||||||
|
main_thread_base_entry_point();
|
||||||
|
}
|
||||||
|
|
||||||
|
int wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) {
|
||||||
|
w32_entry_point_caller();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -4,8 +4,12 @@
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <windowsx.h>
|
||||||
#include <processthreadsapi.h>
|
#include <processthreadsapi.h>
|
||||||
|
|
||||||
|
#pragma comment(lib, "user32")
|
||||||
|
#pragma comment(lib, "advapi32")
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
// Application State
|
// Application State
|
||||||
|
120
src/os/gfx/os_gfx.h
Normal file
120
src/os/gfx/os_gfx.h
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#ifndefine OS_GFX_H
|
||||||
|
#define OS_GFX_H
|
||||||
|
|
||||||
|
// Graphics system information
|
||||||
|
typedef struct OS_GfxInfo OS_GfxInfo;
|
||||||
|
struct OS_GfxInfo {
|
||||||
|
f32 double_click_time;
|
||||||
|
f32 caret_blink_time;
|
||||||
|
f32 default_referesh_rate;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Window Types
|
||||||
|
typedef u32 OS_WindowFlags;
|
||||||
|
enum { OS_WindowFlag_CustomBorder = (1 << 0); };
|
||||||
|
|
||||||
|
typedef void OS_WindowRepaintFunctionType(OS_Handle window, void *user_data);
|
||||||
|
|
||||||
|
// Cursor Types
|
||||||
|
typedef enum OS_Cursor {
|
||||||
|
OS_Cursor_Pointer,
|
||||||
|
OS_Cursor_IBar,
|
||||||
|
OS_Cursor_LeftRight,
|
||||||
|
OS_Cursor_UpDown,
|
||||||
|
OS_Cursor_DownRight,
|
||||||
|
OS_Cursor_UpRight,
|
||||||
|
OS_Cursor_UpDownLeftRight,
|
||||||
|
OS_Cursor_HandPoint,
|
||||||
|
OS_Cursor_Disabled,
|
||||||
|
OS_Cursor_COUNT,
|
||||||
|
} OS_Cursor;
|
||||||
|
|
||||||
|
typedef enum OS_EventKind {
|
||||||
|
OS_EvenKind_NULL,
|
||||||
|
OS_EventKind_Press,
|
||||||
|
OS_EventKind_Release,
|
||||||
|
OS_EventKind_MouseMove,
|
||||||
|
OS_EventKind_Text,
|
||||||
|
OS_EventKind_Scroll,
|
||||||
|
OS_EventKind_WindowLoseFocus,
|
||||||
|
OS_EventKind_WindowClose,
|
||||||
|
OS_EventKind_Wakeup,
|
||||||
|
OS_EventKind_COUNT
|
||||||
|
} OS_EventKind;
|
||||||
|
|
||||||
|
typedef u32 OS_EventFlags;
|
||||||
|
enum { OS_EventFlag_Ctrl = (1 << 0), OS_EventFlag_Shift = (1 << 1), OS_EventFlag_Alt = (1 << 2); };
|
||||||
|
|
||||||
|
typedef struct OS_Event OS_Event;
|
||||||
|
struct OS_Event {
|
||||||
|
OS_Event *next;
|
||||||
|
OS_Event *previous;
|
||||||
|
u64 timestamp_us;
|
||||||
|
OS_Handle window;
|
||||||
|
OS_EventKind kind;
|
||||||
|
OS_EventFlag flags;
|
||||||
|
OS_Key key;
|
||||||
|
b32 is_repeat;
|
||||||
|
b32 right_sided;
|
||||||
|
u32 character;
|
||||||
|
u32 repeat_count;
|
||||||
|
Vec2F32 position;
|
||||||
|
Vec2F32 delta;
|
||||||
|
String8List strings;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct OS_EventList OS_EventList;
|
||||||
|
struct OS_EventList {
|
||||||
|
u64 count;
|
||||||
|
OS_Event *first;
|
||||||
|
OS_Event *last;
|
||||||
|
};
|
||||||
|
|
||||||
|
// %os_hooks Event function helpers (Implementd Per-OS)
|
||||||
|
internal os_eat_event(OS_EventList *events, OS_Event *event);
|
||||||
|
internal b32 os_key_press(OS_EventList *events, OS_Handle window, OS_EventFlags flags, OS_Key key);
|
||||||
|
internal os_key_release(OS_EventList *events, OS_Handle window, OS_EVentFlags flags, OS_Key key);
|
||||||
|
internal b32 os_text(OS_EventList *events, OS_Handle window, u32 character);
|
||||||
|
|
||||||
|
// %os_hooks Main initialization API (Implemented Per-OS)
|
||||||
|
internal void os_gfx_init(void);
|
||||||
|
|
||||||
|
// %os_Hooks Graphics System Info (Implemented Per-OS)
|
||||||
|
internal OS_GfxInfo *os_get_gfx_info(void);
|
||||||
|
|
||||||
|
// %os_hooks Windows (Implemented Per-OS)
|
||||||
|
intarnal OS_Handle os_window_open(Vec2F32 resolution, OS_WindowsFlags flags, String8 title);
|
||||||
|
internal void os_window_close(OS_Handle handle);
|
||||||
|
internal void os_window_first_paint(OS_Handle window_handle);
|
||||||
|
internal void os_window_equip_repaint(OS_Handle window, OS_WindowRepaintFunctionType *repaint, void *user_data);
|
||||||
|
|
||||||
|
internal void os_window_focus(OS_Handle window);
|
||||||
|
internal b32 os_window_is_focused(OS_Handle window);
|
||||||
|
internal b32 os_window_is_fullscreen(OS_Handle window);
|
||||||
|
internal void os_window_set_fullscreen(OS_Handle window, b32 fullscreen);
|
||||||
|
internal b32 os_window_is_maximized(OS_Handle window);
|
||||||
|
internal void os_window_set_maximized(OS_Handle window, b32 maximized);
|
||||||
|
internal void os_window_minimize(OS_Handle window);
|
||||||
|
internal void os_window_bring_to_front(OS_Handle window);
|
||||||
|
internal void os_window_set_monitor(OS_Handle window, OS_Handle monitor);
|
||||||
|
|
||||||
|
internal Rng2F32 os_rect_from_window(OS_Handle window);
|
||||||
|
internal Rng2F32 os_client_rect_from_window(OS_Handle window);
|
||||||
|
internal f32 os_dpi_from_window(OS_Handle window);
|
||||||
|
|
||||||
|
// %os_hooks Events (Implemented Per-OS)
|
||||||
|
internal void os_send_wakeup_event(void);
|
||||||
|
internal EventList os_get_events(Arena *arena, b32 wait);
|
||||||
|
internal OS_EventFlags os_get_event_flags(void);
|
||||||
|
internal Vec2F32 os_mouse_from_window(OS_Handle window);
|
||||||
|
|
||||||
|
// %os_hooks Cursors (Implemented Per-OS)
|
||||||
|
internal void os_set_cursor(OS_Cursr cursor);
|
||||||
|
|
||||||
|
// %os_hooks Native user facing graphical message (Implemented Per-OS)
|
||||||
|
internal void os_graphical_message(b32 error, String8 title, String8 message);
|
||||||
|
|
||||||
|
// %os_hooks Shell Operations ??
|
||||||
|
internal void os_show_in_filesystem_ui(String8 path);
|
||||||
|
|
||||||
|
#endif // OS_GFX_H
|
151
src/os/gfx/win32/os_gfx_win32.c
Normal file
151
src/os/gfx/win32/os_gfx_win32.c
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
// Windows
|
||||||
|
internal OS_Handle os_w32_handle_from_window(OS_W32_Window *window) {}
|
||||||
|
internal OS_W32_Window *os_w32_window_from_handle(OS_Handle window) {}
|
||||||
|
internal OS_W32_Window *os_w32_window_from_hwnd(HWND hwnd) {}
|
||||||
|
internal HWND os_w32_hwnd_from_window(OS_W32_Window *window) {}
|
||||||
|
internal OS_W32_Window *os_w32_window_alloc(void) {}
|
||||||
|
internal void os_w32_window_release(OS_W32_Window *window) {}
|
||||||
|
internal OS_Event *os_w32_push_event(OS_EventKind kind, OS_W32_Window *window) {}
|
||||||
|
internal OS_Key os_w32_os_key_from_vkey(WPARAM vkey) {}
|
||||||
|
internal WPARAM os_w32_vkey_from_os_key(OS_Key key) {}
|
||||||
|
|
||||||
|
internal LRESULT os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||||
|
// Start profilling??
|
||||||
|
LRESULT result = 0;
|
||||||
|
b23 good = 1; // ??
|
||||||
|
|
||||||
|
if (os_w32_event_arena == 0) {
|
||||||
|
result = DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||||
|
good = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (good) {
|
||||||
|
OS_W32_Window *window = os_w32_window_from_hwnd(hwnd);
|
||||||
|
OS_Handle window_handle = os_w32_handle_from_window(window);
|
||||||
|
b32 release = 0; // ??
|
||||||
|
|
||||||
|
switch (uMsg) {
|
||||||
|
default: {
|
||||||
|
result = DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||||
|
} break;
|
||||||
|
case WM_SIZE:
|
||||||
|
case WM_PAINT {
|
||||||
|
if (window->repaint != 0) {
|
||||||
|
PAINTSTRUCT pain_struct = {0}; BeginPaint(hwnd, &paint_struct);
|
||||||
|
window->repaint(os_w32_handle_from_window(window), window->repaint_user_data);
|
||||||
|
EndPaint(hwnd, &paint_struct);
|
||||||
|
} else {
|
||||||
|
result = DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case WM_CLOSE: {
|
||||||
|
os_w32_push_event(OS_EventKind_WindowClose, window);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case WM_DPICHANGED: {
|
||||||
|
f32 new_dpi = (f32)(wParam & 0xffff);
|
||||||
|
window->dpi = new_dpi;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// End profiling
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void os_gfx_init(void) {
|
||||||
|
Arena *arena = arena_alloc();
|
||||||
|
os_w32_gfx_state->arena = push_array(arena, OS_W32_GfxState, 1);
|
||||||
|
os_w32_gfx_satte->gfx_thread_tid = (u32)GetCurrentThreadId();
|
||||||
|
os_w32_gfx_state->hInstance = GetModuleHandle(0);
|
||||||
|
|
||||||
|
// Set DPI Awareness
|
||||||
|
|
||||||
|
// Register grahical window
|
||||||
|
{
|
||||||
|
WNDCLASSEXW wndclass = {sizeof(wndclass)};
|
||||||
|
wndclass.lpfnWndProc = os_w32_wnd_proc;
|
||||||
|
wndclass.hInstance = os_w32_gfx_state->hInstance;
|
||||||
|
wndclass.lpszClassName = L"goff-graphical-window";
|
||||||
|
wndclass.hCursor = LoadCursor(0, IDC_ARROW);
|
||||||
|
wndclass.hIcon = LoadIcon(os_w32_gfx_state->hInstance, MAKEINTRESOURCE(1));
|
||||||
|
wndclass.style = CS_VREDRAW | CS_HREDRAW;
|
||||||
|
ATOM wndatom = RegisterClassEXW(&wndclass);
|
||||||
|
(void)wndatom;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get graphics system info
|
||||||
|
|
||||||
|
// Set initial cursor
|
||||||
|
|
||||||
|
// Fill vkeys -> OS_KEY table
|
||||||
|
}
|
||||||
|
|
||||||
|
// %os_Hooks Graphics System Info (Implemented Per-OS)
|
||||||
|
internal OS_GfxInfo *os_get_gfx_info(void) { return &os_w32_gfx_state->gfx_info; }
|
||||||
|
|
||||||
|
// %os_hooks Windows (Implemented Per-OS)
|
||||||
|
intarnal OS_Handle os_window_open(Vec2F32 resolution, OS_WindowsFlags flags, String8 title) {
|
||||||
|
// make HWND
|
||||||
|
HWND hwnd = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
Temp scratch = scratch_begin(0, 0);
|
||||||
|
String16 title16 = str16_from_8(scratch.arena, title);
|
||||||
|
hwnd = CreateWindowExW(WS_EX_APPWINDOW, L"goff-graphical-window", (WCHAR *)title16.str,
|
||||||
|
WS_OVERLAPPEDWINDOW | WS_SIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, (int)resolution.x,
|
||||||
|
(int)resolution.y, 0, 0, os_w32_gfx_state->hInstance, 0);
|
||||||
|
scratch_end(scratch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make/fill window
|
||||||
|
OS_W32_Window *window = os_w32_window_alloc();
|
||||||
|
{
|
||||||
|
window->hwnd = hwnd;
|
||||||
|
// Set DPI
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_Handle handle = os_w32_handle_from_window(window);
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
internal void os_window_close(OS_Handle handle) {
|
||||||
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
|
os_w32_window_release(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void os_window_first_paint(OS_Handle window_handle) {
|
||||||
|
OS_W32_Window *window = os_w32_window_from_handle(window_handle);
|
||||||
|
window->filst_paint_done = 1;
|
||||||
|
ShowWindow(window->handle, SW_SHOW);
|
||||||
|
if (window->maximized) {
|
||||||
|
ShowWindow(window - hwnd, SW_MAXIMIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal void os_window_equip_repaint(OS_Handle handle, OS_WindowRepaintFunctionType *repaint, void *user_data) {
|
||||||
|
OS_W32_Window *window = os_w32_window_from_handle(handle);
|
||||||
|
window->repaint = repaint;
|
||||||
|
window->repaint_user_data = user_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Rng2F32 os_rect_from_window(OS_Handle handle) {
|
||||||
|
Rng2F32 range = {0};
|
||||||
|
OS_W32_Window *window = os_w32_window_fram_handle(handle);
|
||||||
|
if (window) {
|
||||||
|
RECT rect = {0};
|
||||||
|
GetWindowRect(os_w32_hwnd_from_window(window), &rect);
|
||||||
|
range = os_w32_rng2f32_from_rect(rect);
|
||||||
|
}
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Rng2F32 os_client_rect_from_window(OS_Handle handle) {
|
||||||
|
Rng2f32 range = {0};
|
||||||
|
OS_W32_Window *window = os_w32_window_fram_handle(handle);
|
||||||
|
if (window) {
|
||||||
|
RECT = {0};
|
||||||
|
GetClientRect(os_w32_hwnd_from_window(window), &rect);
|
||||||
|
range = os_w32_rng2f32_from_rect(rect);
|
||||||
|
}
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal f32 os_dpi_from_window(OS_Handle window) {}
|
62
src/os/gfx/win32/os_gfx_win32.h
Normal file
62
src/os/gfx/win32/os_gfx_win32.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#ifndef OS_GFX_WIN32_H
|
||||||
|
#define OS_GFX_WIN32_H
|
||||||
|
|
||||||
|
// Windows
|
||||||
|
typedef struct OS_W32_TitleBarClientArea OS_W32_TitleBarClientArean;
|
||||||
|
struct OS_W32_TitleBarClientArea {
|
||||||
|
OS_W32_TitleBarClientArea *next;
|
||||||
|
Rng2F32 rect;
|
||||||
|
};
|
||||||
|
typedef struct OS_W32_Window OS_W32_Window;
|
||||||
|
struct OS_W32_Window {
|
||||||
|
OS_W32_Window *next;
|
||||||
|
OS_W32_Window *prev;
|
||||||
|
HWND *hwnd;
|
||||||
|
WINDOWPLACEMENT last_window_placement;
|
||||||
|
OS_WindowRepaintFunctionType *repaint;
|
||||||
|
void *repaint_user_data;
|
||||||
|
f32 dpi;
|
||||||
|
b32 first_paint_done;
|
||||||
|
b32 maximized;
|
||||||
|
b32 custome_border;
|
||||||
|
f32 custom_border_title_thickness;
|
||||||
|
f32 custom_border_edge_thickness;
|
||||||
|
b32 custom_border_composition_enabled;
|
||||||
|
Arena *pain_arena;
|
||||||
|
OS_W32_TitleBarClientArea *first_title_bar_client_area;
|
||||||
|
OS_W32_TitleBarClientArea *last_title_bar_client_area;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Global State
|
||||||
|
typedef struct OS_W32_GfxState OS_W32_GfxState;
|
||||||
|
struct OS_W32_GfxState {
|
||||||
|
Arena *arena;
|
||||||
|
u32 gfx_thread_id;
|
||||||
|
HINSTANCE hInstance;
|
||||||
|
HCURSOR hCursor;
|
||||||
|
OS_GfxInfo gfx_info;
|
||||||
|
OS_W32_Window *first_window;
|
||||||
|
OS_W32_Window *last_window;
|
||||||
|
OS_W32_Window *free_window;
|
||||||
|
OS_KEY key_from_vkey_table[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Globals
|
||||||
|
global OS_W32_GfxState *os_w32_gfx_state = 0;
|
||||||
|
global OS_EventList os_w32_event_list = {0};
|
||||||
|
global Arena *os_w32_event_arena = 0;
|
||||||
|
b32 os_w32_resizing = 0;
|
||||||
|
|
||||||
|
// Windows
|
||||||
|
internal OS_Handle os_w32_handle_from_window(OS_W32_Window *window);
|
||||||
|
internal OS_W32_Window *os_w32_window_from_handle(OS_Handle window);
|
||||||
|
internal OS_W32_Window *os_w32_window_from_hwnd(HWND hwnd);
|
||||||
|
internal HWND os_w32_hwnd_from_window(OS_W32_Window *window);
|
||||||
|
internal OS_W32_Window *os_w32_window_alloc(void);
|
||||||
|
internal void os_w32_window_release(OS_W32_Window *window);
|
||||||
|
internal OS_Event *os_w32_push_event(OS_EventKind kind, OS_W32_Window *window);
|
||||||
|
internal OS_Key os_w32_os_key_from_vkey(WPARAM vkey);
|
||||||
|
internal WPARAM os_w32_vkey_from_os_key(OS_Key key);
|
||||||
|
internal LRESULT os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
#endif // OS_GFX_WIN32_H
|
@ -1,5 +1,18 @@
|
|||||||
// clang-format off
|
#include "os/core/os_core.c"
|
||||||
|
#if OS_GRAPHICAL
|
||||||
|
#include "os/gfx/os_gfx.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "core/win32/os_core_win32.c"
|
#if OS_WINDOWS
|
||||||
|
#include "os/core/win32/os_core_win32.c"
|
||||||
|
#else
|
||||||
|
#error OS core layer not implemented for this operating system.
|
||||||
|
#endif
|
||||||
|
|
||||||
// clang-format on
|
#if OS_GRAPHICAL
|
||||||
|
#if OS_WINDOWS
|
||||||
|
#include "os/gfx/win32/os_gfx_win32.c"
|
||||||
|
#else
|
||||||
|
#error OS graphical layer not implemented for this operating system.
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
@ -1,11 +1,27 @@
|
|||||||
#ifndef OS_INC_H
|
#ifndef OS_INC_H
|
||||||
#define OS_INC_H
|
#define OS_INC_H
|
||||||
|
|
||||||
// clang-format off
|
#if !defined(OS_GRAPHICAL)
|
||||||
|
#define OS_GRAPHICAL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "core/os_core.h"
|
#include "os/core/os_core.h"
|
||||||
#include "core/win32/os_core_win32.h"
|
#if OS_GRAHICAL
|
||||||
|
#include "os/gfx/os_gfx.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// clang-format on
|
#if OS_WINDOWS
|
||||||
|
#include "os/core/win32/os_core_win32.h"
|
||||||
|
#else
|
||||||
|
#error OS core layer not implemented for this operating system.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if OS_GRAPHICAL
|
||||||
|
#if OS_WINDOWS
|
||||||
|
#include "os/gfx/win32/os_gfx_win32.h"
|
||||||
|
#else
|
||||||
|
#error OS graphical layer not implemented for this operating system.
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // OS_INC_H
|
#endif // OS_INC_H
|
||||||
|
Loading…
Reference in New Issue
Block a user