Compare commits
3 Commits
master
...
in-progres
Author | SHA1 | Date | |
---|---|---|---|
d3d8421110 | |||
404ec22e57 | |||
79b6e83147 |
9
LICENSE
Normal file
9
LICENSE
Normal file
@ -0,0 +1,9 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 tijani
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
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
|
||||
strings, math, memory allocators, threading, and logging.
|
||||
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
|
||||
`es/core` to provide graphical features such as windows, panels, and all
|
||||
interfaces needed for using the scanner. It is the main user of `os/gfx`.
|
||||
- `os/core` (`OS_`): An abstraction layer that provides core, non-graphical
|
||||
functionality from the operating sytem under a general use abstraction API.
|
||||
This is implemented per supported operating system.
|
||||
- `os/gfx` (`OS_`): This layer builds on top of `os/core`, it provides
|
||||
graphical operating functionalities under a general use abstraction API.
|
||||
|
||||
- `ef/core` (`EF_`): The scanner engine's non-graphical frontend. It implements
|
||||
interfacing with the scanner over usb, colour space settings, and all intricate
|
||||
details that have to do with the software working with the scanner.
|
||||
- `ef/gfx` (`EF_`): The scanner engine`s graphical frontend. It provides all
|
||||
graphical features, including windows, panels, and all other various interfaces
|
||||
needed by the engine to function.
|
||||
|
||||
- `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
|
||||
immediate mode hierarchical user interface data structure building API, and
|
||||
has helper layers for building higher level widgets.
|
@ -44,6 +44,10 @@
|
||||
#define BUILD_DEBUG 1
|
||||
#endif
|
||||
|
||||
#if !defined(BUILD_ENTRY_DEFINING_UNIT)
|
||||
#define BUILD_ENTRY_DEFINING_UNIT 1
|
||||
#endif
|
||||
|
||||
#if !defined(BUILD_VERSION_MAJOR)
|
||||
#define BUILD_VERSION_MAJOR 0
|
||||
#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 bit32 = (1 << 31);
|
||||
|
||||
// Safe Casts
|
||||
internal u16 safe_cast_u16(u32 x);
|
||||
|
||||
// Misc helpers
|
||||
// NOTE(tijani): Divides total size of array by size of one element in the array gives
|
||||
// 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
|
||||
#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
|
||||
|
@ -1,7 +1,10 @@
|
||||
// clang-format off
|
||||
|
||||
#include "base_core.c"
|
||||
#include "base_arena.c"
|
||||
#include "base_strings.c"
|
||||
#include "base_markup.c"
|
||||
#include "base_threading_context.c"
|
||||
#include "base_entry_point.c"
|
||||
|
||||
// clang-format on
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "base_strings.h"
|
||||
#include "base_markup.h"
|
||||
#include "base_threading_context.h"
|
||||
#include "base_entry_point.h"
|
||||
|
||||
// clang-format on
|
||||
|
||||
#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
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
// Handle types
|
||||
typedef struct OS_Handle OS_Handle;
|
||||
struct OS_Handle {
|
||||
u64 l_u64[1];
|
||||
};
|
||||
|
||||
// Process Information
|
||||
typedef struct OS_ProcessInfo OS_ProcessInfo;
|
||||
struct OS_ProcessInfo {
|
||||
@ -45,4 +51,14 @@ internal void os_set_thread_name(String8 name);
|
||||
|
||||
// %os_hooks(implemented per-os) Aborting
|
||||
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
|
||||
|
@ -2,8 +2,8 @@
|
||||
// compatibility with older versions of windows where the modern WIN32
|
||||
// SetThreadDescription function is not available and use old ways.
|
||||
// This way it can be done dynamically at runtime without any hiccups.
|
||||
typedef HRESULT W32_SetThreadDescription(HANDLE hThread, PCWSTR lpThreadDescription);
|
||||
global W32_SetThreadDescription *w32_SetThreadDescription_func = 0;
|
||||
typedef HRESULT W32_SetThreadDescription_Type(HANDLE hThread, PCWSTR lpThreadDescription);
|
||||
global W32_SetThreadDescription_Type *w32_SetThreadDescription_func = 0;
|
||||
|
||||
// %os_hooks(implemented per-os) System and process 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
|
||||
internal u32 os_thread_id(void) {
|
||||
u32 id = GetCurrentThreadID();
|
||||
u32 id = GetCurrentThreadId();
|
||||
return (id);
|
||||
}
|
||||
|
||||
@ -90,3 +90,41 @@ internal void os_set_thread_name(String8 name) {
|
||||
|
||||
// %os_hooks(implemented per-os) Aborting
|
||||
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
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <processthreadsapi.h>
|
||||
|
||||
#pragma comment(lib, "user32")
|
||||
#pragma comment(lib, "advapi32")
|
||||
|
||||
// clang-format on
|
||||
|
||||
// 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
|
||||
#define OS_INC_H
|
||||
|
||||
// clang-format off
|
||||
#if !defined(OS_GRAPHICAL)
|
||||
#define OS_GRAPHICAL 0
|
||||
#endif
|
||||
|
||||
#include "core/os_core.h"
|
||||
#include "core/win32/os_core_win32.h"
|
||||
#include "os/core/os_core.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
|
||||
|
Loading…
Reference in New Issue
Block a user