diff --git a/Client/CMakeLists.txt b/Client/CMakeLists.txt index 731f56f..b53b163 100644 --- a/Client/CMakeLists.txt +++ b/Client/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 2.6) project(NiotsoClient) include_directories(${CMAKE_SOURCE_DIR}/Libraries/FileHandler) +include_directories(${CMAKE_SOURCE_DIR}/Libraries/freetype/include) if(WIN32) set(NIOTSOCLIENT_SOURCES @@ -9,11 +10,12 @@ if(WIN32) MessageHandler.cpp Audio/Startup.cpp Audio/windows/XAudio2.cpp + Graphics/Font.cpp Graphics/Startup.cpp Graphics/Viewport.cpp resources/Resource.rc System/System.cpp ) add_executable(TSO WIN32 ${NIOTSOCLIENT_SOURCES}) - target_link_libraries(TSO FileHandler_shared ole32 opengl32) + target_link_libraries(TSO FileHandler_shared freetype_shared ole32 opengl32) endif() \ No newline at end of file diff --git a/Client/Client.cpp b/Client/Client.cpp index b952617..a5bab02 100644 --- a/Client/Client.cpp +++ b/Client/Client.cpp @@ -69,8 +69,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) } CurrentScene = new LoginScreen(); - if(System::SceneFailed || CurrentScene == NULL){ - if(System::SceneFailed) delete CurrentScene; + if(CurrentScene == NULL || System::SceneFailed){ Shutdown(); return ERROR_INIT | ERROR_INIT_LOGIC | ERROR_LOGIC_CREATE_SCENE; } @@ -99,6 +98,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) if(result == System::SHUTDOWN) break; if(result > 0){ + glClear(GL_COLOR_BUFFER_BIT); CurrentScene->Render(); SwapBuffers(Graphics::hDC); } @@ -130,7 +130,7 @@ int CreateWindowInvisible(HINSTANCE hInst, unsigned Width, unsigned Height, bool NULL, //hCursor NULL, //hbrBackground NULL, //lpszMenuName - "TSO_NIOTSO" //lpszClassName + "TSO_NIOTSO" //lpszClassName }; if(!RegisterClass(&wc)){ @@ -195,6 +195,7 @@ void Shutdown() { Audio::Shutdown(); Graphics::Shutdown(); + System::Shutdown(); if(Window::hWnd){ DestroyWindow(Window::hWnd); diff --git a/Client/EngineInterface.hpp b/Client/EngineInterface.hpp index 6ac10e7..eacc0e2 100644 --- a/Client/EngineInterface.hpp +++ b/Client/EngineInterface.hpp @@ -24,6 +24,15 @@ #define NULL 0 #include "FileHandler.hpp" +#include "ft2build.h" +#include FT_FREETYPE_H + +#ifndef min + #define min(x,y) ((x)<(y)?(x):(y)) +#endif +#ifndef max + #define max(x,y) ((x)>(y)?(x):(y)) +#endif //IsometricEngine.cpp namespace Window { diff --git a/Client/Graphics/Graphics.hpp b/Client/Graphics/Graphics.hpp index af47f24..0cba9cd 100644 --- a/Client/Graphics/Graphics.hpp +++ b/Client/Graphics/Graphics.hpp @@ -27,4 +27,19 @@ namespace Graphics { int InitGL(); void ResizeViewport(unsigned width, unsigned height); + + enum TextAlignment { + ALIGN_LEFT_TOP, + ALIGN_LEFT_CENTER, + ALIGN_CENTER_TOP, + ALIGN_CENTER_CENTER, + ALIGN_RIGHT_TOP, + ALIGN_RIGHT_CENTER + }; + + //Font.cpp + extern FT_Library FreeTypeLibrary; + extern FT_Face FontFace; + void DrawText(Image_t * Image, const wchar_t * String, int x, int y, unsigned width, unsigned height, + TextAlignment Alignment, int font, COLORREF Color); } \ No newline at end of file diff --git a/Client/Graphics/Startup.cpp b/Client/Graphics/Startup.cpp index 836e057..12fef6c 100644 --- a/Client/Graphics/Startup.cpp +++ b/Client/Graphics/Startup.cpp @@ -95,6 +95,7 @@ int InitGL(){ glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glEnable(GL_RESCALE_NORMAL); + glEnable(GL_TEXTURE_2D); glDisable(GL_BLEND); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); diff --git a/Client/Scene/Scene.hpp b/Client/Scene/Scene.hpp index 5850eb2..8c27c45 100644 --- a/Client/Scene/Scene.hpp +++ b/Client/Scene/Scene.hpp @@ -15,6 +15,8 @@ along with this program. If not, see . */ +#include + #define EXIT_SCENE() do { System::SceneFailed = true; delete this; return; } while(0) #define SCENE_EXIT 0 #define SCENE_NEED_REDRAW 1 @@ -22,11 +24,12 @@ class Scene { const float TickPeriod; - float TimeDelta; + float RealTimeDelta; virtual int Run(float TimeDelta) = 0; protected: - Scene(float c) : TickPeriod(c), TimeDelta(0) {} + float TimeDelta; + Scene(float c) : TickPeriod(c), RealTimeDelta(0) {} public: int RunFor(float TimeDelta) { @@ -35,54 +38,95 @@ class Scene { } bool Redraw = false; - this->TimeDelta += TimeDelta; - while(this->TimeDelta >= 0){ + RealTimeDelta += TimeDelta; + while(RealTimeDelta >= 0){ int result = Run(TickPeriod); if(result == System::SHUTDOWN) return System::SHUTDOWN; if(result > 0) Redraw = true; - this->TimeDelta -= TickPeriod; + RealTimeDelta -= TickPeriod; } return (Redraw) ? 1 : -1; } virtual void Render() = 0; + virtual ~Scene() {}; }; +enum { + TEX_EAGAMES, + TEX_MAXIS, + TEX_SETUP, + TEX_COUNT +}; + +static const char * const images[] = {"eagames.bmp", "maxis.png", "setup.bmp"}; + class LoginScreen : public Scene { + float Time; + GLuint texture[TEX_COUNT]; + public: LoginScreen() : Scene(1.0f/15){ - Image_t * Image = File::ReadImageFile("eagames.bmp"); - if(!Image){ - const char * Message; - switch(File::Error){ - case FERR_NOT_FOUND: - Message = "%s does not exist."; - break; - case FERR_OPEN: - Message = "%s could not be opened for reading."; - break; - case FERR_BLANK: - case FERR_UNRECOGNIZED: - case FERR_INVALIDDATA: - Message = "%s is corrupt or invalid."; - break; - case FERR_MEMORY: - Message = "Memory for %s could not be allocated."; - break; - default: - Message = "%s could not be read."; - } + Time = 0; - char Buffer[1024]; - sprintf(Buffer, Message, "eagames.bmp"); - MessageBox(Window::hWnd, Buffer, NULL, MB_OK | MB_ICONERROR); - EXIT_SCENE(); + glMatrixMode(GL_TEXTURE); + glGenTextures(TEX_COUNT, texture); + + for(int i=0; iWidth, Image->Height, 0, GL_BGR, GL_UNSIGNED_BYTE, Image->Data); + free(Image->Data); + free(Image); } } + + ~LoginScreen(){ + glDeleteTextures(TEX_COUNT, texture); + } private: - int Run(float){ + int Run(float TimeDelta){ + Time += TimeDelta; + if(System::UserInput.CloseWindow){ return SCENE_EXIT; } @@ -91,5 +135,13 @@ class LoginScreen : public Scene { public: void Render(){ + glMatrixMode(GL_TEXTURE); + glBindTexture(GL_TEXTURE_2D, texture[(Time>=4) + (Time>=8)]); + glBegin(GL_QUADS); + glTexCoord2i(0,0); glVertex2i(0,0); + glTexCoord2i(1,0); glVertex2i(800,0); + glTexCoord2i(1,1); glVertex2i(800,600); + glTexCoord2i(0,1); glVertex2i(0,600); + glEnd(); } }; \ No newline at end of file diff --git a/Client/System/System.cpp b/Client/System/System.cpp index cca7fe2..45edcd6 100644 --- a/Client/System/System.cpp +++ b/Client/System/System.cpp @@ -34,7 +34,32 @@ namespace System { DEVMODE dm; EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm); System::FramePeriod = 1.0f/dm.dmDisplayFrequency; + + if(FT_Init_FreeType(&Graphics::FreeTypeLibrary)){ + MessageBox(Window::hWnd, "Failed to initialize FreeType.", NULL, MB_OK | MB_ICONERROR); + Graphics::FreeTypeLibrary = NULL; + Shutdown(); + return ERROR_SYSTEM_INIT_FREETYPE; + }; + if(FT_New_Face(Graphics::FreeTypeLibrary, "simdialogue-uni-game.ttf", 0, &Graphics::FontFace)){ + MessageBox(Window::hWnd, "simdialogue-uni-game.ttf does not exist or is corrupt or invalid.", + NULL, MB_OK | MB_ICONERROR); + Graphics::FontFace = NULL; + Shutdown(); + return ERROR_SYSTEM_MISSING_FONT; + } return 0; } + + void Shutdown(){ + if(Graphics::FontFace){ + FT_Done_Face(Graphics::FontFace); + Graphics::FontFace = NULL; + } + if(Graphics::FreeTypeLibrary){ + FT_Done_FreeType(Graphics::FreeTypeLibrary); + Graphics::FreeTypeLibrary = NULL; + } + } } \ No newline at end of file diff --git a/Client/System/System.hpp b/Client/System/System.hpp index 2652e83..b3fe840 100644 --- a/Client/System/System.hpp +++ b/Client/System/System.hpp @@ -18,6 +18,7 @@ //System/System.cpp namespace System { int Initialize(); + void Shutdown(); extern HINSTANCE hInst; extern HANDLE Process; extern HANDLE ProcessHeap; @@ -55,6 +56,10 @@ namespace System { ERROR_CREATE_WINDOW }; #define ERROR_INIT_SYSTEM 0x0200 + enum { + ERROR_SYSTEM_INIT_FREETYPE = 1, + ERROR_SYSTEM_MISSING_FONT + }; #define ERROR_INIT_GRAPHICS 0x0300 enum { ERROR_GRAPHICS_OBTAIN_DC = 1,