2022-12-31 08:35:58 +00:00
# include <cstdio>
2023-01-16 09:10:53 +00:00
# include <thread>
2023-01-05 10:27:14 +00:00
# include <locale.h>
2022-12-31 08:35:58 +00:00
# include <sys/stat.h>
# include <imgui.h>
# include <imgui_impl_sdl.h>
# include <imgui_impl_opengl3.h>
# include <SDL.h>
# if defined(IMGUI_IMPL_OPENGL_ES2)
# include <SDL_opengles2.h>
# else
# include <SDL_opengl.h>
# endif
2023-01-22 14:28:14 +00:00
# include "log.h"
2023-01-06 16:27:39 +00:00
# include "fonts.h"
2022-12-31 08:35:58 +00:00
# include "config.h"
# include "event_loop.h"
2023-01-16 09:10:53 +00:00
# include "logcat_thread.h"
2022-12-31 08:35:58 +00:00
2023-01-05 10:27:14 +00:00
int main ( int , char * * ) {
2023-01-08 12:06:18 +00:00
setlocale ( LC_TIME , " " ) ;
2023-01-05 10:27:14 +00:00
2022-12-31 08:35:58 +00:00
Config config ;
try {
2023-01-04 16:40:35 +00:00
config = load_config ( ) ;
2022-12-31 08:35:58 +00:00
} catch ( const std : : exception & e ) {
2023-01-04 16:40:35 +00:00
fprintf ( stderr , " Failed to load config: %s \n " , e . what ( ) ) ;
2022-12-31 08:35:58 +00:00
return 1 ;
}
2023-01-04 16:40:35 +00:00
try {
create_config_folders_if_necessary ( ) ;
} catch ( const std : : exception & e ) {
fprintf ( stderr , " Failed to create config folder: %s \n " , e . what ( ) ) ;
return 1 ;
2022-12-31 08:35:58 +00:00
}
// Setup SDL
// (Some versions of SDL before <2.0.10 appears to have performance/stalling issues on a minority of Windows systems,
// depending on whether SDL_INIT_GAMECONTROLLER is enabled or disabled.. updating to the latest version of SDL is recommended!)
if ( SDL_Init ( SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER ) ! = 0 )
{
2023-01-17 13:56:56 +00:00
fprintf ( stderr , " SDL_Init(): %s \n " , SDL_GetError ( ) ) ;
return 1 ;
2022-12-31 08:35:58 +00:00
}
// Decide GL+GLSL versions
# if defined(IMGUI_IMPL_OPENGL_ES2)
// GL ES 2.0 + GLSL 100
const char * glsl_version = " #version 100 " ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_FLAGS , 0 ) ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_PROFILE_MASK , SDL_GL_CONTEXT_PROFILE_ES ) ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MAJOR_VERSION , 2 ) ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MINOR_VERSION , 0 ) ;
# elif defined(__APPLE__)
// GL 3.2 Core + GLSL 150
const char * glsl_version = " #version 150 " ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_FLAGS , SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG ) ; // Always required on Mac
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_PROFILE_MASK , SDL_GL_CONTEXT_PROFILE_CORE ) ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MAJOR_VERSION , 3 ) ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MINOR_VERSION , 2 ) ;
# else
// GL 3.0 + GLSL 130
const char * glsl_version = " #version 130 " ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_FLAGS , 0 ) ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_PROFILE_MASK , SDL_GL_CONTEXT_PROFILE_CORE ) ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MAJOR_VERSION , 3 ) ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MINOR_VERSION , 0 ) ;
# endif
// Create window with graphics context
SDL_GL_SetAttribute ( SDL_GL_DOUBLEBUFFER , 1 ) ;
SDL_GL_SetAttribute ( SDL_GL_DEPTH_SIZE , 24 ) ;
SDL_GL_SetAttribute ( SDL_GL_STENCIL_SIZE , 8 ) ;
SDL_WindowFlags window_flags = ( SDL_WindowFlags ) ( SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI ) ;
SDL_Window * window = SDL_CreateWindow ( " LogMeow " , SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED , 1280 , 720 , window_flags ) ;
SDL_GLContext gl_context = SDL_GL_CreateContext ( window ) ;
SDL_GL_MakeCurrent ( window , gl_context ) ;
SDL_GL_SetSwapInterval ( 1 ) ; // Enable vsync
// Setup Dear ImGui context
IMGUI_CHECKVERSION ( ) ;
ImGui : : CreateContext ( ) ;
2023-01-04 16:40:35 +00:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
// needs to be a variable to keep the c-style string around
std : : string ini_file_path = get_config_folder ( ) + " /imgui.ini " ;
io . IniFilename = ini_file_path . c_str ( ) ;
2022-12-31 08:35:58 +00:00
io . ConfigFlags | = ImGuiConfigFlags_NavEnableKeyboard ; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup Dear ImGui style
ImGui : : StyleColorsDark ( ) ;
//ImGui::StyleColorsLight();
// Setup Platform/Renderer backends
ImGui_ImplSDL2_InitForOpenGL ( window , gl_context ) ;
ImGui_ImplOpenGL3_Init ( glsl_version ) ;
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
// - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
// - Read 'docs/FONTS.md' for more instructions and details.
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
//io.Fonts->AddFontDefault();
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
//IM_ASSERT(font != NULL);
2023-01-08 12:06:18 +00:00
ImFont * monospace_font = nullptr ;
2023-01-07 09:15:21 +00:00
# ifdef USE_FONTCONFIG
try {
std : : pair < std : : string , std : : string > fonts = get_fonts ( ) ;
2023-01-08 16:12:22 +00:00
io . Fonts - > AddFontFromFileTTF ( fonts . first . c_str ( ) , config . normal_font_size ) ;
monospace_font = io . Fonts - > AddFontFromFileTTF ( fonts . second . c_str ( ) , config . monospace_font_size ) ;
2023-01-07 09:15:21 +00:00
} catch ( const std : : exception & e ) {
2023-01-16 04:08:35 +00:00
log ( std : : string ( " Failed to get fonts: " ) + e . what ( ) ) ;
2023-01-08 12:06:18 +00:00
}
2023-01-08 16:12:22 +00:00
# endif
2023-01-08 12:06:18 +00:00
if ( ! monospace_font ) {
2023-01-08 16:12:22 +00:00
ImFontConfig font_config ;
font_config . SizePixels = config . monospace_font_size ;
monospace_font = io . Fonts - > AddFontDefault ( & font_config ) ;
2023-01-07 09:15:21 +00:00
}
2022-12-31 08:35:58 +00:00
// Main loop
bool run_event_loop = true ;
2023-01-04 16:40:35 +00:00
float config_write_timer = 0.0f ;
2023-01-17 13:56:56 +00:00
LogcatThread logcat_thread = [ & ] ( ) {
try {
2023-01-17 16:22:12 +00:00
return LogcatThread ( ) ;
2023-01-17 13:56:56 +00:00
} catch ( const std : : exception & e ) {
fprintf ( stderr , " Failed to spawn logcat thread: %s \n " , e . what ( ) ) ;
exit ( 1 ) ;
}
} ( ) ;
2023-01-04 16:40:35 +00:00
while ( run_event_loop ) {
2022-12-31 08:35:58 +00:00
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
SDL_Event event ;
while ( SDL_PollEvent ( & event ) )
{
ImGui_ImplSDL2_ProcessEvent ( & event ) ;
if ( event . type = = SDL_QUIT ) {
run_event_loop = false ;
} else if ( event . type = = SDL_WINDOWEVENT & & event . window . event = = SDL_WINDOWEVENT_CLOSE & & event . window . windowID = = SDL_GetWindowID ( window ) )
run_event_loop = false ;
}
// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame ( ) ;
ImGui_ImplSDL2_NewFrame ( ) ;
ImGui : : NewFrame ( ) ;
2023-01-18 16:34:17 +00:00
event_loop ( monospace_font , config , & config_write_timer , logcat_thread , & run_event_loop ) ;
2022-12-31 08:35:58 +00:00
// Rendering
ImGui : : Render ( ) ;
glViewport ( 0 , 0 , ( int ) io . DisplaySize . x , ( int ) io . DisplaySize . y ) ;
glClearColor ( 0.15f , 0.15f , 0.15f , 1.0f ) ;
glClear ( GL_COLOR_BUFFER_BIT ) ;
ImGui_ImplOpenGL3_RenderDrawData ( ImGui : : GetDrawData ( ) ) ;
SDL_GL_SwapWindow ( window ) ;
}
// Cleanup
ImGui_ImplOpenGL3_Shutdown ( ) ;
ImGui_ImplSDL2_Shutdown ( ) ;
ImGui : : DestroyContext ( ) ;
SDL_GL_DeleteContext ( gl_context ) ;
SDL_DestroyWindow ( window ) ;
SDL_Quit ( ) ;
2023-01-04 16:40:35 +00:00
if ( config_write_timer > 0.0f ) {
try {
write_config ( config ) ;
} catch ( const std : : exception & e ) {
fprintf ( stderr , " Failed to write config: %s \n " , e . what ( ) ) ;
return 1 ;
}
}
2023-01-17 16:22:12 +00:00
logcat_thread . request_stop ( ) ;
2023-01-16 09:10:53 +00:00
logcat_thread . join ( ) ;
2023-01-04 16:40:35 +00:00
2022-12-31 08:35:58 +00:00
return 0 ;
}