mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-04-07 05:46:09 +03:00
chore: initial commit
This commit is contained in:
commit
70b00c5c38
17
.editorconfig
Normal file
17
.editorconfig
Normal file
@ -0,0 +1,17 @@
|
||||
root = true
|
||||
|
||||
[src/**/*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[test/**/*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
35
.github/workflows/pr.yml
vendored
Normal file
35
.github/workflows/pr.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
name: PR
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.config.name }}
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- name: Ubuntu Latest (GCC)
|
||||
os: ubuntu-latest
|
||||
build_type: Release
|
||||
cc: "gcc"
|
||||
cxx: "g++"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Prepare
|
||||
run: mkdir build
|
||||
|
||||
- name: Configure
|
||||
run: cd build && cmake .. -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }}
|
||||
|
||||
- name: Build
|
||||
run: cd build && make install
|
||||
|
||||
- name: Test
|
||||
run: cd build && ./dist/bin/WhoaTest
|
38
.github/workflows/push.yml
vendored
Normal file
38
.github/workflows/push.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
name: Push
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.config.name }}
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- name: Ubuntu Latest (GCC)
|
||||
os: ubuntu-latest
|
||||
build_type: Release
|
||||
cc: "gcc"
|
||||
cxx: "g++"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Prepare
|
||||
run: mkdir build
|
||||
|
||||
- name: Configure
|
||||
run: cd build && cmake .. -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }}
|
||||
|
||||
- name: Build
|
||||
run: cd build && make install
|
||||
|
||||
- name: Test
|
||||
run: cd build && ./dist/bin/WhoaTest
|
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
.DS_Store
|
||||
.vscode
|
||||
.idea
|
||||
|
||||
/build
|
||||
/cmake-build-*
|
||||
|
12
.gitmodules
vendored
Normal file
12
.gitmodules
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
[submodule "lib/common"]
|
||||
path = lib/common
|
||||
url = https://github.com/whoahq/common.git
|
||||
[submodule "lib/squall"]
|
||||
path = lib/squall
|
||||
url = https://github.com/whoahq/squall.git
|
||||
[submodule "lib/typhoon"]
|
||||
path = lib/typhoon
|
||||
url = https://github.com/whoahq/typhoon.git
|
||||
[submodule "lib/system"]
|
||||
path = lib/system
|
||||
url = https://github.com/whoahq/system.git
|
50
CMakeLists.txt
Normal file
50
CMakeLists.txt
Normal file
@ -0,0 +1,50 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||
message(FATAL_ERROR
|
||||
"In-source builds not allowed.
|
||||
Please make a new directory (called a build directory) and run CMake from there.
|
||||
You may need to remove CMakeCache.txt."
|
||||
)
|
||||
endif()
|
||||
|
||||
# OS variables
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14" CACHE STRING "macOS Deployment Target" FORCE)
|
||||
|
||||
# Project
|
||||
project(whoa)
|
||||
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_PREFIX "dist" CACHE PATH "Installation prefix" FORCE)
|
||||
endif()
|
||||
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
# Some templates abuse offsetof
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-invalid-offsetof")
|
||||
|
||||
# OS defines
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
add_definitions(
|
||||
-DGL_SILENCE_DEPRECATION
|
||||
)
|
||||
endif()
|
||||
|
||||
include(lib/system/cmake/system.cmake)
|
||||
|
||||
# Threads
|
||||
if(WHOA_SYSTEM_LINUX OR WHOA_SYSTEM_MAC)
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
find_package(Threads REQUIRED)
|
||||
endif()
|
||||
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(test)
|
||||
add_subdirectory(vendor)
|
47
README.md
Normal file
47
README.md
Normal file
@ -0,0 +1,47 @@
|
||||
# Whoa
|
||||
|
||||
Welcome to Whoa, a reimplementation of World of Warcraft 3.3.5a (build 12340) in C++11.
|
||||
|
||||
## Supported Platforms
|
||||
|
||||
Currently, macOS 10.14+ is supported, including recent versions of macOS on M1 processors. Support for Linux is in progress. Support for Windows is coming soon™.
|
||||
|
||||
## Building
|
||||
|
||||
To build, ensure you have a recent version of CMake installed, and run the following from the `whoa` directory:
|
||||
|
||||
```
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
make install
|
||||
```
|
||||
|
||||
Assuming all went well, you should see a `dist/bin` directory appear in the `build` directory. The `bin` directory will contain a `whoa` executable.
|
||||
|
||||
## Running
|
||||
|
||||
Whoa doesn't currently support reading from MPQ archives. Instead, it assumes you are launching the Whoa executable from the root of a fully extracted MPQ archive set for World of Warcraft 3.3.5a (build 12340). You can obtain a valid set of MPQ archives to extract by installing World of Warcraft 3.3.5a from legally purchased original install media. Whoa does not provide any copy of game data.
|
||||
|
||||
Assuming all goes well, you should be greeted by the login screen, complete with its flying dragon animation loop.
|
||||
|
||||
Whoa is very much a work-in-progress: it does not fully connect to a login server, does not play back sound or music, and does not support customizing settings. These things will be supported over time.
|
||||
|
||||
## FAQ
|
||||
|
||||
**Why?**
|
||||
|
||||
It's fascinating to explore the development practices used to build a modern major video game.
|
||||
|
||||
**Why 3.3.5a?**
|
||||
|
||||
The game and its libraries have become significantly more complex in the intervening 10+ years. By picking 3.3.5a, it's possible to imagine this implementation will eventually be complete.
|
||||
|
||||
**Can I use this in my own development projects?**
|
||||
|
||||
It's probably a bad idea. The game is closed source, and this project is in no way official.
|
||||
|
||||
## Legal
|
||||
|
||||
This project is released into the public domain.
|
||||
|
||||
World of Warcraft: Wrath of the Lich King ©2008 Blizzard Entertainment, Inc. All rights reserved. Wrath of the Lich King is a trademark, and World of Warcraft, Warcraft and Blizzard Entertainment are trademarks or registered trademarks of Blizzard Entertainment, Inc. in the U.S. and/or other countries.
|
4
lib/CMakeLists.txt
Normal file
4
lib/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
add_subdirectory(common)
|
||||
add_subdirectory(squall)
|
||||
add_subdirectory(system)
|
||||
add_subdirectory(typhoon)
|
1
lib/common
Submodule
1
lib/common
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit ff3c28bbd910983147ddc1d99d83c482ae23df7d
|
1
lib/squall
Submodule
1
lib/squall
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit e3b0c356adc0abb4ad5c549951a5423b6edaf64d
|
1
lib/system
Submodule
1
lib/system
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit f886ab5bc35b2e0d968baa8dec3faaccf385fbc3
|
1
lib/typhoon
Submodule
1
lib/typhoon
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 36d177759d273ae599e7c99920466e4886d57a41
|
13
src/CMakeLists.txt
Normal file
13
src/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
add_subdirectory(app)
|
||||
add_subdirectory(async)
|
||||
add_subdirectory(client)
|
||||
add_subdirectory(event)
|
||||
add_subdirectory(glue)
|
||||
add_subdirectory(gx)
|
||||
add_subdirectory(math)
|
||||
add_subdirectory(model)
|
||||
add_subdirectory(net)
|
||||
add_subdirectory(sound)
|
||||
add_subdirectory(ui)
|
||||
add_subdirectory(util)
|
||||
add_subdirectory(world)
|
48
src/app/CMakeLists.txt
Normal file
48
src/app/CMakeLists.txt
Normal file
@ -0,0 +1,48 @@
|
||||
if(WHOA_SYSTEM_MAC)
|
||||
file(GLOB PRIVATE_SOURCES "mac/*.cpp" "mac/*.mm")
|
||||
|
||||
set_source_files_properties(${PRIVATE_SOURCES}
|
||||
PROPERTIES COMPILE_FLAGS "-x objective-c++"
|
||||
)
|
||||
|
||||
add_executable(Whoa ${PRIVATE_SOURCES})
|
||||
|
||||
target_link_libraries(Whoa
|
||||
PRIVATE
|
||||
client
|
||||
event
|
||||
gx
|
||||
net
|
||||
util
|
||||
"-framework AppKit"
|
||||
"-framework Carbon"
|
||||
"-framework IOKit"
|
||||
)
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/mac/MainMenu.nib DESTINATION "bin")
|
||||
endif()
|
||||
|
||||
if(WHOA_SYSTEM_LINUX)
|
||||
file(GLOB PRIVATE_SOURCES "linux/*.cpp")
|
||||
|
||||
add_executable(Whoa ${PRIVATE_SOURCES})
|
||||
|
||||
target_link_libraries(Whoa
|
||||
PRIVATE
|
||||
client
|
||||
event
|
||||
gx
|
||||
net
|
||||
util
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories(Whoa
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Windows executables yet to be done
|
||||
if(WHOA_SYSTEM_MAC OR WHOA_SYSTEM_LINUX)
|
||||
install(TARGETS Whoa DESTINATION "bin")
|
||||
endif()
|
11
src/app/linux/Wowre.cpp
Normal file
11
src/app/linux/Wowre.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "client/Client.hpp"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// TODO
|
||||
|
||||
CommonMain();
|
||||
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
16
src/app/mac/EngineGLLayerView.h
Normal file
16
src/app/mac/EngineGLLayerView.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef APP_MAC_ENGINE_GL_LAYER_VIEW_H
|
||||
#define APP_MAC_ENGINE_GL_LAYER_VIEW_H
|
||||
|
||||
#include "gx/gll/GLLayerView.h"
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
@interface EngineGLLayerView : GLLayerView
|
||||
|
||||
- (void)insertText:(id)string;
|
||||
|
||||
- (void)keyDown:(NSEvent*)event;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
41
src/app/mac/EngineGLLayerView.mm
Normal file
41
src/app/mac/EngineGLLayerView.mm
Normal file
@ -0,0 +1,41 @@
|
||||
#include "app/mac/EngineGLLayerView.h"
|
||||
#include "app/mac/MacClient.h"
|
||||
#include "event/Input.hpp"
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
@implementation EngineGLLayerView
|
||||
|
||||
- (void)insertText:(id)string {
|
||||
// TODO
|
||||
}
|
||||
|
||||
- (void)keyDown:(NSEvent*)event {
|
||||
uint32_t keyCode = event.keyCode;
|
||||
|
||||
MacClient::CheckKeyboardLayout();
|
||||
|
||||
if (keyCode <= 0x7F) {
|
||||
uint32_t key = MacClient::s_keyConversion[keyCode];
|
||||
|
||||
if (key != KEY_NONE) {
|
||||
OsQueuePut(OS_INPUT_KEY_DOWN, key, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (MacClient::GetTextInputEnabled()) {
|
||||
auto events = [NSArray arrayWithObject:event];
|
||||
[self interpretKeyEvents:events];
|
||||
} else {
|
||||
EventRef eventRef = static_cast<EventRef>(const_cast<void*>([event eventRef]));
|
||||
|
||||
uint8_t chr;
|
||||
|
||||
if (GetEventParameter(eventRef, 'kchr', 'TEXT', 0, 1, 0, &chr) == noErr) {
|
||||
if (chr > 0x1F && chr <= 0x7E) {
|
||||
OsQueuePut(OS_INPUT_CHAR, chr, 1, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
30
src/app/mac/MacClient.h
Normal file
30
src/app/mac/MacClient.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef APP_MAC_MAC_CLIENT_H
|
||||
#define APP_MAC_MAC_CLIENT_H
|
||||
|
||||
#include "event/Event.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class MacClient {
|
||||
public:
|
||||
enum ClipboardAction {
|
||||
ClipboardUndo = 1,
|
||||
ClipboardCut = 2,
|
||||
ClipboardCopy = 3,
|
||||
ClipboardPaste = 4,
|
||||
ClipboardSelectAll = 5
|
||||
};
|
||||
|
||||
static void* s_currentKeyboardLayout;
|
||||
static KEY s_specialKeyConversion[128];
|
||||
static KEY s_keyConversion[128];
|
||||
|
||||
static void CheckKeyboardLayout(void);
|
||||
static double GetMouseSpeed(void);
|
||||
static bool GetTextInputEnabled(void);
|
||||
static void InitializeKeyConversion(void);
|
||||
static bool IsUsingGLLayer(void);
|
||||
static void PostClipboardKeyEvents(MacClient::ClipboardAction);
|
||||
static void SetMouseCoalescingEnabled(bool);
|
||||
};
|
||||
|
||||
#endif
|
375
src/app/mac/MacClient.mm
Normal file
375
src/app/mac/MacClient.mm
Normal file
@ -0,0 +1,375 @@
|
||||
#include "app/mac/MacClient.h"
|
||||
#include "event/Input.hpp"
|
||||
#include "os/Compat.hpp"
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/hidsystem/event_status_driver.h>
|
||||
#include <IOKit/hidsystem/IOHIDLib.h>
|
||||
#include <IOKit/hidsystem/IOHIDParameter.h>
|
||||
|
||||
void* MacClient::s_currentKeyboardLayout = nullptr;
|
||||
|
||||
KEY MacClient::s_specialKeyConversion[128] = {
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_1, // kVK_ANSI_1 (0x12)
|
||||
KEY_2, // kVK_ANSI_2 (0x13)
|
||||
KEY_3, // kVK_ANSI_3 (0x14)
|
||||
KEY_4, // kVK_ANSI_4 (0x15)
|
||||
KEY_6, // kVK_ANSI_6 (0x16)
|
||||
KEY_5, // kVK_ANSI_5 (0x17)
|
||||
KEY_NONE,
|
||||
KEY_9, // kVK_ANSI_9 (0x19)
|
||||
KEY_7, // kVK_ANSI_7 (0x1A)
|
||||
KEY_NONE,
|
||||
KEY_8, // kVK_ANSI_8 (0x1C)
|
||||
KEY_0, // kVK_ANSI_0 (0x1D)
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_ENTER, // kVK_Return (0x24)
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_TAB, // kVK_Tab (0x30)
|
||||
KEY_SPACE, // kVK_Space (0x31)
|
||||
KEY_NONE,
|
||||
KEY_BACKSPACE, // kVK_Delete (0x33)
|
||||
KEY_NONE,
|
||||
KEY_ESCAPE, // kVK_Escape (0x35)
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_LSHIFT, // kVK_Shift (0x38)
|
||||
KEY_CAPSLOCK, // kVK_CapsLock (0x39)
|
||||
KEY_LALT, // kVK_Option (0x3A)
|
||||
KEY_LCONTROL, // kVK_Control (0x3B)
|
||||
KEY_RSHIFT, // kVK_RightShift (0x3C)
|
||||
KEY_RALT, // kVK_RightOption (0x3D)
|
||||
KEY_RCONTROL, // kVK_RightControl (0x3E)
|
||||
KEY_NONE,
|
||||
KEY_F17, // kVK_F17 (0x40)
|
||||
KEY_NUMPAD_DECIMAL, // kVK_ANSI_KeypadDecimal (0x41)
|
||||
KEY_NONE,
|
||||
KEY_NUMPAD_MULTIPLY, // kVK_ANSI_KeypadMultiply (0x43)
|
||||
KEY_NONE,
|
||||
KEY_NUMPAD_PLUS, // kVK_ANSI_KeypadPlus (0x45)
|
||||
KEY_NONE,
|
||||
KEY_NUMLOCK, // kVK_ANSI_KeypadClear (0x47)
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NUMPAD_DIVIDE, // kVK_ANSI_KeypadDivide (0x4B)
|
||||
KEY_ENTER, // kVK_ANSI_KeypadEnter (0x4C)
|
||||
KEY_NONE,
|
||||
KEY_NUMPAD_MINUS, // kVK_ANSI_KeypadMinus (0x4E)
|
||||
KEY_F18, // kVK_F18 (0x4F)
|
||||
KEY_F19, // kVK_F19 (0x50)
|
||||
KEY_NUMPAD_EQUALS, // kVK_ANSI_KeypadEquals (0x51)
|
||||
KEY_NUMPAD0, // kVK_ANSI_Keypad0 (0x52)
|
||||
KEY_NUMPAD1, // kVK_ANSI_Keypad1 (0x53)
|
||||
KEY_NUMPAD2, // kVK_ANSI_Keypad2 (0x54)
|
||||
KEY_NUMPAD3, // kVK_ANSI_Keypad3 (0x55)
|
||||
KEY_NUMPAD4, // kVK_ANSI_Keypad4 (0x56)
|
||||
KEY_NUMPAD5, // kVK_ANSI_Keypad5 (0x57)
|
||||
KEY_NUMPAD6, // kVK_ANSI_Keypad6 (0x58)
|
||||
KEY_NUMPAD7, // kVK_ANSI_Keypad7 (0x59)
|
||||
KEY_NONE,
|
||||
KEY_NUMPAD8, // kVK_ANSI_Keypad8 (0x5B)
|
||||
KEY_NUMPAD9, // kVK_ANSI_Keypad9 (0x5C)
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_NONE,
|
||||
KEY_F5, // kVK_F5 (0x60)
|
||||
KEY_F6, // kVK_F6 (0x61)
|
||||
KEY_F7, // kVK_F7 (0x62)
|
||||
KEY_F3, // kVK_F3 (0x63)
|
||||
KEY_F8, // kVK_F8 (0x64)
|
||||
KEY_F9, // kVK_F9 (0x65)
|
||||
KEY_NONE,
|
||||
KEY_F11, // kVK_F11 (0x67)
|
||||
KEY_NONE,
|
||||
KEY_F13, // kVK_F13 (0x69)
|
||||
KEY_F16, // kVK_F16 (0x6A)
|
||||
KEY_F14, // kVK_F14 (0x6B)
|
||||
KEY_NONE,
|
||||
KEY_F10, // kVK_F10 (0x6D)
|
||||
KEY_NONE,
|
||||
KEY_F12, // kVK_F12 (0x6F)
|
||||
KEY_NONE,
|
||||
KEY_F15, // kVK_F15 (0x71)
|
||||
KEY_INSERT, // kVK_Help (0x72)
|
||||
KEY_HOME, // kVK_Home (0x73)
|
||||
KEY_PAGEUP, // kVK_PageUp (0x74)
|
||||
KEY_DELETE, // kVK_ForwardDelete (0x75)
|
||||
KEY_F4, // kVK_F4 (0x76)
|
||||
KEY_END, // kVK_End (0x77)
|
||||
KEY_F2, // kVK_F2 (0x78)
|
||||
KEY_PAGEDOWN, // kVK_PageDown (0x79)
|
||||
KEY_F1, // kVK_F1 (0x7A)
|
||||
KEY_LEFT, // kVK_LeftArrow (0x7B)
|
||||
KEY_RIGHT, // kVK_RightArrow (0x7C)
|
||||
KEY_DOWN, // kVK_DownArrow (0x7D)
|
||||
KEY_UP, // kVK_UpArrow (0x7E)
|
||||
KEY_NONE
|
||||
};
|
||||
|
||||
KEY MacClient::s_keyConversion[128];
|
||||
|
||||
void MacClient::CheckKeyboardLayout() {
|
||||
#if WHOA_SYSTEM_VERSION < WHOA_MACOS_10_6
|
||||
void* KCHR = reinterpret_cast<void*>(GetScriptManagerVariable(smKCHRCache));
|
||||
|
||||
if (MacClient::s_currentKeyboardLayout != KCHR) {
|
||||
MacClient::InitializeKeyConversion();
|
||||
MacClient::s_currentKeyboardLayout = KCHR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WHOA_SYSTEM_VERSION >= WHOA_MACOS_10_6
|
||||
TISInputSourceRef inputSrc = TISCopyCurrentKeyboardLayoutInputSource();
|
||||
CFDataRef layoutData = static_cast<CFDataRef>(TISGetInputSourceProperty(inputSrc, kTISPropertyUnicodeKeyLayoutData));
|
||||
const UCKeyboardLayout* keyboardLayout = reinterpret_cast<const UCKeyboardLayout*>(CFDataGetBytePtr(layoutData));
|
||||
|
||||
if (MacClient::s_currentKeyboardLayout != keyboardLayout) {
|
||||
MacClient::InitializeKeyConversion();
|
||||
MacClient::s_currentKeyboardLayout = const_cast<UCKeyboardLayout*>(keyboardLayout);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
double MacClient::GetMouseSpeed() {
|
||||
#if WHOA_SYSTEM_VERSION < WHOA_MACOS_10_12
|
||||
double mouseSpeed = 1.0;
|
||||
|
||||
NXEventHandle handle = NXOpenEventStatus();
|
||||
|
||||
if (handle) {
|
||||
IOHIDGetAccelerationWithKey(handle, CFSTR(kIOHIDMouseAccelerationType), &mouseSpeed);
|
||||
NXCloseEventStatus(handle);
|
||||
}
|
||||
|
||||
return mouseSpeed;
|
||||
#endif
|
||||
|
||||
#if WHOA_SYSTEM_VERSION >= WHOA_MACOS_10_12
|
||||
double mouseSpeed = 1.0;
|
||||
|
||||
io_service_t service = IORegistryEntryFromPath(kIOMasterPortDefault, kIOServicePlane ":/IOResources/IOHIDSystem");
|
||||
|
||||
if (service != MACH_PORT_NULL) {
|
||||
CFDictionaryRef parameters = static_cast<CFDictionaryRef>(IORegistryEntryCreateCFProperty(service, CFSTR(kIOHIDParametersKey), kCFAllocatorDefault, kNilOptions));
|
||||
CFNumberRef speedParameter = static_cast<CFNumberRef>(CFDictionaryGetValue(parameters, CFSTR(kIOHIDMouseAccelerationType)));
|
||||
|
||||
if (speedParameter) {
|
||||
int32_t number;
|
||||
|
||||
if (CFNumberGetValue(static_cast<CFNumberRef>(speedParameter), kCFNumberSInt32Type, &number)) {
|
||||
mouseSpeed = static_cast<double>(number) / 65536.0;
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(parameters);
|
||||
IOObjectRelease(service);
|
||||
}
|
||||
|
||||
return mouseSpeed;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MacClient::GetTextInputEnabled() {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
void MacClient::InitializeKeyConversion() {
|
||||
memcpy(MacClient::s_keyConversion, MacClient::s_specialKeyConversion, sizeof(MacClient::s_specialKeyConversion));
|
||||
|
||||
#if WHOA_SYSTEM_VERSION < WHOA_MACOS_10_6
|
||||
void* KCHR = reinterpret_cast<void*>(GetScriptManagerVariable(smKCHRCache));
|
||||
|
||||
if (KCHR) {
|
||||
for (uint16_t i = 0; i < 128; i++) {
|
||||
if (MacClient::s_keyConversion[i] == KEY_NONE) {
|
||||
uint16_t translate = i | (1 << 7);
|
||||
uint32_t state = 0;
|
||||
|
||||
uint32_t value = KeyTranslate(KCHR, translate, &state);
|
||||
|
||||
if (state) {
|
||||
value = KeyTranslate(KCHR, translate, &state);
|
||||
}
|
||||
|
||||
if (value) {
|
||||
value = value - 97 <= 25 ? value - 32 : value;
|
||||
|
||||
auto string = CFStringCreateWithBytes(
|
||||
nullptr,
|
||||
reinterpret_cast<uint8_t*>(&value),
|
||||
1,
|
||||
0,
|
||||
false
|
||||
);
|
||||
|
||||
if (string) {
|
||||
CFIndex len;
|
||||
CFRange range = CFRangeMake(0, 1);
|
||||
|
||||
CFStringGetBytes(
|
||||
string,
|
||||
range,
|
||||
kCFStringEncodingISOLatin1,
|
||||
0,
|
||||
0,
|
||||
reinterpret_cast<uint8_t*>(&value),
|
||||
1,
|
||||
&len
|
||||
);
|
||||
|
||||
if (len && value) {
|
||||
MacClient::s_keyConversion[i] = static_cast<KEY>(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WHOA_SYSTEM_VERSION >= WHOA_MACOS_10_6
|
||||
TISInputSourceRef inputSrc = TISCopyCurrentKeyboardLayoutInputSource();
|
||||
CFDataRef layoutData = static_cast<CFDataRef>(TISGetInputSourceProperty(inputSrc, kTISPropertyUnicodeKeyLayoutData));
|
||||
const UCKeyboardLayout* keyboardLayout = reinterpret_cast<const UCKeyboardLayout*>(CFDataGetBytePtr(layoutData));
|
||||
const uint32_t keyboardType = LMGetKbdType();
|
||||
|
||||
if (keyboardLayout) {
|
||||
for (uint16_t i = 0; i < 128; i++) {
|
||||
if (MacClient::s_keyConversion[i] == KEY_NONE) {
|
||||
uint16_t vkey = i;
|
||||
uint32_t state = 0;
|
||||
UniChar buf[1];
|
||||
UniCharCount len;
|
||||
|
||||
OSStatus res = UCKeyTranslate(
|
||||
keyboardLayout,
|
||||
vkey,
|
||||
kUCKeyActionUp,
|
||||
0,
|
||||
keyboardType,
|
||||
0,
|
||||
&state,
|
||||
1,
|
||||
&len,
|
||||
buf
|
||||
);
|
||||
|
||||
if (res != noErr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (state) {
|
||||
res = UCKeyTranslate(
|
||||
keyboardLayout,
|
||||
vkey,
|
||||
kUCKeyActionUp,
|
||||
0,
|
||||
keyboardType,
|
||||
0,
|
||||
&state,
|
||||
1,
|
||||
&len,
|
||||
buf
|
||||
);
|
||||
|
||||
if (res != noErr) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t value = buf[0];
|
||||
|
||||
if (len && value) {
|
||||
value = value >= 97 && value <= 122 ? value - 32 : value;
|
||||
MacClient::s_keyConversion[i] = static_cast<KEY>(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MacClient::IsUsingGLLayer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacClient::PostClipboardKeyEvents(MacClient::ClipboardAction action) {
|
||||
int32_t v1;
|
||||
|
||||
switch (action) {
|
||||
case ClipboardUndo:
|
||||
v1 = 90;
|
||||
break;
|
||||
|
||||
case ClipboardCut:
|
||||
v1 = 88;
|
||||
break;
|
||||
|
||||
case ClipboardCopy:
|
||||
v1 = 67;
|
||||
break;
|
||||
|
||||
case ClipboardPaste:
|
||||
v1 = 86;
|
||||
break;
|
||||
|
||||
case ClipboardSelectAll:
|
||||
v1 = 65;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
OsInputPostEvent(OS_INPUT_KEY_DOWN, 2, 0, 0, 0);
|
||||
OsInputPostEvent(OS_INPUT_KEY_DOWN, v1, 0, 0, 0);
|
||||
OsInputPostEvent(OS_INPUT_KEY_UP, v1, 0, 0, 0);
|
||||
OsInputPostEvent(OS_INPUT_KEY_UP, 2, 0, 0, 0);
|
||||
}
|
||||
|
||||
void MacClient::SetMouseCoalescingEnabled(bool enabled) {
|
||||
#if WHOA_SYSTEM_VERSION < WHOA_MACOS_10_5
|
||||
bool prevEnabled = false;
|
||||
SetMouseCoalescingEnabled(true, &prevEnabled);
|
||||
#endif
|
||||
|
||||
#if WHOA_SYSTEM_VERSION >= WHOA_MACOS_10_5
|
||||
[NSEvent setMouseCoalescingEnabled: enabled];
|
||||
#endif
|
||||
}
|
8
src/app/mac/Main.nib/classes.nib
generated
Executable file
8
src/app/mac/Main.nib/classes.nib
generated
Executable file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
18
src/app/mac/Main.nib/info.nib
generated
Executable file
18
src/app/mac/Main.nib/info.nib
generated
Executable file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>677</string>
|
||||
<key>IBLastKnownRelativeProjectPath</key>
|
||||
<string>../../../WoW.xcodeproj</string>
|
||||
<key>IBOldestOS</key>
|
||||
<integer>3</integer>
|
||||
<key>IBOpenObjects</key>
|
||||
<array/>
|
||||
<key>IBSystem Version</key>
|
||||
<string>9J61</string>
|
||||
<key>targetFramework</key>
|
||||
<string>IBCarbonFramework</string>
|
||||
</dict>
|
||||
</plist>
|
131
src/app/mac/Main.nib/objects.xib
Executable file
131
src/app/mac/Main.nib/objects.xib
Executable file
@ -0,0 +1,131 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<object class="NSIBObjectData">
|
||||
<object name="rootObject" class="NSCustomObject" id="1">
|
||||
</object>
|
||||
<array count="17" name="allObjects">
|
||||
<object class="IBCarbonMenuItem" id="144">
|
||||
<string name="title">Paste</string>
|
||||
<string name="keyEquivalent">v</string>
|
||||
<ostype name="command">past</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="142">
|
||||
<boolean name="separator">TRUE</boolean>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="149">
|
||||
<string name="title">Copy</string>
|
||||
<string name="keyEquivalent">c</string>
|
||||
<ostype name="command">copy</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="183">
|
||||
<string name="title">About World of Warcraft...</string>
|
||||
<int name="keyEquivalentModifier">0</int>
|
||||
<ostype name="command">abou</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenu" id="181">
|
||||
<string name="title">World of Warcraft</string>
|
||||
<string name="name">_NSAppleMenu</string>
|
||||
<array count="3" name="items">
|
||||
<reference idRef="183"/>
|
||||
<object class="IBCarbonMenuItem" id="186">
|
||||
<boolean name="separator">TRUE</boolean>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="187">
|
||||
<string name="title">Switch To Full Screen Mode</string>
|
||||
<string name="keyEquivalent">m</string>
|
||||
<ostype name="command">Full</ostype>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<object class="IBCarbonMenuItem" id="152">
|
||||
<string name="title">Edit</string>
|
||||
<object name="submenu" class="IBCarbonMenu" id="147">
|
||||
<string name="title">Edit</string>
|
||||
<int name="menuID">128</int>
|
||||
<array count="6" name="items">
|
||||
<object class="IBCarbonMenuItem" id="141">
|
||||
<string name="title">Undo</string>
|
||||
<string name="keyEquivalent">z</string>
|
||||
<ostype name="command">undo</ostype>
|
||||
</object>
|
||||
<reference idRef="142"/>
|
||||
<object class="IBCarbonMenuItem" id="143">
|
||||
<string name="title">Cut</string>
|
||||
<string name="keyEquivalent">x</string>
|
||||
<ostype name="command">cut </ostype>
|
||||
</object>
|
||||
<reference idRef="149"/>
|
||||
<reference idRef="144"/>
|
||||
<object class="IBCarbonMenuItem" id="148">
|
||||
<string name="title">Select All</string>
|
||||
<string name="keyEquivalent">a</string>
|
||||
<ostype name="command">sall</ostype>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBCarbonMenu" id="29">
|
||||
<string name="title">Untitled</string>
|
||||
<string name="name">_NSMainMenu</string>
|
||||
<array count="2" name="items">
|
||||
<object class="IBCarbonMenuItem" id="182">
|
||||
<string name="title">World of Warcraft</string>
|
||||
<reference name="submenu" idRef="181"/>
|
||||
</object>
|
||||
<reference idRef="152"/>
|
||||
</array>
|
||||
</object>
|
||||
<reference idRef="141"/>
|
||||
<reference idRef="143"/>
|
||||
<object class="IBCarbonMenuItem" id="198">
|
||||
<string name="title">Show BatchViewer</string>
|
||||
<boolean name="notPreviousAlternate">TRUE</boolean>
|
||||
<ostype name="command">BVwr</ostype>
|
||||
</object>
|
||||
<reference idRef="187"/>
|
||||
<reference idRef="182"/>
|
||||
<object class="IBCarbonMenuItem" id="199">
|
||||
<string name="title">Show GL Layer Setup</string>
|
||||
<boolean name="notPreviousAlternate">TRUE</boolean>
|
||||
<ostype name="command">GLLs</ostype>
|
||||
</object>
|
||||
<object class="IBCarbonMenu" id="197">
|
||||
<string name="title">Batch Viewer</string>
|
||||
<array count="2" name="items">
|
||||
<reference idRef="198"/>
|
||||
<reference idRef="199"/>
|
||||
</array>
|
||||
</object>
|
||||
<reference idRef="186"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="148"/>
|
||||
</array>
|
||||
<array count="17" name="allParents">
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="181"/>
|
||||
<reference idRef="182"/>
|
||||
<reference idRef="29"/>
|
||||
<reference idRef="1"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="147"/>
|
||||
<reference idRef="197"/>
|
||||
<reference idRef="181"/>
|
||||
<reference idRef="29"/>
|
||||
<reference idRef="197"/>
|
||||
<reference idRef="1"/>
|
||||
<reference idRef="181"/>
|
||||
<reference idRef="152"/>
|
||||
<reference idRef="147"/>
|
||||
</array>
|
||||
<dictionary count="3" name="nameTable">
|
||||
<string>BatchViewerMenu</string>
|
||||
<reference idRef="197"/>
|
||||
<string>File's Owner</string>
|
||||
<reference idRef="1"/>
|
||||
<string>MenuBar</string>
|
||||
<reference idRef="29"/>
|
||||
</dictionary>
|
||||
<string name="targetFramework">IBCarbonFramework</string>
|
||||
<unsigned_int name="nextObjectID">200</unsigned_int>
|
||||
</object>
|
597
src/app/mac/Main.xib
Normal file
597
src/app/mac/Main.xib
Normal file
@ -0,0 +1,597 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<archive type="com.apple.InterfaceBuilder3.Carbon.XIB" version="8.00">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1030</int>
|
||||
<string key="IBDocument.SystemVersion">15G19009</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">11000</string>
|
||||
<string key="IBDocument.AppKitVersion">1404.47</string>
|
||||
<string key="IBDocument.HIToolboxVersion">807.20</string>
|
||||
<dictionary class="NSMutableDictionary" key="IBDocument.PluginVersions"/>
|
||||
<array class="NSMutableArray" key="IBDocument.EditedObjectIDs"/>
|
||||
<array key="IBDocument.PluginDependencies" id="0"/>
|
||||
<dictionary class="NSMutableDictionary" key="IBDocument.Metadata"/>
|
||||
<array class="NSMutableArray" key="IBDocument.RootObjects" id="234250886">
|
||||
<object class="IBHIMenu" id="783341525">
|
||||
<string key="NSTitle">Untitled</string>
|
||||
<array class="NSMutableArray" key="NSMenuItems">
|
||||
<object class="IBHIMenuItem" id="374205419">
|
||||
<reference key="NSMenu" ref="783341525"/>
|
||||
<string key="NSTitle">World of Warcraft</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<object class="NSImage" key="NSOnImage" id="678796781">
|
||||
<string key="NSName">NSMenuCheckmark</string>
|
||||
<int key="NSImageFlags">-1396703232</int>
|
||||
</object>
|
||||
<object class="NSImage" key="NSMixedImage" id="788635175">
|
||||
<string key="NSName">NSMenuMixedState</string>
|
||||
<int key="NSImageFlags">-1396703232</int>
|
||||
</object>
|
||||
<string key="NSAction">submenuAction:</string>
|
||||
<reference key="NSTarget" ref="273282363"/>
|
||||
<object class="IBHIMenu" key="NSSubmenu" id="273282363">
|
||||
<string key="NSTitle">World of Warcraft</string>
|
||||
<array class="NSMutableArray" key="NSMenuItems">
|
||||
<object class="IBHIMenuItem" id="962291476">
|
||||
<reference key="NSMenu" ref="273282363"/>
|
||||
<string key="NSTitle">About World of Warcraft...</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="678796781"/>
|
||||
<reference key="NSMixedImage" ref="788635175"/>
|
||||
<string key="title">About World of Warcraft...</string>
|
||||
<string key="keyEquivalent"/>
|
||||
<integer value="0" key="disabled"/>
|
||||
<integer value="0" key="checked"/>
|
||||
<integer value="0" key="submenuParentChoosable"/>
|
||||
<integer value="0" key="dynamic"/>
|
||||
<integer value="0" key="notPreviousAlternate"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="ignoreMeta"/>
|
||||
<integer value="0" key="sectionHeader"/>
|
||||
<integer value="0" key="customDraw"/>
|
||||
<integer value="0" key="autoRepeat"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="updateSingleItem"/>
|
||||
<integer value="0" key="includeInCmdKeyMatching"/>
|
||||
<integer value="0" key="keyEquivalentModifierMask"/>
|
||||
<integer value="1633841013" key="command"/>
|
||||
<nil key="helpTagText"/>
|
||||
<nil key="helpTagExtendedText"/>
|
||||
<integer value="0" key="helpTagDisplaySide"/>
|
||||
</object>
|
||||
<object class="IBHIMenuItem" id="28259413">
|
||||
<reference key="NSMenu" ref="273282363"/>
|
||||
<bool key="NSIsSeparator">YES</bool>
|
||||
<string key="NSTitle"/>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="678796781"/>
|
||||
<reference key="NSMixedImage" ref="788635175"/>
|
||||
<string key="title"/>
|
||||
<string key="keyEquivalent"/>
|
||||
<integer value="0" key="disabled"/>
|
||||
<integer value="0" key="checked"/>
|
||||
<integer value="0" key="submenuParentChoosable"/>
|
||||
<integer value="0" key="dynamic"/>
|
||||
<integer value="0" key="notPreviousAlternate"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="ignoreMeta"/>
|
||||
<integer value="0" key="sectionHeader"/>
|
||||
<integer value="0" key="customDraw"/>
|
||||
<integer value="0" key="autoRepeat"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="updateSingleItem"/>
|
||||
<integer value="0" key="includeInCmdKeyMatching"/>
|
||||
<integer value="1048576" key="keyEquivalentModifierMask"/>
|
||||
<integer value="0" key="command"/>
|
||||
<nil key="helpTagText"/>
|
||||
<nil key="helpTagExtendedText"/>
|
||||
<integer value="0" key="helpTagDisplaySide"/>
|
||||
</object>
|
||||
<object class="IBHIMenuItem" id="716945557">
|
||||
<reference key="NSMenu" ref="273282363"/>
|
||||
<string key="NSTitle">Switch To Full Screen Mode</string>
|
||||
<string key="NSKeyEquiv">m</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="678796781"/>
|
||||
<reference key="NSMixedImage" ref="788635175"/>
|
||||
<string key="title">Switch To Full Screen Mode</string>
|
||||
<string key="keyEquivalent">m</string>
|
||||
<integer value="0" key="disabled"/>
|
||||
<integer value="0" key="checked"/>
|
||||
<integer value="0" key="submenuParentChoosable"/>
|
||||
<integer value="0" key="dynamic"/>
|
||||
<integer value="0" key="notPreviousAlternate"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="ignoreMeta"/>
|
||||
<integer value="0" key="sectionHeader"/>
|
||||
<integer value="0" key="customDraw"/>
|
||||
<integer value="0" key="autoRepeat"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="updateSingleItem"/>
|
||||
<integer value="0" key="includeInCmdKeyMatching"/>
|
||||
<integer value="1048576" key="keyEquivalentModifierMask"/>
|
||||
<integer value="1182100588" key="command"/>
|
||||
<nil key="helpTagText"/>
|
||||
<nil key="helpTagExtendedText"/>
|
||||
<integer value="0" key="helpTagDisplaySide"/>
|
||||
</object>
|
||||
</array>
|
||||
<string key="name">_NSAppleMenu</string>
|
||||
<string key="title">World of Warcraft</string>
|
||||
<integer value="0" key="menuID"/>
|
||||
<integer value="0" key="excludesMarkColumn"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="usePencilGlyph"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="condenseSeparators"/>
|
||||
</object>
|
||||
<string key="title">World of Warcraft</string>
|
||||
<string key="keyEquivalent"/>
|
||||
<integer value="0" key="disabled"/>
|
||||
<integer value="0" key="checked"/>
|
||||
<integer value="0" key="submenuParentChoosable"/>
|
||||
<integer value="0" key="dynamic"/>
|
||||
<integer value="0" key="notPreviousAlternate"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="ignoreMeta"/>
|
||||
<integer value="0" key="sectionHeader"/>
|
||||
<integer value="0" key="customDraw"/>
|
||||
<integer value="0" key="autoRepeat"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="updateSingleItem"/>
|
||||
<integer value="0" key="includeInCmdKeyMatching"/>
|
||||
<integer value="1048576" key="keyEquivalentModifierMask"/>
|
||||
<integer value="0" key="command"/>
|
||||
<nil key="helpTagText"/>
|
||||
<nil key="helpTagExtendedText"/>
|
||||
<integer value="0" key="helpTagDisplaySide"/>
|
||||
</object>
|
||||
<object class="IBHIMenuItem" id="832277564">
|
||||
<reference key="NSMenu" ref="783341525"/>
|
||||
<string key="NSTitle">Edit</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="678796781"/>
|
||||
<reference key="NSMixedImage" ref="788635175"/>
|
||||
<string key="NSAction">submenuAction:</string>
|
||||
<reference key="NSTarget" ref="775244329"/>
|
||||
<object class="IBHIMenu" key="NSSubmenu" id="775244329">
|
||||
<string key="NSTitle">Edit</string>
|
||||
<array class="NSMutableArray" key="NSMenuItems">
|
||||
<object class="IBHIMenuItem" id="525595591">
|
||||
<reference key="NSMenu" ref="775244329"/>
|
||||
<string key="NSTitle">Undo</string>
|
||||
<string key="NSKeyEquiv">z</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="678796781"/>
|
||||
<reference key="NSMixedImage" ref="788635175"/>
|
||||
<string key="title">Undo</string>
|
||||
<string key="keyEquivalent">z</string>
|
||||
<integer value="0" key="disabled"/>
|
||||
<integer value="0" key="checked"/>
|
||||
<integer value="0" key="submenuParentChoosable"/>
|
||||
<integer value="0" key="dynamic"/>
|
||||
<integer value="0" key="notPreviousAlternate"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="ignoreMeta"/>
|
||||
<integer value="0" key="sectionHeader"/>
|
||||
<integer value="0" key="customDraw"/>
|
||||
<integer value="0" key="autoRepeat"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="updateSingleItem"/>
|
||||
<integer value="0" key="includeInCmdKeyMatching"/>
|
||||
<integer value="1048576" key="keyEquivalentModifierMask"/>
|
||||
<integer value="1970168943" key="command"/>
|
||||
<nil key="helpTagText"/>
|
||||
<nil key="helpTagExtendedText"/>
|
||||
<integer value="0" key="helpTagDisplaySide"/>
|
||||
</object>
|
||||
<object class="IBHIMenuItem" id="348288318">
|
||||
<reference key="NSMenu" ref="775244329"/>
|
||||
<bool key="NSIsSeparator">YES</bool>
|
||||
<string key="NSTitle"/>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="678796781"/>
|
||||
<reference key="NSMixedImage" ref="788635175"/>
|
||||
<string key="title"/>
|
||||
<string key="keyEquivalent"/>
|
||||
<integer value="0" key="disabled"/>
|
||||
<integer value="0" key="checked"/>
|
||||
<integer value="0" key="submenuParentChoosable"/>
|
||||
<integer value="0" key="dynamic"/>
|
||||
<integer value="0" key="notPreviousAlternate"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="ignoreMeta"/>
|
||||
<integer value="0" key="sectionHeader"/>
|
||||
<integer value="0" key="customDraw"/>
|
||||
<integer value="0" key="autoRepeat"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="updateSingleItem"/>
|
||||
<integer value="0" key="includeInCmdKeyMatching"/>
|
||||
<integer value="1048576" key="keyEquivalentModifierMask"/>
|
||||
<integer value="0" key="command"/>
|
||||
<nil key="helpTagText"/>
|
||||
<nil key="helpTagExtendedText"/>
|
||||
<integer value="0" key="helpTagDisplaySide"/>
|
||||
</object>
|
||||
<object class="IBHIMenuItem" id="504943467">
|
||||
<reference key="NSMenu" ref="775244329"/>
|
||||
<string key="NSTitle">Cut</string>
|
||||
<string key="NSKeyEquiv">x</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="678796781"/>
|
||||
<reference key="NSMixedImage" ref="788635175"/>
|
||||
<string key="title">Cut</string>
|
||||
<string key="keyEquivalent">x</string>
|
||||
<integer value="0" key="disabled"/>
|
||||
<integer value="0" key="checked"/>
|
||||
<integer value="0" key="submenuParentChoosable"/>
|
||||
<integer value="0" key="dynamic"/>
|
||||
<integer value="0" key="notPreviousAlternate"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="ignoreMeta"/>
|
||||
<integer value="0" key="sectionHeader"/>
|
||||
<integer value="0" key="customDraw"/>
|
||||
<integer value="0" key="autoRepeat"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="updateSingleItem"/>
|
||||
<integer value="0" key="includeInCmdKeyMatching"/>
|
||||
<integer value="1048576" key="keyEquivalentModifierMask"/>
|
||||
<integer value="1668641824" key="command"/>
|
||||
<nil key="helpTagText"/>
|
||||
<nil key="helpTagExtendedText"/>
|
||||
<integer value="0" key="helpTagDisplaySide"/>
|
||||
</object>
|
||||
<object class="IBHIMenuItem" id="1036249919">
|
||||
<reference key="NSMenu" ref="775244329"/>
|
||||
<string key="NSTitle">Copy</string>
|
||||
<string key="NSKeyEquiv">c</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="678796781"/>
|
||||
<reference key="NSMixedImage" ref="788635175"/>
|
||||
<string key="title">Copy</string>
|
||||
<string key="keyEquivalent">c</string>
|
||||
<integer value="0" key="disabled"/>
|
||||
<integer value="0" key="checked"/>
|
||||
<integer value="0" key="submenuParentChoosable"/>
|
||||
<integer value="0" key="dynamic"/>
|
||||
<integer value="0" key="notPreviousAlternate"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="ignoreMeta"/>
|
||||
<integer value="0" key="sectionHeader"/>
|
||||
<integer value="0" key="customDraw"/>
|
||||
<integer value="0" key="autoRepeat"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="updateSingleItem"/>
|
||||
<integer value="0" key="includeInCmdKeyMatching"/>
|
||||
<integer value="1048576" key="keyEquivalentModifierMask"/>
|
||||
<integer value="1668247673" key="command"/>
|
||||
<nil key="helpTagText"/>
|
||||
<nil key="helpTagExtendedText"/>
|
||||
<integer value="0" key="helpTagDisplaySide"/>
|
||||
</object>
|
||||
<object class="IBHIMenuItem" id="780439468">
|
||||
<reference key="NSMenu" ref="775244329"/>
|
||||
<string key="NSTitle">Paste</string>
|
||||
<string key="NSKeyEquiv">v</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="678796781"/>
|
||||
<reference key="NSMixedImage" ref="788635175"/>
|
||||
<string key="title">Paste</string>
|
||||
<string key="keyEquivalent">v</string>
|
||||
<integer value="0" key="disabled"/>
|
||||
<integer value="0" key="checked"/>
|
||||
<integer value="0" key="submenuParentChoosable"/>
|
||||
<integer value="0" key="dynamic"/>
|
||||
<integer value="0" key="notPreviousAlternate"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="ignoreMeta"/>
|
||||
<integer value="0" key="sectionHeader"/>
|
||||
<integer value="0" key="customDraw"/>
|
||||
<integer value="0" key="autoRepeat"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="updateSingleItem"/>
|
||||
<integer value="0" key="includeInCmdKeyMatching"/>
|
||||
<integer value="1048576" key="keyEquivalentModifierMask"/>
|
||||
<integer value="1885434740" key="command"/>
|
||||
<nil key="helpTagText"/>
|
||||
<nil key="helpTagExtendedText"/>
|
||||
<integer value="0" key="helpTagDisplaySide"/>
|
||||
</object>
|
||||
<object class="IBHIMenuItem" id="270786867">
|
||||
<reference key="NSMenu" ref="775244329"/>
|
||||
<string key="NSTitle">Select All</string>
|
||||
<string key="NSKeyEquiv">a</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="678796781"/>
|
||||
<reference key="NSMixedImage" ref="788635175"/>
|
||||
<string key="title">Select All</string>
|
||||
<string key="keyEquivalent">a</string>
|
||||
<integer value="0" key="disabled"/>
|
||||
<integer value="0" key="checked"/>
|
||||
<integer value="0" key="submenuParentChoosable"/>
|
||||
<integer value="0" key="dynamic"/>
|
||||
<integer value="0" key="notPreviousAlternate"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="ignoreMeta"/>
|
||||
<integer value="0" key="sectionHeader"/>
|
||||
<integer value="0" key="customDraw"/>
|
||||
<integer value="0" key="autoRepeat"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="updateSingleItem"/>
|
||||
<integer value="0" key="includeInCmdKeyMatching"/>
|
||||
<integer value="1048576" key="keyEquivalentModifierMask"/>
|
||||
<integer value="1935764588" key="command"/>
|
||||
<nil key="helpTagText"/>
|
||||
<nil key="helpTagExtendedText"/>
|
||||
<integer value="0" key="helpTagDisplaySide"/>
|
||||
</object>
|
||||
</array>
|
||||
<string key="title">Edit</string>
|
||||
<integer value="128" key="menuID"/>
|
||||
<integer value="0" key="excludesMarkColumn"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="usePencilGlyph"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="condenseSeparators"/>
|
||||
</object>
|
||||
<string key="title">Edit</string>
|
||||
<string key="keyEquivalent"/>
|
||||
<integer value="0" key="disabled"/>
|
||||
<integer value="0" key="checked"/>
|
||||
<integer value="0" key="submenuParentChoosable"/>
|
||||
<integer value="0" key="dynamic"/>
|
||||
<integer value="0" key="notPreviousAlternate"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="ignoreMeta"/>
|
||||
<integer value="0" key="sectionHeader"/>
|
||||
<integer value="0" key="customDraw"/>
|
||||
<integer value="0" key="autoRepeat"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="updateSingleItem"/>
|
||||
<integer value="0" key="includeInCmdKeyMatching"/>
|
||||
<integer value="1048576" key="keyEquivalentModifierMask"/>
|
||||
<integer value="0" key="command"/>
|
||||
<nil key="helpTagText"/>
|
||||
<nil key="helpTagExtendedText"/>
|
||||
<integer value="0" key="helpTagDisplaySide"/>
|
||||
</object>
|
||||
</array>
|
||||
<string key="name">_NSMainMenu</string>
|
||||
<string key="title">Untitled</string>
|
||||
<integer value="0" key="menuID"/>
|
||||
<integer value="0" key="excludesMarkColumn"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="usePencilGlyph"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="condenseSeparators"/>
|
||||
</object>
|
||||
<object class="IBHIMenu" id="231014827">
|
||||
<string key="NSTitle">Batch Viewer</string>
|
||||
<array class="NSMutableArray" key="NSMenuItems">
|
||||
<object class="IBHIMenuItem" id="177821328">
|
||||
<reference key="NSMenu" ref="231014827"/>
|
||||
<string key="NSTitle">Show BatchViewer</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="678796781"/>
|
||||
<reference key="NSMixedImage" ref="788635175"/>
|
||||
<string key="title">Show BatchViewer</string>
|
||||
<string key="keyEquivalent"/>
|
||||
<integer value="0" key="disabled"/>
|
||||
<integer value="0" key="checked"/>
|
||||
<integer value="0" key="submenuParentChoosable"/>
|
||||
<integer value="0" key="dynamic"/>
|
||||
<integer value="1" key="notPreviousAlternate"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="ignoreMeta"/>
|
||||
<integer value="0" key="sectionHeader"/>
|
||||
<integer value="0" key="customDraw"/>
|
||||
<integer value="0" key="autoRepeat"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="updateSingleItem"/>
|
||||
<integer value="0" key="includeInCmdKeyMatching"/>
|
||||
<integer value="1048576" key="keyEquivalentModifierMask"/>
|
||||
<integer value="1112962930" key="command"/>
|
||||
<nil key="helpTagText"/>
|
||||
<nil key="helpTagExtendedText"/>
|
||||
<integer value="0" key="helpTagDisplaySide"/>
|
||||
</object>
|
||||
<object class="IBHIMenuItem" id="443792299">
|
||||
<reference key="NSMenu" ref="231014827"/>
|
||||
<string key="NSTitle">Show GL Layer Setup</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="678796781"/>
|
||||
<reference key="NSMixedImage" ref="788635175"/>
|
||||
<string key="title">Show GL Layer Setup</string>
|
||||
<string key="keyEquivalent"/>
|
||||
<integer value="0" key="disabled"/>
|
||||
<integer value="0" key="checked"/>
|
||||
<integer value="0" key="submenuParentChoosable"/>
|
||||
<integer value="0" key="dynamic"/>
|
||||
<integer value="1" key="notPreviousAlternate"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="ignoreMeta"/>
|
||||
<integer value="0" key="sectionHeader"/>
|
||||
<integer value="0" key="customDraw"/>
|
||||
<integer value="0" key="autoRepeat"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="updateSingleItem"/>
|
||||
<integer value="0" key="includeInCmdKeyMatching"/>
|
||||
<integer value="1048576" key="keyEquivalentModifierMask"/>
|
||||
<integer value="1196182643" key="command"/>
|
||||
<nil key="helpTagText"/>
|
||||
<nil key="helpTagExtendedText"/>
|
||||
<integer value="0" key="helpTagDisplaySide"/>
|
||||
</object>
|
||||
</array>
|
||||
<string key="title">Batch Viewer</string>
|
||||
<integer value="0" key="menuID"/>
|
||||
<integer value="0" key="excludesMarkColumn"/>
|
||||
<integer value="0" key="autoDisable"/>
|
||||
<integer value="0" key="usePencilGlyph"/>
|
||||
<integer value="0" key="hidden"/>
|
||||
<integer value="0" key="condenseSeparators"/>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||
<array class="NSMutableArray" key="connectionRecords"/>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
<array key="orderedObjects">
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">0</int>
|
||||
<reference key="object" ref="0"/>
|
||||
<reference key="children" ref="234250886"/>
|
||||
<nil key="parent"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">29</int>
|
||||
<reference key="object" ref="783341525"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="832277564"/>
|
||||
<reference ref="374205419"/>
|
||||
</array>
|
||||
<reference key="parent" ref="0"/>
|
||||
<string key="objectName">MenuBar</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">197</int>
|
||||
<reference key="object" ref="231014827"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="177821328"/>
|
||||
<reference ref="443792299"/>
|
||||
</array>
|
||||
<reference key="parent" ref="0"/>
|
||||
<string key="objectName">BatchViewerMenu</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">152</int>
|
||||
<reference key="object" ref="832277564"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="775244329"/>
|
||||
</array>
|
||||
<reference key="parent" ref="783341525"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">182</int>
|
||||
<reference key="object" ref="374205419"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="273282363"/>
|
||||
</array>
|
||||
<reference key="parent" ref="783341525"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">198</int>
|
||||
<reference key="object" ref="177821328"/>
|
||||
<reference key="parent" ref="231014827"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">199</int>
|
||||
<reference key="object" ref="443792299"/>
|
||||
<reference key="parent" ref="231014827"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">147</int>
|
||||
<reference key="object" ref="775244329"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="780439468"/>
|
||||
<reference ref="348288318"/>
|
||||
<reference ref="1036249919"/>
|
||||
<reference ref="525595591"/>
|
||||
<reference ref="504943467"/>
|
||||
<reference ref="270786867"/>
|
||||
</array>
|
||||
<reference key="parent" ref="832277564"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">181</int>
|
||||
<reference key="object" ref="273282363"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="962291476"/>
|
||||
<reference ref="716945557"/>
|
||||
<reference ref="28259413"/>
|
||||
</array>
|
||||
<reference key="parent" ref="374205419"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">144</int>
|
||||
<reference key="object" ref="780439468"/>
|
||||
<reference key="parent" ref="775244329"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">142</int>
|
||||
<reference key="object" ref="348288318"/>
|
||||
<reference key="parent" ref="775244329"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">149</int>
|
||||
<reference key="object" ref="1036249919"/>
|
||||
<reference key="parent" ref="775244329"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">141</int>
|
||||
<reference key="object" ref="525595591"/>
|
||||
<reference key="parent" ref="775244329"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">143</int>
|
||||
<reference key="object" ref="504943467"/>
|
||||
<reference key="parent" ref="775244329"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">148</int>
|
||||
<reference key="object" ref="270786867"/>
|
||||
<reference key="parent" ref="775244329"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">183</int>
|
||||
<reference key="object" ref="962291476"/>
|
||||
<reference key="parent" ref="273282363"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">187</int>
|
||||
<reference key="object" ref="716945557"/>
|
||||
<reference key="parent" ref="273282363"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">186</int>
|
||||
<reference key="object" ref="28259413"/>
|
||||
<reference key="parent" ref="273282363"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<dictionary class="NSMutableDictionary" key="flattenedProperties"/>
|
||||
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
|
||||
<nil key="activeLocalization"/>
|
||||
<dictionary class="NSMutableDictionary" key="localizations"/>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">200</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes"/>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBCarbonFramework</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CarbonPlugin.macosx</string>
|
||||
<integer value="1030" key="NS.object.0"/>
|
||||
</object>
|
||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||
<string key="IBDocument.LastKnownRelativeProjectPath">../../../WoW.xcodeproj</string>
|
||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||
</data>
|
||||
</archive>
|
19
src/app/mac/MainApp.h
Normal file
19
src/app/mac/MainApp.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef APP_MAC_MAIN_APP_H
|
||||
#define APP_MAC_MAIN_APP_H
|
||||
|
||||
#include "app/mac/MacClient.h"
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
@interface MainApp : NSObject
|
||||
|
||||
@property (retain) NSTimer* m_pollTimer;
|
||||
@property bool isPolling;
|
||||
|
||||
@property (retain) IBOutlet NSMenuItem* captureFrameMenuItem;
|
||||
@property (retain) IBOutlet NSMenuItem* showBatchViewerMenuItem;
|
||||
@property (retain) IBOutlet NSMenuItem* showGLLayerSetupMenuItem;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
90
src/app/mac/MainApp.mm
Normal file
90
src/app/mac/MainApp.mm
Normal file
@ -0,0 +1,90 @@
|
||||
#include "app/mac/MainApp.h"
|
||||
#include "event/Event.hpp"
|
||||
#include "event/Scheduler.hpp"
|
||||
#include "os/Compat.hpp"
|
||||
|
||||
@implementation MainApp
|
||||
|
||||
+ (void)initialize {
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
registerDefaults: [NSDictionary
|
||||
dictionaryWithObject: @"YES"
|
||||
forKey: @"NSDisabledCharacterPaletteMenuItem"]];
|
||||
|
||||
[NSApp
|
||||
setActivationPolicy: NSApplicationActivationPolicyRegular];
|
||||
}
|
||||
|
||||
- (void)applicationDidFinishLaunching:(id)a1 {
|
||||
self.m_pollTimer = [NSTimer
|
||||
timerWithTimeInterval: 0.0001
|
||||
target: self
|
||||
selector: @selector(poll:)
|
||||
userInfo: nil
|
||||
repeats: true];
|
||||
|
||||
[[NSRunLoop currentRunLoop]
|
||||
addTimer: self.m_pollTimer
|
||||
forMode: NSDefaultRunLoopMode];
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
|
||||
// TODO
|
||||
// OsQueuePut(5, 0, 0, 0, 0);
|
||||
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
- (void)captureFrame:(id)a1 {
|
||||
}
|
||||
|
||||
- (void)copy:(id)a3 {
|
||||
MacClient::PostClipboardKeyEvents(MacClient::ClipboardCopy);
|
||||
}
|
||||
|
||||
- (void)cut:(id)a3 {
|
||||
MacClient::PostClipboardKeyEvents(MacClient::ClipboardCut);
|
||||
}
|
||||
|
||||
- (void)paste:(id)a3 {
|
||||
MacClient::PostClipboardKeyEvents(MacClient::ClipboardPaste);
|
||||
}
|
||||
|
||||
- (void)poll:(id)a1 {
|
||||
if (!Event::s_shouldLoopTerminate) {
|
||||
Event::s_shouldLoopTerminate = SchedulerMainProcess();
|
||||
|
||||
if (Event::s_shouldLoopTerminate) {
|
||||
[self.m_pollTimer invalidate];
|
||||
self.m_pollTimer = nil;
|
||||
|
||||
[NSApp stop:self];
|
||||
|
||||
[NSApp
|
||||
postEvent:
|
||||
[NSEvent
|
||||
otherEventWithType: NSEventTypeApplicationDefined
|
||||
location: NSMakePoint(0, 0)
|
||||
modifierFlags: 0
|
||||
timestamp: 0
|
||||
windowNumber: 0
|
||||
context: 0
|
||||
subtype: 0
|
||||
data1: 0
|
||||
data2: 0]
|
||||
atStart: 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showBatchViewer:(id)a1 {
|
||||
}
|
||||
|
||||
- (void)showGLLayerSetup:(id)a1 {
|
||||
}
|
||||
|
||||
- (void)toggleFullscreenMode:(id)a1 {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@end
|
901
src/app/mac/MainMenu.nib/designable.nib
generated
Executable file
901
src/app/mac/MainMenu.nib/designable.nib
generated
Executable file
@ -0,0 +1,901 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.03">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1030</int>
|
||||
<string key="IBDocument.SystemVersion">9J61</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">677</string>
|
||||
<string key="IBDocument.AppKitVersion">949.46</string>
|
||||
<string key="IBDocument.HIToolboxVersion">353.00</string>
|
||||
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<integer value="24"/>
|
||||
</object>
|
||||
<object class="NSArray" key="IBDocument.PluginDependencies">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="IBDocument.Metadata">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSCustomObject" id="1021">
|
||||
<string key="NSClassName">NSApplication</string>
|
||||
</object>
|
||||
<object class="NSCustomObject" id="1014">
|
||||
<string key="NSClassName">FirstResponder</string>
|
||||
</object>
|
||||
<object class="NSCustomObject" id="1050">
|
||||
<string key="NSClassName">NSApplication</string>
|
||||
</object>
|
||||
<object class="NSMenu" id="649796088">
|
||||
<string key="NSTitle">AMainMenu</string>
|
||||
<object class="NSMutableArray" key="NSMenuItems">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSMenuItem" id="694149608">
|
||||
<reference key="NSMenu" ref="649796088"/>
|
||||
<string key="NSTitle">World of Warcraft</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<object class="NSCustomResource" key="NSOnImage" id="229763992">
|
||||
<string key="NSClassName">NSImage</string>
|
||||
<string key="NSResourceName">NSMenuCheckmark</string>
|
||||
</object>
|
||||
<object class="NSCustomResource" key="NSMixedImage" id="909111550">
|
||||
<string key="NSClassName">NSImage</string>
|
||||
<string key="NSResourceName">NSMenuMixedState</string>
|
||||
</object>
|
||||
<string key="NSAction">submenuAction:</string>
|
||||
<object class="NSMenu" key="NSSubmenu" id="110575045">
|
||||
<string key="NSTitle">World of Warcraft</string>
|
||||
<object class="NSMutableArray" key="NSMenuItems">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSMenuItem" id="238522557">
|
||||
<reference key="NSMenu" ref="110575045"/>
|
||||
<string key="NSTitle">MENU_ABOUT</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="304266470">
|
||||
<reference key="NSMenu" ref="110575045"/>
|
||||
<bool key="NSIsDisabled">YES</bool>
|
||||
<bool key="NSIsSeparator">YES</bool>
|
||||
<string key="NSTitle"/>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="41361050">
|
||||
<reference key="NSMenu" ref="110575045"/>
|
||||
<string key="NSTitle">MENU_SWITCH_TO_FULLSCREEN</string>
|
||||
<string key="NSKeyEquiv">m</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="294290359">
|
||||
<reference key="NSMenu" ref="110575045"/>
|
||||
<bool key="NSIsDisabled">YES</bool>
|
||||
<bool key="NSIsSeparator">YES</bool>
|
||||
<string key="NSTitle"/>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="755159360">
|
||||
<reference key="NSMenu" ref="110575045"/>
|
||||
<string key="NSTitle">MENU_HIDE</string>
|
||||
<string key="NSKeyEquiv">h</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="342932134">
|
||||
<reference key="NSMenu" ref="110575045"/>
|
||||
<string key="NSTitle">MENU_HIDE_OTHERS</string>
|
||||
<string key="NSKeyEquiv">h</string>
|
||||
<int key="NSKeyEquivModMask">1572864</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="908899353">
|
||||
<reference key="NSMenu" ref="110575045"/>
|
||||
<string key="NSTitle">MENU_SHOW_ALL</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="1056857174">
|
||||
<reference key="NSMenu" ref="110575045"/>
|
||||
<bool key="NSIsDisabled">YES</bool>
|
||||
<bool key="NSIsSeparator">YES</bool>
|
||||
<string key="NSTitle"/>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="632727374">
|
||||
<reference key="NSMenu" ref="110575045"/>
|
||||
<string key="NSTitle">MENU_QUIT</string>
|
||||
<string key="NSKeyEquiv">q</string>
|
||||
<int key="NSKeyEquivModMask">1572864</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
</object>
|
||||
<string key="NSName">_NSAppleMenu</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="952259628">
|
||||
<reference key="NSMenu" ref="649796088"/>
|
||||
<string key="NSTitle">MENU_EDIT</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
<string key="NSAction">submenuAction:</string>
|
||||
<object class="NSMenu" key="NSSubmenu" id="789758025">
|
||||
<string key="NSTitle">MENU_EDIT</string>
|
||||
<object class="NSMutableArray" key="NSMenuItems">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSMenuItem" id="1058277027">
|
||||
<reference key="NSMenu" ref="789758025"/>
|
||||
<string key="NSTitle">MENU_UNDO</string>
|
||||
<string key="NSKeyEquiv">z</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="1040322652">
|
||||
<reference key="NSMenu" ref="789758025"/>
|
||||
<bool key="NSIsDisabled">YES</bool>
|
||||
<bool key="NSIsSeparator">YES</bool>
|
||||
<string key="NSTitle"/>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="296257095">
|
||||
<reference key="NSMenu" ref="789758025"/>
|
||||
<string key="NSTitle">MENU_EDIT_CUT</string>
|
||||
<string key="NSKeyEquiv">x</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="860595796">
|
||||
<reference key="NSMenu" ref="789758025"/>
|
||||
<string key="NSTitle">MENU_EDIT_COPY</string>
|
||||
<string key="NSKeyEquiv">c</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="29853731">
|
||||
<reference key="NSMenu" ref="789758025"/>
|
||||
<string key="NSTitle">MENU_EDIT_PASTE</string>
|
||||
<string key="NSKeyEquiv">v</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="583158037">
|
||||
<reference key="NSMenu" ref="789758025"/>
|
||||
<string key="NSTitle">MENU_EDIT_SELECT_ALL</string>
|
||||
<string key="NSKeyEquiv">a</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="713487014">
|
||||
<reference key="NSMenu" ref="649796088"/>
|
||||
<string key="NSTitle">MENU_WINDOW</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
<string key="NSAction">submenuAction:</string>
|
||||
<object class="NSMenu" key="NSSubmenu" id="835318025">
|
||||
<string key="NSTitle">MENU_WINDOW</string>
|
||||
<object class="NSMutableArray" key="NSMenuItems">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSMenuItem" id="839061908">
|
||||
<reference key="NSMenu" ref="835318025"/>
|
||||
<string key="NSTitle">Show Batch Viewer</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="825097611">
|
||||
<reference key="NSMenu" ref="835318025"/>
|
||||
<string key="NSTitle">Show GL Layer Setup</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="891014876">
|
||||
<reference key="NSMenu" ref="835318025"/>
|
||||
<string key="NSTitle">Capture Frame</string>
|
||||
<string key="NSKeyEquiv">r</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
</object>
|
||||
<string key="NSName">_NSWindowsMenu</string>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<string key="NSName">_NSMainMenu</string>
|
||||
</object>
|
||||
<object class="NSCustomObject" id="106825686">
|
||||
<string key="NSClassName">MainApp</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||
<object class="NSMutableArray" key="connectionRecords">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">orderFrontStandardAboutPanel:</string>
|
||||
<reference key="source" ref="1021"/>
|
||||
<reference key="destination" ref="238522557"/>
|
||||
</object>
|
||||
<int key="connectionID">142</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">undo:</string>
|
||||
<reference key="source" ref="1014"/>
|
||||
<reference key="destination" ref="1058277027"/>
|
||||
</object>
|
||||
<int key="connectionID">223</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">copy:</string>
|
||||
<reference key="source" ref="1014"/>
|
||||
<reference key="destination" ref="860595796"/>
|
||||
</object>
|
||||
<int key="connectionID">224</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">paste:</string>
|
||||
<reference key="source" ref="1014"/>
|
||||
<reference key="destination" ref="29853731"/>
|
||||
</object>
|
||||
<int key="connectionID">226</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">cut:</string>
|
||||
<reference key="source" ref="1014"/>
|
||||
<reference key="destination" ref="296257095"/>
|
||||
</object>
|
||||
<int key="connectionID">228</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">selectAll:</string>
|
||||
<reference key="source" ref="1014"/>
|
||||
<reference key="destination" ref="583158037"/>
|
||||
</object>
|
||||
<int key="connectionID">232</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">hide:</string>
|
||||
<reference key="source" ref="1014"/>
|
||||
<reference key="destination" ref="755159360"/>
|
||||
</object>
|
||||
<int key="connectionID">367</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">hideOtherApplications:</string>
|
||||
<reference key="source" ref="1014"/>
|
||||
<reference key="destination" ref="342932134"/>
|
||||
</object>
|
||||
<int key="connectionID">368</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">terminate:</string>
|
||||
<reference key="source" ref="1014"/>
|
||||
<reference key="destination" ref="632727374"/>
|
||||
</object>
|
||||
<int key="connectionID">369</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">unhideAllApplications:</string>
|
||||
<reference key="source" ref="1014"/>
|
||||
<reference key="destination" ref="908899353"/>
|
||||
</object>
|
||||
<int key="connectionID">370</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">delegate</string>
|
||||
<reference key="source" ref="1021"/>
|
||||
<reference key="destination" ref="106825686"/>
|
||||
</object>
|
||||
<int key="connectionID">452</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">showGLLayerSetup:</string>
|
||||
<reference key="source" ref="106825686"/>
|
||||
<reference key="destination" ref="825097611"/>
|
||||
</object>
|
||||
<int key="connectionID">454</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">showBatchViewer:</string>
|
||||
<reference key="source" ref="106825686"/>
|
||||
<reference key="destination" ref="839061908"/>
|
||||
</object>
|
||||
<int key="connectionID">455</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">showBatchViewerMenuItem</string>
|
||||
<reference key="source" ref="106825686"/>
|
||||
<reference key="destination" ref="839061908"/>
|
||||
</object>
|
||||
<int key="connectionID">456</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">showGLLayerSetupMenuItem</string>
|
||||
<reference key="source" ref="106825686"/>
|
||||
<reference key="destination" ref="825097611"/>
|
||||
</object>
|
||||
<int key="connectionID">457</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">toggleFullscreenMode:</string>
|
||||
<reference key="source" ref="106825686"/>
|
||||
<reference key="destination" ref="41361050"/>
|
||||
</object>
|
||||
<int key="connectionID">460</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">captureFrameMenuItem</string>
|
||||
<reference key="source" ref="106825686"/>
|
||||
<reference key="destination" ref="891014876"/>
|
||||
</object>
|
||||
<int key="connectionID">462</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">captureFrame:</string>
|
||||
<reference key="source" ref="106825686"/>
|
||||
<reference key="destination" ref="891014876"/>
|
||||
</object>
|
||||
<int key="connectionID">463</int>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
<object class="NSArray" key="orderedObjects">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">0</int>
|
||||
<object class="NSArray" key="object" id="1049">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
<reference key="children" ref="1048"/>
|
||||
<nil key="parent"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-2</int>
|
||||
<reference key="object" ref="1021"/>
|
||||
<reference key="parent" ref="1049"/>
|
||||
<string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-1</int>
|
||||
<reference key="object" ref="1014"/>
|
||||
<reference key="parent" ref="1049"/>
|
||||
<string key="objectName">First Responder</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-3</int>
|
||||
<reference key="object" ref="1050"/>
|
||||
<reference key="parent" ref="1049"/>
|
||||
<string key="objectName">Application</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">29</int>
|
||||
<reference key="object" ref="649796088"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="713487014"/>
|
||||
<reference ref="694149608"/>
|
||||
<reference ref="952259628"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1049"/>
|
||||
<string key="objectName">Main Menu</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">19</int>
|
||||
<reference key="object" ref="713487014"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="835318025"/>
|
||||
</object>
|
||||
<reference key="parent" ref="649796088"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">56</int>
|
||||
<reference key="object" ref="694149608"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="110575045"/>
|
||||
</object>
|
||||
<reference key="parent" ref="649796088"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">217</int>
|
||||
<reference key="object" ref="952259628"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="789758025"/>
|
||||
</object>
|
||||
<reference key="parent" ref="649796088"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">205</int>
|
||||
<reference key="object" ref="789758025"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="583158037"/>
|
||||
<reference ref="1058277027"/>
|
||||
<reference ref="296257095"/>
|
||||
<reference ref="29853731"/>
|
||||
<reference ref="860595796"/>
|
||||
<reference ref="1040322652"/>
|
||||
</object>
|
||||
<reference key="parent" ref="952259628"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">198</int>
|
||||
<reference key="object" ref="583158037"/>
|
||||
<reference key="parent" ref="789758025"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">207</int>
|
||||
<reference key="object" ref="1058277027"/>
|
||||
<reference key="parent" ref="789758025"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">199</int>
|
||||
<reference key="object" ref="296257095"/>
|
||||
<reference key="parent" ref="789758025"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">203</int>
|
||||
<reference key="object" ref="29853731"/>
|
||||
<reference key="parent" ref="789758025"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">197</int>
|
||||
<reference key="object" ref="860595796"/>
|
||||
<reference key="parent" ref="789758025"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">206</int>
|
||||
<reference key="object" ref="1040322652"/>
|
||||
<reference key="parent" ref="789758025"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">57</int>
|
||||
<reference key="object" ref="110575045"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="238522557"/>
|
||||
<reference ref="755159360"/>
|
||||
<reference ref="908899353"/>
|
||||
<reference ref="632727374"/>
|
||||
<reference ref="304266470"/>
|
||||
<reference ref="1056857174"/>
|
||||
<reference ref="342932134"/>
|
||||
<reference ref="41361050"/>
|
||||
<reference ref="294290359"/>
|
||||
</object>
|
||||
<reference key="parent" ref="694149608"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">58</int>
|
||||
<reference key="object" ref="238522557"/>
|
||||
<reference key="parent" ref="110575045"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">134</int>
|
||||
<reference key="object" ref="755159360"/>
|
||||
<reference key="parent" ref="110575045"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">150</int>
|
||||
<reference key="object" ref="908899353"/>
|
||||
<reference key="parent" ref="110575045"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">136</int>
|
||||
<reference key="object" ref="632727374"/>
|
||||
<reference key="parent" ref="110575045"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">236</int>
|
||||
<reference key="object" ref="304266470"/>
|
||||
<reference key="parent" ref="110575045"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">149</int>
|
||||
<reference key="object" ref="1056857174"/>
|
||||
<reference key="parent" ref="110575045"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">145</int>
|
||||
<reference key="object" ref="342932134"/>
|
||||
<reference key="parent" ref="110575045"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">24</int>
|
||||
<reference key="object" ref="835318025"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="839061908"/>
|
||||
<reference ref="825097611"/>
|
||||
<reference ref="891014876"/>
|
||||
</object>
|
||||
<reference key="parent" ref="713487014"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">449</int>
|
||||
<reference key="object" ref="839061908"/>
|
||||
<reference key="parent" ref="835318025"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">450</int>
|
||||
<reference key="object" ref="825097611"/>
|
||||
<reference key="parent" ref="835318025"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">451</int>
|
||||
<reference key="object" ref="106825686"/>
|
||||
<reference key="parent" ref="1049"/>
|
||||
<string key="objectName">MainApp</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">458</int>
|
||||
<reference key="object" ref="41361050"/>
|
||||
<reference key="parent" ref="110575045"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">459</int>
|
||||
<reference key="object" ref="294290359"/>
|
||||
<reference key="parent" ref="110575045"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">461</int>
|
||||
<reference key="object" ref="891014876"/>
|
||||
<reference key="parent" ref="835318025"/>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="flattenedProperties">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSMutableArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>-1.IBPluginDependency</string>
|
||||
<string>-2.IBPluginDependency</string>
|
||||
<string>-3.IBPluginDependency</string>
|
||||
<string>134.IBPluginDependency</string>
|
||||
<string>134.ImportedFromIB2</string>
|
||||
<string>136.IBPluginDependency</string>
|
||||
<string>136.ImportedFromIB2</string>
|
||||
<string>145.IBPluginDependency</string>
|
||||
<string>145.ImportedFromIB2</string>
|
||||
<string>149.IBPluginDependency</string>
|
||||
<string>149.ImportedFromIB2</string>
|
||||
<string>150.IBPluginDependency</string>
|
||||
<string>150.ImportedFromIB2</string>
|
||||
<string>19.IBPluginDependency</string>
|
||||
<string>19.ImportedFromIB2</string>
|
||||
<string>197.IBPluginDependency</string>
|
||||
<string>197.ImportedFromIB2</string>
|
||||
<string>198.IBPluginDependency</string>
|
||||
<string>198.ImportedFromIB2</string>
|
||||
<string>199.IBPluginDependency</string>
|
||||
<string>199.ImportedFromIB2</string>
|
||||
<string>203.IBPluginDependency</string>
|
||||
<string>203.ImportedFromIB2</string>
|
||||
<string>205.IBEditorWindowLastContentRect</string>
|
||||
<string>205.IBPluginDependency</string>
|
||||
<string>205.ImportedFromIB2</string>
|
||||
<string>205.editorWindowContentRectSynchronizationRect</string>
|
||||
<string>206.IBPluginDependency</string>
|
||||
<string>206.ImportedFromIB2</string>
|
||||
<string>207.IBPluginDependency</string>
|
||||
<string>207.ImportedFromIB2</string>
|
||||
<string>217.IBPluginDependency</string>
|
||||
<string>217.ImportedFromIB2</string>
|
||||
<string>236.IBPluginDependency</string>
|
||||
<string>236.ImportedFromIB2</string>
|
||||
<string>24.IBEditorWindowLastContentRect</string>
|
||||
<string>24.IBPluginDependency</string>
|
||||
<string>24.ImportedFromIB2</string>
|
||||
<string>24.editorWindowContentRectSynchronizationRect</string>
|
||||
<string>29.IBEditorWindowLastContentRect</string>
|
||||
<string>29.IBPluginDependency</string>
|
||||
<string>29.ImportedFromIB2</string>
|
||||
<string>29.WindowOrigin</string>
|
||||
<string>29.editorWindowContentRectSynchronizationRect</string>
|
||||
<string>449.IBPluginDependency</string>
|
||||
<string>449.ImportedFromIB2</string>
|
||||
<string>450.IBPluginDependency</string>
|
||||
<string>450.ImportedFromIB2</string>
|
||||
<string>451.IBPluginDependency</string>
|
||||
<string>458.IBPluginDependency</string>
|
||||
<string>458.ImportedFromIB2</string>
|
||||
<string>459.IBPluginDependency</string>
|
||||
<string>459.ImportedFromIB2</string>
|
||||
<string>461.IBPluginDependency</string>
|
||||
<string>56.IBPluginDependency</string>
|
||||
<string>56.ImportedFromIB2</string>
|
||||
<string>57.IBEditorWindowLastContentRect</string>
|
||||
<string>57.IBPluginDependency</string>
|
||||
<string>57.ImportedFromIB2</string>
|
||||
<string>57.editorWindowContentRectSynchronizationRect</string>
|
||||
<string>58.IBPluginDependency</string>
|
||||
<string>58.ImportedFromIB2</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<integer value="1" id="9"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>{{1422, 1180}, {243, 113}}</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>{{197, 734}, {243, 243}}</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>{{1548, 966}, {218, 63}}</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>{{525, 802}, {197, 73}}</string>
|
||||
<string>{{1295, 1029}, {390, 20}}</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>{74, 862}</string>
|
||||
<string>{{11, 977}, {478, 20}}</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<boolean value="YES" id="5"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="5"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="5"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>{{49, 388}, {312, 153}}</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>{{23, 794}, {245, 183}}</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="unlocalizedProperties">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
</object>
|
||||
<nil key="activeLocalization"/>
|
||||
<object class="NSMutableDictionary" key="localizations">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
</object>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">463</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">MainApp</string>
|
||||
<string key="superclassName">NSObject</string>
|
||||
<object class="NSMutableDictionary" key="actions">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSMutableArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>captureFrame:</string>
|
||||
<string>cut:</string>
|
||||
<string>paste:</string>
|
||||
<string>selectAll:</string>
|
||||
<string>showBatchViewer:</string>
|
||||
<string>showGLLayerSetup:</string>
|
||||
<string>toggleFullscreenMode:</string>
|
||||
<string>undo:</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>id</string>
|
||||
<string>id</string>
|
||||
<string>id</string>
|
||||
<string>id</string>
|
||||
<string>id</string>
|
||||
<string>id</string>
|
||||
<string>id</string>
|
||||
<string>id</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="outlets">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSMutableArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>captureFrameMenuItem</string>
|
||||
<string>showBatchViewerMenuItem</string>
|
||||
<string>showGLLayerSetupMenuItem</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>NSMenuItem</string>
|
||||
<string>NSMenuItem</string>
|
||||
<string>NSMenuItem</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">Source/MainApp.h</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">MainApp</string>
|
||||
<string key="superclassName">NSObject</string>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBUserSource</string>
|
||||
<string key="minorKey"/>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">NSObject</string>
|
||||
<object class="NSMutableDictionary" key="actions">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSMutableArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>didAdjustSubviews:</string>
|
||||
<string>willAdjustSubviews:</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>RBSplitView</string>
|
||||
<string>RBSplitView</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="35014534">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">../../../Engine/Source/Gx/CGxDeviceGLL/GLLayer/RBSplitView.h</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">RBSplitSubview</string>
|
||||
<string key="superclassName">NSView</string>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">../../../Engine/Source/Gx/CGxDeviceGLL/GLLayer/RBSplitSubview.h</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">RBSplitSubview</string>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="60681676">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">../../../Engine/Source/Gx/CGxDeviceGLL/GLLayer/RBSplitViewPrivateDefines.h</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">RBSplitView</string>
|
||||
<string key="superclassName">RBSplitSubview</string>
|
||||
<object class="NSMutableDictionary" key="outlets">
|
||||
<string key="NS.key.0">delegate</string>
|
||||
<string key="NS.object.0">id</string>
|
||||
</object>
|
||||
<reference key="sourceIdentifier" ref="35014534"/>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">RBSplitView</string>
|
||||
<reference key="sourceIdentifier" ref="60681676"/>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">StackTableView</string>
|
||||
<string key="superclassName">NSTableView</string>
|
||||
<object class="NSMutableDictionary" key="actions">
|
||||
<string key="NS.key.0">copy:</string>
|
||||
<string key="NS.object.0">id</string>
|
||||
</object>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">../../../Engine/Source/Gx/CGxDeviceGLL/GLLayer/StackCrawlViewer.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.LastKnownRelativeProjectPath">../../WoW.xcodeproj</string>
|
||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||
</data>
|
||||
</archive>
|
BIN
src/app/mac/MainMenu.nib/keyedobjects.nib
generated
Executable file
BIN
src/app/mac/MainMenu.nib/keyedobjects.nib
generated
Executable file
Binary file not shown.
126
src/app/mac/MainMenu.xib
Normal file
126
src/app/mac/MainMenu.xib
Normal file
@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="15G19009" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment version="1030" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<outlet property="delegate" destination="451" id="452"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application"/>
|
||||
<menu title="AMainMenu" systemMenu="main" id="29" userLabel="Main Menu">
|
||||
<items>
|
||||
<menuItem title="World of Warcraft" id="56">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="World of Warcraft" systemMenu="apple" id="57">
|
||||
<items>
|
||||
<menuItem title="MENU_ABOUT" id="58">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="236"/>
|
||||
<menuItem title="MENU_SWITCH_TO_FULLSCREEN" keyEquivalent="m" id="458">
|
||||
<connections>
|
||||
<action selector="toggleFullscreenMode:" target="451" id="460"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="459"/>
|
||||
<menuItem title="MENU_HIDE" keyEquivalent="h" id="134">
|
||||
<connections>
|
||||
<action selector="hide:" target="-1" id="367"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="MENU_HIDE_OTHERS" keyEquivalent="h" id="145">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="-1" id="368"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="MENU_SHOW_ALL" id="150">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="-1" id="370"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="149"/>
|
||||
<menuItem title="MENU_QUIT" keyEquivalent="q" id="136">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="terminate:" target="-1" id="369"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="MENU_EDIT" id="217">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="MENU_EDIT" id="205">
|
||||
<items>
|
||||
<menuItem title="MENU_UNDO" keyEquivalent="z" id="207">
|
||||
<connections>
|
||||
<action selector="undo:" target="-1" id="223"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="206"/>
|
||||
<menuItem title="MENU_EDIT_CUT" keyEquivalent="x" id="199">
|
||||
<connections>
|
||||
<action selector="cut:" target="-1" id="228"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="MENU_EDIT_COPY" keyEquivalent="c" id="197">
|
||||
<connections>
|
||||
<action selector="copy:" target="-1" id="224"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="MENU_EDIT_PASTE" keyEquivalent="v" id="203">
|
||||
<connections>
|
||||
<action selector="paste:" target="-1" id="226"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="MENU_EDIT_SELECT_ALL" keyEquivalent="a" id="198">
|
||||
<connections>
|
||||
<action selector="selectAll:" target="-1" id="232"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="MENU_WINDOW" id="19">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="MENU_WINDOW" systemMenu="window" id="24">
|
||||
<items>
|
||||
<menuItem title="Show Batch Viewer" id="449">
|
||||
<connections>
|
||||
<action selector="showBatchViewer:" target="451" id="455"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show GL Layer Setup" id="450">
|
||||
<connections>
|
||||
<action selector="showGLLayerSetup:" target="451" id="454"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Capture Frame" keyEquivalent="r" id="461">
|
||||
<connections>
|
||||
<action selector="captureFrame:" target="451" id="463"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<customObject id="451" userLabel="MainApp" customClass="MainApp">
|
||||
<connections>
|
||||
<outlet property="captureFrameMenuItem" destination="461" id="462"/>
|
||||
<outlet property="showBatchViewerMenuItem" destination="449" id="456"/>
|
||||
<outlet property="showGLLayerSetupMenuItem" destination="450" id="457"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
</objects>
|
||||
</document>
|
12
src/app/mac/View.h
Normal file
12
src/app/mac/View.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef APP_MAC_VIEW_H
|
||||
#define APP_MAC_VIEW_H
|
||||
|
||||
#include <objc/objc-runtime.h>
|
||||
|
||||
struct GLWindowCallbacks;
|
||||
|
||||
void AssignEngineViewCallbacks(GLWindowCallbacks*);
|
||||
|
||||
Class GetEngineViewClass(void);
|
||||
|
||||
#endif
|
27
src/app/mac/View.mm
Normal file
27
src/app/mac/View.mm
Normal file
@ -0,0 +1,27 @@
|
||||
#include "app/mac/View.h"
|
||||
#include "app/mac/EngineGLLayerView.h"
|
||||
#include "app/mac/WindowCallbacks.h"
|
||||
#include "gx/gll/GLWindow.h"
|
||||
|
||||
GLWindowCallbacks EngineViewCallbacks = {
|
||||
&MacOnResized,
|
||||
&MacOnMouseDown,
|
||||
&MacOnMouseMoved,
|
||||
&MacOnMouseUp,
|
||||
&MacOnKeyDown,
|
||||
&MacOnKeyUp
|
||||
};
|
||||
|
||||
void AssignEngineViewCallbacks(GLWindowCallbacks* callbacks) {
|
||||
*callbacks = EngineViewCallbacks;
|
||||
|
||||
// TODO
|
||||
// (callbacks + 100) = 0;
|
||||
|
||||
// TODO
|
||||
// dword_12B9F54 = sub_A15850;
|
||||
}
|
||||
|
||||
Class GetEngineViewClass() {
|
||||
return [EngineGLLayerView class];
|
||||
}
|
41
src/app/mac/Whoa.mm
Normal file
41
src/app/mac/Whoa.mm
Normal file
@ -0,0 +1,41 @@
|
||||
#include "app/mac/WoWApplication.h"
|
||||
#include "app/mac/MacClient.h"
|
||||
#include "client/Client.hpp"
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
int32_t main(int32_t argc, char* argv[]) {
|
||||
// TODO
|
||||
// MacClient::SetupCommandLine(argc, argv, v10);
|
||||
|
||||
if (MacClient::IsUsingGLLayer()) {
|
||||
// TODO
|
||||
// GxSetRequestedApi(3);
|
||||
|
||||
// TODO
|
||||
// OsInputSetIsUsingCocoaEventLoop(1);
|
||||
|
||||
[WoWApplication sharedApplication];
|
||||
|
||||
#if WHOA_SYSTEM_VERSION < WHOA_MACOS_10_8
|
||||
[NSBundle
|
||||
loadNibNamed: @"MainMenu"
|
||||
owner: NSApp];
|
||||
#endif
|
||||
|
||||
#if WHOA_SYSTEM_VERSION >= WHOA_MACOS_10_8
|
||||
[[NSBundle mainBundle]
|
||||
loadNibNamed: @"MainMenu"
|
||||
owner: NSApp
|
||||
topLevelObjects: nil];
|
||||
#endif
|
||||
|
||||
[NSRunLoop currentRunLoop];
|
||||
|
||||
[NSApp mainMenu];
|
||||
|
||||
CommonMain();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
19
src/app/mac/WindowCallbacks.h
Normal file
19
src/app/mac/WindowCallbacks.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef APP_MAC_WINDOW_CALLBACKS_H
|
||||
#define APP_MAC_WINDOW_CALLBACKS_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
void MacOnKeyDown(NSEvent*);
|
||||
|
||||
void MacOnKeyUp(NSEvent*);
|
||||
|
||||
void MacOnMouseDown(int16_t, int32_t, int32_t);
|
||||
|
||||
void MacOnMouseMoved(int32_t, int32_t);
|
||||
|
||||
void MacOnMouseUp(int16_t, int32_t, int32_t);
|
||||
|
||||
void MacOnResized(int32_t width, int32_t height, bool a3);
|
||||
|
||||
#endif
|
188
src/app/mac/WindowCallbacks.mm
Normal file
188
src/app/mac/WindowCallbacks.mm
Normal file
@ -0,0 +1,188 @@
|
||||
#include "app/mac/WindowCallbacks.h"
|
||||
#include "app/mac/MacClient.h"
|
||||
#include "event/Input.hpp"
|
||||
#include "gx/gll/CGxDeviceGLL.hpp"
|
||||
#include "gx/Device.hpp"
|
||||
#include "gx/Window.hpp"
|
||||
#include "util/BlizzardCore.hpp"
|
||||
|
||||
void MacOnKeyDown(NSEvent* event) {
|
||||
BLIZZARD_ASSERT(false);
|
||||
}
|
||||
|
||||
void MacOnKeyUp(NSEvent* event) {
|
||||
uint32_t keyCode = event.keyCode;
|
||||
|
||||
MacClient::CheckKeyboardLayout();
|
||||
|
||||
if (keyCode <= 0x7F) {
|
||||
uint32_t key = MacClient::s_keyConversion[keyCode];
|
||||
|
||||
if (key != KEY_NONE) {
|
||||
OsQueuePut(OS_INPUT_KEY_UP, key, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MacOnMouseDown(int16_t button, int32_t x, int32_t y) {
|
||||
NSEvent* event = [NSApp currentEvent];
|
||||
uint32_t modifierFlags = event.modifierFlags;
|
||||
|
||||
uint32_t v8 = 0;
|
||||
|
||||
if (modifierFlags & NSShiftKeyMask) {
|
||||
v8 |= 0x2;
|
||||
}
|
||||
|
||||
if (modifierFlags & NSAlternateKeyMask) {
|
||||
v8 |= 0x8;
|
||||
}
|
||||
|
||||
if (modifierFlags & NSCommandKeyMask) {
|
||||
v8 |= 0x1;
|
||||
}
|
||||
|
||||
if (modifierFlags & NSControlKeyMask) {
|
||||
v8 |= 0x10;
|
||||
}
|
||||
|
||||
if (modifierFlags & NSAlphaShiftKeyMask) {
|
||||
v8 |= 0x4;
|
||||
}
|
||||
|
||||
int16_t buttonNumber = button + 1;
|
||||
int16_t buttonIndex = button;
|
||||
|
||||
if (buttonNumber > 0xF) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Input::s_buttonDown[buttonIndex]) {
|
||||
return;
|
||||
}
|
||||
|
||||
int16_t effectiveButtonNumber = buttonNumber;
|
||||
|
||||
Input::s_buttonDown[buttonIndex] = 1;
|
||||
|
||||
if (buttonNumber == 1) {
|
||||
effectiveButtonNumber = 1;
|
||||
|
||||
if (v8 & 0x1) {
|
||||
Input::s_simulatedRightButtonClick = 1;
|
||||
|
||||
// TODO
|
||||
// if (Input::byte_12B94E2) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
effectiveButtonNumber = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (buttonNumber == 2) {
|
||||
if (Input::s_simulatedRightButtonClick) {
|
||||
return;
|
||||
} else {
|
||||
effectiveButtonNumber = 2;
|
||||
}
|
||||
}
|
||||
|
||||
MOUSEBUTTON mouseButton = ConvertButtonNumberToMOUSEBUTTON(effectiveButtonNumber);
|
||||
|
||||
if (mouseButton) {
|
||||
if (Input::s_mouseMode == 0) {
|
||||
Input::s_currentMouse = { x, y };
|
||||
}
|
||||
|
||||
OsQueuePut(OS_INPUT_MOUSE_DOWN, mouseButton, x, y, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void MacOnMouseMoved(int32_t x, int32_t y) {
|
||||
if (Input::s_mouseMode == 1) {
|
||||
NSEvent* event = [NSApp currentEvent];
|
||||
|
||||
int32_t deltaX = static_cast<int32_t>(floor(event.deltaX));
|
||||
int32_t deltaY = static_cast<int32_t>(floor(event.deltaY));
|
||||
|
||||
OsQueuePut(OS_INPUT_MOUSE_MOVE_RELATIVE, 0, deltaX, deltaY, 0);
|
||||
} else {
|
||||
Input::s_currentMouse = { x, y };
|
||||
|
||||
OsQueuePut(OS_INPUT_MOUSE_MOVE, 0, x, y, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void MacOnMouseUp(int16_t button, int32_t x, int32_t y) {
|
||||
NSEvent* event = [NSApp currentEvent];
|
||||
uint32_t modifierFlags = event.modifierFlags;
|
||||
|
||||
int16_t buttonNumber = button + 1;
|
||||
int16_t buttonIndex = button;
|
||||
|
||||
if (buttonNumber > 0xF) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Input::s_buttonDown[buttonIndex]) {
|
||||
return;
|
||||
}
|
||||
|
||||
int16_t effectiveButtonNumber = buttonNumber;
|
||||
|
||||
Input::s_buttonDown[buttonIndex] = 0;
|
||||
|
||||
if (buttonNumber == 1) {
|
||||
effectiveButtonNumber = 1;
|
||||
|
||||
if (Input::s_simulatedRightButtonClick) {
|
||||
effectiveButtonNumber = 2;
|
||||
Input::s_simulatedRightButtonClick = 0;
|
||||
|
||||
// TODO
|
||||
// if (Input::byte_12B94E2) {
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
if (buttonNumber == 2) {
|
||||
if (Input::s_simulatedRightButtonClick) {
|
||||
return;
|
||||
} else {
|
||||
effectiveButtonNumber = 2;
|
||||
}
|
||||
}
|
||||
|
||||
MOUSEBUTTON mouseButton = ConvertButtonNumberToMOUSEBUTTON(effectiveButtonNumber);
|
||||
|
||||
if (mouseButton) {
|
||||
if (Input::s_mouseMode != 0) {
|
||||
Input::s_currentMouse = { x, y };
|
||||
}
|
||||
|
||||
OsQueuePut(OS_INPUT_MOUSE_UP, mouseButton, x, y, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void MacOnResized(int32_t width, int32_t height, bool a3) {
|
||||
if (a3) {
|
||||
return;
|
||||
}
|
||||
|
||||
static_cast<CGxDeviceGLL*>(g_theGxDevicePtr)->Resize(width, height);
|
||||
|
||||
OsQueuePut(OS_INPUT_SIZE, width, height, 0, 0);
|
||||
|
||||
// TODO SubA61E60(width, height)
|
||||
|
||||
auto bounds = GetSavedWindowBounds();
|
||||
Rect newBounds = {
|
||||
bounds->top,
|
||||
bounds->left,
|
||||
static_cast<int16_t>(bounds->top + height),
|
||||
static_cast<int16_t>(bounds->left + width)
|
||||
};
|
||||
SetSavedWindowBounds(newBounds);
|
||||
}
|
11
src/app/mac/WoWApplication.h
Normal file
11
src/app/mac/WoWApplication.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef APP_MAC_WOW_APPLICATION_H
|
||||
#define APP_MAC_WOW_APPLICATION_H
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
@interface WoWApplication : NSApplication
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
24
src/app/mac/WoWApplication.mm
Normal file
24
src/app/mac/WoWApplication.mm
Normal file
@ -0,0 +1,24 @@
|
||||
#include "app/mac/WoWApplication.h"
|
||||
#include "gx/gll/GLLayerView.h"
|
||||
|
||||
@implementation WoWApplication
|
||||
|
||||
- (void)sendEvent:(NSEvent*)event {
|
||||
auto responder = [[NSApp keyWindow] firstResponder];
|
||||
|
||||
if (responder && [responder isKindOfClass: [GLLayerView class]]) {
|
||||
NSEventType type = [event type];
|
||||
|
||||
if (type == NSKeyDown && (event.keyCode == 114 || (event.keyCode == 48 && event.modifierFlags & NSControlKeyMask))) {
|
||||
[responder keyDown: event];
|
||||
return;
|
||||
} else if (type == NSKeyUp) {
|
||||
[responder keyUp: event];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
[super sendEvent:event];
|
||||
}
|
||||
|
||||
@end
|
143
src/async/AsyncFile.cpp
Normal file
143
src/async/AsyncFile.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
#include "async/AsyncFile.hpp"
|
||||
#include "async/AsyncFileRead.hpp"
|
||||
#include "async/CAsyncQueue.hpp"
|
||||
#include "event/Event.hpp"
|
||||
#include "util/SFile.hpp"
|
||||
#include <common/Prop.hpp>
|
||||
#include <common/Time.hpp>
|
||||
|
||||
CAsyncObject* AsyncFileReadAllocObject() {
|
||||
AsyncFileRead::s_queueLock.Enter();
|
||||
|
||||
CAsyncObject* object = AsyncFileRead::s_asyncFileReadFreeList.Head();
|
||||
|
||||
if (!object) {
|
||||
object = AsyncFileRead::s_asyncFileReadFreeList.NewNode(1, 0, 0x0);
|
||||
}
|
||||
|
||||
object->link.Unlink();
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
|
||||
object->file = nullptr;
|
||||
object->buffer = nullptr;
|
||||
object->size = 0;
|
||||
object->userArg = nullptr;
|
||||
object->userPostloadCallback = nullptr;
|
||||
object->userFailedCallback = nullptr;
|
||||
object->queue = nullptr;
|
||||
object->isProcessed = 0;
|
||||
object->isRead = 0;
|
||||
object->isCurrent = 0;
|
||||
object->char24 = 0;
|
||||
object->char25 = 0;
|
||||
object->ptr1C = 0;
|
||||
object->priority = 126;
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
void AsyncFileReadDestroyObject(CAsyncObject* object) {
|
||||
AsyncFileRead::s_queueLock.Enter();
|
||||
|
||||
if (object->isCurrent) {
|
||||
// TODO
|
||||
// nullsub_3();
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
|
||||
while (object->isCurrent) {
|
||||
OsSleep(1);
|
||||
}
|
||||
|
||||
AsyncFileRead::s_queueLock.Enter();
|
||||
}
|
||||
|
||||
object->link.Unlink();
|
||||
|
||||
if (object->file) {
|
||||
SFile::Close(object->file);
|
||||
}
|
||||
|
||||
AsyncFileRead::s_asyncFileReadFreeList.LinkToHead(object);
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
}
|
||||
|
||||
void AsyncFileReadInitialize(uint32_t threadSleep, uint32_t handlerTimeout) {
|
||||
AsyncFileRead::s_threadSleep = std::min(threadSleep, 100u);
|
||||
AsyncFileRead::s_handlerTimeout = std::max(handlerTimeout, 20u);
|
||||
|
||||
EventRegisterEx(EVENT_ID_POLL, &AsyncFileReadPollHandler, nullptr, 0.0f);
|
||||
if (SFile::IsStreamingMode()) {
|
||||
// TODO
|
||||
// EventRegisterEx(EVENT_ID_IDLE, &Sub4B9F40, nullptr, -1.0f);
|
||||
}
|
||||
|
||||
AsyncFileRead::s_asyncWaitObject = nullptr;
|
||||
AsyncFileRead::s_progressCallback = nullptr;
|
||||
AsyncFileRead::s_progressParam = nullptr;
|
||||
AsyncFileRead::s_ingameProgressCallback = nullptr;
|
||||
AsyncFileRead::s_ingameStartCallback = nullptr;
|
||||
AsyncFileRead::s_propContext = PropGetSelectedContext();
|
||||
|
||||
AsyncFileRead::s_shutdownEvent.Reset();
|
||||
|
||||
int32_t numQueues = SFile::IsStreamingMode() != 0 ? 3 : 1;
|
||||
for (int32_t i = 0; i < numQueues; i++) {
|
||||
CAsyncQueue* queue = AsyncFileReadCreateQueue();
|
||||
const char* queueName = AsyncFileRead::s_asyncQueueNames[i];
|
||||
|
||||
AsyncFileRead::s_asyncQueues[i] = queue;
|
||||
AsyncFileReadCreateThread(queue, queueName);
|
||||
}
|
||||
|
||||
if (SFile::IsStreamingMode()) {
|
||||
AsyncFileRead::s_asyncQueues[2]->int20 = 1;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// - Something related to AsyncFileRead::s_userQueueLock
|
||||
}
|
||||
|
||||
void AsyncFileReadObject(CAsyncObject* object, int32_t a2) {
|
||||
CAsyncQueue* queue = AsyncFileRead::s_asyncQueues[0];
|
||||
|
||||
if (SFile::IsStreamingMode()) {
|
||||
// TODO
|
||||
// int32_t v3 = SFile::FileIsLocal(object->file, 6);
|
||||
//
|
||||
// if (!v3 || v3 == 2) {
|
||||
// int32_t v4 = object->priority <= 127;
|
||||
// object->char24 = 1;
|
||||
// queue = AsyncFileRead::s_asyncQueues[1];
|
||||
//
|
||||
// if (!v4) {
|
||||
// queue = AsyncFileRead::s_asyncQueues[2];
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
AsyncFileRead::s_queueLock.Enter();
|
||||
|
||||
object->queue = queue;
|
||||
|
||||
if (AsyncFileRead::s_asyncWaitObject == object) {
|
||||
object->priority = object->priority > 127 ? 128 : 0;
|
||||
// TODO
|
||||
// object->ptr1C = g_theGxDevicePtr + 3944;
|
||||
object->char25 = 0;
|
||||
} else if (queue->int20) {
|
||||
// TODO
|
||||
// Sub4BA530(object, a2);
|
||||
} else {
|
||||
AsyncFileReadLinkObject(object, a2);
|
||||
}
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
|
||||
if (SFile::IsStreamingMode()) {
|
||||
// TODO
|
||||
// SFile::LogFileAccess(object->file, 0, 0);
|
||||
}
|
||||
}
|
14
src/async/AsyncFile.hpp
Normal file
14
src/async/AsyncFile.hpp
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef ASYNC_ASYNC_FILE_HPP
|
||||
#define ASYNC_ASYNC_FILE_HPP
|
||||
|
||||
#include "async/CAsyncObject.hpp"
|
||||
|
||||
CAsyncObject* AsyncFileReadAllocObject(void);
|
||||
|
||||
void AsyncFileReadDestroyObject(CAsyncObject* object);
|
||||
|
||||
void AsyncFileReadInitialize(uint32_t threadSleep, uint32_t handlerTimeout);
|
||||
|
||||
void AsyncFileReadObject(CAsyncObject* object, int32_t a2);
|
||||
|
||||
#endif
|
196
src/async/AsyncFileRead.cpp
Normal file
196
src/async/AsyncFileRead.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
#include "async/AsyncFileRead.hpp"
|
||||
#include "util/SFile.hpp"
|
||||
#include <common/Prop.hpp>
|
||||
#include <common/Time.hpp>
|
||||
|
||||
uint32_t AsyncFileRead::s_threadSleep;
|
||||
uint32_t AsyncFileRead::s_handlerTimeout = 100;
|
||||
CAsyncObject* AsyncFileRead::s_asyncWaitObject;
|
||||
void* AsyncFileRead::s_progressCallback;
|
||||
void* AsyncFileRead::s_progressParam;
|
||||
int32_t AsyncFileRead::s_progressCount;
|
||||
void* AsyncFileRead::s_ingameProgressCallback;
|
||||
void* AsyncFileRead::s_ingameStartCallback;
|
||||
void* AsyncFileRead::s_propContext;
|
||||
SEvent AsyncFileRead::s_shutdownEvent = SEvent(1, 0);
|
||||
const char* AsyncFileRead::s_asyncQueueNames[NUM_ASYNC_QUEUES] = {
|
||||
"Disk Queue",
|
||||
"Net Geometry Queue",
|
||||
"Net Texture Queue"
|
||||
};
|
||||
CAsyncQueue* AsyncFileRead::s_asyncQueues[NUM_ASYNC_QUEUES];
|
||||
SCritSect AsyncFileRead::s_queueLock;
|
||||
SCritSect AsyncFileRead::s_userQueueLock;
|
||||
TSList<CAsyncQueue, TSGetLink<CAsyncQueue>> AsyncFileRead::s_asyncQueueList;
|
||||
TSList<CAsyncThread, TSGetLink<CAsyncThread>> AsyncFileRead::s_asyncThreadList;
|
||||
STORM_EXPLICIT_LIST(CAsyncObject, link) AsyncFileRead::s_asyncFileReadPostList;
|
||||
STORM_EXPLICIT_LIST(CAsyncObject, link) AsyncFileRead::s_asyncFileReadFreeList;
|
||||
|
||||
CAsyncQueue* AsyncFileReadCreateQueue() {
|
||||
CAsyncQueue* queue = AsyncFileRead::s_asyncQueueList.NewNode(0, 2, 0x8);
|
||||
return queue;
|
||||
}
|
||||
|
||||
void AsyncFileReadCreateThread(CAsyncQueue* queue, const char* queueName) {
|
||||
CAsyncThread* thread = AsyncFileRead::s_asyncThreadList.NewNode(0, 2, 0x8);
|
||||
|
||||
thread->queue = queue;
|
||||
thread->currentObject = nullptr;
|
||||
|
||||
SThread::Create(AsyncFileReadThread, thread, thread->thread, const_cast<char*>(queueName), 0);
|
||||
}
|
||||
|
||||
void AsyncFileReadLinkObject(CAsyncObject* object, int32_t a2) {
|
||||
if (!object->queue) {
|
||||
return;
|
||||
}
|
||||
|
||||
object->link.Unlink();
|
||||
|
||||
auto& readList = object->queue->readList;
|
||||
|
||||
for (auto currentObject = readList.Head(); currentObject; currentObject = readList.Link(currentObject)->Next()) {
|
||||
uint8_t priority = object->priority;
|
||||
uint8_t currentPriority = currentObject->priority;
|
||||
|
||||
if (priority <= currentPriority && (a2 || priority != currentPriority)) {
|
||||
readList.LinkNode(object, 2, currentObject);
|
||||
object->char25 = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
readList.LinkToTail(object);
|
||||
object->char25 = 0;
|
||||
}
|
||||
|
||||
int32_t AsyncFileReadPollHandler(const void*, void*) {
|
||||
uint32_t start = OsGetAsyncTimeMsPrecise();
|
||||
|
||||
while (1) {
|
||||
AsyncFileRead::s_queueLock.Enter();
|
||||
|
||||
CAsyncObject* object = AsyncFileRead::s_asyncFileReadPostList.Head();
|
||||
|
||||
if (!object) {
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
break;
|
||||
}
|
||||
|
||||
AsyncFileRead::s_asyncFileReadPostList.UnlinkNode(object);
|
||||
|
||||
if (AsyncFileRead::s_asyncWaitObject == object) {
|
||||
AsyncFileRead::s_asyncWaitObject = nullptr;
|
||||
}
|
||||
|
||||
object->isProcessed = 1;
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
|
||||
object->userPostloadCallback(object->userArg);
|
||||
|
||||
AsyncFileRead::s_progressCount--;
|
||||
|
||||
// Check if we're exceeded the allowed running time
|
||||
if (OsGetAsyncTimeMsPrecise() - start > AsyncFileRead::s_handlerTimeout) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
// for (int32_t i = 0; i < DwordB4A224; i++) {
|
||||
// DwordB4A228[i]();
|
||||
// }
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t AsyncFileReadThread(void* param) {
|
||||
CAsyncThread* thread = static_cast<CAsyncThread*>(param);
|
||||
|
||||
PropSelectContext(AsyncFileRead::s_propContext);
|
||||
|
||||
while (AsyncFileRead::s_shutdownEvent.Wait(0)) {
|
||||
uint32_t sleep = 0;
|
||||
CAsyncObject* object;
|
||||
|
||||
while (1) {
|
||||
AsyncFileRead::s_queueLock.Enter();
|
||||
|
||||
object = thread->queue->readList.Head();
|
||||
|
||||
if (object && thread->queue->int20 && /* TODO */ true) {
|
||||
// TODO
|
||||
// Sub4BA530(object, 1);
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!object) {
|
||||
object = thread->queue->list14.Head();
|
||||
}
|
||||
|
||||
if (!object) {
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
break;
|
||||
}
|
||||
|
||||
object->link.Unlink();
|
||||
object->queue = nullptr;
|
||||
object->isCurrent = 1;
|
||||
thread->currentObject = object;
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
|
||||
int32_t tries = 10;
|
||||
while (1) {
|
||||
if (SFile::IsStreamingMode() && object->file) {
|
||||
// TODO
|
||||
// Sub421820(object->file, (object->priority > 127) + 1, 1);
|
||||
}
|
||||
|
||||
if (SFile::Read(object->file, object->buffer, object->size, nullptr, nullptr, nullptr)) {
|
||||
break;
|
||||
}
|
||||
|
||||
tries--;
|
||||
|
||||
// Handle failure
|
||||
if (tries == 0) {
|
||||
// TODO
|
||||
// Sub421850((object->file, v17, 512);
|
||||
// v10 = Sub7717E0();
|
||||
// Sub771A80(v10, v18, 512);
|
||||
// nullsub_3(v17);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AsyncFileRead::s_queueLock.Enter();
|
||||
|
||||
AsyncFileRead::s_asyncFileReadPostList.LinkToTail(object);
|
||||
|
||||
thread->currentObject = nullptr;
|
||||
object->isCurrent = 0;
|
||||
object->isRead = 1;
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
|
||||
if (AsyncFileRead::s_threadSleep) {
|
||||
sleep++;
|
||||
|
||||
if (sleep == AsyncFileRead::s_threadSleep) {
|
||||
OsSleep(1);
|
||||
sleep = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OsSleep(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
46
src/async/AsyncFileRead.hpp
Normal file
46
src/async/AsyncFileRead.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef ASYNC_ASYNC_FILE_READ_HPP
|
||||
#define ASYNC_ASYNC_FILE_READ_HPP
|
||||
|
||||
#include "async/CAsyncQueue.hpp"
|
||||
#include "async/CAsyncThread.hpp"
|
||||
#include <common/Prop.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
#define NUM_ASYNC_QUEUES 3
|
||||
|
||||
class CAsyncObject;
|
||||
|
||||
class AsyncFileRead {
|
||||
public:
|
||||
// Static variables
|
||||
static uint32_t s_threadSleep;
|
||||
static uint32_t s_handlerTimeout;
|
||||
static CAsyncObject* s_asyncWaitObject;
|
||||
static void* s_progressCallback;
|
||||
static void* s_progressParam;
|
||||
static int32_t s_progressCount;
|
||||
static void* s_ingameProgressCallback;
|
||||
static void* s_ingameStartCallback;
|
||||
static HPROPCONTEXT s_propContext;
|
||||
static SEvent s_shutdownEvent;
|
||||
static const char* s_asyncQueueNames[];
|
||||
static CAsyncQueue* s_asyncQueues[];
|
||||
static SCritSect s_queueLock;
|
||||
static SCritSect s_userQueueLock;
|
||||
static TSList<CAsyncQueue, TSGetLink<CAsyncQueue>> s_asyncQueueList;
|
||||
static TSList<CAsyncThread, TSGetLink<CAsyncThread>> s_asyncThreadList;
|
||||
static STORM_EXPLICIT_LIST(CAsyncObject, link) s_asyncFileReadPostList;
|
||||
static STORM_EXPLICIT_LIST(CAsyncObject, link) s_asyncFileReadFreeList;
|
||||
};
|
||||
|
||||
CAsyncQueue* AsyncFileReadCreateQueue(void);
|
||||
|
||||
void AsyncFileReadCreateThread(CAsyncQueue* queue, const char* queueName);
|
||||
|
||||
void AsyncFileReadLinkObject(CAsyncObject* object, int32_t a2);
|
||||
|
||||
int32_t AsyncFileReadPollHandler(const void*, void*);
|
||||
|
||||
uint32_t AsyncFileReadThread(void* thread);
|
||||
|
||||
#endif
|
30
src/async/CAsyncObject.hpp
Normal file
30
src/async/CAsyncObject.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef ASYNC_C_ASYNC_OBJECT_HPP
|
||||
#define ASYNC_C_ASYNC_OBJECT_HPP
|
||||
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class SFile;
|
||||
class CAsyncQueue;
|
||||
|
||||
class CAsyncObject {
|
||||
public:
|
||||
// Member variables
|
||||
SFile* file;
|
||||
void* buffer;
|
||||
uint32_t size;
|
||||
void* userArg;
|
||||
void (*userPostloadCallback)(void*);
|
||||
void (*userFailedCallback)(void*);
|
||||
CAsyncQueue* queue;
|
||||
void* ptr1C;
|
||||
uint8_t priority;
|
||||
uint8_t isProcessed;
|
||||
uint8_t isRead;
|
||||
uint8_t isCurrent;
|
||||
uint8_t char24;
|
||||
uint8_t char25;
|
||||
uint8_t padding[2];
|
||||
TSLink<CAsyncObject> link;
|
||||
};
|
||||
|
||||
#endif
|
16
src/async/CAsyncQueue.hpp
Normal file
16
src/async/CAsyncQueue.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef ASYNC_C_ASYNC_QUEUE_HPP
|
||||
#define ASYNC_C_ASYNC_QUEUE_HPP
|
||||
|
||||
#include "async/CAsyncObject.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class CAsyncQueue : public TSLinkedNode<CAsyncQueue> {
|
||||
public:
|
||||
// Member variables
|
||||
STORM_EXPLICIT_LIST(CAsyncObject, link) readList;
|
||||
STORM_EXPLICIT_LIST(CAsyncObject, link) list14;
|
||||
int32_t int20;
|
||||
};
|
||||
|
||||
#endif
|
19
src/async/CAsyncThread.hpp
Normal file
19
src/async/CAsyncThread.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef ASYNC_C_ASYNC_THREAD_HPP
|
||||
#define ASYNC_C_ASYNC_THREAD_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <storm/List.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
class CAsyncObject;
|
||||
class CAsyncQueue;
|
||||
|
||||
class CAsyncThread : public TSLinkedNode<CAsyncThread> {
|
||||
public:
|
||||
// Member variables
|
||||
SThread thread;
|
||||
CAsyncQueue* queue;
|
||||
CAsyncObject* currentObject;
|
||||
};
|
||||
|
||||
#endif
|
19
src/async/CMakeLists.txt
Normal file
19
src/async/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
file(GLOB PRIVATE_SOURCES "*.cpp")
|
||||
|
||||
add_library(async STATIC
|
||||
${PRIVATE_SOURCES}
|
||||
)
|
||||
|
||||
target_include_directories(async
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
target_link_libraries(async
|
||||
PRIVATE
|
||||
event
|
||||
util
|
||||
PUBLIC
|
||||
common
|
||||
storm
|
||||
)
|
25
src/client/CMakeLists.txt
Normal file
25
src/client/CMakeLists.txt
Normal file
@ -0,0 +1,25 @@
|
||||
file(GLOB PRIVATE_SOURCES "*.cpp")
|
||||
|
||||
add_library(client STATIC
|
||||
${PRIVATE_SOURCES}
|
||||
)
|
||||
|
||||
target_include_directories(client
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
target_link_libraries(client
|
||||
PRIVATE
|
||||
async
|
||||
event
|
||||
gx
|
||||
model
|
||||
net
|
||||
ui
|
||||
util
|
||||
world
|
||||
PUBLIC
|
||||
common
|
||||
storm
|
||||
)
|
437
src/client/Client.cpp
Normal file
437
src/client/Client.cpp
Normal file
@ -0,0 +1,437 @@
|
||||
#include "client/Client.hpp"
|
||||
#include "client/ClientServices.hpp"
|
||||
#include "client/Console.hpp"
|
||||
#include "async/AsyncFile.hpp"
|
||||
#include "glue/CGlueMgr.hpp"
|
||||
#include "gx/Device.hpp"
|
||||
#include "gx/Screen.hpp"
|
||||
#include "gx/Texture.hpp"
|
||||
#include "model/Model2.hpp"
|
||||
#include "ui/FrameScript.hpp"
|
||||
#include "ui/FrameXML.hpp"
|
||||
#include "util/BlizzardCore.hpp"
|
||||
#include "util/CVar.hpp"
|
||||
#include "world/World.hpp"
|
||||
#include <cstring>
|
||||
#include <common/Prop.hpp>
|
||||
#include <storm/Error.hpp>
|
||||
|
||||
CVar* Client::g_accountListVar;
|
||||
HEVENTCONTEXT Client::g_clientEventContext;
|
||||
|
||||
void AsyncFileInitialize() {
|
||||
// TODO
|
||||
AsyncFileReadInitialize(0, 100);
|
||||
}
|
||||
|
||||
void BaseInitializeGlobal() {
|
||||
PropInitialize();
|
||||
}
|
||||
|
||||
void ClientMiscInitialize() {
|
||||
// TODO
|
||||
|
||||
Client::g_accountListVar = CVar::Register(
|
||||
"accountList",
|
||||
"List of wow accounts for saved Blizzard account",
|
||||
0,
|
||||
"",
|
||||
nullptr,
|
||||
4,
|
||||
false,
|
||||
nullptr,
|
||||
false
|
||||
);
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void ClientPostClose(int32_t a1) {
|
||||
// TODO s_finalDialog = a1;
|
||||
EventPostCloseEx(nullptr);
|
||||
}
|
||||
|
||||
int32_t DestroyEngineCallback(const void* a1, void* a2) {
|
||||
// TODO
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t InitializeEngineCallback(const void* a1, void* a2) {
|
||||
// TODO
|
||||
// sub_4D2A30();
|
||||
|
||||
AsyncFileInitialize();
|
||||
TextureInitialize();
|
||||
|
||||
// ModelBlobLoad("world\\model.blob");
|
||||
|
||||
// if (SFile::IsStreamingMode()) {
|
||||
// TextureLoadBlob("world\\liquid.tex");
|
||||
// }
|
||||
|
||||
ScrnInitialize(0);
|
||||
// ConsoleScreenInitialize(a2);
|
||||
|
||||
// s_cvarTextureFilteringMode = CVar::Register(
|
||||
// "textureFilteringMode",
|
||||
// "Texture filtering mode",
|
||||
// 1,
|
||||
// "1",
|
||||
// &TextureFilteringCallback,
|
||||
// 1,
|
||||
// 0,
|
||||
// 0,
|
||||
// 0
|
||||
// );
|
||||
|
||||
// s_cvarUIFaster = CVar::Register(
|
||||
// "UIFaster",
|
||||
// "UI acceleration option",
|
||||
// 0,
|
||||
// "3",
|
||||
// &UIFasterCalllback,
|
||||
// 1,
|
||||
// 0,
|
||||
// 0,
|
||||
// 0
|
||||
// );
|
||||
|
||||
// s_cvarTextureCacheSize = CVar::Register(
|
||||
// "textureCacheSize",
|
||||
// "Texture cache size in bytes",
|
||||
// 1,
|
||||
// "32",
|
||||
// &TextureCacheSizeCallback,
|
||||
// 1,
|
||||
// 0,
|
||||
// 0,
|
||||
// 0
|
||||
// );
|
||||
|
||||
// sub_4B6580(*(_DWORD *)(dword_B2F9FC + 48) << 20);
|
||||
|
||||
// AddConsoleDeviceDefaultCallback(SetDefaults);
|
||||
|
||||
// if (ConsoleDeviceHardwareChanged()) {
|
||||
// v3 = 0;
|
||||
|
||||
// do {
|
||||
// SetDefaults(v3++);
|
||||
// } while (v3 < 3);
|
||||
// }
|
||||
|
||||
auto m2Flags = M2RegisterCVars();
|
||||
M2Initialize(m2Flags, 0);
|
||||
|
||||
// v4 = *(_DWORD *)(dword_B2FA00 + 48);
|
||||
// sub_4B61C0(dword_AB6128[v4]);
|
||||
// sub_4B6230(dword_AB6140[v4]);
|
||||
|
||||
WowClientInit();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t InitializeGlobal() {
|
||||
// TODO
|
||||
|
||||
// SCmdRegisterArgList(&ProcessCommandLine(void)::s_wowArgList, 17u);
|
||||
|
||||
// CmdLineProcess();
|
||||
|
||||
// sub_403600("WoW.mfil");
|
||||
|
||||
// if (dword_B2FA10 != 2) {
|
||||
// sub_403560();
|
||||
// }
|
||||
|
||||
// LOBYTE(v24) = 0;
|
||||
|
||||
// if (sub_422140()) {
|
||||
// LOBYTE(v24) = OsDirectoryExists((int)"WTF/Account") == 0;
|
||||
// }
|
||||
|
||||
// ClientServices::LoadCDKey();
|
||||
|
||||
ConsoleInitializeClientCommand();
|
||||
|
||||
ConsoleInitializeClientCVar("Config.wtf");
|
||||
|
||||
// sub_7663F0();
|
||||
|
||||
// v18 = 0;
|
||||
// v19 = 0;
|
||||
// ptr = 0;
|
||||
// v21 = 0;
|
||||
|
||||
// sub_406740(&v18, &CVar::Load);
|
||||
|
||||
// if (ptr) {
|
||||
// SMemFree(ptr, a_pad, -2, 0);
|
||||
// }
|
||||
|
||||
// CVar::Register("dbCompress", "Database compression", 0, "-1", 0, 5, 0, 0, 0);
|
||||
|
||||
// v2 = CVar::Register("locale", "Set the game locale", 0, "****", &LocaleChangedCallback, 5, 0, 0, 0);
|
||||
|
||||
// if (!SStrCmp(v2->m_stringValue.m_str, "****", 0x7FFFFFFFu)) {
|
||||
// CVar::Set(v2, "enUS", 1, 0, 0, 1);
|
||||
// }
|
||||
|
||||
// CVar::Register("useEnglishAudio", "override the locale and use English audio", 0, "0", 0, 5, 0, 0, 0);
|
||||
|
||||
// if (sub_422140()) {
|
||||
// sub_4036B0(v24, 0, a2, (int)v2, (char)v24);
|
||||
// }
|
||||
|
||||
// SStrCopy(&a1a, v2->m_stringValue.m_str, 5);
|
||||
|
||||
// sub_402D50(&a1a);
|
||||
|
||||
// CVar::Set(v2, &a1a, 1, 0, 0, 1);
|
||||
|
||||
// SStrPrintf(dest, 260, "%s%s", *(_DWORD *)off_AB6158, v2->m_stringValue.m_str);
|
||||
|
||||
// sub_421B50(dest);
|
||||
|
||||
// sub_423D70();
|
||||
|
||||
// sub_405DD0();
|
||||
|
||||
// CVar* v3 = CVar::Register(
|
||||
// "processAffinityMask",
|
||||
// "Sets which core(s) WoW may execute on - changes require restart to take effect",
|
||||
// 2,
|
||||
// "0",
|
||||
// &sub_4022E0,
|
||||
// 0,
|
||||
// 0,
|
||||
// 0,
|
||||
// 0
|
||||
// );
|
||||
|
||||
// CVar* v4 = CVar::Lookup("videoOptionsVersion");
|
||||
|
||||
// if (!v4 || v4->m_intValue < 3) {
|
||||
// SStrPrintf(v23, 8, "%u", 0);
|
||||
// CVar::Set(v3, v23, 1, 0, 0, 1);
|
||||
// CVar::Update((int)v3);
|
||||
// }
|
||||
|
||||
// v5 = v3->m_intValue;
|
||||
|
||||
// if (v5) {
|
||||
// SSetCurrentProcessAffinityMask(v5);
|
||||
// }
|
||||
|
||||
BaseInitializeGlobal();
|
||||
|
||||
EventInitialize(1, 0);
|
||||
|
||||
// CVar* v6 = CVar::Register(
|
||||
// "timingTestError",
|
||||
// "Error reported by the timing validation system",
|
||||
// 6,
|
||||
// "0",
|
||||
// 0,
|
||||
// 5,
|
||||
// 0,
|
||||
// 0,
|
||||
// 0
|
||||
// );
|
||||
// v7 = v6;
|
||||
|
||||
// CVar* v8 = CVar::Register(
|
||||
// "timingMethod",
|
||||
// "Desired method for game timing",
|
||||
// 2,
|
||||
// "0",
|
||||
// &sub_403200,
|
||||
// 5,
|
||||
// 0,
|
||||
// v6,
|
||||
// 0
|
||||
// );
|
||||
|
||||
// sub_86D430(v8->m_intValue);
|
||||
|
||||
// ConsoleCommandRegister("timingInfo", (int)sub_4032A0, 0, 0);
|
||||
|
||||
// v9 = sub_86AD50();
|
||||
|
||||
// v10 = v9 == v7->m_intValue;
|
||||
|
||||
// dword_B2F9D8 = v9;
|
||||
|
||||
// if (!v10) {
|
||||
// sprintf(&v17, "%d", v9);
|
||||
// CVar::SetReadOnly((int)v7, 0);
|
||||
// CVar::Set(v7, &v17, 1, 0, 0, 1);
|
||||
// CVar::Update((int)v7);
|
||||
// CVar::SetReadOnly((int)v7, 1);
|
||||
// ConsolePrintf("Timing test error: %d", (int)v7);
|
||||
// }
|
||||
|
||||
// WowClientDB<Startup_StringsRec>::Load(&g_Startup_StringsDB, 0, ".\\Client.cpp", 0x12E3u);
|
||||
// Startup_StringsRec* v11 = g_Startup_StringsDB.GetRecordByIndex(1);
|
||||
// const char* v12;
|
||||
|
||||
// if (v11) {
|
||||
// v12 = v11->m_text;
|
||||
// } else {
|
||||
// v12 = "World of Warcraft";
|
||||
// }
|
||||
|
||||
// TODO
|
||||
// - replace with above logic for loading from Startup_Strings.dbc
|
||||
const char* v12 = "World of Warcraft";
|
||||
|
||||
char v15[260];
|
||||
|
||||
SStrCopy(v15, v12, 0x7FFFFFFF);
|
||||
|
||||
ConsoleDeviceInitialize(v15);
|
||||
|
||||
// OsIMEInitialize();
|
||||
|
||||
// uint32_t v13 = OsGetAsyncTimeMs();
|
||||
// g_rndSeed.SetSeed(v13);
|
||||
|
||||
Client::g_clientEventContext = EventCreateContextEx(
|
||||
1,
|
||||
&InitializeEngineCallback,
|
||||
&DestroyEngineCallback,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CommonMain() {
|
||||
StormInitialize();
|
||||
|
||||
// TODO
|
||||
// - error log setup
|
||||
// - misc other setup
|
||||
|
||||
if (InitializeGlobal()) {
|
||||
EventDoMessageLoop();
|
||||
|
||||
// TODO
|
||||
// sub_406B70();
|
||||
}
|
||||
|
||||
// TODO
|
||||
// - misc cleanup
|
||||
}
|
||||
|
||||
void BlizzardAssertCallback(const char* a1, const char* a2, const char* a3, uint32_t a4) {
|
||||
if (*a2) {
|
||||
SErrDisplayError(0, a3, a4, a2, 0, 1, 0x11111111);
|
||||
} else {
|
||||
SErrDisplayError(0, a3, a4, a1, 0, 1, 0x11111111);
|
||||
}
|
||||
}
|
||||
|
||||
void StormInitialize() {
|
||||
// TODO
|
||||
// SStrInitialize();
|
||||
// SErrInitialize();
|
||||
// SLogInitialize();
|
||||
// SFile::Initialize();
|
||||
|
||||
Blizzard::Debug::SetAssertHandler(BlizzardAssertCallback);
|
||||
}
|
||||
|
||||
void WowClientInit() {
|
||||
// TODO
|
||||
// EventRegister(EVENT_ID_5, (int)sub_4020E0);
|
||||
// _cfltcvt_init_0();
|
||||
|
||||
ClientMiscInitialize();
|
||||
|
||||
// sub_401B60();
|
||||
// ClientDBInitialize();
|
||||
// LoadingScreenInitialize();
|
||||
|
||||
FrameScript_Initialize(0);
|
||||
|
||||
// TODO
|
||||
// SI2::Init(0);
|
||||
// sub_6F66B0();
|
||||
|
||||
FrameXML_RegisterDefault();
|
||||
GlueScriptEventsInitialize();
|
||||
ScriptEventsInitialize();
|
||||
|
||||
// TODO
|
||||
// sub_6F75E0();
|
||||
// sub_401FF0();
|
||||
|
||||
ClientServices::Initialize();
|
||||
// TODO ClientServices::SetMessageHandler(SMSG_TUTORIAL_FLAGS, (int)sub_530920, 0);
|
||||
|
||||
// TODO
|
||||
// v2 = CVar::Lookup("EnableVoiceChat");
|
||||
// if (v2 && *(_DWORD *)(v2 + 48)) {
|
||||
// ComSatClient_Init();
|
||||
// }
|
||||
|
||||
// TODO
|
||||
// DBCache_RegisterHandlers();
|
||||
// DBCache_Initialize(a1);
|
||||
|
||||
// TODO
|
||||
// sub_78E400();
|
||||
|
||||
CWorld::Initialize();
|
||||
|
||||
// TODO
|
||||
// ShadowInit();
|
||||
// GxuLightInitialize();
|
||||
// GxuLightBucketSizeSet(16.665001);
|
||||
// InputControlInitialize();
|
||||
|
||||
CGlueMgr::Initialize();
|
||||
|
||||
// TODO
|
||||
// if (GetConsoleMessage()) {
|
||||
// v3 = (const char *)GetConsoleMessage();
|
||||
// CGlueMgr::AddChangedOptionWarning(v3);
|
||||
// SetConsoleMessage(0);
|
||||
// }
|
||||
|
||||
// TODO
|
||||
// if (sub_422140()) {
|
||||
// sub_421630();
|
||||
// }
|
||||
|
||||
// TODO
|
||||
// if (byte_B2F9E1 != 1) {
|
||||
// if ((g_playIntroMovie + 48) == 1) {
|
||||
// CVar::Set(g_playIntroMovie, "0", 1, 0, 0, 1);
|
||||
// CGlueMgr::SetScreen("movie");
|
||||
// } else {
|
||||
// CGlueMgr::SetScreen("login");
|
||||
// }
|
||||
// } else {
|
||||
// if ((dword_B2F980 + 48) == 1) {
|
||||
// CVar::Set(dword_B2F980, "0", 1, 0, 0, 1);
|
||||
// CVar::Set(g_playIntroMovie, "0", 1, 0, 0, 1);
|
||||
// CGlueMgr::SetScreen("movie");
|
||||
// } else {
|
||||
// CGlueMgr::SetScreen("login");
|
||||
// }
|
||||
// }
|
||||
|
||||
// TODO
|
||||
// - temporary until above logic is implemented
|
||||
CGlueMgr::SetScreen("login");
|
||||
|
||||
// TODO
|
||||
// CGlueMgr::m_pendingTimerAlert = dword_B2F9D8;
|
||||
// sub_7FC5A0();
|
||||
// EventRegister(EVENT_ID_POLL, &PollNet);
|
||||
}
|
22
src/client/Client.hpp
Normal file
22
src/client/Client.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef CLIENT_CLIENT_HPP
|
||||
#define CLIENT_CLIENT_HPP
|
||||
|
||||
#include "event/Event.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class CVar;
|
||||
|
||||
namespace Client {
|
||||
extern CVar* g_accountListVar;
|
||||
extern HEVENTCONTEXT g_clientEventContext;
|
||||
}
|
||||
|
||||
void ClientPostClose(int32_t);
|
||||
|
||||
void CommonMain(void);
|
||||
|
||||
void StormInitialize(void);
|
||||
|
||||
void WowClientInit(void);
|
||||
|
||||
#endif
|
10
src/client/ClientRealmResponseAdapter.hpp
Normal file
10
src/client/ClientRealmResponseAdapter.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef CLIENT_CLIENT_REALM_RESPONSE_ADAPTER_HPP
|
||||
#define CLIENT_CLIENT_REALM_RESPONSE_ADAPTER_HPP
|
||||
|
||||
#include "net/Connection.hpp"
|
||||
|
||||
class ClientRealmResponseAdapter : public RealmResponse {
|
||||
public:
|
||||
};
|
||||
|
||||
#endif
|
92
src/client/ClientServices.cpp
Normal file
92
src/client/ClientServices.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
#include "client/ClientServices.hpp"
|
||||
#include "client/ClientRealmResponseAdapter.hpp"
|
||||
#include "net/Connection.hpp"
|
||||
#include "net/Login.hpp"
|
||||
#include <storm/Memory.hpp>
|
||||
#include <storm/String.hpp>
|
||||
#include <new>
|
||||
|
||||
ClientConnection* g_clientConnection;
|
||||
|
||||
RealmResponse* ClientServices::s_clientRealmResponse;
|
||||
ClientConnection* ClientServices::s_currentConnection;
|
||||
ClientServices* ClientServices::s_instance;
|
||||
Login* ClientServices::s_loginObj;
|
||||
bool ClientServices::s_newLogin;
|
||||
|
||||
ClientConnection* ClientServices::Connection() {
|
||||
// TODO assertion?
|
||||
|
||||
return ClientServices::s_currentConnection;
|
||||
}
|
||||
|
||||
ClientServices* ClientServices::GetInstance() {
|
||||
if (ClientServices::s_instance) {
|
||||
return ClientServices::s_instance;
|
||||
}
|
||||
|
||||
auto instanceMem = SMemAlloc(sizeof(ClientServices), __FILE__, __LINE__, 0x0);
|
||||
auto instance = new (instanceMem) ClientServices();
|
||||
ClientServices::s_instance = instance;
|
||||
|
||||
return ClientServices::s_instance;
|
||||
}
|
||||
|
||||
void ClientServices::Initialize() {
|
||||
if (!g_clientConnection) {
|
||||
auto adapterMem = SMemAlloc(sizeof(ClientRealmResponseAdapter), __FILE__, __LINE__, 0x0);
|
||||
auto clientRealmResponse = new (adapterMem) ClientRealmResponseAdapter();
|
||||
ClientServices::s_clientRealmResponse = clientRealmResponse;
|
||||
|
||||
auto connectionMem = SMemAlloc(sizeof(ClientConnection), __FILE__, __LINE__, 0x0);
|
||||
auto clientConnection = new (connectionMem) ClientConnection(ClientServices::s_clientRealmResponse);
|
||||
g_clientConnection = clientConnection;
|
||||
}
|
||||
|
||||
ClientServices::s_currentConnection = g_clientConnection;
|
||||
|
||||
// TODO ConsoleCommandRegister("logout", &Sub6B2030, 5, nullptr);
|
||||
}
|
||||
|
||||
Login* ClientServices::LoginConnection() {
|
||||
return ClientServices::s_loginObj;
|
||||
}
|
||||
|
||||
void ClientServices::Logon(const char* accountName, const char* password) {
|
||||
if (ClientServices::s_newLogin) {
|
||||
if (ClientServices::s_loginObj) {
|
||||
// TODO
|
||||
// ClientServices::s_loginObj->Vfunc48(1);
|
||||
|
||||
ClientServices::s_loginObj = nullptr;
|
||||
}
|
||||
|
||||
ClientServices::s_newLogin = false;
|
||||
}
|
||||
|
||||
auto useBattlenet = SStrChr(accountName, '@') != 0;
|
||||
|
||||
Login* loginObj;
|
||||
|
||||
if (useBattlenet) {
|
||||
// TODO
|
||||
} else {
|
||||
auto loginMem = SMemAlloc(sizeof(GruntLogin), __FILE__, __LINE__, 0x0);
|
||||
loginObj = new (loginMem) GruntLogin();
|
||||
}
|
||||
|
||||
ClientServices::s_loginObj = loginObj;
|
||||
ClientServices::s_loginObj->Init(ClientServices::GetInstance());
|
||||
|
||||
// TODO
|
||||
|
||||
ClientServices::s_loginObj->SetLogonCreds(accountName, password);
|
||||
|
||||
// TODO
|
||||
|
||||
ClientServices::s_loginObj->Logon(nullptr, nullptr);
|
||||
}
|
||||
|
||||
void ClientServices::LoginServerStatus(LOGIN_STATE state, LOGIN_RESULT result, const char* addrStr, const char* stateStr, const char* resultStr, uint16_t a7) {
|
||||
// TODO
|
||||
}
|
30
src/client/ClientServices.hpp
Normal file
30
src/client/ClientServices.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef CLIENT_CLIENT_SERVICES_HPP
|
||||
#define CLIENT_CLIENT_SERVICES_HPP
|
||||
|
||||
#include "net/login/LoginResponse.hpp"
|
||||
|
||||
class ClientConnection;
|
||||
class Login;
|
||||
class RealmResponse;
|
||||
|
||||
class ClientServices : public LoginResponse {
|
||||
public:
|
||||
// Static variables
|
||||
static RealmResponse* s_clientRealmResponse;
|
||||
static ClientConnection* s_currentConnection;
|
||||
static ClientServices* s_instance;
|
||||
static Login* s_loginObj;
|
||||
static bool s_newLogin;
|
||||
|
||||
// Static functions
|
||||
static ClientConnection* Connection();
|
||||
static ClientServices* GetInstance();
|
||||
static void Initialize();
|
||||
static Login* LoginConnection();
|
||||
static void Logon(const char* accountName, const char* password);
|
||||
|
||||
// Virtual member functions
|
||||
virtual void LoginServerStatus(LOGIN_STATE state, LOGIN_RESULT result, const char* addrStr, const char* stateStr, const char* resultStr, uint16_t a7);
|
||||
};
|
||||
|
||||
#endif
|
191
src/client/Console.cpp
Normal file
191
src/client/Console.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
#include "client/Console.hpp"
|
||||
#include "gx/Device.hpp"
|
||||
#include "util/CVar.hpp"
|
||||
#include <cstring>
|
||||
|
||||
CVar* s_cvGxMaximize;
|
||||
CVar* s_cvGxResolution;
|
||||
CVar* s_cvGxWidescreen;
|
||||
CVar* s_cvGxWindow;
|
||||
DefaultSettings s_defaults;
|
||||
bool s_hwDetect;
|
||||
bool s_hwChanged;
|
||||
CGxFormat s_requestedFormat;
|
||||
|
||||
bool CVGxMaximizeCallback(CVar*, const char*, const char*, void*) {
|
||||
// TODO
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CVGxResolutionCallback(CVar*, const char*, const char*, void*) {
|
||||
// TODO
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CVGxWindowCallback(CVar*, const char*, const char*, void*) {
|
||||
// TODO
|
||||
return true;
|
||||
}
|
||||
|
||||
void RegisterGxCVars() {
|
||||
auto& format = s_defaults.format;
|
||||
|
||||
// TODO CURRENT_LANGUAGE check?
|
||||
auto v1 = true;
|
||||
|
||||
s_cvGxWidescreen = CVar::Register(
|
||||
"widescreen",
|
||||
"Allow widescreen support",
|
||||
0x0,
|
||||
"1",
|
||||
nullptr,
|
||||
1,
|
||||
false,
|
||||
nullptr,
|
||||
false
|
||||
);
|
||||
|
||||
s_cvGxWindow = CVar::Register(
|
||||
"gxWindow",
|
||||
"toggle fullscreen/window",
|
||||
0x1 | 0x2,
|
||||
v1 ? "1" : "0",
|
||||
&CVGxWindowCallback,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
s_cvGxMaximize = CVar::Register(
|
||||
"gxMaximize",
|
||||
"maximize game window",
|
||||
0x1 | 0x2,
|
||||
v1 ? "1" : "0",
|
||||
&CVGxMaximizeCallback,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
// TODO s_cvGxColorBits
|
||||
// TODO s_cvGxDepthBits
|
||||
|
||||
char resolution[260];
|
||||
SStrPrintf(resolution, 260, "%dx%d", format.size.x, format.size.y);
|
||||
s_cvGxResolution = CVar::Register(
|
||||
"gxResolution",
|
||||
"resolution",
|
||||
0x1 | 0x2,
|
||||
resolution,
|
||||
&CVGxResolutionCallback,
|
||||
1,
|
||||
false,
|
||||
nullptr,
|
||||
false
|
||||
);
|
||||
|
||||
// TODO s_cvGxRefresh
|
||||
// TODO s_cvGxTripleBuffer
|
||||
// TODO s_cvGxApi
|
||||
// TODO s_cvGxVSync
|
||||
// TODO s_cvGxAspect
|
||||
// TODO s_cvGxCursor
|
||||
// TODO s_cvGxMultisample
|
||||
// TODO s_cvGxFixLag
|
||||
// TODO s_cvGxStereoEnabled
|
||||
// TODO s_cvGxOverride
|
||||
// TODO s_cvGxAspect
|
||||
// TODO s_cvGxMaxFPS
|
||||
// TODO s_cvGxMaxFPSBk
|
||||
// TODO s_cvWindowResizeLock
|
||||
// TODO s_cvFixedFunction
|
||||
}
|
||||
|
||||
void UpdateGxCVars() {
|
||||
// TODO others
|
||||
|
||||
s_cvGxWindow->Update();
|
||||
s_cvGxResolution->Update();
|
||||
|
||||
// TODO others
|
||||
|
||||
s_cvGxMaximize->Update();
|
||||
|
||||
// TODO others
|
||||
}
|
||||
|
||||
void SetGxCVars(const CGxFormat& format) {
|
||||
char value[1024];
|
||||
|
||||
// TODO s_cvGxColorBits
|
||||
// TODO s_cvGxDepthBits
|
||||
|
||||
SStrPrintf(value, sizeof(value), "%d", format.window);
|
||||
s_cvGxWindow->Set(value, true, false, false, true);
|
||||
|
||||
SStrPrintf(value, sizeof(value), "%dx%d", format.size.x, format.size.y);
|
||||
s_cvGxResolution->Set(value, true, false, false, true);
|
||||
|
||||
// TODO s_cvGxRefresh
|
||||
// TODO others
|
||||
|
||||
SStrPrintf(value, sizeof(value), "%d", format.maximize);
|
||||
s_cvGxMaximize->Set(value, true, false, false, true);
|
||||
|
||||
// TODO others
|
||||
|
||||
UpdateGxCVars();
|
||||
}
|
||||
|
||||
void ConsoleInitializeClientCommand() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void ConsoleInitializeClientCVar(const char* a1) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void ConsoleDeviceInitialize(const char* title) {
|
||||
// TODO
|
||||
|
||||
// TODO proper logic
|
||||
s_hwDetect = true;
|
||||
|
||||
// TODO
|
||||
|
||||
RegisterGxCVars();
|
||||
|
||||
// TODO ConsoleCommandRegister("gxRestart", &CCGxRestart, 1, nullptr);
|
||||
|
||||
// TODO
|
||||
|
||||
// TODO
|
||||
// - source the size values correctly
|
||||
s_requestedFormat.size.x = 1024;
|
||||
s_requestedFormat.size.y = 768;
|
||||
s_requestedFormat.colorFormat = CGxFormat::Fmt_Argb8888;
|
||||
s_requestedFormat.depthFormat = CGxFormat::Fmt_Ds248;
|
||||
|
||||
if (s_hwDetect || s_hwChanged) {
|
||||
// TODO Sub76B3F0(&UnkCABAF0, &UnkCABB38);
|
||||
// TODO s_cvFixedFunction->Set("0", 1, 0, 0, 1);
|
||||
// TODO memcpy(&s_requestedFormat, &s_defaults.format, sizeof(s_requestedFormat));
|
||||
|
||||
s_requestedFormat.window = s_cvGxWindow->GetInt() != 0;
|
||||
s_requestedFormat.maximize = s_cvGxMaximize->GetInt() != 0;
|
||||
|
||||
// TODO temporary override
|
||||
s_requestedFormat.maximize = 0;
|
||||
|
||||
SetGxCVars(s_requestedFormat);
|
||||
}
|
||||
|
||||
CGxFormat format;
|
||||
memcpy(&format, &s_requestedFormat, sizeof(s_requestedFormat));
|
||||
|
||||
CGxDevice* device = GxDevCreate(GxApi_GLL, nullptr, format);
|
||||
|
||||
// TODO
|
||||
}
|
16
src/client/Console.hpp
Normal file
16
src/client/Console.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef CLIENT_CONSOLE_HPP
|
||||
#define CLIENT_CONSOLE_HPP
|
||||
|
||||
#include "gx/CGxFormat.hpp"
|
||||
|
||||
struct DefaultSettings {
|
||||
CGxFormat format;
|
||||
};
|
||||
|
||||
void ConsoleInitializeClientCommand();
|
||||
|
||||
void ConsoleInitializeClientCVar(const char* a1);
|
||||
|
||||
void ConsoleDeviceInitialize(const char* title);
|
||||
|
||||
#endif
|
40
src/event/CEvent.cpp
Normal file
40
src/event/CEvent.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "event/CEvent.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
|
||||
CCharEvent& CCharEvent::operator=(const EVENT_DATA_CHAR& data) {
|
||||
this->ch = data.ch;
|
||||
this->metaKeyState = data.metaKeyState;
|
||||
this->repeat = data.repeat;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CKeyEvent& CKeyEvent::operator=(const EVENT_DATA_KEY& data) {
|
||||
this->key = data.key;
|
||||
this->metaKeyState = data.metaKeyState;
|
||||
this->repeat = data.repeat;
|
||||
this->time = data.time;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CMouseEvent& CMouseEvent::operator=(const EVENT_DATA_MOUSE& data) {
|
||||
this->mode = data.mode;
|
||||
this->button = data.button;
|
||||
this->buttonState = data.buttonState;
|
||||
this->metaKeyState = data.metaKeyState;
|
||||
this->flags = data.flags;
|
||||
this->time = data.time;
|
||||
this->wheelDistance = data.wheelDistance;
|
||||
|
||||
NDCToDDC(data.x, data.y, &this->x, &this->y);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSizeEvent& CSizeEvent::operator=(const EVENT_DATA_SIZE& data) {
|
||||
this->w = data.w;
|
||||
this->h = data.h;
|
||||
|
||||
return *this;
|
||||
}
|
39
src/event/CEvent.hpp
Normal file
39
src/event/CEvent.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef EVENT_C_EVENT_HPP
|
||||
#define EVENT_C_EVENT_HPP
|
||||
|
||||
#include "event/Types.hpp"
|
||||
#include <cstdint>
|
||||
#include <common/Ref.hpp>
|
||||
|
||||
class CEvent : public TRefCnt {
|
||||
public:
|
||||
// Member variables
|
||||
uint32_t id;
|
||||
void* param;
|
||||
};
|
||||
|
||||
class CCharEvent : public CEvent, public EVENT_DATA_CHAR {
|
||||
public:
|
||||
// Member functions
|
||||
CCharEvent& operator=(const EVENT_DATA_CHAR&);
|
||||
};
|
||||
|
||||
class CKeyEvent : public CEvent, public EVENT_DATA_KEY {
|
||||
public:
|
||||
// Member functions
|
||||
CKeyEvent& operator=(const EVENT_DATA_KEY&);
|
||||
};
|
||||
|
||||
class CMouseEvent : public CEvent, public EVENT_DATA_MOUSE {
|
||||
public:
|
||||
// Member functions
|
||||
CMouseEvent& operator=(const EVENT_DATA_MOUSE&);
|
||||
};
|
||||
|
||||
class CSizeEvent : public CEvent, public EVENT_DATA_SIZE {
|
||||
public:
|
||||
// Member functions
|
||||
CSizeEvent& operator=(const EVENT_DATA_SIZE&);
|
||||
};
|
||||
|
||||
#endif
|
27
src/event/CMakeLists.txt
Normal file
27
src/event/CMakeLists.txt
Normal file
@ -0,0 +1,27 @@
|
||||
file(GLOB PRIVATE_SOURCES "*.cpp")
|
||||
|
||||
if(WHOA_SYSTEM_MAC)
|
||||
file(GLOB MAC_SOURCES
|
||||
"mac/*.cpp"
|
||||
"mac/*.mm"
|
||||
)
|
||||
list(APPEND PRIVATE_SOURCES ${MAC_SOURCES})
|
||||
endif()
|
||||
|
||||
add_library(event STATIC
|
||||
${PRIVATE_SOURCES}
|
||||
)
|
||||
|
||||
target_include_directories(event
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
target_link_libraries(event
|
||||
PRIVATE
|
||||
gx
|
||||
PUBLIC
|
||||
common
|
||||
storm
|
||||
tempest
|
||||
)
|
112
src/event/Context.cpp
Normal file
112
src/event/Context.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
#include "event/Context.hpp"
|
||||
#include "event/Event.hpp"
|
||||
#include "event/EvtThread.hpp"
|
||||
#include <common/Time.hpp>
|
||||
#include <storm/Atomic.hpp>
|
||||
|
||||
HEVENTCONTEXT AttachContextToThread(EvtContext* context) {
|
||||
SInterlockedIncrement(&Event::s_threadListContention);
|
||||
Event::s_threadListCritsect.Enter();
|
||||
|
||||
// Select the thread with the highest weight total
|
||||
EvtThread* thread = nullptr;
|
||||
EvtThread* t = Event::s_threadList.Head();
|
||||
|
||||
while (t) {
|
||||
if (!thread || t->m_weightTotal < thread->m_weightTotal) {
|
||||
thread = t;
|
||||
}
|
||||
|
||||
t = t->Next();
|
||||
}
|
||||
|
||||
if (thread) {
|
||||
TSingletonInstanceId<EvtContext, offsetof(EvtContext, m_id)>::s_idTable.Insert(context);
|
||||
|
||||
uint32_t v13 = OsGetAsyncTimeMs();
|
||||
|
||||
if (v13 != context->m_schedNextWakeTime.m_val) {
|
||||
context->m_schedNextWakeTime.m_val = v13;
|
||||
context->m_schedNextWakeTime.Relink();
|
||||
}
|
||||
|
||||
Event::s_threadSlotCritsects[thread->m_threadSlot].Enter();
|
||||
|
||||
thread->m_contextQueue.Enqueue(context);
|
||||
|
||||
Event::s_threadSlotCritsects[thread->m_threadSlot].Leave();
|
||||
|
||||
thread->m_wakeEvent.Set();
|
||||
|
||||
uint32_t v14 = context->m_schedWeight + thread->m_weightTotal;
|
||||
uint32_t v15 = thread->m_contextCount + 1;
|
||||
thread->m_contextCount = v15;
|
||||
thread->m_weightTotal = v14;
|
||||
thread->m_weightAvg = v14 / v15;
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
|
||||
Event::s_threadListCritsect.Leave();
|
||||
SInterlockedDecrement(&Event::s_threadListContention);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void DetachContextFromThread(uint32_t a1, EvtContext* a2) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
EvtContext* GetNextContext(uint32_t hThread) {
|
||||
EvtContext* context;
|
||||
|
||||
Event::s_threadSlotCritsects[hThread].Enter();
|
||||
|
||||
context = Event::s_threadSlots[hThread]->m_contextQueue.Dequeue();
|
||||
|
||||
Event::s_threadSlotCritsects[hThread].Leave();
|
||||
|
||||
if (hThread == Event::s_mainThread) {
|
||||
Event::s_currentEvtContext = context;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void PutContext(uint32_t nextWakeTime, uint32_t newSmoothWeight, EvtContext* context, uint32_t hThread) {
|
||||
if (nextWakeTime != context->m_schedNextWakeTime.m_val) {
|
||||
context->m_schedNextWakeTime.m_val = nextWakeTime;
|
||||
context->m_schedNextWakeTime.Relink();
|
||||
}
|
||||
|
||||
if (context->m_schedSmoothWeight != newSmoothWeight) {
|
||||
uint32_t v8 = context->m_schedWeight;
|
||||
context->m_schedSmoothWeight = newSmoothWeight;
|
||||
|
||||
int32_t v9;
|
||||
|
||||
if (newSmoothWeight <= v8) {
|
||||
v9 = v8 - newSmoothWeight;
|
||||
} else {
|
||||
v9 = newSmoothWeight - v8;
|
||||
}
|
||||
|
||||
context->m_schedRebalance = v9 >= v8 >> 3;
|
||||
}
|
||||
|
||||
if (!SInterlockedIncrement(&Event::s_threadListContention)) {
|
||||
Event::s_threadListCritsect.Enter();
|
||||
|
||||
// TODO
|
||||
|
||||
Event::s_threadListCritsect.Leave();
|
||||
}
|
||||
|
||||
SInterlockedDecrement(&Event::s_threadListContention);
|
||||
|
||||
if (hThread < Event::s_threadSlotCount) {
|
||||
Event::s_threadSlotCritsects[hThread].Enter();
|
||||
Event::s_threadSlots[hThread]->m_contextQueue.Enqueue(context);
|
||||
Event::s_threadSlotCritsects[hThread].Leave();
|
||||
}
|
||||
}
|
17
src/event/Context.hpp
Normal file
17
src/event/Context.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef EVENT_CONTEXT_HPP
|
||||
#define EVENT_CONTEXT_HPP
|
||||
|
||||
#include "event/Types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class EvtContext;
|
||||
|
||||
HEVENTCONTEXT AttachContextToThread(EvtContext* context);
|
||||
|
||||
void DetachContextFromThread(uint32_t a1, EvtContext* a2);
|
||||
|
||||
EvtContext* GetNextContext(uint32_t hThread);
|
||||
|
||||
void PutContext(uint32_t nextWakeTime, uint32_t newSmoothWeight, EvtContext* context, uint32_t hThread);
|
||||
|
||||
#endif
|
136
src/event/Event.cpp
Normal file
136
src/event/Event.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
#include "event/Event.hpp"
|
||||
#include "event/EvtContext.hpp"
|
||||
#include "event/EvtThread.hpp"
|
||||
#include "event/Input.hpp"
|
||||
#include "event/Queue.hpp"
|
||||
#include "event/Scheduler.hpp"
|
||||
#include <cstring>
|
||||
#include <common/Prop.hpp>
|
||||
#include <common/Time.hpp>
|
||||
#include <storm/String.hpp>
|
||||
|
||||
SEvent Event::s_startEvent = SEvent(1, 0);
|
||||
SEvent Event::s_shutdownEvent = SEvent(1, 0);
|
||||
int32_t Event::s_netServer;
|
||||
int32_t Event::s_threadSlotCount;
|
||||
SCritSect* Event::s_threadSlotCritsects;
|
||||
EvtThread** Event::s_threadSlots;
|
||||
uint32_t Event::s_mainThread;
|
||||
TSGrowableArray<SThread*> Event::s_schedulerThreads;
|
||||
ATOMIC32 Event::s_threadListContention { -1 };
|
||||
SCritSect Event::s_threadListCritsect;
|
||||
TSList<EvtThread, TSGetLink<EvtThread>> Event::s_threadList;
|
||||
EvtContext* Event::s_currentEvtContext;
|
||||
ATOMIC32 Event::s_interactiveCount;
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
bool Event::s_shouldLoopTerminate;
|
||||
#endif
|
||||
|
||||
void OsNetPump(uint32_t timeout) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void EventInitialize(int32_t threadCount, int32_t netServer) {
|
||||
IEvtInputInitialize();
|
||||
|
||||
int32_t v2 = threadCount;
|
||||
|
||||
if (threadCount < 1) {
|
||||
v2 = 1;
|
||||
}
|
||||
|
||||
IEvtSchedulerInitialize(v2, netServer);
|
||||
|
||||
// TODO
|
||||
// OsInputSetEventPollProc(&sub_47DCA0);
|
||||
}
|
||||
|
||||
int32_t EventIsControlKeyDown() {
|
||||
return EventIsKeyDown(KEY_LCONTROL) || EventIsKeyDown(KEY_RCONTROL);
|
||||
}
|
||||
|
||||
int32_t EventIsKeyDown(KEY key) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t EventIsShiftKeyDown() {
|
||||
return EventIsKeyDown(KEY_LSHIFT) || EventIsKeyDown(KEY_RSHIFT);
|
||||
}
|
||||
|
||||
HEVENTCONTEXT EventCreateContextEx(int32_t interactive, int32_t (*initializeHandler)(const void*, void*), int32_t (*destroyHandler)(const void*, void*), uint32_t idleTime, uint32_t debugFlags) {
|
||||
return IEvtSchedulerCreateContext(interactive, initializeHandler, destroyHandler, idleTime, debugFlags);
|
||||
}
|
||||
|
||||
void EventDoMessageLoop() {
|
||||
IEvtSchedulerProcess();
|
||||
}
|
||||
|
||||
void EventPostCloseEx(HEVENTCONTEXT contextHandle) {
|
||||
if (!contextHandle) {
|
||||
contextHandle = PropGet(PROP_EVENTCONTEXT);
|
||||
}
|
||||
|
||||
if (contextHandle) {
|
||||
uint32_t contextId = *reinterpret_cast<uint32_t*>(contextHandle);
|
||||
int32_t findMask;
|
||||
EvtContext* context = TSingletonInstanceId<EvtContext, offsetof(EvtContext, m_id)>::s_idTable.Ptr(
|
||||
contextId,
|
||||
0,
|
||||
&findMask
|
||||
);
|
||||
|
||||
if (context) {
|
||||
context->m_critsect.Enter();
|
||||
|
||||
if (context->m_schedState == EvtContext::SCHEDSTATE_ACTIVE) {
|
||||
context->m_schedState = EvtContext::SCHEDSTATE_CLOSED;
|
||||
}
|
||||
|
||||
context->m_critsect.Leave();
|
||||
|
||||
if (findMask != -1) {
|
||||
TSingletonInstanceId<EvtContext, offsetof(EvtContext, m_id)>::s_idTable.Unlock(
|
||||
findMask & (INSTANCE_TABLE_SLOT_COUNT - 1),
|
||||
findMask >= INSTANCE_TABLE_SLOT_COUNT
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EventRegister(EVENTID id, EVENTHANDLERFUNC handler) {
|
||||
EventRegisterEx(id, handler, nullptr, 0.0f);
|
||||
}
|
||||
|
||||
void EventRegisterEx(EVENTID id, EVENTHANDLERFUNC handler, void* param, float priority) {
|
||||
if (id < 0 || id > EVENTIDS || handler == nullptr) {
|
||||
// TODO
|
||||
// SErrSetLastError(0x57u);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
HEVENTCONTEXT hContext = PropGet(PROP_EVENTCONTEXT);
|
||||
|
||||
uint32_t contextId = *reinterpret_cast<uint32_t*>(hContext);
|
||||
int32_t findMask;
|
||||
|
||||
EvtContext* context = TSingletonInstanceId<EvtContext, offsetof(EvtContext, m_id)>::s_idTable.Ptr(
|
||||
contextId,
|
||||
0,
|
||||
&findMask
|
||||
);
|
||||
|
||||
if (context) {
|
||||
IEvtQueueRegister(context, id, handler, param, priority);
|
||||
|
||||
if (findMask != -1) {
|
||||
TSingletonInstanceId<EvtContext, offsetof(EvtContext, m_id)>::s_idTable.Unlock(
|
||||
findMask & (INSTANCE_TABLE_SLOT_COUNT - 1),
|
||||
findMask >= INSTANCE_TABLE_SLOT_COUNT
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
56
src/event/Event.hpp
Normal file
56
src/event/Event.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef EVENT_EVENT_HPP
|
||||
#define EVENT_EVENT_HPP
|
||||
|
||||
#include "event/CEvent.hpp"
|
||||
#include "event/Types.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/Array.hpp>
|
||||
#include <storm/Atomic.hpp>
|
||||
#include <storm/List.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
class EvtContext;
|
||||
class EvtThread;
|
||||
|
||||
namespace Event {
|
||||
extern SEvent s_startEvent;
|
||||
extern SEvent s_shutdownEvent;
|
||||
extern int32_t s_netServer;
|
||||
extern int32_t s_originalThreadPriority;
|
||||
extern int32_t s_threadSlotCount;
|
||||
extern SCritSect* s_threadSlotCritsects;
|
||||
extern EvtThread** s_threadSlots;
|
||||
extern uint32_t s_mainThread;
|
||||
extern TSGrowableArray<SThread*> s_schedulerThreads;
|
||||
extern ATOMIC32 s_threadListContention;
|
||||
extern SCritSect s_threadListCritsect;
|
||||
extern TSList<EvtThread, TSGetLink<EvtThread>> s_threadList;
|
||||
extern EvtContext* s_currentEvtContext;
|
||||
extern ATOMIC32 s_interactiveCount;
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
extern bool s_shouldLoopTerminate;
|
||||
#endif
|
||||
}
|
||||
|
||||
HEVENTCONTEXT EventCreateContextEx(int32_t interactive, int32_t (*initializeHandler)(const void*, void*), int32_t (*destroyHandler)(const void*, void*), uint32_t idleTime, uint32_t debugFlags);
|
||||
|
||||
void EventDoMessageLoop();
|
||||
|
||||
void EventInitialize(int32_t threadCount, int32_t netServer);
|
||||
|
||||
int32_t EventIsControlKeyDown();
|
||||
|
||||
int32_t EventIsKeyDown(KEY key);
|
||||
|
||||
int32_t EventIsShiftKeyDown();
|
||||
|
||||
void EventPostCloseEx(HEVENTCONTEXT contextHandle);
|
||||
|
||||
void EventRegister(EVENTID id, int32_t (*handler)(const void*, void*));
|
||||
|
||||
void EventRegisterEx(EVENTID id, int32_t (*handler)(const void*, void*), void* param, float priority);
|
||||
|
||||
void OsNetPump(uint32_t timeout);
|
||||
|
||||
#endif
|
30
src/event/EvtContext.cpp
Normal file
30
src/event/EvtContext.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include "event/EvtContext.hpp"
|
||||
#include <common/Time.hpp>
|
||||
|
||||
EvtContext::EvtContext(uint32_t flags, uint32_t idleTime, uint32_t schedWeight, void* callContext, int32_t startWatchdog) :
|
||||
TSingletonInstanceId<EvtContext, offsetof(TInstanceId<EvtContext>, m_id)>(),
|
||||
m_critsect(),
|
||||
m_schedNextWakeTime(),
|
||||
m_queueHandlerList(),
|
||||
m_queueMessageList(),
|
||||
m_queueSyncKeyDownList()
|
||||
// TODO
|
||||
// m_timerIdTable()
|
||||
{
|
||||
this->m_currTime = 0;
|
||||
this->m_schedState = SCHEDSTATE_ACTIVE;
|
||||
this->m_schedLastIdle = OsGetAsyncTimeMs();
|
||||
this->m_schedFlags = flags;
|
||||
this->m_schedIdleTime = idleTime;
|
||||
this->m_schedInitialIdleTime = idleTime;
|
||||
this->m_schedWeight = schedWeight;
|
||||
this->m_schedSmoothWeight = schedWeight;
|
||||
this->m_schedRebalance = 0;
|
||||
this->m_queueSyncButtonState = 0;
|
||||
this->m_propContext = PropCreateContext();
|
||||
this->m_callContext = callContext;
|
||||
this->m_startWatchdog = startWatchdog;
|
||||
}
|
||||
|
||||
EvtContextQueue::EvtContextQueue() : TSPriorityQueue<EvtContext>(offsetof(EvtContext, m_schedNextWakeTime)) {
|
||||
}
|
57
src/event/EvtContext.hpp
Normal file
57
src/event/EvtContext.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
#ifndef EVENT_EVT_CONTEXT_HPP
|
||||
#define EVENT_EVT_CONTEXT_HPP
|
||||
|
||||
#include "event/EvtHandler.hpp"
|
||||
#include "event/EvtKeyDown.hpp"
|
||||
#include "event/EvtMessage.hpp"
|
||||
#include "event/EvtTimer.hpp"
|
||||
#include "event/Types.hpp"
|
||||
#include <cstdint>
|
||||
#include <common/Instance.hpp>
|
||||
#include <common/Prop.hpp>
|
||||
#include <storm/Queue.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
class EvtContext : public TSingletonInstanceId<EvtContext, offsetof(TInstanceId<EvtContext>, m_id)> {
|
||||
public:
|
||||
// Types
|
||||
enum SCHEDSTATE {
|
||||
SCHEDSTATE_ACTIVE = 0x0,
|
||||
SCHEDSTATE_CLOSED = 0x1,
|
||||
SCHEDSTATE_DESTROYED = 0x2,
|
||||
_UNIQUE_SYMBOL_SCHEDSTATE_96 = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
// Member variables
|
||||
SCritSect m_critsect;
|
||||
uint32_t m_currTime;
|
||||
SCHEDSTATE m_schedState;
|
||||
TSTimerPriority<uint32_t> m_schedNextWakeTime;
|
||||
uint32_t m_schedLastIdle;
|
||||
uint32_t m_schedFlags;
|
||||
uint32_t m_schedIdleTime;
|
||||
uint32_t m_schedInitialIdleTime;
|
||||
uint32_t m_schedWeight;
|
||||
uint32_t m_schedSmoothWeight;
|
||||
int32_t m_schedRebalance;
|
||||
TSExplicitList<EvtHandler, offsetof(EvtHandler, link)> m_queueHandlerList[EVENTIDS];
|
||||
TSExplicitList<EvtMessage, offsetof(EvtMessage, link)> m_queueMessageList;
|
||||
uint32_t m_queueSyncButtonState;
|
||||
TSExplicitList<EvtKeyDown, offsetof(EvtKeyDown, link)> m_queueSyncKeyDownList;
|
||||
// TODO
|
||||
// EvtIdTable<EvtTimer*> m_timerIdTable;
|
||||
EvtTimerQueue m_timerQueue;
|
||||
HPROPCONTEXT m_propContext;
|
||||
void* m_callContext;
|
||||
uint32_t m_startWatchdog;
|
||||
|
||||
// Member functions
|
||||
EvtContext(uint32_t, uint32_t, uint32_t, void*, int32_t);
|
||||
};
|
||||
|
||||
class EvtContextQueue : public TSPriorityQueue<EvtContext> {
|
||||
public:
|
||||
EvtContextQueue();
|
||||
};
|
||||
|
||||
#endif
|
17
src/event/EvtHandler.hpp
Normal file
17
src/event/EvtHandler.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef EVENT_EVT_HANDLER_HPP
|
||||
#define EVENT_EVT_HANDLER_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class EvtHandler {
|
||||
public:
|
||||
// Member variables
|
||||
TSLink<EvtHandler> link;
|
||||
int32_t (*func)(const void*, void*);
|
||||
void* param;
|
||||
float priority;
|
||||
int32_t marker;
|
||||
};
|
||||
|
||||
#endif
|
14
src/event/EvtKeyDown.hpp
Normal file
14
src/event/EvtKeyDown.hpp
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef EVENT_EVT_KEY_DOWN_HPP
|
||||
#define EVENT_EVT_KEY_DOWN_HPP
|
||||
|
||||
#include "event/Types.hpp"
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class EvtKeyDown {
|
||||
public:
|
||||
// Member variables
|
||||
TSLink<EvtKeyDown> link;
|
||||
KEY key;
|
||||
};
|
||||
|
||||
#endif
|
16
src/event/EvtMessage.hpp
Normal file
16
src/event/EvtMessage.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef EVENT_EVT_MESSAGE_HPP
|
||||
#define EVENT_EVT_MESSAGE_HPP
|
||||
|
||||
#include "event/Types.hpp"
|
||||
#include <common/Instance.hpp>
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class EvtMessage : public TExtraInstanceRecyclable<EvtMessage> {
|
||||
public:
|
||||
// Member variables
|
||||
TSLink<EvtMessage> link;
|
||||
EVENTID id;
|
||||
char data[4];
|
||||
};
|
||||
|
||||
#endif
|
4
src/event/EvtThread.cpp
Normal file
4
src/event/EvtThread.cpp
Normal file
@ -0,0 +1,4 @@
|
||||
#include "event/EvtThread.hpp"
|
||||
|
||||
EvtThread::EvtThread() : TSLinkedNode<EvtThread>() {
|
||||
}
|
25
src/event/EvtThread.hpp
Normal file
25
src/event/EvtThread.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef EVENT_EVT_THREAD_HPP
|
||||
#define EVENT_EVT_THREAD_HPP
|
||||
|
||||
#include "event/EvtContext.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/List.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
class EvtThread : public TSLinkedNode<EvtThread> {
|
||||
public:
|
||||
// Member variables
|
||||
uint32_t m_threadSlot;
|
||||
uint32_t m_threadCount;
|
||||
uint32_t m_weightTotal;
|
||||
uint32_t m_weightAvg;
|
||||
uint32_t m_contextCount;
|
||||
uint32_t m_rebalance;
|
||||
SEvent m_wakeEvent = SEvent(0, 0);
|
||||
EvtContextQueue m_contextQueue;
|
||||
|
||||
// Member functions
|
||||
EvtThread();
|
||||
};
|
||||
|
||||
#endif
|
27
src/event/EvtTimer.hpp
Normal file
27
src/event/EvtTimer.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef EVENT_EVT_TIMER_HPP
|
||||
#define EVENT_EVT_TIMER_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <storm/Queue.hpp>
|
||||
|
||||
class EvtTimer {
|
||||
public:
|
||||
// Member variables
|
||||
uint32_t id;
|
||||
TSTimerPriority<uint32_t> targetTime;
|
||||
float timeout;
|
||||
int32_t (*handler)(const void*, void*);
|
||||
void* param;
|
||||
int32_t (*guidHandler)(const void*, uint64_t, void*);
|
||||
uint64_t guidParam;
|
||||
void* guidParam2;
|
||||
};
|
||||
|
||||
class EvtTimerQueue : public TSPriorityQueue<EvtTimer> {
|
||||
public:
|
||||
EvtTimerQueue()
|
||||
: TSPriorityQueue<EvtTimer>(offsetof(EvtTimer, targetTime))
|
||||
{};
|
||||
};
|
||||
|
||||
#endif
|
686
src/event/Input.cpp
Normal file
686
src/event/Input.cpp
Normal file
@ -0,0 +1,686 @@
|
||||
#include "event/Input.hpp"
|
||||
#include "event/EvtContext.hpp"
|
||||
#include "event/Queue.hpp"
|
||||
#include "gx/Window.hpp"
|
||||
#include <common/Time.hpp>
|
||||
#include <storm/String.hpp>
|
||||
#include <storm/Unicode.hpp>
|
||||
#include <tempest/Rect.hpp>
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
#include "app/mac/MacClient.h"
|
||||
#endif
|
||||
|
||||
namespace Input {
|
||||
CRect s_boundingRect;
|
||||
int32_t s_queueHead;
|
||||
int32_t s_queueTail;
|
||||
OSEVENT s_queue[32];
|
||||
|
||||
MOUSEBUTTON s_buttonConversion[16] = {
|
||||
MOUSE_BUTTON_NONE,
|
||||
MOUSE_BUTTON_LEFT,
|
||||
MOUSE_BUTTON_RIGHT,
|
||||
MOUSE_BUTTON_MIDDLE,
|
||||
MOUSE_BUTTON_XBUTTON1,
|
||||
MOUSE_BUTTON_XBUTTON2,
|
||||
MOUSE_BUTTON_XBUTTON3,
|
||||
MOUSE_BUTTON_XBUTTON4,
|
||||
MOUSE_BUTTON_XBUTTON5,
|
||||
MOUSE_BUTTON_XBUTTON6,
|
||||
MOUSE_BUTTON_XBUTTON7,
|
||||
MOUSE_BUTTON_XBUTTON8,
|
||||
MOUSE_BUTTON_XBUTTON9,
|
||||
MOUSE_BUTTON_XBUTTON10,
|
||||
MOUSE_BUTTON_XBUTTON11,
|
||||
MOUSE_BUTTON_XBUTTON12,
|
||||
};
|
||||
}
|
||||
|
||||
int32_t Input::s_buttonDown[16];
|
||||
uint32_t Input::s_buttonState;
|
||||
C2iVector Input::s_currentMouse;
|
||||
uint32_t Input::s_mouseHoldButton;
|
||||
MOUSEMODE Input::s_mouseMode;
|
||||
int32_t Input::s_numlockState;
|
||||
int32_t Input::s_simulatedRightButtonClick;
|
||||
uint32_t Input::s_metaKeyState;
|
||||
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
int32_t Input::s_savedMouseSpeed;
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
double Input::s_savedMouseSpeed;
|
||||
#endif
|
||||
|
||||
void PostChar(EvtContext* context, int32_t ch, int32_t repeat) {
|
||||
EVENT_DATA_CHAR data;
|
||||
|
||||
data.ch = ch;
|
||||
data.metaKeyState = Input::s_metaKeyState;
|
||||
data.repeat = repeat;
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_CHAR, &data);
|
||||
}
|
||||
|
||||
void PostKeyDown(EvtContext* context, int32_t key, int32_t repeat, int32_t time) {
|
||||
if (key <= KEY_LASTMETAKEY) {
|
||||
if ((1 << key) & Input::s_metaKeyState) {
|
||||
return;
|
||||
}
|
||||
|
||||
Input::s_metaKeyState |= 1 << key;
|
||||
}
|
||||
|
||||
EVENT_DATA_KEY data;
|
||||
|
||||
data.key = static_cast<KEY>(key);
|
||||
data.metaKeyState = Input::s_metaKeyState;
|
||||
data.repeat = repeat;
|
||||
data.time = time;
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_KEYDOWN, &data);
|
||||
}
|
||||
|
||||
void PostKeyUp(EvtContext* context, int32_t key, int32_t repeat, int32_t time) {
|
||||
if (key <= KEY_LASTMETAKEY) {
|
||||
if ( !((1 << key) & Input::s_metaKeyState) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Input::s_metaKeyState &= ~(1 << key);
|
||||
}
|
||||
|
||||
EVENT_DATA_KEY data;
|
||||
|
||||
data.key = static_cast<KEY>(key);
|
||||
data.metaKeyState = Input::s_metaKeyState;
|
||||
data.repeat = repeat;
|
||||
data.time = time;
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_KEYUP, &data);
|
||||
}
|
||||
|
||||
void PostMouseDown(EvtContext* context, MOUSEBUTTON button, int32_t x, int32_t y, int32_t time) {
|
||||
Input::s_buttonState |= button;
|
||||
|
||||
EVENT_DATA_MOUSE data;
|
||||
|
||||
data.mode = Input::s_mouseMode;
|
||||
data.button = button;
|
||||
data.buttonState = Input::s_buttonState;
|
||||
data.metaKeyState = Input::s_metaKeyState;
|
||||
data.flags = GenerateMouseFlags();
|
||||
data.time = time;
|
||||
|
||||
ConvertPosition(x, y, &data.x, &data.y);
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_MOUSEDOWN, &data);
|
||||
}
|
||||
|
||||
void PostMouseMove(EvtContext* context, int32_t x, int32_t y, int32_t time) {
|
||||
EVENT_DATA_MOUSE data;
|
||||
|
||||
data.mode = Input::s_mouseMode;
|
||||
data.button = MOUSE_BUTTON_NONE;
|
||||
data.buttonState = Input::s_buttonState;
|
||||
data.metaKeyState = Input::s_metaKeyState;
|
||||
data.flags = GenerateMouseFlags();
|
||||
data.time = time;
|
||||
|
||||
ConvertPosition(x, y, &data.x, &data.y);
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_MOUSEMOVE, &data);
|
||||
}
|
||||
|
||||
void PostMouseUp(EvtContext* context, MOUSEBUTTON button, int32_t x, int32_t y, uint32_t flags, int32_t time) {
|
||||
Input::s_buttonState &= ~button;
|
||||
|
||||
EVENT_DATA_MOUSE data;
|
||||
|
||||
data.mode = Input::s_mouseMode;
|
||||
data.button = button;
|
||||
data.buttonState = Input::s_buttonState;
|
||||
data.metaKeyState = Input::s_metaKeyState;
|
||||
data.flags = flags | GenerateMouseFlags();
|
||||
data.time = time;
|
||||
|
||||
ConvertPosition(x, y, &data.x, &data.y);
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_MOUSEUP, &data);
|
||||
|
||||
CheckMouseModeState();
|
||||
}
|
||||
|
||||
void PostSize(EvtContext* context, int32_t w, int32_t h) {
|
||||
EVENT_DATA_SIZE data;
|
||||
|
||||
data.w = w;
|
||||
data.h = h;
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_SIZE, &data);
|
||||
}
|
||||
|
||||
void ProcessInput(const int32_t param[], OSINPUT id, int32_t* shutdown, EvtContext* context) {
|
||||
if (!context) {
|
||||
// TODO
|
||||
// nullsub_3();
|
||||
// SErrSetLastError(0x57u);
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case OS_INPUT_CAPTURE_CHANGED:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_CHAR:
|
||||
PostChar(
|
||||
context,
|
||||
param[0],
|
||||
param[1]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case OS_INPUT_STRING:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_IME:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_SIZE:
|
||||
PostSize(
|
||||
context,
|
||||
param[0],
|
||||
param[1]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case OS_INPUT_CLOSE:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_FOCUS:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_KEY_DOWN:
|
||||
PostKeyDown(
|
||||
context,
|
||||
param[0],
|
||||
param[1],
|
||||
param[3]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case OS_INPUT_KEY_UP:
|
||||
PostKeyUp(
|
||||
context,
|
||||
param[0],
|
||||
param[1],
|
||||
param[3]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case OS_INPUT_MOUSE_DOWN:
|
||||
PostMouseDown(
|
||||
context,
|
||||
static_cast<MOUSEBUTTON>(param[0]),
|
||||
param[1],
|
||||
param[2],
|
||||
param[3]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case OS_INPUT_MOUSE_MOVE:
|
||||
PostMouseMove(
|
||||
context,
|
||||
param[1],
|
||||
param[2],
|
||||
param[3]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case OS_INPUT_MOUSE_WHEEL:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_MOUSE_MOVE_RELATIVE:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_MOUSE_UP:
|
||||
PostMouseUp(
|
||||
context,
|
||||
static_cast<MOUSEBUTTON>(param[0]),
|
||||
param[1],
|
||||
param[2],
|
||||
0,
|
||||
param[3]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case OS_INPUT_14:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_15:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_16:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_17:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_18:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_SHUTDOWN:
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckMouseModeState() {
|
||||
if (Input::s_mouseHoldButton) {
|
||||
if (Input::s_mouseHoldButton != (Input::s_mouseHoldButton & Input::s_buttonState)) {
|
||||
// TODO
|
||||
// EventSetMouseMode(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MOUSEBUTTON ConvertButtonNumberToMOUSEBUTTON(int32_t buttonNumber) {
|
||||
return Input::s_buttonConversion[buttonNumber];
|
||||
}
|
||||
|
||||
void ConvertPosition(int32_t clientx, int32_t clienty, float* x, float* y) {
|
||||
if (Input::s_boundingRect.maxX - Input::s_boundingRect.minX != 0.0 && Input::s_boundingRect.maxY - Input::s_boundingRect.minY != 0.0) {
|
||||
C2Vector pt = {
|
||||
static_cast<float>(clientx),
|
||||
static_cast<float>(clienty)
|
||||
};
|
||||
|
||||
if (!Input::s_boundingRect.IsPointInside(pt)) {
|
||||
// TODO
|
||||
// - handle out of bounds positions
|
||||
}
|
||||
}
|
||||
|
||||
tagRECT windowDim;
|
||||
OsGetDefaultWindowRect(&windowDim);
|
||||
|
||||
*x = static_cast<float>(clientx) / static_cast<float>(windowDim.right - windowDim.left);
|
||||
*y = 1.0 - (static_cast<float>(clienty) / static_cast<float>(windowDim.bottom - windowDim.top));
|
||||
}
|
||||
|
||||
uint32_t GenerateMouseFlags() {
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (Input::s_mouseMode == MOUSE_MODE_RELATIVE) {
|
||||
flags |= 0x2;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
const char* GetButtonName(int32_t button) {
|
||||
switch (button) {
|
||||
case 0x1:
|
||||
return "LeftButton";
|
||||
case 0x2:
|
||||
return "MiddleButton";
|
||||
case 0x4:
|
||||
return "RightButton";
|
||||
case 0x8:
|
||||
return "Button4";
|
||||
case 0x10:
|
||||
return "Button5";
|
||||
case 0x20:
|
||||
return "Button6";
|
||||
case 0x40:
|
||||
return "Button7";
|
||||
case 0x80:
|
||||
return "Button8";
|
||||
case 0x100:
|
||||
return "Button9";
|
||||
case 0x200:
|
||||
return "Button10";
|
||||
case 0x400:
|
||||
return "Button11";
|
||||
case 0x800:
|
||||
return "Button12";
|
||||
case 0x1000:
|
||||
return "Button13";
|
||||
case 0x2000:
|
||||
return "Button14";
|
||||
case 0x4000:
|
||||
return "Button15";
|
||||
case 0x8000:
|
||||
return "Button16";
|
||||
case 0x10000:
|
||||
return "Button17";
|
||||
case 0x20000:
|
||||
return "Button18";
|
||||
case 0x40000:
|
||||
return "Button19";
|
||||
case 0x80000:
|
||||
return "Button20";
|
||||
case 0x100000:
|
||||
return "Button21";
|
||||
case 0x200000:
|
||||
return "Button22";
|
||||
case 0x400000:
|
||||
return "Button23";
|
||||
case 0x800000:
|
||||
return "Button24";
|
||||
case 0x1000000:
|
||||
return "Button25";
|
||||
case 0x2000000:
|
||||
return "Button26";
|
||||
case 0x4000000:
|
||||
return "Button27";
|
||||
case 0x8000000:
|
||||
return "Button28";
|
||||
case 0x10000000:
|
||||
return "Button29";
|
||||
case 0x20000000:
|
||||
return "Button30";
|
||||
case 0x40000000:
|
||||
return "Button31";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
void IEvtInputInitialize() {
|
||||
OsInputInitialize();
|
||||
}
|
||||
|
||||
int32_t IEvtInputProcess(EvtContext* context, int32_t* shutdown) {
|
||||
if (context) {
|
||||
// TODO
|
||||
// nullsub_3();
|
||||
|
||||
int32_t v4 = 0;
|
||||
OSINPUT id;
|
||||
int32_t param[4];
|
||||
|
||||
while (OsInputGet(&id, ¶m[0], ¶m[1], ¶m[2], ¶m[3])) {
|
||||
v4 = 1;
|
||||
ProcessInput(param, id, shutdown, context);
|
||||
}
|
||||
|
||||
return v4;
|
||||
} else {
|
||||
// TODO
|
||||
// nullsub_3();
|
||||
// SErrSetLastError(0x57u);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char* KeyCodeToString(KEY key) {
|
||||
static char charBuf[8];
|
||||
|
||||
if (key - 33 <= 222) {
|
||||
SUniSPutUTF8(key, charBuf);
|
||||
return charBuf;
|
||||
}
|
||||
|
||||
if (key <= KEY_SPACE) {
|
||||
switch (key) {
|
||||
case KEY_NONE:
|
||||
return "NONE";
|
||||
case KEY_LSHIFT:
|
||||
return "LSHIFT";
|
||||
case KEY_RSHIFT:
|
||||
return "RSHIFT";
|
||||
case KEY_LCONTROL:
|
||||
return "LCTRL";
|
||||
case KEY_RCONTROL:
|
||||
return "RCTRL";
|
||||
case KEY_LALT:
|
||||
return "LALT";
|
||||
case KEY_RALT:
|
||||
return "RALT";
|
||||
case KEY_SPACE:
|
||||
return "SPACE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
if (key <= KEY_ESCAPE) {
|
||||
switch (key) {
|
||||
case KEY_NUMPAD0:
|
||||
case KEY_NUMPAD1:
|
||||
case KEY_NUMPAD2:
|
||||
case KEY_NUMPAD3:
|
||||
case KEY_NUMPAD4:
|
||||
case KEY_NUMPAD5:
|
||||
case KEY_NUMPAD6:
|
||||
case KEY_NUMPAD7:
|
||||
case KEY_NUMPAD8:
|
||||
case KEY_NUMPAD9:
|
||||
SStrPrintf(charBuf, sizeof(charBuf), "NUMPAD%d", key);
|
||||
return charBuf;
|
||||
case KEY_NUMPAD_PLUS:
|
||||
return "NUMPADPLUS";
|
||||
case KEY_NUMPAD_MINUS:
|
||||
return "NUMPADMINUS";
|
||||
case KEY_NUMPAD_MULTIPLY:
|
||||
return "NUMPADMULTIPLY";
|
||||
case KEY_NUMPAD_DIVIDE:
|
||||
return "NUMPADDIVIDE";
|
||||
case KEY_NUMPAD_DECIMAL:
|
||||
return "NUMPADDECIMAL";
|
||||
case KEY_ESCAPE:
|
||||
return "ESCAPE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
if (key <= KEY_PRINTSCREEN) {
|
||||
switch (key) {
|
||||
case KEY_ENTER:
|
||||
return "ENTER";
|
||||
case KEY_BACKSPACE:
|
||||
return "BACKSPACE";
|
||||
case KEY_TAB:
|
||||
return "TAB";
|
||||
case KEY_LEFT:
|
||||
return "LEFT";
|
||||
case KEY_UP:
|
||||
return "UP";
|
||||
case KEY_RIGHT:
|
||||
return "RIGHT";
|
||||
case KEY_DOWN:
|
||||
return "DOWN";
|
||||
case KEY_INSERT:
|
||||
return "INSERT";
|
||||
case KEY_DELETE:
|
||||
return "DELETE";
|
||||
case KEY_HOME:
|
||||
return "HOME";
|
||||
case KEY_END:
|
||||
return "END";
|
||||
case KEY_PAGEUP:
|
||||
return "PAGEUP";
|
||||
case KEY_PAGEDOWN:
|
||||
return "PAGEDOWN";
|
||||
case KEY_CAPSLOCK:
|
||||
return "CAPSLOCK";
|
||||
case KEY_NUMLOCK:
|
||||
return "NUMLOCK";
|
||||
case KEY_PRINTSCREEN:
|
||||
return "PRINTSCREEN";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
if (key <= KEY_F12) {
|
||||
switch (key) {
|
||||
case KEY_F1:
|
||||
case KEY_F2:
|
||||
case KEY_F3:
|
||||
case KEY_F4:
|
||||
case KEY_F5:
|
||||
case KEY_F6:
|
||||
case KEY_F7:
|
||||
case KEY_F8:
|
||||
case KEY_F9:
|
||||
case KEY_F10:
|
||||
case KEY_F11:
|
||||
case KEY_F12:
|
||||
SStrPrintf(charBuf, sizeof(charBuf), "F%d", key - KEY_F1 + 1);
|
||||
return charBuf;
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
if (key == KEY_NUMPAD_EQUALS) {
|
||||
return "NUMPADEQUALS";
|
||||
}
|
||||
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
int32_t OsInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3) {
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
// TODO
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
// TODO
|
||||
// Unknown logic
|
||||
|
||||
if (!OsInputIsUsingCocoaEventLoop()) {
|
||||
// Legacy Carbon input handling
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// Steelseries WoW Mouse logic
|
||||
|
||||
if (Input::s_queueTail == Input::s_queueHead) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
OsQueueSetParam(3, OsGetAsyncTimeMs());
|
||||
|
||||
return OsQueueGet(id, param0, param1, param2, param3);
|
||||
#endif
|
||||
}
|
||||
|
||||
void OsInputInitialize() {
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
Input::s_numlockState = GetAsyncKeyState(144);
|
||||
PVOID pvParam = 10;
|
||||
SystemParametersInfoA(SPI_GETMOUSESPEED, 0, &pvParam, 0);
|
||||
Input::s_savedMouseSpeed = pvParam;
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
// Legacy Carbon input handling
|
||||
// if (!byte_143EFE0) {
|
||||
// Carbon_OsInputRegisterHICommandHandler(0x71756974, sub_A4F230);
|
||||
// }
|
||||
|
||||
MacClient::SetMouseCoalescingEnabled(true);
|
||||
Input::s_savedMouseSpeed = MacClient::GetMouseSpeed();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool OsInputIsUsingCocoaEventLoop() {
|
||||
// TODO
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OsInputPostEvent(OSINPUT id, int32_t param0, int32_t param1, int32_t param2, int32_t param3) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
int32_t OsQueueGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3) {
|
||||
if (Input::s_queueTail == Input::s_queueHead) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
OSEVENT event = Input::s_queue[Input::s_queueTail];
|
||||
|
||||
*id = event.id;
|
||||
*param0 = event.param[0];
|
||||
*param1 = event.param[1];
|
||||
*param2 = event.param[2];
|
||||
*param3 = event.param[3];
|
||||
|
||||
if (Input::s_queueTail == OS_QUEUE_SIZE - 1) {
|
||||
Input:: s_queueTail = 0;
|
||||
} else {
|
||||
++Input::s_queueTail;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void OsQueuePut(OSINPUT id, int32_t param0, int32_t param1, int32_t param2, int32_t param3) {
|
||||
int32_t nextTail = 0;
|
||||
int32_t nextHead = 0;
|
||||
|
||||
if (Input::s_queueHead != OS_QUEUE_SIZE - 1) {
|
||||
nextHead = Input::s_queueHead + 1;
|
||||
}
|
||||
|
||||
if (nextHead == Input::s_queueTail) {
|
||||
if (nextHead != OS_QUEUE_SIZE - 1) {
|
||||
nextTail = nextHead + 1;
|
||||
}
|
||||
|
||||
Input::s_queueTail = nextTail;
|
||||
}
|
||||
|
||||
OSEVENT* event = &Input::s_queue[Input::s_queueHead];
|
||||
|
||||
event->id = id;
|
||||
event->param[0] = param0;
|
||||
event->param[1] = param1;
|
||||
event->param[2] = param2;
|
||||
event->param[3] = param3;
|
||||
|
||||
Input::s_queueHead = nextHead;
|
||||
}
|
||||
|
||||
void OsQueueSetParam(int32_t index, int32_t param) {
|
||||
int32_t pos = Input::s_queueTail;
|
||||
|
||||
while (pos != Input::s_queueHead) {
|
||||
OSEVENT* event = &Input::s_queue[pos];
|
||||
event->param[index] = param;
|
||||
|
||||
if (pos == OS_QUEUE_SIZE - 1) {
|
||||
pos = 0;
|
||||
} else {
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
}
|
62
src/event/Input.hpp
Normal file
62
src/event/Input.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef EVENT_INPUT_HPP
|
||||
#define EVENT_INPUT_HPP
|
||||
|
||||
#include "event/Types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
#define OS_QUEUE_SIZE 32
|
||||
|
||||
class C2iVector;
|
||||
class CRect;
|
||||
class EvtContext;
|
||||
|
||||
namespace Input {
|
||||
extern int32_t s_buttonDown[16];
|
||||
extern uint32_t s_buttonState;
|
||||
extern C2iVector s_currentMouse;
|
||||
extern uint32_t s_mouseHoldButton;
|
||||
extern MOUSEMODE s_mouseMode;
|
||||
extern int32_t s_numlockState;
|
||||
extern int32_t s_simulatedRightButtonClick;
|
||||
extern uint32_t s_metaKeyState;
|
||||
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
extern int32_t s_savedMouseSpeed;
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
extern double s_savedMouseSpeed;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CheckMouseModeState(void);
|
||||
|
||||
MOUSEBUTTON ConvertButtonNumberToMOUSEBUTTON(int32_t);
|
||||
|
||||
void ConvertPosition(int32_t, int32_t, float*, float*);
|
||||
|
||||
uint32_t GenerateMouseFlags(void);
|
||||
|
||||
const char* GetButtonName(int32_t);
|
||||
|
||||
void IEvtInputInitialize();
|
||||
|
||||
int32_t IEvtInputProcess(EvtContext* context, int32_t* shutdown);
|
||||
|
||||
const char* KeyCodeToString(KEY);
|
||||
|
||||
int32_t OsInputGet(OSINPUT*, int32_t*, int32_t*, int32_t*, int32_t*);
|
||||
|
||||
void OsInputInitialize(void);
|
||||
|
||||
bool OsInputIsUsingCocoaEventLoop(void);
|
||||
|
||||
void OsInputPostEvent(OSINPUT, int32_t, int32_t, int32_t, int32_t);
|
||||
|
||||
int32_t OsQueueGet(OSINPUT*, int32_t*, int32_t*, int32_t*, int32_t*);
|
||||
|
||||
void OsQueuePut(OSINPUT, int32_t, int32_t, int32_t, int32_t);
|
||||
|
||||
void OsQueueSetParam(int32_t, int32_t);
|
||||
|
||||
#endif
|
74
src/event/Queue.cpp
Normal file
74
src/event/Queue.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
#include "event/Queue.hpp"
|
||||
#include "event/EvtContext.hpp"
|
||||
#include "event/EvtHandler.hpp"
|
||||
#include <storm/Error.hpp>
|
||||
|
||||
void IEvtQueueDispatch(EvtContext* context, EVENTID id, const void* data) {
|
||||
STORM_ASSERT(context);
|
||||
|
||||
// TODO
|
||||
// UpdateSyncState(data, &id, context, v3);
|
||||
|
||||
// TODO
|
||||
// if (SErrIsDisplayingError()) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
auto handlerList = &context->m_queueHandlerList[id];
|
||||
|
||||
EvtHandler marker;
|
||||
marker.marker = 1;
|
||||
|
||||
handlerList->LinkNode(&marker, 1, nullptr);
|
||||
|
||||
EvtHandler* handler;
|
||||
|
||||
while (1) {
|
||||
handler = marker.link.Next();
|
||||
|
||||
if (!handler) {
|
||||
break;
|
||||
}
|
||||
|
||||
handlerList->LinkNode(&marker, 1, marker.link.Next());
|
||||
|
||||
if (!handler->marker && !handler->func(data, handler->param)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
handlerList->UnlinkNode(&marker);
|
||||
}
|
||||
|
||||
void IEvtQueueDispatchAll(EvtContext* context) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void IEvtQueueRegister(EvtContext* context, EVENTID id, int32_t (*handler)(const void*, void*), void* param, float priority) {
|
||||
STORM_ASSERT(context);
|
||||
|
||||
auto handlerList = &context->m_queueHandlerList[id];
|
||||
|
||||
EvtHandler* evtHandler;
|
||||
|
||||
void* m = SMemAlloc(sizeof(EvtHandler), __FILE__, __LINE__, 0x8);
|
||||
|
||||
if (m) {
|
||||
evtHandler = new (m) EvtHandler();
|
||||
} else {
|
||||
evtHandler = nullptr;
|
||||
}
|
||||
|
||||
evtHandler->priority = priority;
|
||||
evtHandler->param = param;
|
||||
evtHandler->func = handler;
|
||||
evtHandler->marker = 0;
|
||||
|
||||
EvtHandler* h = handlerList->Head();
|
||||
|
||||
while (h && (priority < h->priority || h->marker)) {
|
||||
h = handlerList->Link(h)->Next();
|
||||
}
|
||||
|
||||
handlerList->LinkNode(evtHandler, 1, h);
|
||||
}
|
14
src/event/Queue.hpp
Normal file
14
src/event/Queue.hpp
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef EVENT_QUEUE_HPP
|
||||
#define EVENT_QUEUE_HPP
|
||||
|
||||
#include "event/Types.hpp"
|
||||
|
||||
class EvtContext;
|
||||
|
||||
void IEvtQueueDispatch(EvtContext* context, EVENTID id, const void* data);
|
||||
|
||||
void IEvtQueueDispatchAll(EvtContext* context);
|
||||
|
||||
void IEvtQueueRegister(EvtContext* context, EVENTID id, int32_t (*handler)(const void*, void*), void* param, float priority);
|
||||
|
||||
#endif
|
382
src/event/Scheduler.cpp
Normal file
382
src/event/Scheduler.cpp
Normal file
@ -0,0 +1,382 @@
|
||||
#include "event/Scheduler.hpp"
|
||||
#include "event/Context.hpp"
|
||||
#include "event/Event.hpp"
|
||||
#include "event/EvtContext.hpp"
|
||||
#include "event/EvtThread.hpp"
|
||||
#include "event/Input.hpp"
|
||||
#include "event/Queue.hpp"
|
||||
#include "event/Synthesize.hpp"
|
||||
#include "event/Timer.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <common/Call.hpp>
|
||||
#include <common/Prop.hpp>
|
||||
#include <common/Time.hpp>
|
||||
#include <storm/Memory.hpp>
|
||||
#include <storm/String.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
#include "event/mac/Event.h"
|
||||
#endif
|
||||
|
||||
void DestroySchedulerThread(uint32_t a1) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
HEVENTCONTEXT IEvtSchedulerCreateContext(int32_t interactive, int32_t (*initializeHandler)(const void*, void*), int32_t (*destroyHandler)(const void*, void*), uint32_t idleTime, uint32_t debugFlags) {
|
||||
if (idleTime < 1) {
|
||||
idleTime = 1;
|
||||
}
|
||||
|
||||
char contextName[256];
|
||||
void* callContext = nullptr;
|
||||
|
||||
if (debugFlags & 0x1) {
|
||||
SStrPrintf(contextName, 256, "Context: interactive = %u, idleTime = %u", interactive, idleTime);
|
||||
callContext = OsCallInitializeContext(contextName);
|
||||
}
|
||||
|
||||
void* m = SMemAlloc(sizeof(EvtContext), __FILE__, __LINE__, 0);
|
||||
|
||||
EvtContext* context;
|
||||
|
||||
if (m) {
|
||||
context = new (m) EvtContext(
|
||||
interactive != 0 ? 2 : 0,
|
||||
idleTime,
|
||||
interactive != 0 ? 1000 : 1,
|
||||
callContext,
|
||||
(debugFlags >> 1) & 1
|
||||
);
|
||||
} else {
|
||||
context = nullptr;
|
||||
}
|
||||
|
||||
if (interactive) {
|
||||
SInterlockedIncrement(&Event::s_interactiveCount);
|
||||
}
|
||||
|
||||
if (initializeHandler) {
|
||||
IEvtQueueRegister(context, EVENT_ID_INITIALIZE, initializeHandler, 0, 1000.0);
|
||||
}
|
||||
|
||||
if (destroyHandler) {
|
||||
IEvtQueueRegister(context, EVENT_ID_DESTROY, destroyHandler, 0, 1000.0);
|
||||
}
|
||||
|
||||
return AttachContextToThread(context);
|
||||
}
|
||||
|
||||
void IEvtSchedulerInitialize(int32_t threadCount, int32_t netServer) {
|
||||
if (Event::s_threadSlotCount) {
|
||||
// SErrDisplayAppFatal("IEvtScheduler already initialized");
|
||||
}
|
||||
|
||||
Event::s_netServer = netServer;
|
||||
|
||||
// TODO
|
||||
// Thread::s_originalThreadPriority = SGetCurrentThreadPriority();
|
||||
|
||||
int32_t threadSlotCount = 1;
|
||||
|
||||
while (threadSlotCount < threadCount) {
|
||||
threadSlotCount *= 2;
|
||||
}
|
||||
|
||||
Event::s_threadSlotCount = threadSlotCount;
|
||||
|
||||
// Allocate SCritSects for each thread slot
|
||||
int32_t v4 = sizeof(SCritSect) * threadSlotCount;
|
||||
|
||||
void* v5 = SMemAlloc((v4 + 4), ".\\EvtSched.cpp", 791, 0);
|
||||
|
||||
if (v5) {
|
||||
Event::s_threadSlotCritsects = new (v5) SCritSect[threadSlotCount];
|
||||
} else {
|
||||
Event::s_threadSlotCritsects = nullptr;
|
||||
}
|
||||
|
||||
// Allocate EvtThread pointers for each thread slot
|
||||
Event::s_threadSlots = static_cast<EvtThread**>(SMemAlloc(sizeof(EvtThread*) * threadSlotCount, __FILE__, __LINE__, 0));
|
||||
memset(Event::s_threadSlots, 0, sizeof(EvtThread*) * threadSlotCount);
|
||||
|
||||
Event::s_startEvent.Reset();
|
||||
Event::s_shutdownEvent.Reset();
|
||||
|
||||
Event::s_mainThread = InitializeSchedulerThread();
|
||||
|
||||
for (int32_t i = 0; i < threadCount - 1; ++i) {
|
||||
void* m = SMemAlloc(sizeof(SThread), __FILE__, __LINE__, 0);
|
||||
|
||||
SThread* thread;
|
||||
|
||||
if (m) {
|
||||
thread = new (m) SThread();
|
||||
} else {
|
||||
thread = nullptr;
|
||||
}
|
||||
|
||||
Event::s_schedulerThreads.SetCount(Event::s_schedulerThreads.Count() + 1);
|
||||
|
||||
Event::s_schedulerThreads[Event::s_schedulerThreads.Count() - 1] = thread;
|
||||
|
||||
char threadName[16];
|
||||
SStrPrintf(threadName, 16, "EvtSched#%d", i);
|
||||
|
||||
if (!SThread::Create(&SchedulerThreadProc, 0, *thread, threadName, 0)) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IEvtSchedulerProcess() {
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
Event::s_startEvent.Set();
|
||||
|
||||
SchedulerThreadProc(1);
|
||||
|
||||
Event::s_mainThread = 0;
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
Event::s_startEvent.Set();
|
||||
|
||||
if (OsInputIsUsingCocoaEventLoop()) {
|
||||
PropSelectContext(0);
|
||||
|
||||
Event::s_startEvent.Wait(0xFFFFFFFF);
|
||||
|
||||
uintptr_t v0 = SGetCurrentThreadId();
|
||||
char v2[64];
|
||||
SStrPrintf(v2, 64, "Engine %x", v0);
|
||||
|
||||
OsCallInitialize(v2);
|
||||
|
||||
RunCocoaEventLoop();
|
||||
|
||||
DestroySchedulerThread(Event::s_mainThread);
|
||||
OsCallDestroy();
|
||||
|
||||
Event::s_mainThread = 0;
|
||||
} else {
|
||||
// Legacy
|
||||
// sub_890180(1);
|
||||
// dword_141B3C8 = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void IEvtSchedulerShutdown() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
uint32_t InitializeSchedulerThread() {
|
||||
SInterlockedIncrement(&Event::s_threadListContention);
|
||||
|
||||
Event::s_threadListCritsect.Enter();
|
||||
|
||||
uint32_t slot = Event::s_threadSlotCount;
|
||||
|
||||
for (int32_t i = 0; i < Event::s_threadSlotCount; ++i) {
|
||||
if (slot == Event::s_threadSlotCount
|
||||
|| Event::s_threadSlots[i] == nullptr
|
||||
|| Event::s_threadSlots[i]->m_threadCount < Event::s_threadSlots[slot]->m_threadCount)
|
||||
{
|
||||
slot = i;
|
||||
|
||||
if (!Event::s_threadSlots[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EvtThread* v4 = Event::s_threadSlots[slot];
|
||||
|
||||
if (!v4) {
|
||||
v4 = Event::s_threadList.NewNode(1, 0, 0x8);
|
||||
|
||||
v4->m_threadCount = 0;
|
||||
v4->m_weightTotal = 0;
|
||||
v4->m_weightAvg = 0;
|
||||
v4->m_contextCount = 0;
|
||||
v4->m_rebalance = 0;
|
||||
v4->m_threadSlot = slot;
|
||||
|
||||
Event::s_threadSlotCritsects[slot].Enter();
|
||||
|
||||
Event::s_threadSlots[slot] = v4;
|
||||
|
||||
Event::s_threadSlotCritsects[slot].Leave();
|
||||
}
|
||||
|
||||
++v4->m_threadCount;
|
||||
|
||||
Event::s_threadListCritsect.Leave();
|
||||
|
||||
SInterlockedDecrement(&Event::s_threadListContention);
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
bool SchedulerMainProcess() {
|
||||
return SchedulerThreadProcProcess(Event::s_mainThread) != 0;
|
||||
}
|
||||
|
||||
uint32_t SchedulerThreadProc(void* mainThread) {
|
||||
uint32_t v1;
|
||||
|
||||
if (mainThread) {
|
||||
v1 = Event::s_mainThread;
|
||||
} else {
|
||||
v1 = InitializeSchedulerThread();
|
||||
}
|
||||
|
||||
PropSelectContext(0);
|
||||
|
||||
Event::s_startEvent.Wait(0xFFFFFFFF);
|
||||
|
||||
uintptr_t v2 = SGetCurrentThreadId();
|
||||
char v4[64];
|
||||
SStrPrintf(v4, 64, "Engine %x", v2);
|
||||
|
||||
OsCallInitialize(v4);
|
||||
|
||||
while (!SchedulerThreadProcProcess(v1));
|
||||
|
||||
DestroySchedulerThread(v1);
|
||||
OsCallDestroy();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t SchedulerThreadProcProcess(uint32_t a1) {
|
||||
// TODO
|
||||
// if (SGetCurrentThreadPriority() != Event::s_originalThreadPriority) {
|
||||
// SSetCurrentThreadPriority(Event::s_originalThreadPriority);
|
||||
// }
|
||||
|
||||
if (!Event::s_shutdownEvent.Wait(0)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
EvtContext* context = GetNextContext(a1);
|
||||
|
||||
int32_t v11;
|
||||
|
||||
if (context) {
|
||||
v11 = context->m_schedNextWakeTime.m_val - OsGetAsyncTimeMs();
|
||||
|
||||
if (v11 < 0) {
|
||||
v11 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t v14;
|
||||
|
||||
if (Event::s_netServer) {
|
||||
if (v11 == -1) {
|
||||
v11 = 100;
|
||||
}
|
||||
|
||||
OsNetPump(v11);
|
||||
|
||||
v14 = 258;
|
||||
} else {
|
||||
v14 = Event::s_threadSlots[a1]->m_wakeEvent.Wait(v11);
|
||||
}
|
||||
|
||||
if (!context) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PropSelectContext(context->m_propContext);
|
||||
PropSet(PROP_EVENTCONTEXT, &context->m_id);
|
||||
OsCallSetContext(context->m_callContext);
|
||||
|
||||
uint32_t currTime = OsGetAsyncTimeMs();
|
||||
uint32_t v19 = context->m_id;
|
||||
|
||||
if (v14 == 258) {
|
||||
if (SynthesizeInitialize(context)) {
|
||||
if (context->m_startWatchdog) {
|
||||
// nullsub_5(20, 1);
|
||||
// *a2 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t v9 = (currTime - context->m_schedLastIdle);
|
||||
context->m_schedLastIdle = currTime;
|
||||
double elapsedSec = v9 * 0.001;
|
||||
|
||||
// TODO
|
||||
// FrameTime::Update(currTime, elapsedSec);
|
||||
|
||||
IEvtTimerDispatch(context);
|
||||
|
||||
if (context->m_schedFlags & 0x2) {
|
||||
int32_t shutdown = 0;
|
||||
IEvtInputProcess(context, &shutdown);
|
||||
|
||||
if (shutdown) {
|
||||
context->m_critsect.Enter();
|
||||
|
||||
if (context->m_schedState == EvtContext::SCHEDSTATE_ACTIVE) {
|
||||
context->m_schedState = EvtContext::SCHEDSTATE_CLOSED;
|
||||
}
|
||||
|
||||
context->m_critsect.Leave();
|
||||
|
||||
IEvtSchedulerShutdown();
|
||||
}
|
||||
}
|
||||
|
||||
SynthesizePoll(context);
|
||||
IEvtQueueDispatchAll(context);
|
||||
SynthesizeIdle(context, currTime, elapsedSec);
|
||||
SynthesizePaint(context);
|
||||
}
|
||||
|
||||
if (a1 == Event::s_mainThread) {
|
||||
// TODO
|
||||
// dword_B417C4 = 0;
|
||||
}
|
||||
|
||||
context->m_critsect.Enter();
|
||||
|
||||
uint32_t closed = context->m_schedState == EvtContext::SCHEDSTATE_CLOSED;
|
||||
|
||||
context->m_critsect.Leave();
|
||||
|
||||
if (closed) {
|
||||
DetachContextFromThread(a1, context);
|
||||
SynthesizeDestroy(context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t nextDelay;
|
||||
|
||||
if (context->m_schedFlags & 0x4) {
|
||||
nextDelay = 0;
|
||||
} else {
|
||||
int32_t v15 = IEvtTimerGetNextTime(context, currTime);
|
||||
int32_t v16 = context->m_schedIdleTime;
|
||||
|
||||
nextDelay = v15;
|
||||
|
||||
if (v16 != context->m_schedInitialIdleTime) {
|
||||
nextDelay = context->m_schedIdleTime;
|
||||
}
|
||||
|
||||
nextDelay = std::min(
|
||||
nextDelay,
|
||||
std::max((uint32_t)0, v16 + context->m_schedLastIdle - currTime)
|
||||
);
|
||||
}
|
||||
|
||||
OsCallResetContext(context->m_callContext);
|
||||
PropSelectContext(nullptr);
|
||||
PutContext(nextDelay + currTime, context->m_schedSmoothWeight, context, a1);
|
||||
|
||||
return 0;
|
||||
}
|
25
src/event/Scheduler.hpp
Normal file
25
src/event/Scheduler.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef EVENT_SCHEDULER_HPP
|
||||
#define EVENT_SCHEDULER_HPP
|
||||
|
||||
#include "event/Types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
void DestroySchedulerThread(uint32_t a1);
|
||||
|
||||
HEVENTCONTEXT IEvtSchedulerCreateContext(int32_t interactive, int32_t (*initializeHandler)(const void*, void*), int32_t (*destroyHandler)(const void*, void*), uint32_t idleTime, uint32_t debugFlags);
|
||||
|
||||
void IEvtSchedulerInitialize(int32_t threadCount, int32_t netServer);
|
||||
|
||||
void IEvtSchedulerProcess();
|
||||
|
||||
void IEvtSchedulerShutdown();
|
||||
|
||||
uint32_t InitializeSchedulerThread();
|
||||
|
||||
bool SchedulerMainProcess();
|
||||
|
||||
uint32_t SchedulerThreadProc(void* mainThread);
|
||||
|
||||
int32_t SchedulerThreadProcProcess(uint32_t a1);
|
||||
|
||||
#endif
|
81
src/event/Synthesize.cpp
Normal file
81
src/event/Synthesize.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include "event/Synthesize.hpp"
|
||||
#include "event/EvtContext.hpp"
|
||||
#include "event/Queue.hpp"
|
||||
#include <common/Time.hpp>
|
||||
|
||||
void SynthesizeDestroy(EvtContext* context) {
|
||||
// TODO
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void SynthesizeIdle(EvtContext* context, uint32_t currTime, float elapsedSec) {
|
||||
bool closed;
|
||||
|
||||
context->m_critsect.Enter();
|
||||
closed = context->m_schedState == EvtContext::SCHEDSTATE_CLOSED;
|
||||
context->m_critsect.Leave();
|
||||
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t schedFlags = context->m_schedFlags;
|
||||
|
||||
if (schedFlags & 0x2) {
|
||||
context->m_schedFlags = schedFlags | 0x4;
|
||||
}
|
||||
|
||||
EVENT_DATA_IDLE data;
|
||||
data.elapsedSec = elapsedSec;
|
||||
data.time = currTime;
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_IDLE, &data);
|
||||
}
|
||||
|
||||
int32_t SynthesizeInitialize(EvtContext* context) {
|
||||
uint32_t schedFlags = context->m_schedFlags;
|
||||
|
||||
if (schedFlags & 0x1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
context->m_schedFlags = schedFlags | 0x1;
|
||||
context->m_schedLastIdle = OsGetAsyncTimeMs();
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_INITIALIZE, nullptr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SynthesizePaint(EvtContext* context) {
|
||||
bool closed;
|
||||
|
||||
context->m_critsect.Enter();
|
||||
closed = context->m_schedState == EvtContext::SCHEDSTATE_CLOSED;
|
||||
context->m_critsect.Leave();
|
||||
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t schedFlags = context->m_schedFlags;
|
||||
|
||||
if (schedFlags & 0x4) {
|
||||
context->m_schedFlags = schedFlags & ~0x4;
|
||||
IEvtQueueDispatch(context, EVENT_ID_PAINT, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void SynthesizePoll(EvtContext* context) {
|
||||
bool closed;
|
||||
|
||||
context->m_critsect.Enter();
|
||||
closed = context->m_schedState == EvtContext::SCHEDSTATE_CLOSED;
|
||||
context->m_critsect.Leave();
|
||||
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_POLL, nullptr);
|
||||
}
|
18
src/event/Synthesize.hpp
Normal file
18
src/event/Synthesize.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef EVENT_SYNTHESIZE_HPP
|
||||
#define EVENT_SYNTHESIZE_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class EvtContext;
|
||||
|
||||
void SynthesizeDestroy(EvtContext* context);
|
||||
|
||||
void SynthesizeIdle(EvtContext* context, uint32_t currTime, float elapsedSec);
|
||||
|
||||
int32_t SynthesizeInitialize(EvtContext* context);
|
||||
|
||||
void SynthesizePaint(EvtContext* context);
|
||||
|
||||
void SynthesizePoll(EvtContext* context);
|
||||
|
||||
#endif
|
29
src/event/Timer.cpp
Normal file
29
src/event/Timer.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
#include "event/Timer.hpp"
|
||||
#include "event/EvtContext.hpp"
|
||||
#include "event/EvtTimer.hpp"
|
||||
#include <storm/Error.hpp>
|
||||
|
||||
int32_t IEvtTimerDispatch(EvtContext* context) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t IEvtTimerGetNextTime(EvtContext* context, uint32_t currTime) {
|
||||
STORM_ASSERT(context);
|
||||
|
||||
context->m_critsect.Enter();
|
||||
|
||||
uint32_t nextTime = -1;
|
||||
|
||||
if (context->m_timerQueue.Count()) {
|
||||
auto queue = static_cast<EvtTimer*>(context->m_timerQueue[0]);
|
||||
auto targetTime = queue->targetTime.m_val;
|
||||
nextTime = targetTime - currTime;
|
||||
nextTime = nextTime < 0 ? 0 : nextTime;
|
||||
}
|
||||
|
||||
context->m_critsect.Leave();
|
||||
|
||||
return nextTime;
|
||||
}
|
12
src/event/Timer.hpp
Normal file
12
src/event/Timer.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef EVENT_TIMER_HPP
|
||||
#define EVENT_TIMER_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class EvtContext;
|
||||
|
||||
int32_t IEvtTimerDispatch(EvtContext* context);
|
||||
|
||||
uint32_t IEvtTimerGetNextTime(EvtContext* context, uint32_t currTime);
|
||||
|
||||
#endif
|
252
src/event/Types.hpp
Normal file
252
src/event/Types.hpp
Normal file
@ -0,0 +1,252 @@
|
||||
#ifndef EVENT_TYPES_HPP
|
||||
#define EVENT_TYPES_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
typedef void* HEVENTCONTEXT;
|
||||
typedef int32_t (*EVENTHANDLERFUNC)(const void*, void*);
|
||||
|
||||
enum EVENTID {
|
||||
EVENT_ID_0 = 0,
|
||||
EVENT_ID_CHAR = 1,
|
||||
EVENT_ID_FOCUS = 2,
|
||||
EVENT_ID_3 = 3,
|
||||
EVENT_ID_DESTROY = 4,
|
||||
EVENT_ID_5 = 5,
|
||||
EVENT_ID_IDLE = 6,
|
||||
EVENT_ID_POLL = 7,
|
||||
EVENT_ID_INITIALIZE = 8,
|
||||
EVENT_ID_KEYDOWN = 9,
|
||||
EVENT_ID_KEYUP = 10,
|
||||
EVENT_ID_KEYDOWN_REPEATING = 11,
|
||||
EVENT_ID_MOUSEDOWN = 12,
|
||||
EVENT_ID_MOUSEMOVE = 13,
|
||||
EVENT_ID_MOUSEMOVE_RELATIVE = 14,
|
||||
EVENT_ID_MOUSEUP = 15,
|
||||
EVENT_ID_MOUSEMODE_CHANGED = 16,
|
||||
EVENT_ID_MOUSEWHEEL = 17,
|
||||
EVENT_ID_18 = 18,
|
||||
EVENT_ID_19 = 19,
|
||||
EVENT_ID_20 = 20,
|
||||
EVENT_ID_21 = 21,
|
||||
EVENT_ID_22 = 22,
|
||||
EVENT_ID_PAINT = 23,
|
||||
EVENT_ID_24 = 24,
|
||||
EVENT_ID_25 = 25,
|
||||
EVENT_ID_26 = 26,
|
||||
EVENT_ID_27 = 27,
|
||||
EVENT_ID_28 = 28,
|
||||
EVENT_ID_29 = 29,
|
||||
EVENT_ID_30 = 30,
|
||||
EVENT_ID_31 = 31,
|
||||
EVENT_ID_32 = 32,
|
||||
EVENT_ID_33 = 33,
|
||||
EVENT_ID_IME = 34,
|
||||
EVENT_ID_SIZE = 35,
|
||||
EVENTIDS = 36
|
||||
};
|
||||
|
||||
enum KEY {
|
||||
KEY_NONE = 0xFFFFFFFF,
|
||||
KEY_LSHIFT = 0x0,
|
||||
KEY_RSHIFT = 0x1,
|
||||
KEY_LCONTROL = 0x2,
|
||||
KEY_RCONTROL = 0x3,
|
||||
KEY_LALT = 0x4,
|
||||
KEY_RALT = 0x5,
|
||||
KEY_LASTMETAKEY = 0x5,
|
||||
KEY_SPACE = 0x20,
|
||||
KEY_0 = 0x30,
|
||||
KEY_1 = 0x31,
|
||||
KEY_2 = 0x32,
|
||||
KEY_3 = 0x33,
|
||||
KEY_4 = 0x34,
|
||||
KEY_5 = 0x35,
|
||||
KEY_6 = 0x36,
|
||||
KEY_7 = 0x37,
|
||||
KEY_8 = 0x38,
|
||||
KEY_9 = 0x39,
|
||||
KEY_A = 0x41,
|
||||
KEY_B = 0x42,
|
||||
KEY_C = 0x43,
|
||||
KEY_D = 0x44,
|
||||
KEY_E = 0x45,
|
||||
KEY_F = 0x46,
|
||||
KEY_G = 0x47,
|
||||
KEY_H = 0x48,
|
||||
KEY_I = 0x49,
|
||||
KEY_J = 0x4A,
|
||||
KEY_K = 0x4B,
|
||||
KEY_L = 0x4C,
|
||||
KEY_M = 0x4D,
|
||||
KEY_N = 0x4E,
|
||||
KEY_O = 0x4F,
|
||||
KEY_P = 0x50,
|
||||
KEY_Q = 0x51,
|
||||
KEY_R = 0x52,
|
||||
KEY_S = 0x53,
|
||||
KEY_T = 0x54,
|
||||
KEY_U = 0x55,
|
||||
KEY_V = 0x56,
|
||||
KEY_W = 0x57,
|
||||
KEY_X = 0x58,
|
||||
KEY_Y = 0x59,
|
||||
KEY_Z = 0x5A,
|
||||
KEY_TILDE = 0x60,
|
||||
KEY_NUMPAD0 = 0x100,
|
||||
KEY_NUMPAD1 = 0x101,
|
||||
KEY_NUMPAD2 = 0x102,
|
||||
KEY_NUMPAD3 = 0x103,
|
||||
KEY_NUMPAD4 = 0x104,
|
||||
KEY_NUMPAD5 = 0x105,
|
||||
KEY_NUMPAD6 = 0x106,
|
||||
KEY_NUMPAD7 = 0x107,
|
||||
KEY_NUMPAD8 = 0x108,
|
||||
KEY_NUMPAD9 = 0x109,
|
||||
KEY_NUMPAD_PLUS = 0x10A,
|
||||
KEY_NUMPAD_MINUS = 0x10B,
|
||||
KEY_NUMPAD_MULTIPLY = 0x10C,
|
||||
KEY_NUMPAD_DIVIDE = 0x10D,
|
||||
KEY_NUMPAD_DECIMAL = 0x10E,
|
||||
KEY_NUMPAD_EQUALS = 0x30C,
|
||||
KEY_PLUS = 0x3D,
|
||||
KEY_MINUS = 0x2D,
|
||||
KEY_BRACKET_OPEN = 0x5B,
|
||||
KEY_BRACKET_CLOSE = 0x5D,
|
||||
KEY_SLASH = 0x2F,
|
||||
KEY_BACKSLASH = 0x5C,
|
||||
KEY_SEMICOLON = 0x3B,
|
||||
KEY_APOSTROPHE = 0x27,
|
||||
KEY_COMMA = 0x2C,
|
||||
KEY_PERIOD = 0x2E,
|
||||
KEY_ESCAPE = 0x200,
|
||||
KEY_ENTER = 0x201,
|
||||
KEY_BACKSPACE = 0x202,
|
||||
KEY_TAB = 0x203,
|
||||
KEY_LEFT = 0x204,
|
||||
KEY_UP = 0x205,
|
||||
KEY_RIGHT = 0x206,
|
||||
KEY_DOWN = 0x207,
|
||||
KEY_INSERT = 0x208,
|
||||
KEY_DELETE = 0x209,
|
||||
KEY_HOME = 0x20A,
|
||||
KEY_END = 0x20B,
|
||||
KEY_PAGEUP = 0x20C,
|
||||
KEY_PAGEDOWN = 0x20D,
|
||||
KEY_CAPSLOCK = 0x20E,
|
||||
KEY_NUMLOCK = 0x20F,
|
||||
KEY_SCROLLLOCK = 0x210,
|
||||
KEY_PAUSE = 0x211,
|
||||
KEY_PRINTSCREEN = 0x212,
|
||||
KEY_F1 = 0x300,
|
||||
KEY_F2 = 0x301,
|
||||
KEY_F3 = 0x302,
|
||||
KEY_F4 = 0x303,
|
||||
KEY_F5 = 0x304,
|
||||
KEY_F6 = 0x305,
|
||||
KEY_F7 = 0x306,
|
||||
KEY_F8 = 0x307,
|
||||
KEY_F9 = 0x308,
|
||||
KEY_F10 = 0x309,
|
||||
KEY_F11 = 0x30A,
|
||||
KEY_F12 = 0x30B,
|
||||
KEY_F13 = 0x212,
|
||||
KEY_F14 = 0x30D,
|
||||
KEY_F15 = 0x30E,
|
||||
KEY_F16 = 0x30F,
|
||||
KEY_F17 = 0x310,
|
||||
KEY_F18 = 0x311,
|
||||
KEY_F19 = 0x312,
|
||||
KEY_LAST = 0x313
|
||||
};
|
||||
|
||||
enum MOUSEBUTTON {
|
||||
MOUSE_BUTTON_NONE = 0x0,
|
||||
MOUSE_BUTTON_LEFT = 0x1,
|
||||
MOUSE_BUTTON_MIDDLE = 0x2,
|
||||
MOUSE_BUTTON_RIGHT = 0x4,
|
||||
MOUSE_BUTTON_XBUTTON1 = 0x8,
|
||||
MOUSE_BUTTON_XBUTTON2 = 0x10,
|
||||
MOUSE_BUTTON_XBUTTON3 = 0x20,
|
||||
MOUSE_BUTTON_XBUTTON4 = 0x40,
|
||||
MOUSE_BUTTON_XBUTTON5 = 0x80,
|
||||
MOUSE_BUTTON_XBUTTON6 = 0x100,
|
||||
MOUSE_BUTTON_XBUTTON7 = 0x200,
|
||||
MOUSE_BUTTON_XBUTTON8 = 0x400,
|
||||
MOUSE_BUTTON_XBUTTON9 = 0x800,
|
||||
MOUSE_BUTTON_XBUTTON10 = 0x1000,
|
||||
MOUSE_BUTTON_XBUTTON11 = 0x2000,
|
||||
MOUSE_BUTTON_XBUTTON12 = 0x4000,
|
||||
MOUSE_BUTTON_ALL = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
enum MOUSEMODE {
|
||||
MOUSE_MODE_NORMAL = 0x0,
|
||||
MOUSE_MODE_RELATIVE = 0x1,
|
||||
MOUSE_MODES = 0x2
|
||||
};
|
||||
|
||||
enum OSINPUT {
|
||||
OS_INPUT_CAPTURE_CHANGED = 0,
|
||||
OS_INPUT_CHAR = 1,
|
||||
OS_INPUT_STRING = 2,
|
||||
OS_INPUT_IME = 3,
|
||||
OS_INPUT_SIZE = 4,
|
||||
OS_INPUT_CLOSE = 5,
|
||||
OS_INPUT_FOCUS = 6,
|
||||
OS_INPUT_KEY_DOWN = 7,
|
||||
OS_INPUT_KEY_UP = 8,
|
||||
OS_INPUT_MOUSE_DOWN = 9,
|
||||
OS_INPUT_MOUSE_MOVE = 10,
|
||||
OS_INPUT_MOUSE_WHEEL = 11,
|
||||
OS_INPUT_MOUSE_MOVE_RELATIVE = 12,
|
||||
OS_INPUT_MOUSE_UP = 13,
|
||||
OS_INPUT_14 = 14,
|
||||
OS_INPUT_15 = 15,
|
||||
OS_INPUT_16 = 16,
|
||||
OS_INPUT_17 = 17,
|
||||
OS_INPUT_18 = 18,
|
||||
OS_INPUT_SHUTDOWN = 19
|
||||
};
|
||||
|
||||
struct OSEVENT {
|
||||
OSINPUT id;
|
||||
int32_t param[4];
|
||||
};
|
||||
|
||||
struct EVENT_DATA_CHAR {
|
||||
int32_t ch;
|
||||
uint32_t metaKeyState;
|
||||
uint32_t repeat;
|
||||
};
|
||||
|
||||
struct EVENT_DATA_IDLE {
|
||||
float elapsedSec;
|
||||
uint32_t time;
|
||||
};
|
||||
|
||||
struct EVENT_DATA_KEY {
|
||||
KEY key;
|
||||
uint32_t metaKeyState;
|
||||
uint32_t repeat;
|
||||
uint32_t time;
|
||||
};
|
||||
|
||||
struct EVENT_DATA_MOUSE {
|
||||
MOUSEMODE mode;
|
||||
MOUSEBUTTON button;
|
||||
uint32_t buttonState;
|
||||
uint32_t metaKeyState;
|
||||
uint32_t flags;
|
||||
float x;
|
||||
float y;
|
||||
int32_t wheelDistance;
|
||||
uint32_t time;
|
||||
};
|
||||
|
||||
struct EVENT_DATA_SIZE {
|
||||
int32_t w;
|
||||
int32_t h;
|
||||
};
|
||||
|
||||
#endif
|
6
src/event/mac/Event.h
Normal file
6
src/event/mac/Event.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef EVENT_MAC_EVENT_H
|
||||
#define EVENT_MAC_EVENT_H
|
||||
|
||||
void RunCocoaEventLoop();
|
||||
|
||||
#endif
|
9
src/event/mac/Event.mm
Normal file
9
src/event/mac/Event.mm
Normal file
@ -0,0 +1,9 @@
|
||||
#include "event/mac/Event.h"
|
||||
#include "event/Event.hpp"
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
void RunCocoaEventLoop() {
|
||||
if (!Event::s_shouldLoopTerminate) {
|
||||
[NSApp run];
|
||||
}
|
||||
}
|
3
src/glue/CCharacterSelection.cpp
Normal file
3
src/glue/CCharacterSelection.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
#include "glue/CCharacterSelection.hpp"
|
||||
|
||||
TSGrowableArray<CharacterSelectionDisplay> CCharacterSelection::s_characterList;
|
16
src/glue/CCharacterSelection.hpp
Normal file
16
src/glue/CCharacterSelection.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef GLUE_C_CHARACTER_SELECTION_HPP
|
||||
#define GLUE_C_CHARACTER_SELECTION_HPP
|
||||
|
||||
#include <storm/Array.hpp>
|
||||
|
||||
struct CharacterSelectionDisplay {
|
||||
// TODO
|
||||
};
|
||||
|
||||
class CCharacterSelection {
|
||||
public:
|
||||
// Static variables
|
||||
static TSGrowableArray<CharacterSelectionDisplay> s_characterList;
|
||||
};
|
||||
|
||||
#endif
|
452
src/glue/CGlueMgr.cpp
Normal file
452
src/glue/CGlueMgr.cpp
Normal file
@ -0,0 +1,452 @@
|
||||
#include "glue/CGlueMgr.hpp"
|
||||
#include "client/Client.hpp"
|
||||
#include "client/ClientServices.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "gx/Device.hpp"
|
||||
#include "math/Utils.hpp"
|
||||
#include "net/Connection.hpp"
|
||||
#include "net/Login.hpp"
|
||||
#include "sound/SI2.hpp"
|
||||
#include "ui/CSimpleModelFFX.hpp"
|
||||
#include "ui/CSimpleTop.hpp"
|
||||
#include "ui/FrameScript.hpp"
|
||||
#include "ui/FrameXML.hpp"
|
||||
#include "ui/Interface.hpp"
|
||||
#include "ui/ScriptFunctions.hpp"
|
||||
#include "util/CVar.hpp"
|
||||
#include "util/Filesystem.hpp"
|
||||
#include "util/Log.hpp"
|
||||
#include <cstdio>
|
||||
#include <common/MD5.hpp>
|
||||
|
||||
unsigned char InterfaceKey[256] = {
|
||||
0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54,
|
||||
0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75,
|
||||
0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34,
|
||||
0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8,
|
||||
0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8,
|
||||
0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A,
|
||||
0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3,
|
||||
0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9,
|
||||
0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22,
|
||||
0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E,
|
||||
0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB,
|
||||
0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7,
|
||||
0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0,
|
||||
0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6,
|
||||
0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A,
|
||||
0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2
|
||||
};
|
||||
|
||||
int32_t CGlueMgr::m_acceptedEULA = 1; // TODO
|
||||
int32_t CGlueMgr::m_acceptedTerminationWithoutNotice;
|
||||
int32_t CGlueMgr::m_acceptedTOS = 1; // TODO
|
||||
char CGlueMgr::m_accountName[1280];
|
||||
float CGlueMgr::m_aspect;
|
||||
bool CGlueMgr::m_authenticated;
|
||||
char CGlueMgr::m_currentScreen[64];
|
||||
CGlueMgr::GLUE_IDLE_STATE CGlueMgr::m_idleState;
|
||||
int32_t CGlueMgr::m_initialized;
|
||||
int32_t CGlueMgr::m_lastLoginResult;
|
||||
int32_t CGlueMgr::m_lastLoginState;
|
||||
int32_t CGlueMgr::m_loginResult;
|
||||
int32_t CGlueMgr::m_loginState;
|
||||
int32_t CGlueMgr::m_matrixRemaining;
|
||||
int32_t CGlueMgr::m_reload;
|
||||
int32_t CGlueMgr::m_scandllOkayToLogIn = 1; // TODO
|
||||
float CGlueMgr::m_screenHeight;
|
||||
float CGlueMgr::m_screenWidth;
|
||||
int32_t CGlueMgr::m_showedDisconnect;
|
||||
CSimpleTop* CGlueMgr::m_simpleTop;
|
||||
int32_t CGlueMgr::m_suspended;
|
||||
|
||||
float CalculateAspectRatio() {
|
||||
auto widescreenVar = CVar::Lookup("widescreen");
|
||||
auto resolutionVar = CVar::Lookup("gxResolution");
|
||||
|
||||
int32_t width = 4;
|
||||
int32_t height = 3;
|
||||
|
||||
if (widescreenVar && widescreenVar->GetInt() && resolutionVar) {
|
||||
char separator;
|
||||
sscanf(resolutionVar->GetString(), "%d%c%d", &width, &separator, &height);
|
||||
}
|
||||
|
||||
return static_cast<float>(width) / static_cast<float>(height);
|
||||
}
|
||||
|
||||
int32_t CGlueMgr::HandleDisplaySizeChanged(const CSizeEvent& event) {
|
||||
if (
|
||||
CGlueMgr::m_screenWidth > 0
|
||||
&& CGlueMgr::m_screenWidth == event.w
|
||||
&& CGlueMgr::m_screenHeight > 0
|
||||
&& CGlueMgr::m_screenHeight == event.h
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
CGlueMgr::m_screenWidth = event.w;
|
||||
CGlueMgr::m_screenHeight = event.h;
|
||||
float aspect = CalculateAspectRatio();
|
||||
|
||||
auto glueParent = static_cast<CSimpleFrame*>(CScriptObject::GetScriptObjectByName("GlueParent", CSimpleFrame::GetObjectType()));
|
||||
if (glueParent) {
|
||||
glueParent->SetFrameScale(1.0f, true);
|
||||
CLayoutFrame::ResizePending();
|
||||
}
|
||||
|
||||
if (AreEqual(CGlueMgr::m_aspect, aspect, 0.0099999998)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
CGlueMgr::m_aspect = aspect;
|
||||
CGlueMgr::m_reload = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO a1: const EVENT_DATA_IDLE*
|
||||
int32_t CGlueMgr::Idle(const void* a1, void* a2) {
|
||||
// TODO
|
||||
|
||||
if (CGlueMgr::m_idleState == IDLE_NONE) {
|
||||
if (CGlueMgr::m_reload) {
|
||||
if (!CGlueMgr::m_suspended) {
|
||||
// TODO CGlueMgr::Suspend();
|
||||
// TODO CGlueMgr::Resume();
|
||||
// TODO Sub4DA360();
|
||||
// TODO CGlueMgr::SetScreen(ByteB6A9E0);
|
||||
}
|
||||
|
||||
CGlueMgr::m_reload = 0;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// if (CGlueMgr::m_accountMsgAvailable) {
|
||||
// FrameScript_SignalEvent(0x22u, 0);
|
||||
// CGlueMgr::m_accountMsgAvailable = 0;
|
||||
// }
|
||||
|
||||
// TODO sub_4D84A0();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CGlueMgr::Initialize() {
|
||||
CGlueMgr::m_initialized = 1;
|
||||
|
||||
// TODO
|
||||
// - cvar stuff (tou, etc)
|
||||
|
||||
CRect windowSize;
|
||||
g_theGxDevicePtr->CapsWindowSize(windowSize);
|
||||
|
||||
CSizeEvent sizeEvent;
|
||||
sizeEvent.id = -1;
|
||||
sizeEvent.w = windowSize.maxX - windowSize.minX;
|
||||
sizeEvent.h = windowSize.maxY - windowSize.minY;
|
||||
|
||||
CGlueMgr::HandleDisplaySizeChanged(sizeEvent);
|
||||
|
||||
FrameXML_RegisterFactory("ModelFFX", &CSimpleModelFFX::Create, 0);
|
||||
|
||||
CGlueMgr::Resume();
|
||||
|
||||
// TODO
|
||||
// CRealmList::Initialize();
|
||||
|
||||
EventRegisterEx(EVENT_ID_IDLE, &CGlueMgr::Idle, 0, 0.0);
|
||||
|
||||
// TODO
|
||||
// CGLCD::Initialize();
|
||||
// sub_552380();
|
||||
|
||||
// TODO
|
||||
// - options changed warning stuff
|
||||
|
||||
// TODO
|
||||
// AccountDataInitializeBasicSystem();
|
||||
}
|
||||
|
||||
void CGlueMgr::LoginServerLogin(const char* accountName, const char* password) {
|
||||
if (!CGlueMgr::m_scandllOkayToLogIn || !CGlueMgr::m_acceptedTOS || !CGlueMgr::m_acceptedEULA || CGlueMgr::m_idleState != IDLE_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!accountName || !*accountName) {
|
||||
auto prompt = FrameScript_GetText("LOGIN_ENTER_NAME", -1, GENDER_NOT_APPLICABLE);
|
||||
FrameScript_SignalEvent(3, "%s%s", "OKAY", prompt);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!password || !*password) {
|
||||
auto prompt = FrameScript_GetText("LOGIN_ENTER_PASSWORD", -1, GENDER_NOT_APPLICABLE);
|
||||
FrameScript_SignalEvent(3, "%s%s", "OKAY", prompt);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CGlueMgr::m_loginResult = -1;
|
||||
CGlueMgr::m_loginState = -1;
|
||||
CGlueMgr::m_lastLoginResult = -1;
|
||||
CGlueMgr::m_lastLoginState = -1;
|
||||
CGlueMgr::m_authenticated = false;
|
||||
CGlueMgr::m_matrixRemaining = 0;
|
||||
CGlueMgr::m_idleState = IDLE_ACCOUNT_LOGIN;
|
||||
CGlueMgr::m_showedDisconnect = 0;
|
||||
|
||||
char* dest = CGlueMgr::m_accountName;
|
||||
for (const char* src = accountName; *src && dest < CGlueMgr::m_accountName + sizeof(CGlueMgr::m_accountName); src++, dest++) {
|
||||
if (src[0] == '|' && src[1] == '|') {
|
||||
src++;
|
||||
}
|
||||
|
||||
*dest = *src;
|
||||
}
|
||||
*dest = '\0';
|
||||
|
||||
SStrUpper(CGlueMgr::m_accountName);
|
||||
|
||||
// Show prompt
|
||||
FrameScript_SignalEvent(3, "%s", "CANCEL");
|
||||
|
||||
ClientServices::Logon(CGlueMgr::m_accountName, password);
|
||||
|
||||
// Zero out password
|
||||
memset(const_cast<char*>(password), 0, SStrLen(password));
|
||||
}
|
||||
|
||||
void CGlueMgr::QuitGame() {
|
||||
ClientPostClose(0);
|
||||
}
|
||||
|
||||
void CGlueMgr::Resume() {
|
||||
// TODO
|
||||
// CGlueMgr::m_disconnectPending = 0;
|
||||
// CGlueMgr::m_reconnect = 0;
|
||||
|
||||
CGlueMgr::m_idleState = IDLE_NONE;
|
||||
|
||||
// TODO
|
||||
// CGlueMgr::m_showedDisconnect = 0;
|
||||
// CGlueMgr::m_characterInfo = 0;
|
||||
|
||||
CGlueMgr::m_suspended = 0;
|
||||
CGlueMgr::m_reload = 0;
|
||||
|
||||
CRect screenRect;
|
||||
g_theGxDevicePtr->CapsWindowSizeInScreenCoords(screenRect);
|
||||
CGlueMgr::m_screenWidth = screenRect.maxX - screenRect.minX;
|
||||
CGlueMgr::m_screenHeight = screenRect.maxY - screenRect.minY;
|
||||
CGlueMgr::m_aspect = CalculateAspectRatio();
|
||||
CoordinateSetAspectRatio(CGlueMgr::m_aspect);
|
||||
|
||||
// Create CSimpleTop
|
||||
CSimpleTop* top;
|
||||
|
||||
void* m = SMemAlloc(sizeof(CSimpleTop), __FILE__, __LINE__, 0);
|
||||
|
||||
if (m) {
|
||||
top = new (m) CSimpleTop();
|
||||
} else {
|
||||
top = nullptr;
|
||||
}
|
||||
|
||||
CGlueMgr::m_simpleTop = top;
|
||||
CGlueMgr::m_simpleTop->m_displaySizeCallback = &CGlueMgr::HandleDisplaySizeChanged;
|
||||
|
||||
// TODO
|
||||
// - setting cursor texture
|
||||
// - setting mouse mode
|
||||
|
||||
FrameScript_Flush();
|
||||
|
||||
SystemRegisterFunctions();
|
||||
RegisterSimpleFrameScriptMethods();
|
||||
GlueScriptEventsRegisterFunctions();
|
||||
CharSelectRegisterScriptFunctions();
|
||||
CharacterCreateRegisterScriptFunctions();
|
||||
|
||||
// TODO
|
||||
// RealmListRegisterScriptFunctions();
|
||||
|
||||
SI2::RegisterScriptFunctions();
|
||||
|
||||
// TODO
|
||||
// AccountMsg_RegisterScriptFunctions();
|
||||
// CGVideoOptions::RegisterScriptFunctions();
|
||||
|
||||
// TODO
|
||||
// FrameScript::s_scriptFunctionsLoaded = 1;
|
||||
|
||||
FrameScript_CreateEvents(g_glueScriptEvents, NUM_GLUE_SCRIPT_EVENTS);
|
||||
|
||||
OsCreateDirectory("Logs", 0);
|
||||
|
||||
CWOWClientStatus status;
|
||||
|
||||
if (!SLogCreate("Logs\\GlueXML.log", 0, status.m_logFile)) {
|
||||
SysMsgPrintf(SYSMSG_WARNING, "Cannot create WOWClient log file \"%s\"!", "Logs\\GlueXML.log");
|
||||
}
|
||||
|
||||
DeleteInterfaceFiles();
|
||||
|
||||
MD5_CTX md5;
|
||||
unsigned char digest1[16];
|
||||
unsigned char digest2[16];
|
||||
|
||||
int32_t v8;
|
||||
unsigned char* v9;
|
||||
unsigned char* v10;
|
||||
|
||||
MD5Init(&md5);
|
||||
|
||||
switch (FrameXML_CheckSignature("Interface\\GlueXML\\GlueXML.toc", 0, InterfaceKey, digest1)) {
|
||||
case 0:
|
||||
status.Add(STATUS_WARNING, "GlueXML missing signature");
|
||||
ClientPostClose(9);
|
||||
return;
|
||||
|
||||
case 1:
|
||||
status.Add(STATUS_WARNING, "GlueXML has corrupt signature");
|
||||
ClientPostClose(9);
|
||||
return;
|
||||
|
||||
case 2:
|
||||
status.Add(STATUS_WARNING, "GlueXML is modified or corrupt");
|
||||
ClientPostClose(9);
|
||||
return;
|
||||
|
||||
case 3:
|
||||
FrameXML_FreeHashNodes();
|
||||
FrameXML_CreateFrames("Interface\\GlueXML\\GlueXML.toc", 0, &md5, &status);
|
||||
|
||||
MD5Final(digest2, &md5);
|
||||
|
||||
v8 = 16;
|
||||
v9 = digest2;
|
||||
v10 = digest1;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ClientPostClose(9);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// - some kind of digest validation?
|
||||
|
||||
FrameScript_SignalEvent(22, nullptr);
|
||||
|
||||
// TODO
|
||||
// CGlueMgr::InitializeFFX();
|
||||
|
||||
// TODO
|
||||
// ClientServices::SetMessageHandler(SMSG_CHARACTER_RENAME_RESULT, CGlueMgr::OnCharRenameResult, 0);
|
||||
// ClientServices::SetMessageHandler(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, CGlueMgr::OnCharDeclineResult, 0);
|
||||
// ClientServices::SetMessageHandler(SMSG_CHAR_CUSTOMIZE, CGlueMgr::OnCharCustomizeResult, 0);
|
||||
// ClientServices::SetMessageHandler(SMSG_REALM_SPLIT, CGlueMgr::OnRealmSplitMsg, 0);
|
||||
// ClientServices::SetMessageHandler(SMSG_KICK_REASON, CGlueMgr::OnKickReasonMsg, 0);
|
||||
// ClientServices::SetMessageHandler(SMSG_CHAR_FACTION_CHANGE, CGlueMgr::OnCharFactionChangeResult, 0);
|
||||
|
||||
// TODO
|
||||
// CGlueMgr::m_pendingServerAlert = 1;
|
||||
// CGlueMgr::m_processServerAlert = 0;
|
||||
// CGlueMgr::m_serverAlert[0] = 0;
|
||||
// v21 = (const char *)ClientServices::GetServerAlertURL();
|
||||
// v22 = (const CHAR *)FrameScript_GetText(v21, -1, 0);
|
||||
// if (!OsURLDownload(v22, CGlueMgr::ServerAlertURLCallback, 0)) {
|
||||
// CGlueMgr::m_pendingServerAlert = 0;
|
||||
// }
|
||||
}
|
||||
|
||||
void CGlueMgr::SetScreen(const char* screen) {
|
||||
FrameScript_SignalEvent(0, "%s", screen);
|
||||
}
|
||||
|
||||
void CGlueMgr::StatusDialogClick() {
|
||||
if (!SStrCmpI(CGlueMgr::m_currentScreen, "patchdownload", STORM_MAX_STR)) {
|
||||
CGlueMgr::SetScreen("login");
|
||||
}
|
||||
|
||||
switch (CGlueMgr::m_idleState) {
|
||||
case IDLE_NONE: {
|
||||
ClientServices::Connection()->Cleanup();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IDLE_ACCOUNT_LOGIN: {
|
||||
ClientServices::LoginConnection()->Logoff();
|
||||
|
||||
CGlueMgr::m_showedDisconnect = 0;
|
||||
CGlueMgr::m_idleState = IDLE_NONE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IDLE_2:
|
||||
case IDLE_3: {
|
||||
ClientServices::Connection()->Cancel(2);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IDLE_4:
|
||||
case IDLE_5:
|
||||
case IDLE_6:
|
||||
case IDLE_10: {
|
||||
ClientServices::Connection()->Cancel(2);
|
||||
|
||||
CGlueMgr::m_showedDisconnect = 0;
|
||||
CGlueMgr::m_idleState = IDLE_NONE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IDLE_7:
|
||||
case IDLE_8:
|
||||
case IDLE_9: {
|
||||
CGlueMgr::m_showedDisconnect = 0;
|
||||
CGlueMgr::m_idleState = IDLE_NONE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IDLE_11: {
|
||||
CGlueMgr::m_showedDisconnect = 0;
|
||||
CGlueMgr::m_idleState = IDLE_NONE;
|
||||
|
||||
// TODO
|
||||
// CGlueMgr::GetCharacterList();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IDLE_12:
|
||||
case IDLE_13: {
|
||||
// TODO
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGlueMgr::Suspend() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGlueMgr::UpdateCurrentScreen(const char* screen) {
|
||||
// TODO
|
||||
|
||||
SStrCopy(CGlueMgr::m_currentScreen, screen, sizeof(CGlueMgr::m_currentScreen));
|
||||
|
||||
// TODO
|
||||
}
|
66
src/glue/CGlueMgr.hpp
Normal file
66
src/glue/CGlueMgr.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
#ifndef GLUE_C_GLUE_MGR_HPP
|
||||
#define GLUE_C_GLUE_MGR_HPP
|
||||
|
||||
#include "event/Event.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class CSimpleTop;
|
||||
|
||||
class CGlueMgr {
|
||||
public:
|
||||
// Types
|
||||
enum GLUE_IDLE_STATE {
|
||||
IDLE_NONE = 0,
|
||||
IDLE_ACCOUNT_LOGIN = 1,
|
||||
IDLE_2 = 2,
|
||||
IDLE_3 = 3,
|
||||
IDLE_4 = 4,
|
||||
IDLE_5 = 5,
|
||||
IDLE_6 = 6,
|
||||
IDLE_7 = 7,
|
||||
IDLE_8 = 8,
|
||||
IDLE_9 = 9,
|
||||
IDLE_10 = 10,
|
||||
IDLE_11 = 11,
|
||||
IDLE_12 = 12,
|
||||
IDLE_13 = 13
|
||||
};
|
||||
|
||||
// Static variables
|
||||
static int32_t m_acceptedEULA;
|
||||
static int32_t m_acceptedTerminationWithoutNotice;
|
||||
static int32_t m_acceptedTOS;
|
||||
static char m_accountName[];
|
||||
static float m_aspect;
|
||||
static bool m_authenticated;
|
||||
static char m_currentScreen[];
|
||||
static GLUE_IDLE_STATE m_idleState;
|
||||
static int32_t m_initialized;
|
||||
static int32_t m_lastLoginResult;
|
||||
static int32_t m_lastLoginState;
|
||||
static int32_t m_loginResult;
|
||||
static int32_t m_loginState;
|
||||
static int32_t m_matrixRemaining;
|
||||
static int32_t m_reload;
|
||||
static int32_t m_scandllOkayToLogIn;
|
||||
static float m_screenHeight;
|
||||
static float m_screenWidth;
|
||||
static int32_t m_showedDisconnect;
|
||||
static CSimpleTop* m_simpleTop;
|
||||
static int32_t m_suspended;
|
||||
|
||||
// Static functions
|
||||
// TODO a1: const EVENT_DATA_IDLE*
|
||||
static int32_t HandleDisplaySizeChanged(const CSizeEvent& event);
|
||||
static int32_t Idle(const void*, void*);
|
||||
static void Initialize();
|
||||
static void LoginServerLogin(const char* accountName, const char* password);
|
||||
static void QuitGame();
|
||||
static void Resume();
|
||||
static void SetScreen(const char*);
|
||||
static void StatusDialogClick();
|
||||
static void Suspend();
|
||||
static void UpdateCurrentScreen(const char* screen);
|
||||
};
|
||||
|
||||
#endif
|
23
src/glue/CMakeLists.txt
Normal file
23
src/glue/CMakeLists.txt
Normal file
@ -0,0 +1,23 @@
|
||||
file(GLOB PRIVATE_SOURCES "*.cpp")
|
||||
|
||||
add_library(glue STATIC
|
||||
${PRIVATE_SOURCES}
|
||||
)
|
||||
|
||||
target_include_directories(glue
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
target_link_libraries(glue
|
||||
PRIVATE
|
||||
client
|
||||
event
|
||||
gx
|
||||
net
|
||||
sound
|
||||
ui
|
||||
util
|
||||
PUBLIC
|
||||
storm
|
||||
)
|
236
src/gx/Blit.cpp
Normal file
236
src/gx/Blit.cpp
Normal file
@ -0,0 +1,236 @@
|
||||
#include "gx/Blit.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
int32_t initBlit = 0;
|
||||
BLIT_FUNCTION s_blits[BlitFormats_Last][BlitFormats_Last][BlitAlphas_Last];
|
||||
|
||||
BlitFormat GxGetBlitFormat(EGxTexFormat format) {
|
||||
static BlitFormat blitTable[] = {
|
||||
BlitFormat_Unknown, // GxTex_Unknown
|
||||
BlitFormat_Abgr8888, // GxTex_Abgr8888
|
||||
BlitFormat_Argb8888, // GxTex_Argb8888
|
||||
BlitFormat_Argb4444, // GxTex_Argb4444
|
||||
BlitFormat_Argb1555, // GxTex_Argb1555
|
||||
BlitFormat_Rgb565, // GxTex_Rgb565
|
||||
BlitFormat_Dxt1, // GxTex_Dxt1
|
||||
BlitFormat_Dxt3, // GxTex_Dxt3
|
||||
BlitFormat_Dxt5, // GxTex_Dxt5
|
||||
BlitFormat_Uv88, // GxTex_Uv88
|
||||
BlitFormat_Gr1616F, // GxTex_Gr1616F
|
||||
BlitFormat_R32F, // GxTex_R32F
|
||||
BlitFormat_D24X8 // GxTex_D24X8
|
||||
};
|
||||
|
||||
return blitTable[format];
|
||||
}
|
||||
|
||||
void Blit_uint16_uint16(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
if (inStride == 2 * size.x && outStride == 2 * size.x) {
|
||||
memcpy(out, in, 2 * size.x * size.y);
|
||||
return;
|
||||
}
|
||||
|
||||
const char* in_ = reinterpret_cast<const char*>(in);
|
||||
char* out_ = reinterpret_cast<char*>(out);
|
||||
|
||||
for (int32_t i = 0; i < size.y; i++) {
|
||||
memcpy(out, in, 2 * size.x);
|
||||
in_ += inStride;
|
||||
out_ += outStride;
|
||||
}
|
||||
}
|
||||
|
||||
void Blit_uint32_uint32(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
if (inStride == 4 * size.x && outStride == 4 * size.x) {
|
||||
memcpy(out, in, 4 * size.x * size.y);
|
||||
return;
|
||||
}
|
||||
|
||||
const char* in_ = reinterpret_cast<const char*>(in);
|
||||
char* out_ = reinterpret_cast<char*>(out);
|
||||
|
||||
for (int32_t i = 0; i < size.y; i++) {
|
||||
memcpy(out, in, 4 * size.x);
|
||||
in_ += inStride;
|
||||
out_ += outStride;
|
||||
}
|
||||
}
|
||||
|
||||
void Blit_Argb8888_Abgr8888(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Argb8888_Argb8888(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
Blit_uint32_uint32(size, in, inStride, out, outStride);
|
||||
}
|
||||
|
||||
void Blit_Argb8888_Argb8888_A1(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Argb8888_Argb8888_A8(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Argb8888_Argb4444(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Argb8888_Argb1555(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Argb8888_Rgb565(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Argb4444_Abgr8888(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Argb4444_Argb4444(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
Blit_uint16_uint16(size, in, inStride, out, outStride);
|
||||
}
|
||||
|
||||
void Blit_Argb1555_Argb1555(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Rgb565_Rgb565(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Dxt1_Argb8888(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Dxt1_Argb1555(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Dxt1_Rgb565(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Dxt1_Dxt1(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
const char* in_ = static_cast<const char*>(in);
|
||||
char* out_ = static_cast<char*>(out);
|
||||
|
||||
int32_t v6 = std::max(size.x, 4);
|
||||
int32_t v7 = std::max(size.y, 4);
|
||||
|
||||
memcpy(out_, in_, (4 * v6 * v7) >> 3);
|
||||
}
|
||||
|
||||
void Blit_Dxt3_Argb8888(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Dxt3_Argb4444(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Dxt35_Dxt35(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
int32_t v5 = std::max(size.x, 4);
|
||||
int32_t v6 = std::max(size.y / 4, 1);
|
||||
|
||||
const char* in_ = static_cast<const char*>(in);
|
||||
char* out_ = static_cast<char*>(out);
|
||||
|
||||
if (inStride == v5 * 4 && outStride == v5 * 4) {
|
||||
memcpy(out_, in_, v5 * v6 * 4);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32_t i = v6; i > 0; i--) {
|
||||
memcpy(out_, in_, v5 * 4);
|
||||
in_ += inStride;
|
||||
out_ += outStride;
|
||||
}
|
||||
}
|
||||
|
||||
void Blit_Dxt5_Argb8888(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Dxt5_Argb4444(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Uv88_Uv88(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_Gr1616F_Gr1616F(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_R32F_R32F(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Blit_D24X8_D24X8(const C2iVector& size, const void* in, uint32_t inStride, void* out, uint32_t outStride) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void InitBlit() {
|
||||
// Source: Argb8888
|
||||
s_blits [BlitFormat_Argb8888] [BlitFormat_Abgr8888] [BlitAlpha_0] = &Blit_Argb8888_Abgr8888;
|
||||
s_blits [BlitFormat_Argb8888] [BlitFormat_Argb8888] [BlitAlpha_0] = &Blit_Argb8888_Argb8888;
|
||||
s_blits [BlitFormat_Argb8888] [BlitFormat_Argb8888] [BlitAlpha_1] = &Blit_Argb8888_Argb8888_A1;
|
||||
s_blits [BlitFormat_Argb8888] [BlitFormat_Argb8888] [BlitAlpha_8] = &Blit_Argb8888_Argb8888_A8;
|
||||
s_blits [BlitFormat_Argb8888] [BlitFormat_Argb4444] [BlitAlpha_0] = &Blit_Argb8888_Argb4444;
|
||||
s_blits [BlitFormat_Argb8888] [BlitFormat_Argb1555] [BlitAlpha_0] = &Blit_Argb8888_Argb1555;
|
||||
s_blits [BlitFormat_Argb8888] [BlitFormat_Rgb565] [BlitAlpha_0] = &Blit_Argb8888_Rgb565;
|
||||
|
||||
// Source: Argb4444
|
||||
s_blits [BlitFormat_Argb4444] [BlitFormat_Abgr8888] [BlitAlpha_0] = &Blit_Argb4444_Abgr8888;
|
||||
s_blits [BlitFormat_Argb4444] [BlitFormat_Argb4444] [BlitAlpha_0] = &Blit_Argb4444_Argb4444;
|
||||
|
||||
// Source: Argb1555
|
||||
s_blits [BlitFormat_Argb1555] [BlitFormat_Argb1555] [BlitAlpha_0] = &Blit_Argb1555_Argb1555;
|
||||
|
||||
// Source: Rgb565
|
||||
s_blits [BlitFormat_Rgb565] [BlitFormat_Rgb565] [BlitAlpha_0] = &Blit_Rgb565_Rgb565;
|
||||
|
||||
// Source: Dxt1
|
||||
s_blits [BlitFormat_Dxt1] [BlitFormat_Argb8888] [BlitAlpha_0] = &Blit_Dxt1_Argb8888;
|
||||
s_blits [BlitFormat_Dxt1] [BlitFormat_Argb1555] [BlitAlpha_0] = &Blit_Dxt1_Argb1555;
|
||||
s_blits [BlitFormat_Dxt1] [BlitFormat_Rgb565] [BlitAlpha_0] = &Blit_Dxt1_Rgb565;
|
||||
s_blits [BlitFormat_Dxt1] [BlitFormat_Dxt1] [BlitAlpha_0] = &Blit_Dxt1_Dxt1;
|
||||
|
||||
// Source: Dxt3
|
||||
s_blits [BlitFormat_Dxt3] [BlitFormat_Argb8888] [BlitAlpha_0] = &Blit_Dxt3_Argb8888;
|
||||
s_blits [BlitFormat_Dxt3] [BlitFormat_Argb4444] [BlitAlpha_0] = &Blit_Dxt3_Argb4444;
|
||||
s_blits [BlitFormat_Dxt3] [BlitFormat_Dxt3] [BlitAlpha_0] = &Blit_Dxt35_Dxt35;
|
||||
|
||||
// Source: Dxt5
|
||||
s_blits [BlitFormat_Dxt5] [BlitFormat_Argb8888] [BlitAlpha_0] = &Blit_Dxt5_Argb8888;
|
||||
s_blits [BlitFormat_Dxt5] [BlitFormat_Argb4444] [BlitAlpha_0] = &Blit_Dxt5_Argb4444;
|
||||
s_blits [BlitFormat_Dxt5] [BlitFormat_Dxt5] [BlitAlpha_0] = &Blit_Dxt35_Dxt35;
|
||||
|
||||
// Source: Uv88
|
||||
s_blits [BlitFormat_Uv88] [BlitFormat_Uv88] [BlitAlpha_0] = &Blit_Uv88_Uv88;
|
||||
|
||||
// Source: Gr1616F
|
||||
s_blits [BlitFormat_Gr1616F] [BlitFormat_Gr1616F] [BlitAlpha_0] = &Blit_Gr1616F_Gr1616F;
|
||||
|
||||
// Source: R32F
|
||||
s_blits [BlitFormat_R32F] [BlitFormat_R32F] [BlitAlpha_0] = &Blit_R32F_R32F;
|
||||
|
||||
// Source: D24X8
|
||||
s_blits [BlitFormat_D24X8] [BlitFormat_D24X8] [BlitAlpha_0] = &Blit_D24X8_D24X8;
|
||||
}
|
||||
|
||||
void Blit(const C2iVector& size, BlitAlpha alpha, const void* src, uint32_t srcStride, BlitFormat srcFmt, void* dst, uint32_t dstStride, BlitFormat dstFmt) {
|
||||
if (!initBlit) {
|
||||
InitBlit();
|
||||
initBlit = 1;
|
||||
}
|
||||
|
||||
BLIT_FUNCTION blit = s_blits[srcFmt][dstFmt][alpha];
|
||||
|
||||
blit(size, src, srcStride, dst, dstStride);
|
||||
}
|
15
src/gx/Blit.hpp
Normal file
15
src/gx/Blit.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef GX_BLIT_HPP
|
||||
#define GX_BLIT_HPP
|
||||
|
||||
#include "gx/Types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class C2iVector;
|
||||
|
||||
typedef void (*BLIT_FUNCTION)(const C2iVector&, const void*, uint32_t, void*, uint32_t);
|
||||
|
||||
void Blit(const C2iVector&, BlitAlpha, const void*, uint32_t, BlitFormat, void*, uint32_t, BlitFormat);
|
||||
|
||||
BlitFormat GxGetBlitFormat(EGxTexFormat);
|
||||
|
||||
#endif
|
213
src/gx/Buffer.cpp
Normal file
213
src/gx/Buffer.cpp
Normal file
@ -0,0 +1,213 @@
|
||||
#include "gx/Buffer.hpp"
|
||||
#include "gx/Device.hpp"
|
||||
|
||||
CGxVertexAttrib vertexAttribsP[] = {
|
||||
{ GxVA_Position, 4, GxVertexAttribOffset(GxVBF_P, GxVA_Position), 12 }
|
||||
};
|
||||
|
||||
CGxVertexAttrib vertexAttribsPN[] = {
|
||||
{ GxVA_Position, 4, GxVertexAttribOffset(GxVBF_PN, GxVA_Position), 24 },
|
||||
{ GxVA_Normal, 4, GxVertexAttribOffset(GxVBF_PN, GxVA_Normal), 24 }
|
||||
};
|
||||
|
||||
CGxVertexAttrib vertexAttribsPNC[] = {
|
||||
{ GxVA_Position, 4, GxVertexAttribOffset(GxVBF_PNC, GxVA_Position), 28 },
|
||||
{ GxVA_Normal, 4, GxVertexAttribOffset(GxVBF_PNC, GxVA_Normal), 28 },
|
||||
{ GxVA_Color0, 0, GxVertexAttribOffset(GxVBF_PNC, GxVA_Color0), 28 }
|
||||
};
|
||||
|
||||
CGxVertexAttrib vertexAttribsPNT[] = {
|
||||
{ GxVA_Position, 4, GxVertexAttribOffset(GxVBF_PNT, GxVA_Position), 32 },
|
||||
{ GxVA_Normal, 4, GxVertexAttribOffset(GxVBF_PNT, GxVA_Normal), 32 },
|
||||
{ GxVA_TexCoord0, 3, GxVertexAttribOffset(GxVBF_PNT, GxVA_TexCoord0), 32 }
|
||||
};
|
||||
|
||||
CGxVertexAttrib vertexAttribsPNCT[] = {
|
||||
{ GxVA_Position, 4, GxVertexAttribOffset(GxVBF_PNCT, GxVA_Position), 36 },
|
||||
{ GxVA_Normal, 4, GxVertexAttribOffset(GxVBF_PNCT, GxVA_Normal), 36 },
|
||||
{ GxVA_Color0, 0, GxVertexAttribOffset(GxVBF_PNCT, GxVA_Color0), 36 },
|
||||
{ GxVA_TexCoord0, 3, GxVertexAttribOffset(GxVBF_PNCT, GxVA_TexCoord0), 36 }
|
||||
};
|
||||
|
||||
CGxVertexAttrib vertexAttribsPNT2[] = {
|
||||
{ GxVA_Position, 4, GxVertexAttribOffset(GxVBF_PNT2, GxVA_Position), 40 },
|
||||
{ GxVA_Normal, 4, GxVertexAttribOffset(GxVBF_PNT2, GxVA_Normal), 40 },
|
||||
{ GxVA_TexCoord0, 3, GxVertexAttribOffset(GxVBF_PNT2, GxVA_TexCoord0), 40 },
|
||||
{ GxVA_TexCoord1, 3, GxVertexAttribOffset(GxVBF_PNT2, GxVA_TexCoord1), 40 }
|
||||
};
|
||||
|
||||
CGxVertexAttrib vertexAttribsPNCT2[] = {
|
||||
{ GxVA_Position, 4, GxVertexAttribOffset(GxVBF_PNCT2, GxVA_Position), 44 },
|
||||
{ GxVA_Normal, 4, GxVertexAttribOffset(GxVBF_PNCT2, GxVA_Normal), 44 },
|
||||
{ GxVA_Color0, 0, GxVertexAttribOffset(GxVBF_PNCT2, GxVA_Color0), 44 },
|
||||
{ GxVA_TexCoord0, 3, GxVertexAttribOffset(GxVBF_PNCT2, GxVA_TexCoord0), 44 },
|
||||
{ GxVA_TexCoord1, 3, GxVertexAttribOffset(GxVBF_PNCT2, GxVA_TexCoord1), 44 }
|
||||
};
|
||||
|
||||
CGxVertexAttrib vertexAttribsPC[] = {
|
||||
{ GxVA_Position, 4, GxVertexAttribOffset(GxVBF_PC, GxVA_Position), 16 },
|
||||
{ GxVA_Color0, 0, GxVertexAttribOffset(GxVBF_PC, GxVA_Color0), 16 }
|
||||
};
|
||||
|
||||
CGxVertexAttrib vertexAttribsPCT[] = {
|
||||
{ GxVA_Position, 4, GxVertexAttribOffset(GxVBF_PCT, GxVA_Position), 24 },
|
||||
{ GxVA_Color0, 0, GxVertexAttribOffset(GxVBF_PCT, GxVA_Color0), 24 },
|
||||
{ GxVA_TexCoord0, 3, GxVertexAttribOffset(GxVBF_PCT, GxVA_TexCoord0), 24 }
|
||||
};
|
||||
|
||||
CGxVertexAttrib vertexAttribsPCT2[] = {
|
||||
{ GxVA_Position, 4, GxVertexAttribOffset(GxVBF_PCT2, GxVA_Position), 32 },
|
||||
{ GxVA_Color0, 0, GxVertexAttribOffset(GxVBF_PCT2, GxVA_Color0), 32 },
|
||||
{ GxVA_TexCoord0, 3, GxVertexAttribOffset(GxVBF_PCT2, GxVA_TexCoord0), 32 },
|
||||
{ GxVA_TexCoord1, 3, GxVertexAttribOffset(GxVBF_PCT2, GxVA_TexCoord1), 32 }
|
||||
};
|
||||
|
||||
CGxVertexAttrib vertexAttribsPT[] = {
|
||||
{ GxVA_Position, 4, GxVertexAttribOffset(GxVBF_PT, GxVA_Position), 20 },
|
||||
{ GxVA_TexCoord0, 3, GxVertexAttribOffset(GxVBF_PT, GxVA_TexCoord0), 20 }
|
||||
};
|
||||
|
||||
CGxVertexAttrib vertexAttribsPT2[] = {
|
||||
{ GxVA_Position, 4, GxVertexAttribOffset(GxVBF_PT2, GxVA_Position), 28 },
|
||||
{ GxVA_TexCoord0, 3, GxVertexAttribOffset(GxVBF_PT2, GxVA_TexCoord0), 28 },
|
||||
{ GxVA_TexCoord1, 3, GxVertexAttribOffset(GxVBF_PT2, GxVA_TexCoord1), 28 }
|
||||
};
|
||||
|
||||
CGxVertexAttrib vertexAttribsPBNT2[] = {
|
||||
{ GxVA_Position, 4, GxVertexAttribOffset(GxVBF_PBNT2, GxVA_Position), 48 },
|
||||
{ GxVA_BlendWeight, 2, GxVertexAttribOffset(GxVBF_PBNT2, GxVA_BlendWeight), 48 },
|
||||
{ GxVA_BlendIndices, 1, GxVertexAttribOffset(GxVBF_PBNT2, GxVA_BlendIndices), 48 },
|
||||
{ GxVA_Normal, 4, GxVertexAttribOffset(GxVBF_PBNT2, GxVA_Normal), 48 },
|
||||
{ GxVA_TexCoord0, 3, GxVertexAttribOffset(GxVBF_PBNT2, GxVA_TexCoord0), 48 },
|
||||
{ GxVA_TexCoord1, 3, GxVertexAttribOffset(GxVBF_PBNT2, GxVA_TexCoord1), 48 }
|
||||
};
|
||||
|
||||
CGxVertexAttrib vertexAttribsPNC2T2[] = {
|
||||
{ GxVA_Position, 4, GxVertexAttribOffset(GxVBF_PNC2T2, GxVA_Position), 48 },
|
||||
{ GxVA_Normal, 4, GxVertexAttribOffset(GxVBF_PNC2T2, GxVA_Normal), 48 },
|
||||
{ GxVA_Color0, 0, GxVertexAttribOffset(GxVBF_PNC2T2, GxVA_Color0), 48 },
|
||||
{ GxVA_Color1, 0, GxVertexAttribOffset(GxVBF_PNC2T2, GxVA_Color0), 48 },
|
||||
{ GxVA_TexCoord0, 3, GxVertexAttribOffset(GxVBF_PNC2T2, GxVA_TexCoord0), 48 },
|
||||
{ GxVA_TexCoord1, 3, GxVertexAttribOffset(GxVBF_PNC2T2, GxVA_TexCoord1), 48 }
|
||||
};
|
||||
|
||||
VertexBufDesc Buffer::s_vertexBufDesc[] = {
|
||||
// GxVBF_P
|
||||
{ vertexAttribsP, 1, 12, GxPrim_Position },
|
||||
|
||||
// GxVBF_PN
|
||||
{ vertexAttribsPN, 2, 24, GxPrim_Position | GxPrim_Normal },
|
||||
|
||||
// GxVBF_PNC
|
||||
{ vertexAttribsPNC, 3, 28, GxPrim_Position | GxPrim_Normal | GxPrim_Color0 },
|
||||
|
||||
// GxVBF_PNT
|
||||
{ vertexAttribsPNT, 3, 32, GxPrim_Position | GxPrim_Normal | GxPrim_TexCoord0 },
|
||||
|
||||
// GxVBF_PNCT
|
||||
{ vertexAttribsPNCT, 4, 36, GxPrim_Position | GxPrim_Normal | GxPrim_Color0 | GxPrim_TexCoord0 },
|
||||
|
||||
// GxVBF_PNT2
|
||||
{ vertexAttribsPNT2, 4, 40, GxPrim_Position | GxPrim_Normal | GxPrim_TexCoord0 | GxPrim_TexCoord1 },
|
||||
|
||||
// GxVBF_PNCT2
|
||||
{ vertexAttribsPNCT2, 5, 44, GxPrim_Position | GxPrim_Normal | GxPrim_Color0 | GxPrim_TexCoord0 | GxPrim_TexCoord1 },
|
||||
|
||||
// GxVBF_PC
|
||||
{ vertexAttribsPC, 2, 16, GxPrim_Position | GxPrim_Color0 },
|
||||
|
||||
// GxVBF_PCT
|
||||
{ vertexAttribsPCT, 3, 24, GxPrim_Position | GxPrim_Color0 | GxPrim_TexCoord0 },
|
||||
|
||||
// GxVBF_PCT2
|
||||
{ vertexAttribsPCT2, 4, 32, GxPrim_Position | GxPrim_Color0 | GxPrim_TexCoord0 | GxPrim_TexCoord1 },
|
||||
|
||||
// GxVBF_PT
|
||||
{ vertexAttribsPT, 2, 20, GxPrim_Position | GxPrim_TexCoord0 },
|
||||
|
||||
// GxVBF_PT2
|
||||
{ vertexAttribsPT2, 3, 28, GxPrim_Position | GxPrim_TexCoord0 | GxPrim_TexCoord1 },
|
||||
|
||||
// GxVBF_PBNT2
|
||||
{ vertexAttribsPBNT2, 6, 48, GxPrim_Position | GxPrim_BlendWeight | GxPrim_BlendIndices | GxPrim_Normal | GxPrim_TexCoord0 | GxPrim_TexCoord1 },
|
||||
|
||||
// GxVBF_PNC2T2
|
||||
{ vertexAttribsPNC2T2, 6, 48, GxPrim_Position | GxPrim_Normal | GxPrim_Color0 | GxPrim_Color1 | GxPrim_TexCoord0 | GxPrim_TexCoord1 }
|
||||
};
|
||||
|
||||
int32_t Buffer::s_vertexBufOffset[GxVertexBufferFormats_Last][GxVAs_Last] = {
|
||||
// GxVBF_P
|
||||
{ 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
|
||||
// GxVBF_PN
|
||||
{ 0, -1, -1, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
|
||||
// GxVBF_PNC
|
||||
{ 0, -1, -1, 12, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
|
||||
// GxVBF_PNT
|
||||
{ 0, -1, -1, 12, -1, -1, 24, -1, -1, -1, -1, -1, -1, -1 },
|
||||
|
||||
// GxVBF_PNCT
|
||||
{ 0, -1, -1, 12, 24, -1, 28, -1, -1, -1, -1, -1, -1, -1 },
|
||||
|
||||
// GxVBF_PNT2
|
||||
{ 0, -1, -1, 12, -1, -1, 24, 32, -1, -1, -1, -1, -1, -1 },
|
||||
|
||||
// GxVBF_PNCT2
|
||||
{ 0, -1, -1, 12, 24, -1, 28, 36, -1, -1, -1, -1, -1, -1 },
|
||||
|
||||
// GxVBF_PC
|
||||
{ 0, -1, -1, -1, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
|
||||
// GxVBF_PCT
|
||||
{ 0, -1, -1, -1, 12, -1, 16, -1, -1, -1, -1, -1, -1, -1 },
|
||||
|
||||
// GxVBF_PCT2
|
||||
{ 0, -1, -1, -1, 12, -1, 16, 24, -1, -1, -1, -1, -1, -1 },
|
||||
|
||||
// GxVBF_PT
|
||||
{ 0, -1, -1, -1, -1, -1, 12, -1, -1, -1, -1, -1, -1, -1 },
|
||||
|
||||
// GxVBF_PT2
|
||||
{ 0, -1, -1, -1, -1, -1, 12, 20, -1, -1, -1, -1, -1, -1 },
|
||||
|
||||
// GxVBF_PBNT2
|
||||
{ 0, 12, 16, 20, -1, -1, 32, 40, -1, -1, -1, -1, -1, -1 },
|
||||
|
||||
// GxVBF_PNC2T2
|
||||
{ 0, -1, -1, 12, 24, 28, 32, 40, -1, -1, -1, -1, -1, -1 }
|
||||
};
|
||||
|
||||
uint32_t GxVertexAttribOffset(EGxVertexBufferFormat format, EGxVertexAttrib attrib) {
|
||||
return Buffer::s_vertexBufOffset[format][attrib];
|
||||
}
|
||||
|
||||
CGxBuf* GxBufCreate(CGxPool* pool, uint32_t itemSize, uint32_t itemCount, uint32_t index) {
|
||||
return g_theGxDevicePtr->BufCreate(pool, itemSize, itemCount, index);
|
||||
}
|
||||
|
||||
char* GxBufLock(CGxBuf* buf) {
|
||||
return g_theGxDevicePtr->BufLock(buf);
|
||||
}
|
||||
|
||||
void GxBufUnlock(CGxBuf* buf, uint32_t size) {
|
||||
g_theGxDevicePtr->BufUnlock(buf, size);
|
||||
buf->unk1C = 1;
|
||||
}
|
||||
|
||||
CGxPool* GxPoolCreate(EGxPoolTarget target, EGxPoolUsage usage, uint32_t size, EGxPoolHintBits hint, char* name) {
|
||||
return g_theGxDevicePtr->PoolCreate(target, usage, size, hint, name);
|
||||
}
|
||||
|
||||
void GxPrimIndexPtr(CGxBuf* buf) {
|
||||
g_theGxDevicePtr->PrimIndexPtr(buf);
|
||||
}
|
||||
|
||||
void GxPrimVertexPtr(CGxBuf* buf, EGxVertexBufferFormat format) {
|
||||
auto desc = &Buffer::s_vertexBufDesc[format];
|
||||
|
||||
g_theGxDevicePtr->PrimVertexFormat(buf, desc->attribs, desc->attribCount);
|
||||
g_theGxDevicePtr->PrimVertexMask(desc->mask);
|
||||
g_theGxDevicePtr->PrimVertexPtr(buf, format);
|
||||
}
|
38
src/gx/Buffer.hpp
Normal file
38
src/gx/Buffer.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef GX_BUFFER_HPP
|
||||
#define GX_BUFFER_HPP
|
||||
|
||||
#include "gx/buffer/CGxBuf.hpp"
|
||||
#include "gx/buffer/CGxPool.hpp"
|
||||
#include "gx/buffer/Types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class CGxBuf;
|
||||
class CGxPool;
|
||||
|
||||
struct VertexBufDesc {
|
||||
CGxVertexAttrib* attribs;
|
||||
uint32_t attribCount;
|
||||
uint32_t size;
|
||||
uint32_t mask;
|
||||
};
|
||||
|
||||
namespace Buffer {
|
||||
extern VertexBufDesc s_vertexBufDesc[GxVertexBufferFormats_Last];
|
||||
extern int32_t s_vertexBufOffset[GxVertexBufferFormats_Last][GxVAs_Last];
|
||||
}
|
||||
|
||||
uint32_t GxVertexAttribOffset(EGxVertexBufferFormat, EGxVertexAttrib);
|
||||
|
||||
CGxBuf* GxBufCreate(CGxPool*, uint32_t, uint32_t, uint32_t);
|
||||
|
||||
char* GxBufLock(CGxBuf* buf);
|
||||
|
||||
void GxBufUnlock(CGxBuf*, uint32_t);
|
||||
|
||||
CGxPool* GxPoolCreate(EGxPoolTarget, EGxPoolUsage, uint32_t, EGxPoolHintBits, char*);
|
||||
|
||||
void GxPrimIndexPtr(CGxBuf*);
|
||||
|
||||
void GxPrimVertexPtr(CGxBuf*, EGxVertexBufferFormat);
|
||||
|
||||
#endif
|
58
src/gx/CCamera.cpp
Normal file
58
src/gx/CCamera.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include "gx/CCamera.hpp"
|
||||
#include "gx/Shader.hpp"
|
||||
#include "gx/Transform.hpp"
|
||||
#include <cmath>
|
||||
#include <tempest/Math.hpp>
|
||||
#include <tempest/Matrix.hpp>
|
||||
#include <tempest/Rect.hpp>
|
||||
|
||||
const C3Vector CCamera::DEFAULT_POSITION = { 100.0f, 0.0f, 0.0f };
|
||||
const float CCamera::DEFAULT_DIST = 100.0f;
|
||||
const float CCamera::DEFAULT_FARZ = 5000.0f;
|
||||
const float CCamera::DEFAULT_NEARZ = 8.0f;
|
||||
|
||||
float CAngle::ClampTo2Pi(float angle) {
|
||||
double v1 = floor(static_cast<double>(CMath::OO_TWO_PI) * angle) * CMath::TWO_PI;
|
||||
|
||||
if (angle < 0.0f) {
|
||||
v1 -= CMath::TWO_PI;
|
||||
}
|
||||
|
||||
return angle - v1;
|
||||
}
|
||||
|
||||
void CAngle::Set(const float& angle) {
|
||||
float clampedAngle = CAngle::ClampTo2Pi(angle);
|
||||
|
||||
if (this->m_data != clampedAngle) {
|
||||
this->m_flags |= CBaseManaged::UPDATED;
|
||||
this->m_data = clampedAngle;
|
||||
}
|
||||
|
||||
this->m_cos = cos(this->m_data);
|
||||
this->m_sin = sin(this->m_data);
|
||||
}
|
||||
|
||||
void CCamera::SetupWorldProjection(const CRect& projectionRect, uint32_t flags) {
|
||||
C44Matrix projMat;
|
||||
float aspect = (projectionRect.maxX - projectionRect.minX) / (projectionRect.maxY - projectionRect.minY);
|
||||
GxuXformCreateProjection_SG(this->m_fov.m_data, aspect, this->m_zNear.m_data, this->m_zFar.m_data, projMat);
|
||||
GxXformSetProjection(projMat);
|
||||
|
||||
C44Matrix viewMat;
|
||||
C3Vector cameraPos = { 0.0f, 0.0f, 0.0f };
|
||||
C3Vector cameraVec = {
|
||||
this->m_target.m_data.x - this->m_position.m_data.x,
|
||||
this->m_target.m_data.y - this->m_position.m_data.y,
|
||||
this->m_target.m_data.z - this->m_position.m_data.z
|
||||
};
|
||||
C3Vector upVec = {
|
||||
this->m_rotation.m_sin * this->m_roll.m_sin,
|
||||
-(this->m_rotation.m_cos * this->m_roll.m_sin),
|
||||
this->m_roll.m_cos
|
||||
};
|
||||
GxuXformCreateLookAtSgCompat(cameraPos, cameraVec, upVec, viewMat);
|
||||
GxXformSetView(viewMat);
|
||||
|
||||
CShaderEffect::UpdateProjMatrix();
|
||||
}
|
70
src/gx/CCamera.hpp
Normal file
70
src/gx/CCamera.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
#ifndef GX_C_CAMERA_HPP
|
||||
#define GX_C_CAMERA_HPP
|
||||
|
||||
#include <common/DataMgr.hpp>
|
||||
|
||||
class CRect;
|
||||
|
||||
class CAngle : public TManaged<float> {
|
||||
public:
|
||||
// Static functions
|
||||
static float ClampTo2Pi(float angle);
|
||||
|
||||
// Member variables
|
||||
float m_cos;
|
||||
float m_sin;
|
||||
|
||||
// Virtual member functions
|
||||
virtual void Set(const float& angle);
|
||||
|
||||
// Member functions
|
||||
CAngle(float angle) {
|
||||
this->Set(angle);
|
||||
};
|
||||
};
|
||||
|
||||
class CCamera : public CDataMgr {
|
||||
public:
|
||||
static const C3Vector DEFAULT_POSITION;
|
||||
static const float DEFAULT_DIST;
|
||||
static const float DEFAULT_FARZ;
|
||||
static const float DEFAULT_NEARZ;
|
||||
|
||||
// Member variables
|
||||
TManaged<C3Vector> m_position;
|
||||
TManaged<C3Vector> m_target;
|
||||
TManaged<float> m_distance;
|
||||
TManaged<float> m_zFar;
|
||||
TManaged<float> m_zNear;
|
||||
CAngle m_aoa;
|
||||
CAngle m_fov;
|
||||
CAngle m_roll;
|
||||
CAngle m_rotation;
|
||||
|
||||
// Member functions
|
||||
CCamera()
|
||||
: m_position(DEFAULT_POSITION)
|
||||
, m_distance(DEFAULT_DIST)
|
||||
, m_zFar(DEFAULT_FARZ)
|
||||
, m_zNear(DEFAULT_NEARZ)
|
||||
, m_aoa(0.0f)
|
||||
, m_fov(0.0f)
|
||||
, m_roll(0.0f)
|
||||
, m_rotation(0.0f)
|
||||
{
|
||||
this->m_managedArray.SetCount(9);
|
||||
|
||||
this->AddManaged(&this->m_position, 7, 0x0);
|
||||
this->AddManaged(&this->m_target, 8, 0x0);
|
||||
this->AddManaged(&this->m_distance, 1, 0x0);
|
||||
this->AddManaged(&this->m_zFar, 2, 0x0);
|
||||
this->AddManaged(&this->m_zNear, 3, 0x0);
|
||||
this->AddManaged(&this->m_aoa, 0, 0x0);
|
||||
this->AddManaged(&this->m_fov, 4, 0x0);
|
||||
this->AddManaged(&this->m_roll, 5, 0x0);
|
||||
this->AddManaged(&this->m_rotation, 6, 0x0);
|
||||
}
|
||||
void SetupWorldProjection(const CRect& projectionRect, uint32_t flags);
|
||||
};
|
||||
|
||||
#endif
|
17
src/gx/CGxBatch.hpp
Normal file
17
src/gx/CGxBatch.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef GX_C_GX_BATCH_HPP
|
||||
#define GX_C_GX_BATCH_HPP
|
||||
|
||||
#include "gx/Types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class CGxBatch {
|
||||
public:
|
||||
// Member variables
|
||||
EGxPrim m_primType;
|
||||
uint32_t m_start;
|
||||
uint32_t m_count;
|
||||
uint16_t m_minIndex;
|
||||
uint16_t m_maxIndex;
|
||||
};
|
||||
|
||||
#endif
|
28
src/gx/CGxCaps.hpp
Normal file
28
src/gx/CGxCaps.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef GX_C_GX_CAPS_HPP
|
||||
#define GX_C_GX_CAPS_HPP
|
||||
|
||||
#include "gx/Types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class CGxCaps {
|
||||
public:
|
||||
int32_t m_pixelCenterOnEdge = 0;
|
||||
int32_t m_texelCenterOnEdge = 0;
|
||||
EGxColorFormat m_colorFormat = GxCF_argb;
|
||||
int32_t m_generateMipMaps = 0;
|
||||
uint32_t m_maxTextureSize = 0;
|
||||
int32_t m_texFmtDxt1 = 0;
|
||||
int32_t m_texFmtDxt3 = 0;
|
||||
int32_t m_texFmtDxt5 = 0;
|
||||
EGxShVS m_vertexShaderTarget = GxShVS_none;
|
||||
EGxShPS m_pixelShaderTarget = GxShPS_none;
|
||||
int32_t m_texFilterAnisotropic = 0;
|
||||
uint32_t m_maxTexAnisotropy = 0;
|
||||
int32_t m_texTarget[GxTexTargets_Last];
|
||||
uint32_t m_texMaxSize[GxTexTargets_Last];
|
||||
int32_t int130 = 1;
|
||||
int32_t int134 = 0;
|
||||
int32_t int138 = 0;
|
||||
};
|
||||
|
||||
#endif
|
1020
src/gx/CGxDevice.cpp
Normal file
1020
src/gx/CGxDevice.cpp
Normal file
File diff suppressed because it is too large
Load Diff
160
src/gx/CGxDevice.hpp
Normal file
160
src/gx/CGxDevice.hpp
Normal file
@ -0,0 +1,160 @@
|
||||
#ifndef GX_C_GX_DEVICE_HPP
|
||||
#define GX_C_GX_DEVICE_HPP
|
||||
|
||||
#include "gx/Buffer.hpp"
|
||||
#include "gx/CGxCaps.hpp"
|
||||
#include "gx/CGxFormat.hpp"
|
||||
#include "gx/CGxMatrixStack.hpp"
|
||||
#include "gx/CGxStateBom.hpp"
|
||||
#include "gx/Types.hpp"
|
||||
#include "gx/Shader.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/Hash.hpp>
|
||||
#include <tempest/Box.hpp>
|
||||
#include <tempest/Rect.hpp>
|
||||
|
||||
class CGxBatch;
|
||||
class CGxTex;
|
||||
class CGxTexFlags;
|
||||
|
||||
struct CGxAppRenderState {
|
||||
CGxStateBom m_value;
|
||||
uint32_t m_stackDepth;
|
||||
int32_t m_dirty;
|
||||
};
|
||||
|
||||
struct CGxPushedRenderState {
|
||||
EGxRenderState m_which;
|
||||
CGxStateBom m_value;
|
||||
uint32_t m_stackDepth;
|
||||
};
|
||||
|
||||
struct ShaderConstants {
|
||||
C4Vector constants[256];
|
||||
uint32_t unk1;
|
||||
uint32_t unk2;
|
||||
};
|
||||
|
||||
class CGxDevice {
|
||||
public:
|
||||
// Static variables
|
||||
static uint32_t s_alphaRef[];
|
||||
static C3Vector s_pointScaleIdentity;
|
||||
static ShaderConstants s_shadowConstants[2];
|
||||
static uint32_t s_streamPoolSize[];
|
||||
static uint32_t s_texFormatBitDepth[];
|
||||
static uint32_t s_texFormatBytesPerBlock[];
|
||||
|
||||
// Static functions
|
||||
static CGxDevice* NewGLL(void);
|
||||
static CGxDevice* NewOpenGl(void);
|
||||
|
||||
// Member variables
|
||||
TSGrowableArray<CGxPushedRenderState> m_pushedStates;
|
||||
TSGrowableArray<size_t> m_stackOffsets;
|
||||
TSGrowableArray<EGxRenderState> m_dirtyStates;
|
||||
CRect m_defWindowRect;
|
||||
CRect m_curWindowRect;
|
||||
EGxApi m_api = GxApis_Last;
|
||||
CGxFormat m_format;
|
||||
CGxCaps m_caps;
|
||||
int32_t m_shaderProfiles[GxShTargets_Last] = { 6, 0, 0, 0, 12, 0 }; // TODO placeholder
|
||||
TSHashTable<CGxShader, HASHKEY_STRI> m_shaderList[GxShTargets_Last];
|
||||
int32_t m_context = 0;
|
||||
CBoundingBox m_viewport;
|
||||
C44Matrix m_projection;
|
||||
C44Matrix m_projNative;
|
||||
CGxMatrixStack m_xforms[GxXforms_Last];
|
||||
uint32_t m_appMasterEnables = 0;
|
||||
uint32_t m_hwMasterEnables = 0;
|
||||
TSList<CGxPool, TSGetLink<CGxPool>> m_poolList;
|
||||
CGxBuf* m_bufLocked[GxPoolTargets_Last];
|
||||
CGxPool* m_vertexPool = nullptr;
|
||||
CGxPool* m_indexPool = nullptr;
|
||||
CGxBuf* m_streamBufs[GxPoolTargets_Last];
|
||||
CGxVertexAttrib m_primVertexFormatAttrib[GxVertexBufferFormats_Last];
|
||||
CGxBuf* m_primVertexFormatBuf[GxVertexBufferFormats_Last];
|
||||
uint32_t m_primVertexMask = 0;
|
||||
uint32_t m_primVertexDirty = 0;
|
||||
EGxVertexBufferFormat m_primVertexFormat = GxVertexBufferFormats_Last;
|
||||
CGxBuf* m_primVertexBuf = nullptr;
|
||||
uint32_t m_primVertexSize;
|
||||
CGxBuf* m_primIndexBuf = nullptr;
|
||||
int32_t m_primIndexDirty = 0;
|
||||
TSFixedArray<CGxAppRenderState> m_appRenderStates;
|
||||
TSFixedArray<CGxStateBom> m_hwRenderStates;
|
||||
uint32_t m_baseMipLevel = 0; // TODO placeholder
|
||||
|
||||
// Virtual member functions
|
||||
virtual void ITexMarkAsUpdated(CGxTex*) = 0;
|
||||
virtual void IRsSendToHw(EGxRenderState) = 0;
|
||||
virtual void ICursorCreate(const CGxFormat& format);
|
||||
virtual int32_t DeviceCreate(long (*)(void*, uint32_t, uint32_t, long), const CGxFormat&);
|
||||
virtual int32_t DeviceSetFormat(const CGxFormat&);
|
||||
virtual void CapsWindowSize(CRect&) = 0;
|
||||
virtual void CapsWindowSizeInScreenCoords(CRect& dst) = 0;
|
||||
virtual void ScenePresent(void);
|
||||
virtual void SceneClear(uint32_t, CImVector) {};
|
||||
virtual void XformSetProjection(const C44Matrix&);
|
||||
virtual void XformSetView(const C44Matrix&);
|
||||
virtual void Draw(CGxBatch*, int32_t) {};
|
||||
virtual void ValidateDraw(CGxBatch*, int32_t);
|
||||
virtual void MasterEnableSet(EGxMasterEnables, int32_t);
|
||||
virtual void PoolSizeSet(CGxPool*, uint32_t) = 0;
|
||||
virtual char* BufLock(CGxBuf*);
|
||||
virtual int32_t BufUnlock(CGxBuf*, uint32_t);
|
||||
virtual int32_t TexCreate(EGxTexTarget, uint32_t, uint32_t, uint32_t, EGxTexFormat, EGxTexFormat, CGxTexFlags, void*, void (*)(EGxTexCommand, uint32_t, uint32_t, uint32_t, uint32_t, void*, uint32_t&, const void*&), const char*, CGxTex*&);
|
||||
virtual void TexDestroy(CGxTex* texId);
|
||||
virtual void ShaderCreate(CGxShader*[], EGxShTarget, const char*, const char*, int32_t);
|
||||
virtual void ShaderConstantsSet(EGxShTarget, uint32_t, const float*, uint32_t);
|
||||
virtual void IShaderCreate(CGxShader*) = 0;
|
||||
virtual int32_t StereoEnabled(void) = 0;
|
||||
|
||||
// Member functions
|
||||
CGxDevice();
|
||||
CGxBuf* BufCreate(CGxPool*, uint32_t, uint32_t, uint32_t);
|
||||
CGxBuf* BufStream(EGxPoolTarget, uint32_t, uint32_t);
|
||||
void DeviceCreatePools(void);
|
||||
void DeviceCreateStreamBufs(void);
|
||||
const CRect& DeviceCurWindow(void);
|
||||
void DeviceSetCurWindow(const CRect&);
|
||||
void DeviceSetDefWindow(CRect const&);
|
||||
const CRect& DeviceDefWindow(void);
|
||||
int32_t IDevIsWindowed();
|
||||
void IRsDirty(EGxRenderState);
|
||||
void IRsForceUpdate(void);
|
||||
void IRsForceUpdate(EGxRenderState);
|
||||
void IRsInit(void);
|
||||
void IRsSync(int32_t);
|
||||
void IShaderBind(void) {};
|
||||
void IShaderLoad(CGxShader*[], EGxShTarget, const char*, const char*, int32_t);
|
||||
void ITexBind(void) {};
|
||||
void ITexWHDStartEnd(CGxTex*, uint32_t&, uint32_t&, uint32_t&, uint32_t&);
|
||||
int32_t MasterEnable(EGxMasterEnables);
|
||||
CGxPool* PoolCreate(EGxPoolTarget, EGxPoolUsage, uint32_t, EGxPoolHintBits, const char*);
|
||||
void PrimIndexPtr(CGxBuf*);
|
||||
void PrimVertexFormat(CGxBuf*, CGxVertexAttrib*, uint32_t);
|
||||
void PrimVertexMask(uint32_t);
|
||||
void PrimVertexPtr(CGxBuf*, EGxVertexBufferFormat);
|
||||
void RsGet(EGxRenderState, int32_t&);
|
||||
void RsSet(EGxRenderState, int32_t);
|
||||
void RsSet(EGxRenderState, void*);
|
||||
void RsSetAlphaRef(void);
|
||||
void RsPop(void);
|
||||
void RsPush(void);
|
||||
void ShaderConstantsClear(void);
|
||||
char* ShaderConstantsLock(EGxShTarget target);
|
||||
void ShaderConstantsUnlock(EGxShTarget target, uint32_t index, uint32_t count);
|
||||
void TexMarkForUpdate(CGxTex*, const CiRect&, int32_t);
|
||||
void TexSetWrap(CGxTex* texId, EGxTexWrapMode wrapU, EGxTexWrapMode wrapV);
|
||||
void XformPop(EGxXform xf);
|
||||
void XformProjection(C44Matrix&);
|
||||
void XformProjNative(C44Matrix&);
|
||||
void XformPush(EGxXform xf);
|
||||
void XformSet(EGxXform xf, const C44Matrix& matrix);
|
||||
void XformSetViewport(float, float, float, float, float, float);
|
||||
void XformView(C44Matrix&);
|
||||
void XformViewport(float&, float&, float&, float&, float&, float&);
|
||||
};
|
||||
|
||||
#endif
|
32
src/gx/CGxFormat.hpp
Normal file
32
src/gx/CGxFormat.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef GX_C_GX_FORMAT_HPP
|
||||
#define GX_C_GX_FORMAT_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
class CGxFormat {
|
||||
public:
|
||||
// Types
|
||||
enum Format {
|
||||
Fmt_Rgb565 = 0,
|
||||
Fmt_ArgbX888 = 1,
|
||||
Fmt_Argb8888 = 2,
|
||||
Fmt_Argb2101010 = 3,
|
||||
Fmt_Ds160 = 4,
|
||||
Fmt_Ds24X = 5,
|
||||
Fmt_Ds248 = 6,
|
||||
Fmt_Ds320 = 7,
|
||||
Formats_Last = 8
|
||||
};
|
||||
|
||||
// Member variables
|
||||
int8_t window;
|
||||
int32_t maximize;
|
||||
Format depthFormat;
|
||||
C2iVector size;
|
||||
uint32_t sampleCount;
|
||||
Format colorFormat;
|
||||
uint32_t refreshRate;
|
||||
};
|
||||
|
||||
#endif
|
30
src/gx/CGxMatrixStack.cpp
Normal file
30
src/gx/CGxMatrixStack.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include "gx/CGxMatrixStack.hpp"
|
||||
|
||||
CGxMatrixStack::CGxMatrixStack() {
|
||||
this->m_flags[0] = 0x1;
|
||||
}
|
||||
|
||||
void CGxMatrixStack::Pop() {
|
||||
if (this->m_level > 0) {
|
||||
this->m_level--;
|
||||
}
|
||||
|
||||
this->m_dirty = 1;
|
||||
}
|
||||
|
||||
void CGxMatrixStack::Push() {
|
||||
if (this->m_level < 3) {
|
||||
this->m_level++;
|
||||
}
|
||||
|
||||
this->m_mtx[this->m_level] = this->m_mtx[this->m_level - 1];
|
||||
this->m_flags[this->m_level] = this->m_flags[this->m_level - 1];
|
||||
|
||||
this->m_dirty = 1;
|
||||
}
|
||||
|
||||
C44Matrix& CGxMatrixStack::Top() {
|
||||
this->m_dirty = 1;
|
||||
this->m_flags[this->m_level] &= 0xFFFFFFFE;
|
||||
return this->m_mtx[this->m_level];
|
||||
}
|
22
src/gx/CGxMatrixStack.hpp
Normal file
22
src/gx/CGxMatrixStack.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef GX_C_GX_MATRIX_STACK_HPP
|
||||
#define GX_C_GX_MATRIX_STACK_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <tempest/Matrix.hpp>
|
||||
|
||||
class CGxMatrixStack {
|
||||
public:
|
||||
// Member variables
|
||||
uint32_t m_level = 0;
|
||||
int8_t m_dirty = 0;
|
||||
C44Matrix m_mtx[4];
|
||||
uint32_t m_flags[4] = {};
|
||||
|
||||
// Member functions
|
||||
CGxMatrixStack();
|
||||
void Pop(void);
|
||||
void Push(void);
|
||||
C44Matrix& Top(void);
|
||||
};
|
||||
|
||||
#endif
|
85
src/gx/CGxStateBom.cpp
Normal file
85
src/gx/CGxStateBom.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
#include "gx/CGxStateBom.hpp"
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
const CGxStateBom& CGxStateBom::operator=(int32_t value) {
|
||||
this->m_data.i[0] = value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const CGxStateBom& CGxStateBom::operator=(uint32_t value) {
|
||||
this->m_data.i[0] = value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const CGxStateBom& CGxStateBom::operator=(float value) {
|
||||
this->m_data.f[0] = value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const CGxStateBom& CGxStateBom::operator=(void* value) {
|
||||
this->m_data.p = value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const CGxStateBom& CGxStateBom::operator=(C3Vector& value) {
|
||||
this->m_data.f[0] = value.x;
|
||||
this->m_data.f[1] = value.y;
|
||||
this->m_data.f[2] = value.z;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool CGxStateBom::operator!=(int32_t value) {
|
||||
return this->m_data.i[0] != value;
|
||||
}
|
||||
|
||||
bool CGxStateBom::operator!=(uint32_t value) {
|
||||
return this->m_data.i[0] != value;
|
||||
}
|
||||
|
||||
bool CGxStateBom::operator!=(float value) {
|
||||
return this->m_data.f[0] != value;
|
||||
}
|
||||
|
||||
bool CGxStateBom::operator!=(void* value) {
|
||||
return this->m_data.p != value;
|
||||
}
|
||||
|
||||
bool CGxStateBom::operator!=(C3Vector& value) {
|
||||
return this->m_data.f[0] != value.x
|
||||
|| this->m_data.f[1] != value.y
|
||||
|| this->m_data.f[2] != value.z;
|
||||
}
|
||||
|
||||
bool CGxStateBom::operator!=(CGxStateBom& value) {
|
||||
return (this->m_data.i[0] - value.m_data.i[0])
|
||||
| (this->m_data.i[1] - value.m_data.i[1])
|
||||
| (this->m_data.i[2] - value.m_data.i[2])
|
||||
| (this->filler - value.filler);
|
||||
}
|
||||
|
||||
CGxStateBom::operator CImVector() const {
|
||||
CImVector color;
|
||||
color.value = this->m_data.i[0];
|
||||
return color;
|
||||
}
|
||||
|
||||
CGxStateBom::operator float() const {
|
||||
return this->m_data.f[0];
|
||||
}
|
||||
|
||||
CGxStateBom::operator int32_t() const {
|
||||
return this->m_data.i[0];
|
||||
}
|
||||
|
||||
CGxStateBom::operator uint32_t() const {
|
||||
return this->m_data.i[0];
|
||||
}
|
||||
|
||||
CGxStateBom::operator void*() const {
|
||||
return this->m_data.p;
|
||||
}
|
39
src/gx/CGxStateBom.hpp
Normal file
39
src/gx/CGxStateBom.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef GX_C_GX_STATE_BOM_HPP
|
||||
#define GX_C_GX_STATE_BOM_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class C3Vector;
|
||||
class CImVector;
|
||||
|
||||
class CGxStateBom {
|
||||
public:
|
||||
// Member variables
|
||||
union {
|
||||
int32_t i[3];
|
||||
float f[3];
|
||||
void* p;
|
||||
} m_data;
|
||||
|
||||
int32_t filler;
|
||||
|
||||
// Member functions
|
||||
const CGxStateBom& operator=(float);
|
||||
const CGxStateBom& operator=(int32_t);
|
||||
const CGxStateBom& operator=(uint32_t);
|
||||
const CGxStateBom& operator=(void*);
|
||||
const CGxStateBom& operator=(C3Vector&);
|
||||
bool operator!=(float);
|
||||
bool operator!=(int32_t);
|
||||
bool operator!=(uint32_t);
|
||||
bool operator!=(void*);
|
||||
bool operator!=(C3Vector&);
|
||||
bool operator!=(CGxStateBom&);
|
||||
explicit operator CImVector() const;
|
||||
explicit operator float() const;
|
||||
explicit operator int32_t() const;
|
||||
explicit operator uint32_t() const;
|
||||
explicit operator void*() const;
|
||||
};
|
||||
|
||||
#endif
|
43
src/gx/CMakeLists.txt
Normal file
43
src/gx/CMakeLists.txt
Normal file
@ -0,0 +1,43 @@
|
||||
file(GLOB GX_SOURCES
|
||||
"*.cpp"
|
||||
"buffer/*.cpp"
|
||||
"font/*.cpp"
|
||||
"shader/*.cpp"
|
||||
"texture/*.cpp"
|
||||
)
|
||||
|
||||
if(WHOA_SYSTEM_MAC)
|
||||
file(GLOB GLL_SOURCES "gll/*.cpp" "gll/*.mm")
|
||||
set_source_files_properties(${GLL_SOURCES}
|
||||
PROPERTIES COMPILE_FLAGS "-x objective-c++"
|
||||
)
|
||||
list(APPEND GX_SOURCES ${GLL_SOURCES})
|
||||
endif()
|
||||
|
||||
add_library(gx STATIC ${GX_SOURCES})
|
||||
|
||||
target_include_directories(gx
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
target_link_libraries(gx
|
||||
PRIVATE
|
||||
event
|
||||
math
|
||||
model
|
||||
ui
|
||||
util
|
||||
PUBLIC
|
||||
freetype-2.0
|
||||
storm
|
||||
tempest
|
||||
)
|
||||
|
||||
if(WHOA_SYSTEM_MAC)
|
||||
target_link_libraries(gx
|
||||
PRIVATE
|
||||
"-framework AppKit"
|
||||
"-framework OpenGL"
|
||||
)
|
||||
endif()
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user