From 7634722c16a478ca9783077f19eb55d4cef3b4cc Mon Sep 17 00:00:00 2001 From: devZoGok Date: Sat, 4 Dec 2021 12:48:21 +0200 Subject: [PATCH] initial commit --- .gitmodules | 3 + CMakeLists.txt | 21 +++++ abstractAppState.cpp | 47 +++++++++++ abstractAppState.h | 37 +++++++++ inputManager.cpp | 122 ++++++++++++++++++++++++++++ inputManager.h | 20 +++++ mapping.h | 60 ++++++++++++++ stateManager.cpp | 49 +++++++++++ stateManager.h | 27 +++++++ util.cpp | 189 +++++++++++++++++++++++++++++++++++++++++++ util.h | 30 +++++++ 11 files changed, 605 insertions(+) create mode 100644 .gitmodules create mode 100644 CMakeLists.txt create mode 100644 abstractAppState.cpp create mode 100644 abstractAppState.h create mode 100644 inputManager.cpp create mode 100644 inputManager.h create mode 100755 mapping.h create mode 100644 stateManager.cpp create mode 100644 stateManager.h create mode 100644 util.cpp create mode 100644 util.h diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..6a3c5b3 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "external/glfw"] + path = external/glfw + url = https://github.com/glfw/glfw diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a5b1def --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.2) +project(gameBase) + +set(CMAKE_BUILD_TYPE Debug) +cmake_policy(SET CMP0015 NEW) + +set(states abstractAppState.cpp) +set(core inputManager.cpp mapping.h stateManager.cpp) +set(util util.cpp) + +add_library(gameBase ${states} ${core} ${util}) + +set(GLFW_DIR external/glfw) +set(LIB_NAME gameBase) + +add_subdirectory(${GLFW_DIR}) +set(GLFW_LIB_DIR build/${GLFW_DIR}/src) +target_include_directories(${LIB_NAME} PUBLIC ${GLFW_DIR}/include/GLFW) +target_link_directories(${LIB_NAME} PUBLIC ${GLFW_LIB_DIR}) + +target_link_libraries(gameBase glfw) diff --git a/abstractAppState.cpp b/abstractAppState.cpp new file mode 100644 index 0000000..0e27678 --- /dev/null +++ b/abstractAppState.cpp @@ -0,0 +1,47 @@ +#include "abstractAppState.h" +#include "util.h" +#include "mapping.h" + +using namespace std; + +namespace gameBase { + void AbstractAppState::onAttached(){ + attached = true; + + for(int i = 0; i < bindingsLines.size(); i++){ + int semicolon; + + for(int j = 0; j < bindingsLines[i].length(); j++) + if(bindingsLines[i].c_str()[j] == ':') + semicolon = j; + + Mapping::BindType type = (Mapping::BindType)atoi(bindingsLines[i].substr(semicolon + 1, 1).c_str()); + bool action = atoi(bindingsLines[i].substr(semicolon + 3, 1).c_str()); + int trigger = atoi(bindingsLines[i].substr(semicolon + 5, string::npos).c_str()); + + Mapping *m = new Mapping; + m->bind = (Mapping::Bind)(3 + i); + m->type = type; + m->action = action; + m->trigger = trigger; + mappings.push_back(m); + } + } + + void AbstractAppState::onDettached(){ + attached = false; + } + + void AbstractAppState::update(){} + + void AbstractAppState::removeMapping(Mapping::Bind bind){ + int id = -1; + + for(int i = 0; i < mappings.size(); i++) + if(mappings[i]->bind == bind) + id = i; + + if(id != -1) + mappings.erase(mappings.begin() + id); + } +} diff --git a/abstractAppState.h b/abstractAppState.h new file mode 100644 index 0000000..e3a62f3 --- /dev/null +++ b/abstractAppState.h @@ -0,0 +1,37 @@ +#ifndef ABSTRACT_APP_STATE_H +#define ABSTRACT_APP_STATE_H + +#include "mapping.h" + +#include +#include + +namespace gameBase { + class AbstractAppState{ + public: + virtual void update(); + virtual void onAttached(); + virtual void onDettached(); + inline int getType(){return type;} + inline Mapping* getMapping(int id){return mappings[id];} + inline std::vector& getMappings(){return mappings;} + inline int getNumMappings(){return mappings.size();} + inline bool isAttached(){return attached;} + void removeMapping(Mapping::Bind); + virtual void onAction(Mapping::Bind,bool){} + virtual void onAnalog(Mapping::Bind,float){} + virtual void onRawKeyButton(short){} + virtual void onRawMouseButton(short){} + virtual void onRawJoystickAxis(short,float){} + virtual void onRawJoystickButton(short){} + protected: + AbstractAppState(){} + ~AbstractAppState(){} + std::vector mappings; + std::vector bindingsLines; + int type; + bool attached = false; + }; +} + +#endif diff --git a/inputManager.cpp b/inputManager.cpp new file mode 100644 index 0000000..c59d747 --- /dev/null +++ b/inputManager.cpp @@ -0,0 +1,122 @@ +#include "inputManager.h" +#include "stateManager.h" +#include "util.h" + +#include +#include +#include + +namespace gameBase{ + double *posX, *posY, strX, strY; + int width, height; + + void foo(GLFWwindow *window, double newPosX, double newPosY){ + strX = (*posX - newPosX) / width, strY = (newPosY - *posY) / height; + } + + InputManager::InputManager(StateManager *stateManager, GLFWwindow *window){ + this->stateManager = stateManager; + this->window = window; + posX = new double, posY = new double; + } + + InputManager::~InputManager(){} + + void InputManager::update(){ + glfwGetWindowSize(window, &width, &height); + + + glfwGetCursorPos(window, posX, posY); + int joystick; + int numAxis = 3, numButtons = 6; + const u8 *buttons; + const float *axis; + + if(glfwJoystickPresent(GLFW_JOYSTICK_1)){ + joystick = GLFW_JOYSTICK_1; + axis = glfwGetJoystickAxes(joystick, &numAxis); + buttons = glfwGetJoystickButtons(joystick, &numButtons); + } + + for(int j = 0; j < stateManager->getAppStates().size(); j++){ + AbstractAppState *a = stateManager->getAppStates()[j]; + + for(int i = 0; i < a->getNumMappings(); i++){ + Mapping *m = a->getMapping(i); + + if(m->action){ + bool pressed; + + switch(m->type){ + case Mapping::KEYBOARD: + pressed = glfwGetKey(window, m->trigger); + break; + case Mapping::MOUSE_KEY: + pressed = glfwGetMouseButton(window, m->trigger); + break; + case Mapping::JOYSTICK_KEY: + if(glfwJoystickPresent(GLFW_JOYSTICK_1)) + pressed = buttons[m->trigger]; + + break; + } + + if((pressed && !m->pressed) || (!pressed&&m->pressed)){ + m->pressed = pressed; + a->onAction(m->bind, pressed); + } + } + else{ + switch(m->type){ + case Mapping::MOUSE_AXIS: + { + float str; + + switch(m->trigger){ + case Mapping::MOUSE_AXIS_LEFT: + case Mapping::MOUSE_AXIS_RIGHT: + str = strX; + break; + case Mapping::MOUSE_AXIS_UP: + case Mapping::MOUSE_AXIS_DOWN: + str = strY; + break; + } + a->onAnalog(m->bind, str); + break; + } + case Mapping::JOYSTICK_AXIS: + { + int axisId = (m->trigger - (m->trigger % 2 > 0)) / 2; + float str = (fabs(axis[axisId]) >= .1 ? axis[axisId] : 0); + + if(fabs(str) > 0) + a->onAnalog(m->bind, str); + + break; + } + } + } + } + + for(int i = 0; i < 350; i++){ + if(glfwGetKey(window, i)) + a->onRawKeyButton(i); + else if(glfwGetMouseButton(window, i)) + a->onRawMouseButton(i); + } + + glfwSetCursorPosCallback(window, foo); + + if(glfwJoystickPresent(GLFW_JOYSTICK_1)){ + for(int i = 0; i < numAxis; i++) + if(abs(axis[i]) == 1) + a->onRawJoystickAxis(i, axis[i]); + + for(int i = 0; i < numButtons; i++) + if(buttons[i]) + a->onRawJoystickButton(i); + } + } + } +} diff --git a/inputManager.h b/inputManager.h new file mode 100644 index 0000000..8972813 --- /dev/null +++ b/inputManager.h @@ -0,0 +1,20 @@ +#ifndef INPUT_MANAGER_H +#define INPUT_MANAGER_H + +class GLFWwindow; + +namespace gameBase{ + class StateManager; + + class InputManager{ + public: + InputManager(StateManager*, GLFWwindow*); + ~InputManager(); + void update(); + private: + StateManager *stateManager; + GLFWwindow *window; + }; +} + +#endif diff --git a/mapping.h b/mapping.h new file mode 100755 index 0000000..b3e37a9 --- /dev/null +++ b/mapping.h @@ -0,0 +1,60 @@ +#pragma once +#ifndef KEY_H +#define KEY_H + +namespace gameBase{ + struct Mapping{ + enum Bind{ + LEFT_CLICK, + SCROLLING_UP, + SCROLLING_DOWN, + LEFT, + RIGHT, + DELETE_CHAR, + CAPS_LOCK, + SHIFT_CAPS, + SPACE, + PLUS, + MINUS, + DEVSTERISK, + TOGGLE_MAIN_MENU, + HALT, + ZOOM_IN, + ZOOM_OUT, + LOOK_AROUND, + LOOK_UP, + LOOK_DOWN, + LOOK_LEFT, + LOOK_RIGHT, + DRAG_BOX, + DESELECT, + LEFT_CONTROL, + LEFT_SHIFT, + SELECT_PATROL_POINTS, + LAUNCH, + TOGGLE_SUB, + INSTALL_AWM, + INSTALL_AAM, + GROUP_0, + GROUP_1, + GROUP_2, + GROUP_3, + GROUP_4, + GROUP_5, + GROUP_6, + GROUP_7, + GROUP_8, + GROUP_9, + LAST_BIND + }; + enum BindType{KEYBOARD, MOUSE_KEY, MOUSE_AXIS, JOYSTICK_KEY, JOYSTICK_AXIS}; + enum AuxTriggers{MOUSE_AXIS_LEFT = 310, MOUSE_AXIS_RIGHT = 311, MOUSE_AXIS_UP = 312, MOUSE_AXIS_DOWN = 313}; + + Bind bind; + BindType type; + int trigger; + bool action, pressed = false; + }; +} + +#endif diff --git a/stateManager.cpp b/stateManager.cpp new file mode 100644 index 0000000..8b6c924 --- /dev/null +++ b/stateManager.cpp @@ -0,0 +1,49 @@ +#include "stateManager.h" + +namespace gameBase { + void StateManager::update(){ + for(int i = 0; i < appStates.size(); i++) + appStates[i]->update(); + } + + void StateManager::attachState(AbstractAppState *a){ + appStates.push_back(a); + a->onAttached(); + } + + void StateManager::dettachState(AbstractAppState *a){ + int id=-1; + + for(int i = 0; i < appStates.size() && id == -1; i++) + if(appStates[i] == a) + id = i; + + if(id != -1){ + a->onDettached(); + appStates.erase(appStates.begin() + id); + } + } + + void StateManager::dettachStateByType(int type){ + int id = -1; + + for(int i = 0; i < appStates.size() && id == -1; i++) + if(appStates[i]->getType() == type) + id = i; + + if(id != -1){ + appStates[id]->onDettached(); + appStates.erase(appStates.begin() + id); + } + } + + AbstractAppState* StateManager::getStateByType(int type){ + AbstractAppState *a = nullptr; + + for(int i = 0; i < appStates.size() && !a; i++) + if(appStates[i]->getType() == type) + a = appStates[i]; + + return a; + } +} diff --git a/stateManager.h b/stateManager.h new file mode 100644 index 0000000..d061999 --- /dev/null +++ b/stateManager.h @@ -0,0 +1,27 @@ +#ifndef STATE_MANAGER_H +#define STATE_MANAGER_H + +#include + +#include "abstractAppState.h" + +namespace gameBase { + class StateManager{ + public: + StateManager(){} + ~StateManager(){} + void update(); + void attachState(AbstractAppState *a); + void dettachState(AbstractAppState*); + void dettachStateByType(int); + inline void dettachStateById(int id){appStates.erase(appStates.begin() + id);} + inline AbstractAppState* getStateById(int i){return appStates[i];} + AbstractAppState* getStateByType(int); + inline std::vector getAppStates(){return appStates;} + inline int getNumAppStates(){return appStates.size();} + private: + std::vector appStates; + }; +} + +#endif diff --git a/util.cpp b/util.cpp new file mode 100644 index 0000000..63425f5 --- /dev/null +++ b/util.cpp @@ -0,0 +1,189 @@ +#include + +#include "util.h" +#include "mapping.h" +#include "stateManager.h" +#include "abstractAppState.h" + +using namespace std; +using namespace chrono; + +namespace gameBase{ + std::string keyStrings[]{ + "Escape", + "Enter", + "Tab", + "Backspace", + "Insert", + "Delete", + "Right", + "Left", + "Up", + "Down", + "PageUp", + "PageDown", + "Home", + "End", + "CapsLock", + "ScrollLock", + "NumLock", + "PrintScreen", + "Space", + "Pause", + "Numpad .", + "Numpad /", + "Numpad *", + "Numpad -", + "Numpad +", + "Numpad enter", + "=", + "Left shift", + "Left control", + "Left alt", + "Left super", + "Right shift", + "Right control", + "Right alt", + "Right super", + "Left click", + "Right click", + "Middle click" + }; + + int triggers[]{ + GLFW_KEY_ESCAPE, + GLFW_KEY_ENTER, + GLFW_KEY_TAB, + GLFW_KEY_BACKSPACE, + GLFW_KEY_INSERT, + GLFW_KEY_DELETE, + GLFW_KEY_RIGHT, + GLFW_KEY_LEFT, + GLFW_KEY_UP, + GLFW_KEY_DOWN, + GLFW_KEY_PAGE_UP, + GLFW_KEY_PAGE_DOWN, + GLFW_KEY_HOME, + GLFW_KEY_END, + GLFW_KEY_CAPS_LOCK, + GLFW_KEY_SCROLL_LOCK, + GLFW_KEY_NUM_LOCK, + GLFW_KEY_PRINT_SCREEN, + GLFW_KEY_SPACE, + GLFW_KEY_PAUSE, + GLFW_KEY_KP_DECIMAL, + GLFW_KEY_KP_DIVIDE, + GLFW_KEY_KP_MULTIPLY, + GLFW_KEY_KP_SUBTRACT, + GLFW_KEY_KP_ADD, + GLFW_KEY_KP_ENTER, + GLFW_KEY_EQUAL, + GLFW_KEY_LEFT_SHIFT, + GLFW_KEY_LEFT_CONTROL, + GLFW_KEY_LEFT_ALT, + GLFW_KEY_LEFT_SUPER, + GLFW_KEY_RIGHT_SHIFT, + GLFW_KEY_RIGHT_CONTROL, + GLFW_KEY_RIGHT_ALT, + GLFW_KEY_RIGHT_SUPER, + GLFW_MOUSE_BUTTON_LEFT, + GLFW_MOUSE_BUTTON_RIGHT, + GLFW_MOUSE_BUTTON_MIDDLE + }; + + string fromIntToString(int data[3]){ + string output; + + switch((Mapping::BindType)data[0]){ + case Mapping::KEYBOARD: + case Mapping::MOUSE_KEY: + { + bool specialKey = false; + int numSpecialKeys = sizeof(triggers) / sizeof(int); + + for(int i = 0; i < numSpecialKeys; i++){ + if(data[2] == triggers[i]){ + specialKey = true; + output = keyStrings[i]; + } + + if(!specialKey){ + char c[]{data[2]}; + output = string(c); + } + } + + break; + } + case Mapping::MOUSE_AXIS: + output = "MOUSE_AXIS_" + to_string(data[2]) + (data[1] ? "+" : "-"); + break; + case Mapping::JOYSTICK_KEY: + output = "JOYSTICK_BUTTON_" + to_string(data[2]); + break; + case Mapping::JOYSTICK_AXIS: + output = "JOYSTICK_AXIS_" + to_string(data[2]) + (data[1] ? "+" : "-"); + break; + } + return output; + } + + int* fromStringToInt(string data){ + int *output = new int[3], length = data.length(); + + if(data.substr(0, 11) == "MOUSE_AXIS_"){ + output[0] = Mapping::MOUSE_AXIS; + output[1] = 0; + output[2] = atoi(data.substr(11, string::npos - 1).c_str()) + (int)data.c_str()[12] == '+'; + } + else if(data.substr(0, 16) == "JOYSTICK_BUTTON_"){ + output[0] = Mapping::JOYSTICK_KEY; + output[1] = 1; + output[2] = atoi(data.substr(16, string::npos - 1).c_str()); + } + else if(data.substr(0, 14) == "JOYSTICK_AXIS_"){ + output[0] = Mapping::JOYSTICK_AXIS; + output[1] = 0; + output[2] = 2*atoi(data.substr(14, 1).c_str()) + (data.c_str()[15] == '+' ? 1 : 0); + } + else{ + bool specialKey = false; + int numSpecialKeys = sizeof(triggers) / sizeof(int); + + for(int i = 0; i < numSpecialKeys; i++) + if(data == keyStrings[i]){ + specialKey = true; + output[0] = numSpecialKeys - i <= 3 ? Mapping::MOUSE_KEY:Mapping::KEYBOARD; + output[2] = triggers[i]; + } + + if(!specialKey){ + output[0] = Mapping::KEYBOARD; + output[2] = data.c_str()[0]; + } + + output[1] = 1; + } + + return output; + } + + wstring stringToWstring(string str){ + wstring wstr = L""; + + for(char ch : str) + wstr += ch; + + return wstr; + } + + string wstringToString(wstring wstr){ + string str = ""; + + for(wchar_t ch : wstr) + if(ch < 256) + str += ch; + + return str; + } +} diff --git a/util.h b/util.h new file mode 100644 index 0000000..50c1e32 --- /dev/null +++ b/util.h @@ -0,0 +1,30 @@ +#ifndef UTILS_H +#define UTILS_H + +#include +#include +#include +#include + +namespace gameBase{ + typedef char s8; + typedef short s16; + typedef int s32; + typedef long long s64; + + typedef unsigned char u8; + typedef unsigned short u16; + typedef unsigned int u32; + typedef unsigned long long u64; + + inline s64 getTime(){return (s64)(std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1));} + void readFile(std::string, std::vector&, int = 0, int = -1); + void writeFile(std::string, std::vector&); + std::string convert(std::string); + int* fromStringToInt(std::string); + std::string fromIntToString(int[3]); + std::wstring stringToWstring(std::string); + std::string wstringToString(std::wstring); +} + +#endif