switched to CRITICAL_SECTION, reorganized win32main

master
Allen Webster 2016-05-29 13:07:24 -04:00
parent 1db0ad31c2
commit 5c604d8273
2 changed files with 270 additions and 257 deletions

View File

@ -1,6 +1,6 @@
#define MAJOR 4 #define MAJOR 4
#define MINOR 0 #define MINOR 0
#define PATCH 6 #define PATCH 7
#define VN__(a,b,c) #a"."#b"."#c #define VN__(a,b,c) #a"."#b"."#c
#define VN_(a,b,c) VN__(a,b,c) #define VN_(a,b,c) VN__(a,b,c)

View File

@ -115,7 +115,6 @@ struct Sys_Bubble : public Bubble{
struct Win32_Vars{ struct Win32_Vars{
HWND window_handle; HWND window_handle;
HDC window_hdc;
Render_Target target; Render_Target target;
Win32_Input_Chunk input_chunk; Win32_Input_Chunk input_chunk;
@ -131,8 +130,8 @@ struct Win32_Vars{
DWORD clipboard_sequence; DWORD clipboard_sequence;
Thread_Group groups[THREAD_GROUP_COUNT]; Thread_Group groups[THREAD_GROUP_COUNT];
HANDLE locks[LOCK_COUNT]; CRITICAL_SECTION locks[LOCK_COUNT];
HANDLE DEBUG_sysmem_lock; CRITICAL_SECTION DEBUG_sysmem_lock;
Thread_Memory *thread_memory; Thread_Memory *thread_memory;
@ -203,55 +202,43 @@ Win32Ptr(void *h){
// Memory (not exposed to application, but needed in system_shared.cpp) // Memory (not exposed to application, but needed in system_shared.cpp)
// //
#if FRED_INTERNAL
internal internal
Sys_Get_Memory_Sig(system_get_memory_){ Sys_Get_Memory_Sig(system_get_memory_){
void *ptr = 0; void *ptr = 0;
if (size > 0){ if (size > 0){
#if FRED_INTERNAL
ptr = VirtualAlloc(0, size + sizeof(Sys_Bubble), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); ptr = VirtualAlloc(0, size + sizeof(Sys_Bubble), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
Sys_Bubble *bubble = (Sys_Bubble*)ptr; Sys_Bubble *bubble = (Sys_Bubble*)ptr;
bubble->flags = MEM_BUBBLE_SYS_DEBUG; bubble->flags = MEM_BUBBLE_SYS_DEBUG;
bubble->line_number = line_number; bubble->line_number = line_number;
bubble->file_name = file_name; bubble->file_name = file_name;
bubble->size = size; bubble->size = size;
WaitForSingleObject(win32vars.DEBUG_sysmem_lock, INFINITE); EnterCriticalSection(&win32vars.DEBUG_sysmem_lock);
insert_bubble(&win32vars.internal_bubble, bubble); insert_bubble(&win32vars.internal_bubble, bubble);
ReleaseSemaphore(win32vars.DEBUG_sysmem_lock, 1, 0); LeaveCriticalSection(&win32vars.DEBUG_sysmem_lock);
ptr = bubble + 1; ptr = bubble + 1;
#else
ptr = VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
#endif
} }
return(ptr); return(ptr);
} }
internal internal
Sys_Free_Memory_Sig(system_free_memory){ Sys_Free_Memory_Sig(system_free_memory){
if (block){ if (block){
#if FRED_INTERNAL
Sys_Bubble *bubble = ((Sys_Bubble*)block) - 1; Sys_Bubble *bubble = ((Sys_Bubble*)block) - 1;
Assert((bubble->flags & MEM_BUBBLE_DEBUG_MASK) == MEM_BUBBLE_SYS_DEBUG); Assert((bubble->flags & MEM_BUBBLE_DEBUG_MASK) == MEM_BUBBLE_SYS_DEBUG);
WaitForSingleObject(win32vars.DEBUG_sysmem_lock, INFINITE); EnterCriticalSection(&win32vars.DEBUG_sysmem_lock);
remove_bubble(bubble); remove_bubble(bubble);
ReleaseSemaphore(win32vars.DEBUG_sysmem_lock, 1, 0); LeaveCriticalSection(&win32vars.DEBUG_sysmem_lock);
VirtualFree(bubble, 0, MEM_RELEASE); VirtualFree(bubble, 0, MEM_RELEASE);
}
}
#else #else
internal
Sys_Get_Memory_Sig(system_get_memory_){
void *ptr = 0;
if (size > 0){
ptr = VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
}
return(ptr);
}
internal
Sys_Free_Memory_Sig(system_free_memory){
if (block){
VirtualFree(block, 0, MEM_RELEASE); VirtualFree(block, 0, MEM_RELEASE);
}
}
#endif #endif
}
}
#define Win32GetMemory(size) system_get_memory_(size, __LINE__, __FILE__) #define Win32GetMemory(size) system_get_memory_(size, __LINE__, __FILE__)
#define Win32FreeMemory(ptr) system_free_memory(ptr) #define Win32FreeMemory(ptr) system_free_memory(ptr)
@ -652,12 +639,12 @@ Sys_Post_Clipboard_Sig(system_post_clipboard){
internal internal
Sys_Acquire_Lock_Sig(system_acquire_lock){ Sys_Acquire_Lock_Sig(system_acquire_lock){
WaitForSingleObject(win32vars.locks[id], INFINITE); EnterCriticalSection(&win32vars.locks[id]);
} }
internal internal
Sys_Release_Lock_Sig(system_release_lock){ Sys_Release_Lock_Sig(system_release_lock){
ReleaseSemaphore(win32vars.locks[id], 1, 0); LeaveCriticalSection(&win32vars.locks[id]);
} }
internal DWORD internal DWORD
@ -1599,153 +1586,13 @@ WinMain(HINSTANCE hInstance,
int argc = __argc; int argc = __argc;
char **argv = __argv; char **argv = __argv;
HANDLE original_out = GetStdHandle(STD_OUTPUT_HANDLE);
memset(&win32vars, 0, sizeof(win32vars)); memset(&win32vars, 0, sizeof(win32vars));
memset(&exchange_vars, 0, sizeof(exchange_vars)); memset(&exchange_vars, 0, sizeof(exchange_vars));
#if FRED_INTERNAL
win32vars.internal_bubble.next = &win32vars.internal_bubble;
win32vars.internal_bubble.prev = &win32vars.internal_bubble;
win32vars.internal_bubble.flags = MEM_BUBBLE_SYS_DEBUG;
#endif
if (!Win32LoadAppCode()){
// TODO(allen): Failed to load app code, serious problem.
return 99;
}
System_Functions system_;
System_Functions *system = &system_;
win32vars.system = system;
Win32LoadSystemCode();
ConvertThreadToFiber(0);
win32vars.coroutine_free = win32vars.coroutine_data;
for (i32 i = 0; i+1 < ArrayCount(win32vars.coroutine_data); ++i){
win32vars.coroutine_data[i].next = win32vars.coroutine_data + i + 1;
}
LPVOID base;
#if FRED_INTERNAL
base = (LPVOID)Tbytes(1);
#else
base = (LPVOID)0;
#endif
memory_vars.vars_memory_size = Mbytes(2);
memory_vars.vars_memory = VirtualAlloc(base, memory_vars.vars_memory_size,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
#if FRED_INTERNAL
base = (LPVOID)Tbytes(2);
#else
base = (LPVOID)0;
#endif
memory_vars.target_memory_size = Mbytes(512);
memory_vars.target_memory = VirtualAlloc(base, memory_vars.target_memory_size,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
base = (LPVOID)0;
memory_vars.user_memory_size = Mbytes(2);
memory_vars.user_memory = VirtualAlloc(base, memory_vars.target_memory_size,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
// //
// Threads and Coroutines
if (!memory_vars.vars_memory){ //
return 4;
}
DWORD required = GetCurrentDirectory(0, 0);
required += 1;
required *= 4;
char *current_directory_mem = (char*)system_get_memory(required);
DWORD written = GetCurrentDirectory(required, current_directory_mem);
String current_directory = make_string(current_directory_mem, written, required);
terminate_with_null(&current_directory);
replace_char(current_directory, '\\', '/');
Command_Line_Parameters clparams;
clparams.argv = argv;
clparams.argc = argc;
char **files;
i32 *file_count;
files = 0;
file_count = 0;
i32 output_size =
win32vars.app.read_command_line(system,
&memory_vars,
current_directory,
&win32vars.settings,
&files, &file_count,
clparams);
if (output_size > 0){
DWORD written;
WriteFile(original_out, memory_vars.target_memory, output_size, &written, 0);
}
if (output_size != 0) return 0;
#ifdef FRED_SUPER
char *custom_file_default = "4coder_custom.dll";
char *custom_file = 0;
if (win32vars.settings.custom_dll) custom_file = win32vars.settings.custom_dll;
else custom_file = custom_file_default;
win32vars.custom = LoadLibraryA(custom_file);
if (!win32vars.custom && custom_file != custom_file_default){
if (!win32vars.settings.custom_dll_is_strict){
win32vars.custom = LoadLibraryA(custom_file_default);
}
}
if (win32vars.custom){
win32vars.custom_api.get_alpha_4coder_version = (_Get_Version_Function*)
GetProcAddress(win32vars.custom, "get_alpha_4coder_version");
if (win32vars.custom_api.get_alpha_4coder_version == 0 ||
win32vars.custom_api.get_alpha_4coder_version(MAJOR, MINOR, PATCH) == 0){
OutputDebugStringA("Error: application and custom version numbers don't match");
return 22;
}
win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)
GetProcAddress(win32vars.custom, "get_bindings");
win32vars.custom_api.view_routine = (View_Routine_Function*)
GetProcAddress(win32vars.custom, "view_routine");
}
#endif
if (win32vars.custom_api.get_bindings == 0){
win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)get_bindings;
}
if (win32vars.custom_api.view_routine == 0){
win32vars.custom_api.view_routine = (View_Routine_Function*)view_routine;
}
FreeConsole();
sysshared_filter_real_files(files, file_count);
LARGE_INTEGER lpf;
QueryPerformanceFrequency(&lpf);
win32vars.performance_frequency = lpf.QuadPart;
QueryPerformanceCounter(&lpf);
win32vars.start_pcount = lpf.QuadPart;
FILETIME filetime;
GetSystemTimeAsFileTime(&filetime);
win32vars.start_time = ((u64)filetime.dwHighDateTime << 32) | (filetime.dwLowDateTime);
win32vars.start_time /= 10;
Win32KeycodeInit();
Thread_Context background[4]; Thread_Context background[4];
memset(background, 0, sizeof(background)); memset(background, 0, sizeof(background));
@ -1774,28 +1621,168 @@ WinMain(HINSTANCE hInstance,
Assert(win32vars.locks); Assert(win32vars.locks);
for (i32 i = 0; i < LOCK_COUNT; ++i){ for (i32 i = 0; i < LOCK_COUNT; ++i){
win32vars.locks[i] = CreateSemaphore(0, 1, 1, 0); InitializeCriticalSection(&win32vars.locks[i]);
}
InitializeCriticalSection(&win32vars.DEBUG_sysmem_lock);
ConvertThreadToFiber(0);
win32vars.coroutine_free = win32vars.coroutine_data;
for (i32 i = 0; i+1 < ArrayCount(win32vars.coroutine_data); ++i){
win32vars.coroutine_data[i].next = win32vars.coroutine_data + i + 1;
}
//
// Memory Initialization
//
#if FRED_INTERNAL
win32vars.internal_bubble.next = &win32vars.internal_bubble;
win32vars.internal_bubble.prev = &win32vars.internal_bubble;
win32vars.internal_bubble.flags = MEM_BUBBLE_SYS_DEBUG;
#endif
LPVOID base;
#if FRED_INTERNAL
base = (LPVOID)Tbytes(1);
#else
base = (LPVOID)0;
#endif
memory_vars.vars_memory_size = Mbytes(2);
memory_vars.vars_memory = VirtualAlloc(base, memory_vars.vars_memory_size,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
#if FRED_INTERNAL
base = (LPVOID)Tbytes(2);
#else
base = (LPVOID)0;
#endif
memory_vars.target_memory_size = Mbytes(512);
memory_vars.target_memory =
VirtualAlloc(base, memory_vars.target_memory_size,
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
base = (LPVOID)0;
memory_vars.user_memory_size = Mbytes(2);
memory_vars.user_memory =
VirtualAlloc(base, memory_vars.target_memory_size,
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!memory_vars.vars_memory){
exit(1);
} }
win32vars.DEBUG_sysmem_lock = CreateSemaphore(0, 1, 1, 0);
Win32LoadRenderCode();
win32vars.target.max = Mbytes(1); win32vars.target.max = Mbytes(1);
win32vars.target.push_buffer = (byte*)system_get_memory(win32vars.target.max); win32vars.target.push_buffer = (byte*)system_get_memory(win32vars.target.max);
win32vars.cursor_ibeam = LoadCursor(NULL, IDC_IBEAM);
win32vars.cursor_arrow = LoadCursor(NULL, IDC_ARROW); //
win32vars.cursor_leftright = LoadCursor(NULL, IDC_SIZEWE); // System and Application Layer Linkage
win32vars.cursor_updown = LoadCursor(NULL, IDC_SIZENS); //
if (!Win32LoadAppCode()){
exit(1);
}
System_Functions system_;
System_Functions *system = &system_;
win32vars.system = system;
Win32LoadSystemCode();
Win32LoadRenderCode();
//
// Read Command Line
//
DWORD required = GetCurrentDirectory(0, 0);
required += 1;
required *= 4;
char *current_directory_mem = (char*)system_get_memory(required);
DWORD written = GetCurrentDirectory(required, current_directory_mem);
String current_directory = make_string(current_directory_mem, written, required);
terminate_with_null(&current_directory);
replace_char(current_directory, '\\', '/');
Command_Line_Parameters clparams;
clparams.argv = argv;
clparams.argc = argc;
char **files;
i32 *file_count;
files = 0;
file_count = 0;
win32vars.app.read_command_line(system,
&memory_vars,
current_directory,
&win32vars.settings,
&files, &file_count,
clparams);
sysshared_filter_real_files(files, file_count);
//
// Custom Layer Linkage
//
#ifdef FRED_SUPER
char *custom_file_default = "4coder_custom.dll";
char *custom_file = 0;
if (win32vars.settings.custom_dll) custom_file = win32vars.settings.custom_dll;
else custom_file = custom_file_default;
win32vars.custom = LoadLibraryA(custom_file);
if (!win32vars.custom && custom_file != custom_file_default){
if (!win32vars.settings.custom_dll_is_strict){
win32vars.custom = LoadLibraryA(custom_file_default);
}
}
if (win32vars.custom){
win32vars.custom_api.get_alpha_4coder_version = (_Get_Version_Function*)
GetProcAddress(win32vars.custom, "get_alpha_4coder_version");
if (win32vars.custom_api.get_alpha_4coder_version == 0 ||
win32vars.custom_api.get_alpha_4coder_version(MAJOR, MINOR, PATCH) == 0){
OutputDebugStringA("Error: application and custom version numbers don't match");
exit(1);
}
win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)
GetProcAddress(win32vars.custom, "get_bindings");
win32vars.custom_api.view_routine = (View_Routine_Function*)
GetProcAddress(win32vars.custom, "view_routine");
}
#endif
if (win32vars.custom_api.get_bindings == 0){
win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)get_bindings;
}
if (win32vars.custom_api.view_routine == 0){
win32vars.custom_api.view_routine = (View_Routine_Function*)view_routine;
}
//
// Window and GL Initialization
//
WNDCLASS window_class = {}; WNDCLASS window_class = {};
window_class.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC; window_class.style = CS_HREDRAW|CS_VREDRAW;
window_class.lpfnWndProc = Win32Callback; window_class.lpfnWndProc = Win32Callback;
window_class.hInstance = hInstance; window_class.hInstance = hInstance;
window_class.lpszClassName = "4coder-win32-wndclass"; window_class.lpszClassName = "4coder-win32-wndclass";
window_class.hIcon = LoadIcon(hInstance, "main"); window_class.hIcon = LoadIcon(hInstance, "main");
if (!RegisterClass(&window_class)){ if (!RegisterClass(&window_class)){
return 1; exit(1);
} }
RECT window_rect = {}; RECT window_rect = {};
@ -1833,28 +1820,23 @@ WinMain(HINSTANCE hInstance,
window_style |= WS_MAXIMIZE; window_style |= WS_MAXIMIZE;
} }
// TODO(allen): not Windows XP compatible, do we care? win32vars.window_handle =
// SetProcessDPIAware(); CreateWindowA(window_class.lpszClassName,
HWND window_handle = {};
window_handle = CreateWindowA(
window_class.lpszClassName,
WINDOW_NAME, window_style, WINDOW_NAME, window_style,
window_x, window_y, window_x, window_y,
window_rect.right - window_rect.left, window_rect.right - window_rect.left,
window_rect.bottom - window_rect.top, window_rect.bottom - window_rect.top,
0, 0, hInstance, 0); 0, 0, hInstance, 0);
if (window_handle == 0){ if (win32vars.window_handle == 0){
return 2; exit(1);
} }
// TODO(allen): errors?
win32vars.window_handle = window_handle;
HDC hdc = GetDC(window_handle);
win32vars.window_hdc = hdc;
GetClientRect(window_handle, &window_rect); // TODO(allen): not Windows XP compatible, do we care?
// SetProcessDPIAware();
GetClientRect(win32vars.window_handle, &window_rect);
static PIXELFORMATDESCRIPTOR pfd = { static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), sizeof(PIXELFORMATDESCRIPTOR),
@ -1874,6 +1856,8 @@ WinMain(HINSTANCE hInstance,
0, 0,
0, 0, 0 }; 0, 0, 0 };
HDC hdc = GetDC(win32vars.window_handle);
{
i32 pixel_format; i32 pixel_format;
pixel_format = ChoosePixelFormat(hdc, &pfd); pixel_format = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, pixel_format, &pfd); SetPixelFormat(hdc, pixel_format, &pfd);
@ -1881,6 +1865,8 @@ WinMain(HINSTANCE hInstance,
win32vars.target.handle = hdc; win32vars.target.handle = hdc;
win32vars.target.context = wglCreateContext(hdc); win32vars.target.context = wglCreateContext(hdc);
wglMakeCurrent(hdc, (HGLRC)win32vars.target.context); wglMakeCurrent(hdc, (HGLRC)win32vars.target.context);
}
ReleaseDC(win32vars.window_handle, hdc);
#if FRED_INTERNAL #if FRED_INTERNAL
// NOTE(casey): This slows down GL but puts error messages to the debug console immediately whenever you do something wrong // NOTE(casey): This slows down GL but puts error messages to the debug console immediately whenever you do something wrong
@ -1902,6 +1888,11 @@ WinMain(HINSTANCE hInstance,
Win32Resize(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top); Win32Resize(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top);
//
// Misc System Initializations
//
win32vars.clipboard_sequence = GetClipboardSequenceNumber(); win32vars.clipboard_sequence = GetClipboardSequenceNumber();
if (win32vars.clipboard_sequence == 0){ if (win32vars.clipboard_sequence == 0){
@ -1932,6 +1923,29 @@ WinMain(HINSTANCE hInstance,
} }
} }
LARGE_INTEGER lpf;
QueryPerformanceFrequency(&lpf);
win32vars.performance_frequency = lpf.QuadPart;
QueryPerformanceCounter(&lpf);
win32vars.start_pcount = lpf.QuadPart;
FILETIME filetime;
GetSystemTimeAsFileTime(&filetime);
win32vars.start_time = ((u64)filetime.dwHighDateTime << 32) | (filetime.dwLowDateTime);
win32vars.start_time /= 10;
Win32KeycodeInit();
win32vars.cursor_ibeam = LoadCursor(NULL, IDC_IBEAM);
win32vars.cursor_arrow = LoadCursor(NULL, IDC_ARROW);
win32vars.cursor_leftright = LoadCursor(NULL, IDC_SIZEWE);
win32vars.cursor_updown = LoadCursor(NULL, IDC_SIZENS);
//
// Main Loop
//
win32vars.app.init(win32vars.system, &win32vars.target, win32vars.app.init(win32vars.system, &win32vars.target,
&memory_vars, &exchange_vars, &memory_vars, &exchange_vars,
win32vars.clipboard_contents, current_directory, win32vars.clipboard_contents, current_directory,
@ -1943,11 +1957,10 @@ WinMain(HINSTANCE hInstance,
win32vars.first = 1; win32vars.first = 1;
timeBeginPeriod(1); timeBeginPeriod(1);
SetForegroundWindow(win32vars.window_handle);
SetActiveWindow(win32vars.window_handle);
system_acquire_lock(FRAME_LOCK); system_acquire_lock(FRAME_LOCK);
SetForegroundWindow(window_handle);
SetActiveWindow(window_handle);
MSG msg; MSG msg;
for (;win32vars.input_chunk.pers.keep_playing;){ for (;win32vars.input_chunk.pers.keep_playing;){
// TODO(allen): Find a good way to wait on a pipe // TODO(allen): Find a good way to wait on a pipe
@ -2096,7 +2109,7 @@ WinMain(HINSTANCE hInstance,
} }
} }
return 0; return(0);
} }
#if 0 #if 0