Initial commit: wowee native WoW 3.3.5a client

This commit is contained in:
Kelsi 2026-02-02 12:24:50 -08:00
commit ce6cb8f38e
147 changed files with 32347 additions and 0 deletions

1403
src/core/application.cpp Normal file

File diff suppressed because it is too large Load diff

81
src/core/input.cpp Normal file
View file

@ -0,0 +1,81 @@
#include "core/input.hpp"
namespace wowee {
namespace core {
Input& Input::getInstance() {
static Input instance;
return instance;
}
void Input::update() {
// Copy current state to previous
previousKeyState = currentKeyState;
previousMouseState = currentMouseState;
previousMousePosition = mousePosition;
// Get current keyboard state
const Uint8* keyState = SDL_GetKeyboardState(nullptr);
for (int i = 0; i < NUM_KEYS; ++i) {
currentKeyState[i] = keyState[i];
}
// Get current mouse state
int mouseX, mouseY;
Uint32 mouseState = SDL_GetMouseState(&mouseX, &mouseY);
mousePosition = glm::vec2(static_cast<float>(mouseX), static_cast<float>(mouseY));
for (int i = 0; i < NUM_MOUSE_BUTTONS; ++i) {
currentMouseState[i] = (mouseState & SDL_BUTTON(i)) != 0;
}
// Calculate mouse delta
mouseDelta = mousePosition - previousMousePosition;
// Reset wheel delta (will be set by handleEvent)
mouseWheelDelta = 0.0f;
}
void Input::handleEvent(const SDL_Event& event) {
if (event.type == SDL_MOUSEWHEEL) {
mouseWheelDelta = static_cast<float>(event.wheel.y);
}
}
bool Input::isKeyPressed(SDL_Scancode key) const {
if (key < 0 || key >= NUM_KEYS) return false;
return currentKeyState[key];
}
bool Input::isKeyJustPressed(SDL_Scancode key) const {
if (key < 0 || key >= NUM_KEYS) return false;
return currentKeyState[key] && !previousKeyState[key];
}
bool Input::isKeyJustReleased(SDL_Scancode key) const {
if (key < 0 || key >= NUM_KEYS) return false;
return !currentKeyState[key] && previousKeyState[key];
}
bool Input::isMouseButtonPressed(int button) const {
if (button < 0 || button >= NUM_MOUSE_BUTTONS) return false;
return currentMouseState[button];
}
bool Input::isMouseButtonJustPressed(int button) const {
if (button < 0 || button >= NUM_MOUSE_BUTTONS) return false;
return currentMouseState[button] && !previousMouseState[button];
}
bool Input::isMouseButtonJustReleased(int button) const {
if (button < 0 || button >= NUM_MOUSE_BUTTONS) return false;
return !currentMouseState[button] && previousMouseState[button];
}
void Input::setMouseLocked(bool locked) {
mouseLocked = locked;
SDL_SetRelativeMouseMode(locked ? SDL_TRUE : SDL_FALSE);
}
} // namespace core
} // namespace wowee

52
src/core/logger.cpp Normal file
View file

@ -0,0 +1,52 @@
#include "core/logger.hpp"
#include <chrono>
#include <iomanip>
#include <ctime>
namespace wowee {
namespace core {
Logger& Logger::getInstance() {
static Logger instance;
return instance;
}
void Logger::log(LogLevel level, const std::string& message) {
if (level < minLevel) {
return;
}
std::lock_guard<std::mutex> lock(mutex);
// Get current time
auto now = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(now);
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) % 1000;
std::tm tm;
localtime_r(&time, &tm);
// Format: [YYYY-MM-DD HH:MM:SS.mmm] [LEVEL] message
std::cout << "["
<< std::put_time(&tm, "%Y-%m-%d %H:%M:%S")
<< "." << std::setfill('0') << std::setw(3) << ms.count()
<< "] [";
switch (level) {
case LogLevel::DEBUG: std::cout << "DEBUG"; break;
case LogLevel::INFO: std::cout << "INFO "; break;
case LogLevel::WARNING: std::cout << "WARN "; break;
case LogLevel::ERROR: std::cout << "ERROR"; break;
case LogLevel::FATAL: std::cout << "FATAL"; break;
}
std::cout << "] " << message << std::endl;
}
void Logger::setLogLevel(LogLevel level) {
minLevel = level;
}
} // namespace core
} // namespace wowee

134
src/core/window.cpp Normal file
View file

@ -0,0 +1,134 @@
#include "core/window.hpp"
#include "core/logger.hpp"
#include <GL/glew.h>
namespace wowee {
namespace core {
Window::Window(const WindowConfig& config)
: config(config)
, width(config.width)
, height(config.height) {
}
Window::~Window() {
shutdown();
}
bool Window::initialize() {
LOG_INFO("Initializing window: ", config.title);
// Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) {
LOG_ERROR("Failed to initialize SDL: ", SDL_GetError());
return false;
}
// Set OpenGL attributes
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
// Create window
Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
if (config.fullscreen) {
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
}
if (config.resizable) {
flags |= SDL_WINDOW_RESIZABLE;
}
window = SDL_CreateWindow(
config.title.c_str(),
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
width,
height,
flags
);
if (!window) {
LOG_ERROR("Failed to create window: ", SDL_GetError());
return false;
}
// Create OpenGL context
glContext = SDL_GL_CreateContext(window);
if (!glContext) {
LOG_ERROR("Failed to create OpenGL context: ", SDL_GetError());
return false;
}
// Set VSync
if (SDL_GL_SetSwapInterval(config.vsync ? 1 : 0) != 0) {
LOG_WARNING("Failed to set VSync: ", SDL_GetError());
}
// Initialize GLEW
glewExperimental = GL_TRUE;
GLenum glewError = glewInit();
if (glewError != GLEW_OK) {
LOG_ERROR("Failed to initialize GLEW: ", glewGetErrorString(glewError));
return false;
}
// Log OpenGL info
LOG_INFO("OpenGL Version: ", glGetString(GL_VERSION));
LOG_INFO("GLSL Version: ", glGetString(GL_SHADING_LANGUAGE_VERSION));
LOG_INFO("Renderer: ", glGetString(GL_RENDERER));
LOG_INFO("Vendor: ", glGetString(GL_VENDOR));
// Set up OpenGL defaults
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
LOG_INFO("Window initialized successfully");
return true;
}
void Window::shutdown() {
if (glContext) {
SDL_GL_DeleteContext(glContext);
glContext = nullptr;
}
if (window) {
SDL_DestroyWindow(window);
window = nullptr;
}
SDL_Quit();
LOG_INFO("Window shutdown complete");
}
void Window::swapBuffers() {
SDL_GL_SwapWindow(window);
}
void Window::pollEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
// ImGui will handle events in UI manager
// For now, just handle quit
if (event.type == SDL_QUIT) {
shouldCloseFlag = true;
}
else if (event.type == SDL_WINDOWEVENT) {
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
width = event.window.data1;
height = event.window.data2;
glViewport(0, 0, width, height);
LOG_DEBUG("Window resized to ", width, "x", height);
}
}
}
}
} // namespace core
} // namespace wowee