refactor: move 4J implementations into platform/sdl2

This commit is contained in:
MatthewBeshay
2026-04-02 16:03:08 +11:00
parent 35b63da24d
commit e5a859f8a7
264 changed files with 336 additions and 415 deletions
+680
View File
@@ -0,0 +1,680 @@
#include "Input.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_gamecontroller.h>
#include <SDL2/SDL_joystick.h>
#include <SDL2/SDL_keyboard.h>
#include <SDL2/SDL_mouse.h>
#include <SDL2/SDL_scancode.h>
#include <SDL2/SDL_stdinc.h>
#include <SDL2/SDL_video.h>
#include <SDL2/begin_code.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include "../../4J.Common/4J_InputActions.h"
#include "../PlatformTypes.h"
C_4JInput InputManager;
static const int KEY_COUNT = SDL_NUM_SCANCODES;
static const int BTN_COUNT = SDL_CONTROLLER_BUTTON_MAX;
static const int AXS_COUNT = SDL_CONTROLLER_AXIS_MAX;
static const float MOUSE_SCALE = 0.015f;
// Vars
static bool s_sdlInitialized = false;
static bool s_keysCurrent[KEY_COUNT] = {};
static bool s_keysPrev[KEY_COUNT] = {};
static bool s_btnsCurrent[BTN_COUNT] = {};
static bool s_btnsPrev[BTN_COUNT] = {};
static bool s_axisCurrent[AXS_COUNT] = {};
static bool s_axisPrev[AXS_COUNT] = {};
static float axisVal[AXS_COUNT] = {};
static bool s_mouseLeftCurrent = false, s_mouseLeftPrev = false;
static bool s_mouseRightCurrent = false, s_mouseRightPrev = false;
static bool s_menuDisplayed[4] = {};
static bool s_prevMenuDisplayed = false;
static bool s_snapTaken = false;
static float s_accumRelX = 0, s_accumRelY = 0;
static float s_snapRelX = 0, s_snapRelY = 0;
static int s_mouseX = 0, s_mouseY = 0;
static int s_scrollTicksForButtonPressed = 0;
static int s_scrollTicksForGetValue = 0;
static int s_scrollTicksSnap = 0;
static bool s_scrollSnapTaken = false;
// Text input state (non-blocking keyboard)
static bool s_keyboardActive = false;
static std::string s_textInputBuf;
static int (*s_keyboardCallback)(void*, const bool) = nullptr;
static void* s_keyboardCallbackParam = nullptr;
// We set all the watched keys
// I don't know if I'll need to change this if we add chat support soon.
static const int s_watchedKeys[] = {
SDL_SCANCODE_W, SDL_SCANCODE_A, SDL_SCANCODE_S,
SDL_SCANCODE_D, SDL_SCANCODE_SPACE, SDL_SCANCODE_LSHIFT,
SDL_SCANCODE_RSHIFT, SDL_SCANCODE_E, SDL_SCANCODE_Q,
SDL_SCANCODE_F, SDL_SCANCODE_C, SDL_SCANCODE_ESCAPE,
SDL_SCANCODE_RETURN, SDL_SCANCODE_F3, SDL_SCANCODE_F5,
SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT,
SDL_SCANCODE_RIGHT, SDL_SCANCODE_PAGEUP, SDL_SCANCODE_PAGEDOWN,
SDL_SCANCODE_TAB, SDL_SCANCODE_LCTRL, SDL_SCANCODE_RCTRL,
SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3,
SDL_SCANCODE_4, SDL_SCANCODE_5, SDL_SCANCODE_6,
SDL_SCANCODE_7, SDL_SCANCODE_8, SDL_SCANCODE_9,
SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_C,
SDL_SCANCODE_V};
static const int s_watchedKeyCount =
(int)(sizeof(s_watchedKeys) / sizeof(s_watchedKeys[0]));
static inline bool KDown(int sc) {
return (sc > 0 && sc < KEY_COUNT) ? s_keysCurrent[sc] : false;
}
static inline bool KPressed(int sc) {
return (sc > 0 && sc < KEY_COUNT) ? !s_keysPrev[sc] && s_keysCurrent[sc]
: false;
}
static inline bool KReleased(int sc) {
return (sc > 0 && sc < KEY_COUNT) ? s_keysPrev[sc] && !s_keysCurrent[sc]
: false;
}
static inline bool MouseLDown() { return s_mouseLeftCurrent; }
static inline bool MouseLPressed() {
return s_mouseLeftCurrent && !s_mouseLeftPrev;
}
static inline bool MouseLReleased() {
return !s_mouseLeftCurrent && s_mouseLeftPrev;
}
static inline bool MouseRDown() { return s_mouseRightCurrent; }
static inline bool MouseRPressed() {
return s_mouseRightCurrent && !s_mouseRightPrev;
}
static inline bool MouseRReleased() {
return !s_mouseRightCurrent && s_mouseRightPrev;
}
// holds controller object
static SDL_GameController* controller = nullptr;
// Watched controller buttons set
static const SDL_GameControllerButton s_watchedBtns[] = {
SDL_CONTROLLER_BUTTON_A,
SDL_CONTROLLER_BUTTON_B,
SDL_CONTROLLER_BUTTON_X,
SDL_CONTROLLER_BUTTON_Y,
SDL_CONTROLLER_BUTTON_BACK,
SDL_CONTROLLER_BUTTON_GUIDE,
SDL_CONTROLLER_BUTTON_START,
SDL_CONTROLLER_BUTTON_LEFTSTICK,
SDL_CONTROLLER_BUTTON_RIGHTSTICK,
SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
SDL_CONTROLLER_BUTTON_DPAD_UP,
SDL_CONTROLLER_BUTTON_DPAD_DOWN,
SDL_CONTROLLER_BUTTON_DPAD_LEFT,
SDL_CONTROLLER_BUTTON_DPAD_RIGHT};
static const int s_watchedBtnsCount =
(int)(sizeof(s_watchedBtns) / sizeof(s_watchedBtns[0]));
static inline bool CDown(int cb) {
return (cb >= 0 && cb < BTN_COUNT) ? s_btnsCurrent[cb] : false;
}
static inline bool CPressed(int cb) {
return (cb >= 0 && cb < BTN_COUNT) ? !s_btnsPrev[cb] && s_btnsCurrent[cb]
: false;
}
static inline bool CReleased(int cb) {
return (cb >= 0 && cb < BTN_COUNT) ? s_btnsPrev[cb] && !s_btnsCurrent[cb]
: false;
}
// Sets controller dead zone
static int deadZone = 8000;
// Watched controller axes set
static const SDL_GameControllerAxis s_watchedAxis[] = {
SDL_CONTROLLER_AXIS_LEFTX, SDL_CONTROLLER_AXIS_LEFTY,
SDL_CONTROLLER_AXIS_RIGHTX, SDL_CONTROLLER_AXIS_RIGHTY,
SDL_CONTROLLER_AXIS_TRIGGERLEFT, SDL_CONTROLLER_AXIS_TRIGGERRIGHT};
static const int s_watchedAxisCount =
(int)(sizeof(s_watchedAxis) / sizeof(s_watchedAxis[0]));
static inline bool ADown(int ca) {
return (ca >= 0 && ca < AXS_COUNT) ? s_axisCurrent[ca] : false;
}
static inline bool APressed(int ca) {
return (ca >= 0 && ca < AXS_COUNT) ? !s_axisPrev[ca] && s_axisCurrent[ca]
: false;
}
static inline bool AReleased(int ca) {
return (ca >= 0 && ca < AXS_COUNT) ? s_axisPrev[ca] && !s_axisCurrent[ca]
: false;
}
// get directly into SDL events before the game queue can steal them.
// this took me a while.
static int SDLCALL EventWatcher(void*, SDL_Event* e) {
if (e->type == SDL_MOUSEWHEEL) {
int y = e->wheel.y;
if (e->wheel.direction == SDL_MOUSEWHEEL_FLIPPED) {
y = -y;
}
s_scrollTicksForGetValue += y;
s_scrollTicksForButtonPressed += y;
} else if (e->type == SDL_MOUSEBUTTONDOWN) {
if (e->button.button == 4) {
s_scrollTicksForGetValue++;
s_scrollTicksForButtonPressed++;
} else if (e->button.button == 5) {
s_scrollTicksForGetValue--;
s_scrollTicksForButtonPressed--;
}
} else if (e->type == SDL_MOUSEMOTION) {
s_accumRelX += (float)e->motion.xrel;
s_accumRelY += (float)e->motion.yrel;
} else if (e->type == SDL_TEXTINPUT && s_keyboardActive) {
s_textInputBuf += e->text.text;
} else if (e->type == SDL_CONTROLLERDEVICEADDED) { // Will search for
// controller if none
for (int i = 0; i < SDL_NumJoysticks(); i++) {
if (SDL_IsGameController(i)) {
controller = SDL_GameControllerOpen(i);
break;
}
}
} else if (controller) { // only checks when a controller exists
if (e->type == SDL_CONTROLLERDEVICEREMOVED) {
SDL_Joystick* joy = SDL_GameControllerGetJoystick(controller);
if (SDL_JoystickInstanceID(joy) == e->cdevice.which) {
SDL_GameControllerClose(controller);
controller = nullptr;
}
} else if (e->type == SDL_CONTROLLERBUTTONDOWN) {
if (e->cbutton.button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER) {
s_scrollTicksForGetValue++;
s_scrollTicksForButtonPressed++;
} else if (e->cbutton.button ==
SDL_CONTROLLER_BUTTON_RIGHTSHOULDER) {
s_scrollTicksForGetValue--;
s_scrollTicksForButtonPressed--;
}
}
}
return 1;
}
static int ScrollSnap() {
if (!s_scrollSnapTaken) {
s_scrollTicksSnap = s_scrollTicksForButtonPressed;
s_scrollTicksForButtonPressed = 0;
s_scrollSnapTaken = true;
}
return s_scrollTicksSnap;
}
static void TakeSnapIfNeeded() {
if (!s_snapTaken) {
s_snapRelX = s_accumRelX;
s_accumRelX = 0;
s_snapRelY = s_accumRelY;
s_accumRelY = 0;
s_snapTaken = true;
}
}
// We initialize the SDL input
void C_4JInput::Initialise(int, unsigned char, unsigned char, unsigned char) {
if (!s_sdlInitialized) {
if (SDL_WasInit(SDL_INIT_VIDEO) == 0) {
SDL_Init(SDL_INIT_VIDEO);
}
if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) == 0) {
SDL_Init(SDL_INIT_GAMECONTROLLER);
}
SDL_AddEventWatch(EventWatcher, NULL);
s_sdlInitialized = true;
}
memset(s_keysCurrent, 0, sizeof(s_keysCurrent));
memset(s_keysPrev, 0, sizeof(s_keysPrev));
memset(s_btnsCurrent, 0, sizeof(s_btnsCurrent));
memset(s_btnsPrev, 0, sizeof(s_btnsPrev));
memset(s_axisCurrent, 0, sizeof(s_axisCurrent));
memset(s_axisPrev, 0, sizeof(s_axisPrev));
memset(s_menuDisplayed, 0, sizeof(s_menuDisplayed));
s_mouseLeftCurrent = s_mouseLeftPrev = s_mouseRightCurrent =
s_mouseRightPrev = false;
s_accumRelX = s_accumRelY = s_snapRelX = s_snapRelY = 0;
// i really gotta name these vars better..
s_scrollTicksForButtonPressed = s_scrollTicksForGetValue =
s_scrollTicksSnap = 0;
s_snapTaken = s_scrollSnapTaken = s_prevMenuDisplayed = false;
if (s_sdlInitialized) {
SDL_SetRelativeMouseMode(SDL_TRUE);
// looks for controller
for (int i = 0; i < SDL_NumJoysticks(); i++) {
if (SDL_IsGameController(i)) {
controller = SDL_GameControllerOpen(i);
break;
}
}
}
}
// Erase one UTF-8 codepoint from the end of a string.
static void utf8_pop_back(std::string& str) {
if (str.empty()) return;
size_t i = str.size() - 1;
while (i > 0 && (str[i] & 0xC0) == 0x80) --i;
str.erase(i);
}
// Each tick we update the input state by polling SDL, this is where we get the
// kbd and mouse state.
void C_4JInput::Tick() {
if (!s_sdlInitialized) return;
memcpy(s_keysPrev, s_keysCurrent, sizeof(s_keysCurrent));
memcpy(s_btnsPrev, s_btnsCurrent, sizeof(s_btnsCurrent));
memcpy(s_axisPrev, s_axisCurrent, sizeof(s_axisCurrent));
s_mouseLeftPrev = s_mouseLeftCurrent;
s_mouseRightPrev = s_mouseRightCurrent;
s_snapTaken = false;
s_scrollSnapTaken = false;
s_snapRelX = s_snapRelY = 0;
s_scrollTicksSnap = 0;
SDL_PumpEvents();
if (s_menuDisplayed[0]) {
s_scrollTicksForGetValue = 0;
}
const Uint8* state = SDL_GetKeyboardState(NULL);
for (int i = 0; i < s_watchedKeyCount; ++i) {
int sc = s_watchedKeys[i];
if (sc > 0 && sc < KEY_COUNT) s_keysCurrent[sc] = state[sc] != 0;
}
Uint32 btns = SDL_GetMouseState(&s_mouseX, &s_mouseY);
s_mouseLeftCurrent = (btns & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0;
s_mouseRightCurrent = (btns & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0;
if (!SDL_GetRelativeMouseMode()) {
s_accumRelX = 0;
s_accumRelY = 0;
}
if (!SDL_GetKeyboardFocus()) {
SDL_Window* mf = SDL_GetMouseFocus();
if (mf) {
SDL_RaiseWindow(mf);
SDL_SetWindowGrab(mf, SDL_TRUE);
}
}
// If there is a controller update the buttons and sticks
if (controller) {
for (int i = 0; i < s_watchedBtnsCount; ++i) {
int cb = s_watchedBtns[i];
if (cb >= 0 && cb < BTN_COUNT)
s_btnsCurrent[cb] =
SDL_GameControllerGetButton(controller, s_watchedBtns[i]);
}
for (int i = 0; i < s_watchedAxisCount; ++i) {
int ca = s_watchedAxis[i];
if (ca >= 0 && ca < AXS_COUNT) {
int aVal =
SDL_GameControllerGetAxis(controller, s_watchedAxis[i]);
if (s_watchedAxis[i] == SDL_CONTROLLER_AXIS_TRIGGERLEFT ||
s_watchedAxis[i] == SDL_CONTROLLER_AXIS_TRIGGERRIGHT)
s_axisCurrent[ca] = aVal > deadZone;
else {
s_axisCurrent[ca] = (aVal > deadZone || aVal < -deadZone);
axisVal[ca] = aVal / 32768.0f;
}
}
}
}
// Handle non-blocking keyboard input completion
if (s_keyboardActive) {
if (KPressed(SDL_SCANCODE_BACKSPACE)) {
utf8_pop_back(s_textInputBuf);
}
if (KPressed(SDL_SCANCODE_RETURN) || KPressed(SDL_SCANCODE_KP_ENTER)) {
s_keyboardActive = false;
SDL_StopTextInput();
// Consume the key so it doesn't also trigger ACTION_MENU_OK
s_keysCurrent[SDL_SCANCODE_RETURN] = false;
s_keysCurrent[SDL_SCANCODE_KP_ENTER] = false;
if (s_keyboardCallback) {
s_keyboardCallback(s_keyboardCallbackParam, true);
s_keyboardCallback = nullptr;
s_keyboardCallbackParam = nullptr;
}
} else if (KPressed(SDL_SCANCODE_ESCAPE)) {
s_keyboardActive = false;
s_textInputBuf.clear();
SDL_StopTextInput();
// Consume the key so it doesn't also trigger ACTION_MENU_CANCEL
s_keysCurrent[SDL_SCANCODE_ESCAPE] = false;
if (s_keyboardCallback) {
s_keyboardCallback(s_keyboardCallbackParam, false);
s_keyboardCallback = nullptr;
s_keyboardCallbackParam = nullptr;
}
}
}
}
int C_4JInput::GetHotbarSlotPressed(int iPad) {
if (iPad != 0) return -1;
constexpr size_t NUM_HOTBAR_SLOTS = 9;
static const int sc[NUM_HOTBAR_SLOTS] = {
SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3,
SDL_SCANCODE_4, SDL_SCANCODE_5, SDL_SCANCODE_6,
SDL_SCANCODE_7, SDL_SCANCODE_8, SDL_SCANCODE_9,
};
static bool s_wasDown[NUM_HOTBAR_SLOTS] = {};
for (int i = 0; i < NUM_HOTBAR_SLOTS; ++i) {
bool down = KDown(sc[i]);
bool pressed = down && !s_wasDown[i];
s_wasDown[i] = down;
if (pressed) return i;
}
return -1;
}
// KFN = Keyboard functions, CFN = Controller functions, AFN = Axis functions
#define ACTION_CASES(KFN, CFN, AFN) \
case ACTION_MENU_UP: \
return KFN(SDL_SCANCODE_UP) || CFN(SDL_CONTROLLER_BUTTON_DPAD_UP); \
case ACTION_MENU_DOWN: \
return KFN(SDL_SCANCODE_DOWN) || CFN(SDL_CONTROLLER_BUTTON_DPAD_DOWN); \
case ACTION_MENU_LEFT: \
return KFN(SDL_SCANCODE_LEFT) || CFN(SDL_CONTROLLER_BUTTON_DPAD_LEFT); \
case ACTION_MENU_RIGHT: \
return KFN(SDL_SCANCODE_RIGHT) || \
CFN(SDL_CONTROLLER_BUTTON_DPAD_RIGHT); \
case ACTION_MENU_PAGEUP: \
return KFN(SDL_SCANCODE_PAGEUP); \
case ACTION_MENU_PAGEDOWN: \
return KFN(SDL_SCANCODE_PAGEDOWN); \
case ACTION_MENU_OK: \
return KFN(SDL_SCANCODE_RETURN) || KFN(SDL_SCANCODE_Z) || \
CFN(SDL_CONTROLLER_BUTTON_A); \
case ACTION_MENU_CANCEL: \
return KFN(SDL_SCANCODE_ESCAPE) || KFN(SDL_SCANCODE_X) || \
CFN(SDL_CONTROLLER_BUTTON_B); \
case ACTION_MENU_A: \
return KFN(SDL_SCANCODE_Z) || KFN(SDL_SCANCODE_RETURN) || \
CFN(SDL_CONTROLLER_BUTTON_A); \
case ACTION_MENU_B: \
return KFN(SDL_SCANCODE_X) || KFN(SDL_SCANCODE_ESCAPE) || \
CFN(SDL_CONTROLLER_BUTTON_B); \
case ACTION_MENU_X: \
return KFN(SDL_SCANCODE_C) || CFN(SDL_CONTROLLER_BUTTON_X); \
case ACTION_MENU_Y: \
return KFN(SDL_SCANCODE_V) || CFN(SDL_CONTROLLER_BUTTON_Y); \
case MINECRAFT_ACTION_JUMP: \
return KFN(SDL_SCANCODE_SPACE) || CFN(SDL_CONTROLLER_BUTTON_A); \
case MINECRAFT_ACTION_FORWARD: \
return KFN(SDL_SCANCODE_W) || AFN(SDL_CONTROLLER_AXIS_LEFTY); \
case MINECRAFT_ACTION_BACKWARD: \
return KFN(SDL_SCANCODE_S) || AFN(SDL_CONTROLLER_AXIS_LEFTY); \
case MINECRAFT_ACTION_LEFT: \
return KFN(SDL_SCANCODE_A) || AFN(SDL_CONTROLLER_AXIS_LEFTX); \
case MINECRAFT_ACTION_RIGHT: \
return KFN(SDL_SCANCODE_D) || AFN(SDL_CONTROLLER_AXIS_LEFTX); \
case MINECRAFT_ACTION_INVENTORY: \
return KFN(SDL_SCANCODE_E) || CFN(SDL_CONTROLLER_BUTTON_Y); \
case MINECRAFT_ACTION_PAUSEMENU: \
return KFN(SDL_SCANCODE_ESCAPE) || CFN(SDL_CONTROLLER_BUTTON_START); \
case MINECRAFT_ACTION_DROP: \
return KFN(SDL_SCANCODE_Q) || CFN(SDL_CONTROLLER_BUTTON_B); \
case MINECRAFT_ACTION_CRAFTING: \
return KFN(SDL_SCANCODE_C) || CFN(SDL_CONTROLLER_BUTTON_X); \
case MINECRAFT_ACTION_RENDER_THIRD_PERSON: \
return KFN(SDL_SCANCODE_F5) || CFN(SDL_CONTROLLER_BUTTON_LEFTSTICK); \
case MINECRAFT_ACTION_GAME_INFO: \
return KFN(SDL_SCANCODE_F3); \
case MINECRAFT_ACTION_DPAD_LEFT: \
return KFN(SDL_SCANCODE_LEFT) || CFN(SDL_CONTROLLER_BUTTON_DPAD_LEFT); \
case MINECRAFT_ACTION_DPAD_RIGHT: \
return KFN(SDL_SCANCODE_RIGHT) || \
CFN(SDL_CONTROLLER_BUTTON_DPAD_RIGHT); \
case MINECRAFT_ACTION_DPAD_UP: \
return KFN(SDL_SCANCODE_UP) || CFN(SDL_CONTROLLER_BUTTON_DPAD_UP); \
case MINECRAFT_ACTION_DPAD_DOWN: \
return KFN(SDL_SCANCODE_DOWN) || CFN(SDL_CONTROLLER_BUTTON_DPAD_DOWN); \
default: \
return false;
bool C_4JInput::ButtonDown(int iPad, unsigned char ucAction) {
if (iPad != 0) return false;
if (s_keyboardActive) return false;
if (ucAction == 255) {
for (int i = 0; i < s_watchedKeyCount; ++i)
if (s_keysCurrent[s_watchedKeys[i]]) return true;
return s_mouseLeftCurrent || s_mouseRightCurrent;
}
switch (ucAction) {
case MINECRAFT_ACTION_ACTION:
return MouseLDown() || KDown(SDL_SCANCODE_RETURN) ||
ADown(SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
case MINECRAFT_ACTION_USE:
return MouseRDown() || KDown(SDL_SCANCODE_F) ||
ADown(SDL_CONTROLLER_AXIS_TRIGGERLEFT);
case MINECRAFT_ACTION_SNEAK_TOGGLE:
return KDown(SDL_SCANCODE_LSHIFT) || KDown(SDL_SCANCODE_RSHIFT) ||
CDown(SDL_CONTROLLER_BUTTON_RIGHTSTICK);
case MINECRAFT_ACTION_SPRINT:
return KDown(SDL_SCANCODE_LCTRL) || KDown(SDL_SCANCODE_RCTRL);
case MINECRAFT_ACTION_LEFT_SCROLL:
case ACTION_MENU_LEFT_SCROLL:
return ScrollSnap() > 0;
case MINECRAFT_ACTION_RIGHT_SCROLL:
case ACTION_MENU_RIGHT_SCROLL:
return ScrollSnap() < 0;
ACTION_CASES(KDown, CDown, ADown)
}
}
// The part that handles completing the action of pressing a button.
bool C_4JInput::ButtonPressed(int iPad, unsigned char ucAction) {
if (iPad != 0 || ucAction == 255) return false;
if (s_keyboardActive) return false;
switch (ucAction) {
case MINECRAFT_ACTION_ACTION:
return MouseLPressed() || KPressed(SDL_SCANCODE_RETURN) ||
APressed(SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
case MINECRAFT_ACTION_USE:
return MouseRPressed() || KPressed(SDL_SCANCODE_F) ||
APressed(SDL_CONTROLLER_AXIS_TRIGGERLEFT);
case MINECRAFT_ACTION_SNEAK_TOGGLE:
return KPressed(SDL_SCANCODE_LSHIFT) ||
KPressed(SDL_SCANCODE_RSHIFT) ||
CPressed(SDL_CONTROLLER_BUTTON_RIGHTSTICK);
case MINECRAFT_ACTION_SPRINT:
return KPressed(SDL_SCANCODE_LCTRL) || KPressed(SDL_SCANCODE_RCTRL);
case MINECRAFT_ACTION_LEFT_SCROLL:
case ACTION_MENU_LEFT_SCROLL:
return ScrollSnap() > 0;
case MINECRAFT_ACTION_RIGHT_SCROLL:
case ACTION_MENU_RIGHT_SCROLL:
return ScrollSnap() < 0;
ACTION_CASES(KPressed, CPressed, APressed)
}
}
// The part that handles Releasing a button.
bool C_4JInput::ButtonReleased(int iPad, unsigned char ucAction) {
if (iPad != 0 || ucAction == 255) return false;
if (s_keyboardActive) return false;
switch (ucAction) {
case MINECRAFT_ACTION_ACTION:
return MouseLReleased() || KReleased(SDL_SCANCODE_RETURN) ||
AReleased(SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
case MINECRAFT_ACTION_USE:
return MouseRReleased() || KReleased(SDL_SCANCODE_F) ||
AReleased(SDL_CONTROLLER_AXIS_TRIGGERLEFT);
case MINECRAFT_ACTION_SNEAK_TOGGLE:
return KReleased(SDL_SCANCODE_LSHIFT) ||
KReleased(SDL_SCANCODE_RSHIFT) ||
CReleased(SDL_CONTROLLER_BUTTON_RIGHTSTICK);
case MINECRAFT_ACTION_SPRINT:
KReleased(SDL_SCANCODE_LCTRL) || KReleased(SDL_SCANCODE_RCTRL);
case MINECRAFT_ACTION_LEFT_SCROLL:
case ACTION_MENU_LEFT_SCROLL:
case MINECRAFT_ACTION_RIGHT_SCROLL:
case ACTION_MENU_RIGHT_SCROLL:
return false;
ACTION_CASES(KReleased, CReleased, AReleased)
}
}
unsigned int C_4JInput::GetValue(int iPad, unsigned char ucAction, bool) {
if (iPad != 0) return 0;
if (ucAction == MINECRAFT_ACTION_LEFT_SCROLL) {
if (s_scrollTicksForGetValue > 0) {
unsigned int v = (unsigned int)s_scrollTicksForGetValue;
s_scrollTicksForGetValue = 0;
return v;
}
return 0u;
}
if (ucAction == MINECRAFT_ACTION_RIGHT_SCROLL) {
if (s_scrollTicksForGetValue < 0) {
unsigned int v = (unsigned int)(-s_scrollTicksForGetValue);
s_scrollTicksForGetValue = 0;
return v;
}
return 0u;
}
return ButtonDown(iPad, ucAction) ? 1u : 0u;
}
// Left stick movement, the one that moves the player around or selects menu
// options. (Soon be tested.)
float C_4JInput::GetJoypadStick_LX(int, bool) {
if (ADown(SDL_CONTROLLER_AXIS_LEFTX))
return axisVal[SDL_CONTROLLER_AXIS_LEFTX];
return (KDown(SDL_SCANCODE_D) ? 1.f : 0.f) -
(KDown(SDL_SCANCODE_A) ? 1.f : 0.f);
}
float C_4JInput::GetJoypadStick_LY(int, bool) {
if (ADown(SDL_CONTROLLER_AXIS_LEFTY))
return -axisVal[SDL_CONTROLLER_AXIS_LEFTY];
return (KDown(SDL_SCANCODE_W) ? 1.f : 0.f) -
(KDown(SDL_SCANCODE_S) ? 1.f : 0.f);
}
// We use mouse movement and convert it into a Right Stick output using
// logarithmic scaling This is the most important mouse part. Yet it's so small.
static float MouseAxis(float raw) {
if (fabsf(raw) < 0.0001f) return 0.f; // from 4j previous code
return (raw >= 0.f ? 1.f : -1.f) * sqrtf(fabsf(raw));
}
// We apply the Stick movement on the R(Right) X(2D Position)
float C_4JInput::GetJoypadStick_RX(int, bool) {
if (ADown(SDL_CONTROLLER_AXIS_RIGHTX))
return axisVal[SDL_CONTROLLER_AXIS_RIGHTX];
if (!SDL_GetRelativeMouseMode()) return 0.f;
TakeSnapIfNeeded();
return MouseAxis(s_snapRelX * MOUSE_SCALE);
}
// Bis. but with Y(2D Position)
float C_4JInput::GetJoypadStick_RY(int, bool) {
if (ADown(SDL_CONTROLLER_AXIS_RIGHTY))
return -axisVal[SDL_CONTROLLER_AXIS_RIGHTY];
if (!SDL_GetRelativeMouseMode()) return 0.f;
TakeSnapIfNeeded();
return MouseAxis(-s_snapRelY * MOUSE_SCALE);
}
unsigned char C_4JInput::GetJoypadLTrigger(int, bool) {
return (s_mouseRightCurrent ||
s_axisCurrent[SDL_CONTROLLER_AXIS_TRIGGERLEFT])
? 255
: 0;
}
unsigned char C_4JInput::GetJoypadRTrigger(int, bool) {
return (s_mouseLeftCurrent ||
s_axisCurrent[SDL_CONTROLLER_AXIS_TRIGGERRIGHT])
? 255
: 0;
}
int C_4JInput::GetMouseX() { return s_mouseX; }
int C_4JInput::GetMouseY() { return s_mouseY; }
// We detect if a Menu is visible on the player's screen to the mouse being
// stuck.
void C_4JInput::SetMenuDisplayed(int iPad, bool bVal) {
if (iPad >= 0 && iPad < 4) s_menuDisplayed[iPad] = bVal;
if (!s_sdlInitialized || bVal == s_prevMenuDisplayed) return;
SDL_SetRelativeMouseMode(bVal ? SDL_FALSE : SDL_TRUE);
s_prevMenuDisplayed = bVal;
}
int C_4JInput::GetScrollDelta() {
int v = s_scrollTicksForButtonPressed;
s_scrollTicksForButtonPressed = 0;
return v;
}
void C_4JInput::SetDeadzoneAndMovementRange(unsigned int, unsigned int) {}
void C_4JInput::SetGameJoypadMaps(unsigned char, unsigned char, unsigned int) {}
unsigned int C_4JInput::GetGameJoypadMaps(unsigned char, unsigned char) {
return 0;
}
void C_4JInput::SetJoypadMapVal(int, unsigned char) {}
unsigned char C_4JInput::GetJoypadMapVal(int) { return 0; }
void C_4JInput::SetJoypadSensitivity(int, float) {}
void C_4JInput::SetJoypadStickAxisMap(int, unsigned int, unsigned int) {}
void C_4JInput::SetJoypadStickTriggerMap(int, unsigned int, unsigned int) {}
void C_4JInput::SetKeyRepeatRate(float, float) {}
void C_4JInput::SetDebugSequence(const char*, int (*)(void*), void*) {}
float C_4JInput::GetIdleSeconds(int) { return 0.f; }
bool C_4JInput::IsPadConnected(int iPad) { return iPad == 0; }
EKeyboardResult C_4JInput::RequestKeyboard(const wchar_t*, const wchar_t*, int,
unsigned int,
int (*callback)(void*, const bool),
void* scene,
C_4JInput::EKeyboardMode) {
s_keyboardActive = true;
s_textInputBuf.clear();
s_keyboardCallback = callback;
s_keyboardCallbackParam = scene;
SDL_StartTextInput();
return EKeyboard_Pending;
}
bool C_4JInput::GetMenuDisplayed(int iPad) {
if (iPad >= 0 && iPad < 4) return s_menuDisplayed[iPad];
return false;
}
const char* C_4JInput::GetText() { return s_textInputBuf.c_str(); }
bool C_4JInput::VerifyStrings(wchar_t**, int,
int (*)(void*, STRING_VERIFY_RESPONSE*), void*) {
return true;
}
void C_4JInput::CancelQueuedVerifyStrings(int (*)(void*,
STRING_VERIFY_RESPONSE*),
void*) {}
void C_4JInput::CancelAllVerifyInProgress() {}
// Primary pad (moved from Profile)
namespace {
int s_inputPrimaryPad = 0;
}
int C_4JInput::GetPrimaryPad() { return s_inputPrimaryPad; }
void C_4JInput::SetPrimaryPad(int iPad) { s_inputPrimaryPad = iPad; }
+147
View File
@@ -0,0 +1,147 @@
#pragma once
#include <cstdint>
#include "../IPlatformInput.h"
#define MAP_STYLE_0 0
#define MAP_STYLE_1 1
#define MAP_STYLE_2 2
#define _360_JOY_BUTTON_A 0x00000001
#define _360_JOY_BUTTON_B 0x00000002
#define _360_JOY_BUTTON_X 0x00000004
#define _360_JOY_BUTTON_Y 0x00000008
#define _360_JOY_BUTTON_START 0x00000010
#define _360_JOY_BUTTON_BACK 0x00000020
#define _360_JOY_BUTTON_RB 0x00000040
#define _360_JOY_BUTTON_LB 0x00000080
#define _360_JOY_BUTTON_RTHUMB 0x00000100
#define _360_JOY_BUTTON_LTHUMB 0x00000200
#define _360_JOY_BUTTON_DPAD_UP 0x00000400
#define _360_JOY_BUTTON_DPAD_DOWN 0x00000800
#define _360_JOY_BUTTON_DPAD_LEFT 0x00001000
#define _360_JOY_BUTTON_DPAD_RIGHT 0x00002000
// fake digital versions of analog values
#define _360_JOY_BUTTON_LSTICK_RIGHT 0x00004000
#define _360_JOY_BUTTON_LSTICK_LEFT 0x00008000
#define _360_JOY_BUTTON_RSTICK_DOWN 0x00010000
#define _360_JOY_BUTTON_RSTICK_UP 0x00020000
#define _360_JOY_BUTTON_RSTICK_RIGHT 0x00040000
#define _360_JOY_BUTTON_RSTICK_LEFT 0x00080000
#define _360_JOY_BUTTON_LSTICK_DOWN 0x00100000
#define _360_JOY_BUTTON_LSTICK_UP 0x00200000
#define _360_JOY_BUTTON_RT 0x00400000
#define _360_JOY_BUTTON_LT 0x00800000
// Stick axis maps - to allow changes for SouthPaw in-game axis mapping
#define AXIS_MAP_LX 0
#define AXIS_MAP_LY 1
#define AXIS_MAP_RX 2
#define AXIS_MAP_RY 3
// Trigger map - to allow for swap triggers in-game
#define TRIGGER_MAP_0 0
#define TRIGGER_MAP_1 1
class C_4JInput : public IPlatformInput {
public:
void Initialise(int iInputStateC, unsigned char ucMapC,
unsigned char ucActionC, unsigned char ucMenuActionC);
void Tick(void);
void SetDeadzoneAndMovementRange(unsigned int uiDeadzone,
unsigned int uiMovementRangeMax);
void SetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction,
unsigned int uiActionVal);
unsigned int GetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction);
void SetJoypadMapVal(int iPad, unsigned char ucMap);
unsigned char GetJoypadMapVal(int iPad);
void SetJoypadSensitivity(int iPad, float fSensitivity);
unsigned int GetValue(int iPad, unsigned char ucAction,
bool bRepeat = false);
bool ButtonPressed(int iPad, unsigned char ucAction = 255); // toggled
bool ButtonReleased(int iPad, unsigned char ucAction); // toggled
bool ButtonDown(int iPad,
unsigned char ucAction = 255); // button held down
// Functions to remap the axis and triggers for in-game (not menus) -
// SouthPaw, etc
void SetJoypadStickAxisMap(int iPad, unsigned int uiFrom,
unsigned int uiTo);
void SetJoypadStickTriggerMap(int iPad, unsigned int uiFrom,
unsigned int uiTo);
void SetKeyRepeatRate(float fRepeatDelaySecs, float fRepeatRateSecs);
void SetDebugSequence(const char* chSequenceA, int (*Func)(void*),
void* lpParam);
float GetIdleSeconds(int iPad);
bool IsPadConnected(int iPad);
// In-Game values which may have been remapped due to Southpaw, swap
// triggers, etc
float GetJoypadStick_LX(int iPad, bool bCheckMenuDisplay = true);
float GetJoypadStick_LY(int iPad, bool bCheckMenuDisplay = true);
float GetJoypadStick_RX(int iPad, bool bCheckMenuDisplay = true);
float GetJoypadStick_RY(int iPad, bool bCheckMenuDisplay = true);
unsigned char GetJoypadLTrigger(int iPad, bool bCheckMenuDisplay = true);
unsigned char GetJoypadRTrigger(int iPad, bool bCheckMenuDisplay = true);
void SetMenuDisplayed(int iPad, bool bVal);
int GetHotbarSlotPressed(int iPad);
int GetScrollDelta();
// Legacy keyboard request overloads with integer string-table ids used to
// live here. The remaining public API keeps the direct text/callback form.
EKeyboardResult RequestKeyboard(const wchar_t* Title, const wchar_t* Text,
int iPad, unsigned int uiMaxChars,
int (*Func)(void*, const bool),
void* lpParam,
C_4JInput::EKeyboardMode eMode);
bool GetMenuDisplayed(int);
const char* GetText();
// Online check strings against offensive list - TCR 92
// TCR # 092 CMTV Player Text String Verification
// Requirement Any player-entered text visible to another player on
// Xbox LIVE must be verified using the Xbox LIVE service before being
// transmitted. Text that is rejected by the Xbox LIVE service must not be
// displayed.
//
// Remarks
// This requirement applies to any player-entered string that can
// be exposed to other players on Xbox LIVE. It includes session names,
// content descriptions, text messages, tags, team names, mottos, comments,
// and so on.
//
// Games may decide to not send the text, blank it out, or use
// generic text if the text was rejected by the Xbox LIVE service.
//
// Games verify the text by calling the XStringVerify function.
//
// Exemption It is not required to use the Xbox LIVE service to
// verify real-time text communication. An example of real-time text
// communication is in-game text chat.
//
// Intent Protect players from inappropriate language.
bool VerifyStrings(wchar_t** pwStringA, int iStringC,
int (*Func)(void*, STRING_VERIFY_RESPONSE*),
void* lpParam);
void CancelQueuedVerifyStrings(int (*Func)(void*, STRING_VERIFY_RESPONSE*),
void* lpParam);
void CancelAllVerifyInProgress(void);
int GetMouseX();
int GetMouseY();
// Primary pad (moved from Profile)
int GetPrimaryPad();
void SetPrimaryPad(int iPad);
// bool InputDetected(int userIndex, wchar_t* inputText);
};
// Singleton
extern C_4JInput InputManager;
+201
View File
@@ -0,0 +1,201 @@
#include "Profile.h"
#include <cstdio>
#include <cstring>
#include "../../4J.Common/4J_ProfileConstants.h"
#include "../sdl2/Input.h"
C_4JProfile ProfileManager;
namespace {
constexpr PlayerUID kFakeXuidBase = 0xe000d45248242f2eULL;
struct ProfileGameSettings {
bool bSettingsChanged;
unsigned char ucMusicVolume;
unsigned char ucSoundFXVolume;
unsigned char ucSensitivity;
unsigned char ucGamma;
unsigned char ucPad01;
unsigned short usBitmaskValues;
unsigned int uiDebugBitmask;
union {
struct {
unsigned char ucTutorialCompletion[TUTORIAL_PROFILE_STORAGE_BYTES];
std::uint32_t dwSelectedSkin;
unsigned char ucMenuSensitivity;
unsigned char ucInterfaceOpacity;
unsigned char ucPad02;
unsigned char usPad03;
unsigned int uiBitmaskValues;
unsigned int uiSpecialTutorialBitmask;
std::uint32_t dwSelectedCape;
unsigned int uiFavoriteSkinA[MAX_FAVORITE_SKINS];
unsigned char ucCurrentFavoriteSkinPos;
unsigned int uiMashUpPackWorldsDisplay;
unsigned char ucLanguage;
};
unsigned char ucReservedSpace[192];
};
};
static_assert(sizeof(ProfileGameSettings) == 204,
"ProfileGameSettings must match GAME_SETTINGS profile storage");
void* s_profileData[XUSER_MAX_COUNT] = {};
C_4JProfile::PROFILESETTINGS s_dashboardSettings[XUSER_MAX_COUNT] = {};
char s_gamertags[XUSER_MAX_COUNT][16] = {};
std::wstring s_displayNames[XUSER_MAX_COUNT];
int s_lockedProfile = 0;
int (*s_defaultOptionsCallback)(void*, C_4JProfile::PROFILESETTINGS*,
const int iPad) = nullptr;
void* s_defaultOptionsCallbackParam = nullptr;
bool isValidPad(int iPad) { return iPad >= 0 && iPad < XUSER_MAX_COUNT; }
void ensureFakeIdentity(int iPad) {
if (!isValidPad(iPad) || s_gamertags[iPad][0] != '\0') {
return;
}
std::snprintf(s_gamertags[iPad], sizeof(s_gamertags[iPad]), "Player%d",
iPad + 1);
s_displayNames[iPad] = std::wstring(L"Player") + std::to_wstring(iPad + 1);
}
void initialiseDefaultGameSettings(ProfileGameSettings* gameSettings) {
gameSettings->ucMenuSensitivity = 100;
gameSettings->ucInterfaceOpacity = 80;
gameSettings->usBitmaskValues |= 0x0200;
gameSettings->usBitmaskValues |= 0x0400;
gameSettings->usBitmaskValues |= 0x1000;
gameSettings->usBitmaskValues |= 0x8000;
gameSettings->uiBitmaskValues = 0L;
gameSettings->uiBitmaskValues |= GAMESETTING_CLOUDS;
gameSettings->uiBitmaskValues |= GAMESETTING_ONLINE;
gameSettings->uiBitmaskValues |= GAMESETTING_FRIENDSOFFRIENDS;
gameSettings->uiBitmaskValues |= GAMESETTING_DISPLAYUPDATEMSG;
gameSettings->uiBitmaskValues &= ~GAMESETTING_BEDROCKFOG;
gameSettings->uiBitmaskValues |= GAMESETTING_DISPLAYHUD;
gameSettings->uiBitmaskValues |= GAMESETTING_DISPLAYHAND;
gameSettings->uiBitmaskValues |= GAMESETTING_CUSTOMSKINANIM;
gameSettings->uiBitmaskValues |= GAMESETTING_DEATHMESSAGES;
gameSettings->uiBitmaskValues |= (GAMESETTING_UISIZE & 0x00000800);
gameSettings->uiBitmaskValues |=
(GAMESETTING_UISIZE_SPLITSCREEN & 0x00004000);
gameSettings->uiBitmaskValues |= GAMESETTING_ANIMATEDCHARACTER;
for (int i = 0; i < MAX_FAVORITE_SKINS; ++i) {
gameSettings->uiFavoriteSkinA[i] = 0xFFFFFFFF;
}
gameSettings->ucCurrentFavoriteSkinPos = 0;
gameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF;
gameSettings->uiBitmaskValues &= ~GAMESETTING_PS3EULAREAD;
gameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT;
gameSettings->uiBitmaskValues &= ~GAMESETTING_PSVITANETWORKMODEADHOC;
gameSettings->ucTutorialCompletion[0] = 0xFF;
gameSettings->ucTutorialCompletion[1] = 0xFF;
gameSettings->ucTutorialCompletion[2] = 0x0F;
gameSettings->ucTutorialCompletion[28] |= 1 << 0;
}
} // namespace
void C_4JProfile::Initialise(std::uint32_t, std::uint32_t, unsigned short,
unsigned int, unsigned int, std::uint32_t*,
int iGameDefinedDataSizeX4, unsigned int*) {
s_lockedProfile = 0;
std::memset(s_dashboardSettings, 0, sizeof(s_dashboardSettings));
for (int i = 0; i < XUSER_MAX_COUNT; ++i) {
delete[] static_cast<unsigned char*>(s_profileData[i]);
s_profileData[i] = new unsigned char[iGameDefinedDataSizeX4 / 4];
std::memset(s_profileData[i], 0, iGameDefinedDataSizeX4 / 4);
initialiseDefaultGameSettings(
static_cast<ProfileGameSettings*>(s_profileData[i]));
ensureFakeIdentity(i);
}
}
int C_4JProfile::GetLockedProfile() { return s_lockedProfile; }
void C_4JProfile::SetLockedProfile(int iProf) { s_lockedProfile = iProf; }
bool C_4JProfile::IsSignedIn(int iQuadrant) { return iQuadrant == 0; }
bool C_4JProfile::IsSignedInLive(int iProf) { return IsSignedIn(iProf); }
bool C_4JProfile::IsGuest(int) { return false; }
bool C_4JProfile::QuerySigninStatus() { return true; }
void C_4JProfile::GetXUID(int iPad, PlayerUID* pXuid, bool) {
if (pXuid)
*pXuid =
kFakeXuidBase + static_cast<PlayerUID>(isValidPad(iPad) ? iPad : 0);
}
bool C_4JProfile::AreXUIDSEqual(PlayerUID xuid1, PlayerUID xuid2) {
return xuid1 == xuid2;
}
bool C_4JProfile::XUIDIsGuest(PlayerUID) { return false; }
bool C_4JProfile::AllowedToPlayMultiplayer(int) { return true; }
bool C_4JProfile::GetChatAndContentRestrictions(int, bool* pbChatRestricted,
bool* pbContentRestricted,
int* piAge) {
if (pbChatRestricted) *pbChatRestricted = false;
if (pbContentRestricted) *pbContentRestricted = false;
if (piAge) *piAge = 18;
return true;
}
char* C_4JProfile::GetGamertag(int iPad) {
const int p = isValidPad(iPad) ? iPad : 0;
ensureFakeIdentity(p);
return s_gamertags[p];
}
std::wstring C_4JProfile::GetDisplayName(int iPad) {
const int p = isValidPad(iPad) ? iPad : 0;
ensureFakeIdentity(p);
return s_displayNames[p];
}
int C_4JProfile::SetDefaultOptionsCallback(int (*Func)(void*, PROFILESETTINGS*,
const int iPad),
void* lpParam) {
s_defaultOptionsCallback = Func;
s_defaultOptionsCallbackParam = lpParam;
return 0;
}
C_4JProfile::PROFILESETTINGS* C_4JProfile::GetDashboardProfileSettings(
int iPad) {
return &s_dashboardSettings[isValidPad(iPad) ? iPad : 0];
}
void* C_4JProfile::GetGameDefinedProfileData(int iQuadrant) {
return isValidPad(iQuadrant) ? s_profileData[iQuadrant] : nullptr;
}
void C_4JProfile::AllowedPlayerCreatedContent(int, bool, bool* allAllowed,
bool* friendsAllowed) {
if (allAllowed) *allAllowed = true;
if (friendsAllowed) *friendsAllowed = true;
}
bool C_4JProfile::CanViewPlayerCreatedContent(int, bool, PlayerUID*,
unsigned int) {
return true;
}
// GetPrimaryPad/SetPrimaryPad — delegates to InputManager.
// Kept here temporarily for call sites that still use ProfileManager.
// These forward to the canonical copies in C_4JInput.
int C_4JProfile::GetPrimaryPad() {
extern C_4JInput InputManager;
return InputManager.GetPrimaryPad();
}
void C_4JProfile::SetPrimaryPad(int iPad) {
extern C_4JInput InputManager;
InputManager.SetPrimaryPad(iPad);
}
+131
View File
@@ -0,0 +1,131 @@
#pragma once
#include <cstdint>
#include <string>
#include "../../4J.Common/4J_Compat.h"
#include "../IPlatformProfile.h"
#include "../PlatformTypes.h"
#define TITLEID_MINECRAFT 0x584111F7
#define CONTEXT_GAME_STATE 0
#define CONTEXT_GAME_STATE_BLANK 0
#define CONTEXT_GAME_STATE_RIDING_PIG 1
#define CONTEXT_GAME_STATE_RIDING_MINECART 2
#define CONTEXT_GAME_STATE_BOATING 3
#define CONTEXT_GAME_STATE_FISHING 4
#define CONTEXT_GAME_STATE_CRAFTING 5
#define CONTEXT_GAME_STATE_FORGING 6
#define CONTEXT_GAME_STATE_NETHER 7
#define CONTEXT_GAME_STATE_CD 8
#define CONTEXT_GAME_STATE_MAP 9
#define CONTEXT_GAME_STATE_ENCHANTING 5
#define CONTEXT_GAME_STATE_BREWING 5
#define CONTEXT_GAME_STATE_ANVIL 6
#define CONTEXT_GAME_STATE_TRADING 0
#define CONTEXT_PRESENCE_IDLE 0
#define CONTEXT_PRESENCE_MENUS 1
#define CONTEXT_PRESENCE_MULTIPLAYER 2
#define CONTEXT_PRESENCE_MULTIPLAYEROFFLINE 3
#define CONTEXT_PRESENCE_MULTIPLAYER_1P 4
#define CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE 5
class C_4JProfile : public IPlatformProfile {
public:
// --- Methods with real logic (implemented in .cpp) ---
void Initialise(std::uint32_t dwTitleID, std::uint32_t dwOfferID,
unsigned short usProfileVersion,
unsigned int uiProfileValuesC,
unsigned int uiProfileSettingsC,
std::uint32_t* pdwProfileSettingsA,
int iGameDefinedDataSizeX4,
unsigned int* puiGameDefinedDataChangedBitmask);
int GetLockedProfile();
void SetLockedProfile(int iProf);
bool IsSignedIn(int iQuadrant);
bool IsSignedInLive(int iProf);
bool IsGuest(int iQuadrant);
bool QuerySigninStatus();
void GetXUID(int iPad, PlayerUID* pXuid, bool bOnlineXuid);
bool AreXUIDSEqual(PlayerUID xuid1, PlayerUID xuid2);
bool XUIDIsGuest(PlayerUID xuid);
bool AllowedToPlayMultiplayer(int iProf);
bool GetChatAndContentRestrictions(int iPad, bool* pbChatRestricted,
bool* pbContentRestricted, int* piAge);
char* GetGamertag(int iPad);
std::wstring GetDisplayName(int iPad);
int SetDefaultOptionsCallback(int (*Func)(void*, PROFILESETTINGS*,
const int iPad),
void* lpParam);
PROFILESETTINGS* GetDashboardProfileSettings(int iPad);
void* GetGameDefinedProfileData(int iQuadrant);
void AllowedPlayerCreatedContent(int iPad, bool thisQuadrantOnly,
bool* allAllowed, bool* friendsAllowed);
bool CanViewPlayerCreatedContent(int iPad, bool thisQuadrantOnly,
PlayerUID* pXuids, unsigned int xuidCount);
// --- Dead stubs (inline no-ops, kept for call-site compat) ---
void Tick() {}
unsigned int RequestSignInUI(bool, bool, bool, bool, bool,
int (*)(void*, const bool, const int), void*,
int = XUSER_INDEX_ANY) {
return 0;
}
unsigned int DisplayOfflineProfile(int (*)(void*, const bool, const int),
void*, int = XUSER_INDEX_ANY) {
return 0;
}
unsigned int RequestConvertOfflineToGuestUI(int (*)(void*, const bool,
const int),
void*, int = XUSER_INDEX_ANY) {
return 0;
}
void SetPrimaryPlayerChanged(bool) {}
void ShowProfileCard(int, PlayerUID) {}
bool GetProfileAvatar(int, int (*)(void*, std::uint8_t*, unsigned int),
void*) {
return false;
}
void CancelProfileAvatarRequest() {}
void SetSignInChangeCallback(void (*)(void*, bool, unsigned int), void*) {}
void SetNotificationsCallback(void (*)(void*, std::uint32_t, unsigned int),
void*) {}
bool RegionIsNorthAmerica() { return false; }
bool LocaleIsUSorCanada() { return false; }
int GetLiveConnectionStatus() { return 0; }
bool IsSystemUIDisplayed() { return false; }
void SetProfileReadErrorCallback(void (*)(void*), void*) {}
int SetOldProfileVersionCallback(int (*)(void*, unsigned char*,
const unsigned short, const int),
void*) {
return 0;
}
void WriteToProfile(int, bool = false, bool = false) {}
void ForceQueuedProfileWrites(int = XUSER_INDEX_ANY) {}
void ResetProfileProcessState() {}
void RegisterAward(int, int, EAwardType, bool = false,
CXuiStringTable* = nullptr, int = -1, int = -1, int = -1,
char* = nullptr, unsigned int = 0L) {}
int GetAwardId(int) { return 0; }
EAwardType GetAwardType(int) { return eAwardType_Achievement; }
bool CanBeAwarded(int, int) { return false; }
void Award(int, int, bool = false) {}
bool IsAwardsFlagSet(int, int) { return false; }
void RichPresenceInit(int, int) {}
void RegisterRichPresenceContext(int) {}
void SetRichPresenceContextValue(int, int, int) {}
void SetCurrentGameActivity(int, int, bool = false) {}
void SetDebugFullOverride(bool) {}
// GetPrimaryPad/SetPrimaryPad moved to InputManager
int GetPrimaryPad();
void SetPrimaryPad(int iPad);
};
// Singleton
extern C_4JProfile ProfileManager;
File diff suppressed because it is too large Load Diff
+715
View File
@@ -0,0 +1,715 @@
#pragma once
#include "gl3_loader.h"
// NOTE: gl3_loader.h must be included before these two
#include <GL/gl.h>
#include <GL/glu.h>
#include <cstdint>
#include <cstdlib>
#include "../IPlatformRenderer.h"
class C4JRender : public IPlatformRenderer {
public:
void Tick();
void UpdateGamma(unsigned short usGamma);
// Matrix stack
void MatrixMode(int type);
void MatrixSetIdentity();
void MatrixTranslate(float x, float y, float z);
void MatrixRotate(float angle, float x, float y, float z);
void MatrixScale(float x, float y, float z);
void MatrixPerspective(float fovy, float aspect, float zNear, float zFar);
void MatrixOrthogonal(float left, float right, float bottom, float top,
float zNear, float zFar);
void MatrixPop();
void MatrixPush();
void MatrixMult(float* mat);
const float* MatrixGet(int type);
void Set_matrixDirty();
// Core
void Initialise();
void InitialiseContext();
void SetWindowSize(int w, int h);
void SetFullscreen(bool fs);
void StartFrame();
void DoScreenGrabOnNextPresent();
void Present();
void Clear(int flags);
void SetClearColour(const float colourRGBA[4]);
void SetChunkOffset(float x, float y, float z);
bool IsWidescreen();
bool IsHiDef();
void GetFramebufferSize(int& width, int& height);
void CaptureThumbnail(ImageFileBuffer* pngOut);
void CaptureScreen(ImageFileBuffer* jpgOut,
XSOCIAL_PREVIEWIMAGE* previewOut);
void BeginConditionalSurvey(int identifier);
void EndConditionalSurvey();
void BeginConditionalRendering(int identifier);
void EndConditionalRendering();
void DrawVertices(ePrimitiveType PrimitiveType, int count, void* dataIn,
eVertexType vType, ePixelShaderType psType);
// Command buffers
void CBuffLockStaticCreations();
int CBuffCreate(int count);
void CBuffDelete(int first, int count);
void CBuffStart(int index, bool full = false);
void CBuffClear(int index);
int CBuffSize(int index);
void CBuffEnd();
bool CBuffCall(int index, bool full = true);
void CBuffTick();
void CBuffDeferredModeStart();
void CBuffDeferredModeEnd();
// Textures
int TextureCreate();
void TextureFree(int idx);
void TextureBind(int idx);
void TextureBindVertex(int idx, bool scaleLight = false);
void TextureSetTextureLevels(int levels);
int TextureGetTextureLevels();
void TextureData(int width, int height, void* data, int level,
eTextureFormat format = TEXTURE_FORMAT_RxGyBzAw);
void TextureDataUpdate(int xoffset, int yoffset, int width, int height,
void* data, int level);
void TextureSetParam(int param, int value);
void TextureDynamicUpdateStart();
void TextureDynamicUpdateEnd();
int LoadTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo,
int** ppDataOut);
int LoadTextureData(std::uint8_t* pbData, std::uint32_t byteCount,
D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut);
int SaveTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo,
int* ppDataOut);
int SaveTextureDataToMemory(void* pOutput, int outputCapacity,
int* outputLength, int width, int height,
int* ppDataIn);
void ReadPixels(int x, int y, int w, int h, void* buf);
void TextureGetStats();
void* TextureGetTexture(int idx);
// State control
void StateSetColour(float r, float g, float b, float a);
void StateSetDepthMask(bool enable);
void StateSetBlendEnable(bool enable);
void StateSetBlendFunc(int src, int dst);
void StateSetBlendFactor(unsigned int colour);
void StateSetAlphaFunc(int func, float param);
void StateSetDepthFunc(int func);
void StateSetFaceCull(bool enable);
void StateSetFaceCullCW(bool enable);
void StateSetLineWidth(float width);
void StateSetWriteEnable(bool red, bool green, bool blue, bool alpha);
void StateSetDepthTestEnable(bool enable);
void StateSetAlphaTestEnable(bool enable);
void StateSetDepthSlopeAndBias(float slope, float bias);
void StateSetFogEnable(bool enable);
void StateSetFogMode(int mode);
void StateSetFogNearDistance(float dist);
void StateSetFogFarDistance(float dist);
void StateSetFogDensity(float density);
void StateSetFogColour(float red, float green, float blue);
void StateSetLightingEnable(bool enable);
void StateSetVertexTextureUV(float u, float v);
void StateSetLightColour(int light, float red, float green, float blue);
void StateSetLightAmbientColour(float red, float green, float blue);
void StateSetLightDirection(int light, float x, float y, float z);
void StateSetLightEnable(int light, bool enable);
void StateSetViewport(eViewportType viewportType);
void StateSetEnableViewportClipPlanes(bool enable);
void StateSetTexGenCol(int col, float x, float y, float z, float w,
bool eyeSpace);
void StateSetStencil(int Function, std::uint8_t stencil_ref,
std::uint8_t stencil_func_mask,
std::uint8_t stencil_write_mask);
void StateSetForceLOD(int LOD);
void StateSetTextureEnable(bool enable);
void StateSetActiveTexture(int tex);
// Event tracking
void BeginEvent(const wchar_t* eventName);
void EndEvent();
// PLM event handling
void Suspend();
bool Suspended();
void Resume();
// Linux window management
bool ShouldClose();
void Close();
void Shutdown();
};
extern C4JRender RenderManager;
// OpenGL Interception Macros
#ifndef GL_MODELVIEW_MATRIX
#define GL_MODELVIEW_MATRIX 0x0BA6
#endif
#ifndef GL_PROJECTION_MATRIX
#define GL_PROJECTION_MATRIX 0x0BA7
#endif
#ifndef GL_MODELVIEW
#define GL_MODELVIEW 0x1700
#endif
#ifndef GL_PROJECTION
#define GL_PROJECTION 0x1701
#endif
#ifndef GL_TEXTURE
#define GL_TEXTURE 0x1702
#endif
#ifndef GL_S
#define GL_S 0x2000
#endif
#ifndef GL_T
#define GL_T 0x2001
#endif
#ifndef GL_R
#define GL_R 0x2002
#endif
#ifndef GL_Q
#define GL_Q 0x2003
#endif
#ifndef GL_TEXTURE_GEN_S
#define GL_TEXTURE_GEN_S 0x0C60
#endif
#ifndef GL_TEXTURE_GEN_T
#define GL_TEXTURE_GEN_T 0x0C61
#endif
#ifndef GL_TEXTURE_GEN_Q
#define GL_TEXTURE_GEN_Q 0x0C63
#endif
#ifndef GL_TEXTURE_GEN_R
#define GL_TEXTURE_GEN_R 0x0C62
#endif
#ifndef GL_TEXTURE_GEN_MODE
#define GL_TEXTURE_GEN_MODE 0x2500
#endif
#ifndef GL_OBJECT_LINEAR
#define GL_OBJECT_LINEAR 0x2401
#endif
#ifndef GL_EYE_LINEAR
#define GL_EYE_LINEAR 0x2400
#endif
#ifndef GL_OBJECT_PLANE
#define GL_OBJECT_PLANE 0x2501
#endif
#ifndef GL_EYE_PLANE
#define GL_EYE_PLANE 0x2502
#endif
#ifndef GL_TEXTURE_2D
#define GL_TEXTURE_2D 0x0DE1
#endif
#ifndef GL_BLEND
#define GL_BLEND 0x0BE2
#endif
#ifndef GL_CULL_FACE
#define GL_CULL_FACE 0x0B44
#endif
#ifndef GL_ALPHA_TEST
#define GL_ALPHA_TEST 0x0BC0
#endif
#ifndef GL_DEPTH_TEST
#define GL_DEPTH_TEST 0x0B71
#endif
#ifndef GL_FOG
#define GL_FOG 0x0B60
#endif
#ifndef GL_LIGHTING
#define GL_LIGHTING 0x0B50
#endif
#ifndef GL_LIGHT0
#define GL_LIGHT0 0x4000
#endif
#ifndef GL_LIGHT1
#define GL_LIGHT1 0x4001
#endif
#ifndef CLEAR_DEPTH_FLAG
#define CLEAR_DEPTH_FLAG 0x00000100
#endif
#ifndef CLEAR_COLOUR_FLAG
#define CLEAR_COLOUR_FLAG 0x00004000
#endif
#ifndef GL_DEPTH_BUFFER_BIT
#define GL_DEPTH_BUFFER_BIT 0x00000100
#endif
#ifndef GL_COLOR_BUFFER_BIT
#define GL_COLOR_BUFFER_BIT 0x00004000
#endif
#ifndef GL_SRC_ALPHA
#define GL_SRC_ALPHA 0x0302
#endif
#ifndef GL_ONE_MINUS_SRC_ALPHA
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
#endif
#ifndef GL_ONE
#define GL_ONE 1
#endif
#ifndef GL_ZERO
#define GL_ZERO 0
#endif
#ifndef GL_DST_ALPHA
#define GL_DST_ALPHA 0x0304
#endif
#ifndef GL_SRC_COLOR
#define GL_SRC_COLOR 0x0300
#endif
#ifndef GL_DST_COLOR
#define GL_DST_COLOR 0x0306
#endif
#ifndef GL_ONE_MINUS_DST_COLOR
#define GL_ONE_MINUS_DST_COLOR 0x0307
#endif
#ifndef GL_ONE_MINUS_SRC_COLOR
#define GL_ONE_MINUS_SRC_COLOR 0x0301
#endif
#ifndef GL_CONSTANT_ALPHA
#define GL_CONSTANT_ALPHA 0x8003
#endif
#ifndef GL_ONE_MINUS_CONSTANT_ALPHA
#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
#endif
#ifndef GL_GREATER
#define GL_GREATER 0x0204
#endif
#ifndef GL_EQUAL
#define GL_EQUAL 0x0202
#endif
#ifndef GL_LEQUAL
#define GL_LEQUAL 0x0203
#endif
#ifndef GL_GEQUAL
#define GL_GEQUAL 0x0206
#endif
#ifndef GL_ALWAYS
#define GL_ALWAYS 0x0207
#endif
#ifndef GL_TEXTURE_MIN_FILTER
#define GL_TEXTURE_MIN_FILTER 0x2801
#endif
#ifndef GL_TEXTURE_MAG_FILTER
#define GL_TEXTURE_MAG_FILTER 0x2800
#endif
#ifndef GL_TEXTURE_WRAP_S
#define GL_TEXTURE_WRAP_S 0x2802
#endif
#ifndef GL_TEXTURE_WRAP_T
#define GL_TEXTURE_WRAP_T 0x2803
#endif
#ifndef GL_NEAREST
#define GL_NEAREST 0x2600
#endif
#ifndef GL_LINEAR
#define GL_LINEAR 0x2601
#endif
#ifndef GL_EXP
#define GL_EXP 0x0800
#endif
#ifndef GL_NEAREST_MIPMAP_LINEAR
#define GL_NEAREST_MIPMAP_LINEAR 0x2702
#endif
#ifndef GL_CLAMP
#define GL_CLAMP 0x2900
#endif
#ifndef GL_REPEAT
#define GL_REPEAT 0x2901
#endif
#ifndef GL_FOG_START
#define GL_FOG_START 0x0B63
#endif
#ifndef GL_FOG_END
#define GL_FOG_END 0x0B64
#endif
#ifndef GL_FOG_MODE
#define GL_FOG_MODE 0x0B65
#endif
#ifndef GL_FOG_DENSITY
#define GL_FOG_DENSITY 0x0B62
#endif
#ifndef GL_FOG_COLOR
#define GL_FOG_COLOR 0x0B66
#endif
#ifndef GL_POSITION
#define GL_POSITION 0x1203
#endif
#ifndef GL_AMBIENT
#define GL_AMBIENT 0x1200
#endif
#ifndef GL_DIFFUSE
#define GL_DIFFUSE 0x1201
#endif
#ifndef GL_SPECULAR
#define GL_SPECULAR 0x1202
#endif
#ifndef GL_LIGHT_MODEL_AMBIENT
#define GL_LIGHT_MODEL_AMBIENT 0x0B53
#endif
#ifndef GL_LINES
#define GL_LINES 0x0001
#endif
#ifndef GL_LINE_STRIP
#define GL_LINE_STRIP 0x0003
#endif
#ifndef GL_QUADS
#define GL_QUADS 0x0007
#endif
#ifndef GL_TRIANGLE_FAN
#define GL_TRIANGLE_FAN 0x0006
#endif
#ifndef GL_TRIANGLE_STRIP
#define GL_TRIANGLE_STRIP 0x0005
#endif
// glCallList / display list macros
#undef glNewList
#define glNewList(_list, _mode) RenderManager.CBuffStart(_list)
#undef glEndList
#define glEndList() RenderManager.CBuffEnd()
#undef glCallList
#define glCallList(_list) RenderManager.CBuffCall(_list)
// glGenLists / glDeleteLists, lists are not supported in core!!!!!
#undef glGenLists
#define glGenLists(range) RenderManager.CBuffCreate(range)
#undef glDeleteLists
#define glDeleteLists(list, range) RenderManager.CBuffDelete(list, range)
#ifndef GL_SHADEMODEL_IS_FUNCTION
#undef glShadeModel
#define glShadeModel(mode) \
do { \
} while (0)
#endif
#undef glTranslatef
#define glTranslatef(x, y, z) \
do { \
RenderManager.MatrixTranslate(x, y, z); \
} while (0)
#undef glRotatef
#define glRotatef(a, x, y, z) \
do { \
RenderManager.MatrixRotate((a) * (3.14159265358979f / 180.f), x, y, \
z); \
} while (0)
#undef glScalef
#define glScalef(x, y, z) \
do { \
RenderManager.MatrixScale(x, y, z); \
} while (0)
#undef glScaled
#define glScaled(x, y, z) \
do { \
RenderManager.MatrixScale((float)(x), (float)(y), (float)(z)); \
} while (0)
#undef glPushMatrix
#define glPushMatrix() \
do { \
RenderManager.MatrixPush(); \
} while (0)
#undef glPopMatrix
#define glPopMatrix() \
do { \
RenderManager.MatrixPop(); \
} while (0)
#undef glLoadIdentity
#define glLoadIdentity() \
do { \
RenderManager.MatrixSetIdentity(); \
} while (0)
#undef glMatrixMode
#define glMatrixMode(mode) \
do { \
RenderManager.MatrixMode(mode); \
} while (0)
#undef glMultMatrixf
#define glMultMatrixf(m) \
do { \
RenderManager.MatrixMult(m); \
} while (0)
#undef glColor4f
#define glColor4f(r, g, b, a) \
do { \
RenderManager.StateSetColour(r, g, b, a); \
} while (0)
#undef glColor3f
#define glColor3f(r, g, b) \
do { \
RenderManager.StateSetColour(r, g, b, 1.0f); \
} while (0)
#undef glAlphaFunc
#define glAlphaFunc(func, ref) \
do { \
RenderManager.StateSetAlphaFunc(func, ref); \
} while (0)
#undef glEnable
#define glEnable(cap) \
do { \
if ((cap) == 0x0B60 /*GL_FOG*/) \
RenderManager.StateSetFogEnable(true); \
else if ((cap) == 0x0B50 /*GL_LIGHTING*/) \
RenderManager.StateSetLightingEnable(true); \
else if ((cap) == 0x0BC0 /*GL_ALPHA_TEST*/) \
RenderManager.StateSetAlphaTestEnable(true); \
else if ((cap) == 0x0DE1 /*GL_TEXTURE_2D*/) \
RenderManager.StateSetTextureEnable(true); \
else if ((cap) == 0x4000 /*GL_LIGHT0*/) \
RenderManager.StateSetLightEnable(0, true); \
else if ((cap) == 0x4001 /*GL_LIGHT1*/) \
RenderManager.StateSetLightEnable(1, true); \
else if ((cap) == 0x0B57 /*GL_COLOR_MATERIAL*/ \
|| (cap) == 0x0BA1 /*GL_NORMALIZE*/ \
|| (cap) == 0x803A /*GL_RESCALE_NORMAL*/ \
|| (cap) == 0x0C60 /*GL_TEXTURE_GEN_S*/ \
|| (cap) == 0x0C61 /*GL_TEXTURE_GEN_T*/ \
|| (cap) == 0x0C62 /*GL_TEXTURE_GEN_R*/ \
|| (cap) == 0x0C63 /*GL_TEXTURE_GEN_Q*/) { /* empty */ \
} else \
::glEnable(cap); \
} while (0)
#undef glDisable
#define glDisable(cap) \
do { \
if ((cap) == 0x0B60 /*GL_FOG*/) \
RenderManager.StateSetFogEnable(false); \
else if ((cap) == 0x0B50 /*GL_LIGHTING*/) \
RenderManager.StateSetLightingEnable(false); \
else if ((cap) == 0x0BC0 /*GL_ALPHA_TEST*/) \
RenderManager.StateSetAlphaTestEnable(false); \
else if ((cap) == 0x0DE1 /*GL_TEXTURE_2D*/) \
RenderManager.StateSetTextureEnable(false); \
else if ((cap) == 0x4000 /*GL_LIGHT0*/) \
RenderManager.StateSetLightEnable(0, false); \
else if ((cap) == 0x4001 /*GL_LIGHT1*/) \
RenderManager.StateSetLightEnable(1, false); \
else if ((cap) == 0x0B57 /*GL_COLOR_MATERIAL*/ \
|| (cap) == 0x0BA1 /*GL_NORMALIZE*/ \
|| (cap) == 0x803A /*GL_RESCALE_NORMAL*/ \
|| (cap) == 0x0C60 /*GL_TEXTURE_GEN_S*/ \
|| (cap) == 0x0C61 /*GL_TEXTURE_GEN_T*/ \
|| (cap) == 0x0C62 /*GL_TEXTURE_GEN_R*/ \
|| (cap) == 0x0C63 /*GL_TEXTURE_GEN_Q*/) { /* empty */ \
} else \
::glDisable(cap); \
} while (0)
#undef glFogi
#define glFogi(pname, param) \
do { \
if ((pname) == 0x0B65 /*GL_FOG_MODE*/) \
RenderManager.StateSetFogMode(param); \
} while (0)
#undef glFogf
#define glFogf(pname, param) \
do { \
if ((pname) == 0x0B63 /*GL_FOG_START*/) \
RenderManager.StateSetFogNearDistance(param); \
else if ((pname) == 0x0B64 /*GL_FOG_END*/) \
RenderManager.StateSetFogFarDistance(param); \
else if ((pname) == 0x0B62 /*GL_FOG_DENSITY*/) \
RenderManager.StateSetFogDensity(param); \
} while (0)
#undef glOrtho
#define glOrtho(left, right, bottom, top, zNear, zFar) \
do { \
RenderManager.MatrixOrthogonal(left, right, bottom, top, zNear, zFar); \
} while (0)
#undef gluPerspective
#define gluPerspective(fovy, aspect, zNear, zFar) \
do { \
RenderManager.MatrixPerspective(fovy, aspect, zNear, zFar); \
} while (0)
#undef glMultiTexCoord2f
#define glMultiTexCoord2f(tex, u, v) \
do { \
if ((tex) == 0x84C1 /*GL_TEXTURE1*/) \
RenderManager.StateSetVertexTextureUV(u, v); \
} while (0)
#undef glActiveTexture
#define glActiveTexture(tex) \
do { \
RenderManager.StateSetActiveTexture(tex); \
::glActiveTexture(tex); \
} while (0)
#undef glClientActiveTexture
#define glClientActiveTexture(tex) \
do { \
RenderManager.StateSetActiveTexture(tex); \
} while (0)
// declarations
int glGenTextures_4J();
void glGenTextures_4J(int n, unsigned int* textures);
void glDeleteTextures_4J(int id);
void glDeleteTextures_4J(int n, const unsigned int* textures);
void glTexImage2D_4J(int target, int level, int internalformat, int width,
int height, int border, int format, int type,
void* pixels);
// helprs
void glGenQueries_4J_Helper(unsigned int* id);
void glGetQueryObjectu_4J_Helper(unsigned int id, unsigned int pname,
unsigned int* val);
template <typename T>
inline void glGenTextures_4J(T* buf) {
unsigned int id = 0;
::glGenTextures(1, &id);
buf->put((int)id);
buf->flip();
}
template <typename T>
inline void glDeleteTextures_4J(T* buf) {
if (buf->limit() > 0) {
unsigned int id = (unsigned int)buf->get(0);
::glDeleteTextures(1, &id);
}
}
template <typename T>
inline void glTexCoordPointer_4J(int size, int type, T* pointer) {}
template <typename T>
inline void glNormalPointer_4J(int type, T* pointer) {}
template <typename T>
inline void glColorPointer_4J(int size, bool normalized, int stride,
T* pointer) {}
template <typename T>
inline void glVertexPointer_4J(int size, int type, T* pointer) {}
template <typename T>
inline void glTexImage2D_4J(int target, int level, int internalformat,
int width, int height, int border, int format,
int type, T* pixels) {
void* data = pixels ? pixels->getBuffer() : nullptr;
::glTexImage2D((unsigned int)target, level, internalformat, width, height,
border, (unsigned int)format, (unsigned int)type, data);
}
template <typename T>
inline void glCallLists_4J(T* lists) {
int base = lists->position();
int count = lists->limit() - base;
for (int i = 0; i < count; i++) {
RenderManager.CBuffCall(lists->get(base + i));
}
}
template <typename T>
inline void glGenQueries_4J(T* buf) {
unsigned int id = 0;
glGenQueries_4J_Helper(&id);
buf->put((int)id);
buf->flip();
}
template <typename T>
inline void glGetQueryObjectu_4J(int id, int pname, T* params) {
unsigned int val = 0;
glGetQueryObjectu_4J_Helper((unsigned int)id, (unsigned int)pname, &val);
params->put((int)val);
params->flip();
}
template <typename T>
inline void glFog_4J(int pname, T* params) {
float* p = params->_getDataPointer();
if (pname == 0x0B66 /* GL_FOG_COLOR */)
RenderManager.StateSetFogColour(p[0], p[1], p[2]);
}
template <typename T>
inline void glLight_4J(int light, int pname, T* params) {
float* p = params->_getDataPointer();
if (pname == 0x1203 /* GL_POSITION */)
RenderManager.StateSetLightDirection(light == 0x4000 ? 0 : 1, p[0],
p[1], p[2]);
else if (pname == 0x1200 /* GL_AMBIENT */)
RenderManager.StateSetLightAmbientColour(p[0], p[1], p[2]);
else if (pname == 0x1201 /* GL_DIFFUSE */)
RenderManager.StateSetLightColour(light == 0x4000 ? 0 : 1, p[0], p[1],
p[2]);
}
template <typename T>
inline void glLightModel_4J(int pname, T* params) {
float* p = params->_getDataPointer();
if (pname == 0x0B53 /* GL_LIGHT_MODEL_AMBIENT */)
RenderManager.StateSetLightAmbientColour(p[0], p[1], p[2]);
}
template <typename T>
inline void glTexGen_4J(int coord, int pname, T* params) {}
inline void glReadPixels_4J(int x, int y, int width, int height, int format,
int type, void* pixels) {
::glReadPixels(x, y, width, height, (unsigned int)format,
(unsigned int)type, pixels);
}
inline void glReadPixels_4J(int x, int y, int width, int height, int format,
int type, unsigned char* pixels) {
::glReadPixels(x, y, width, height, (unsigned int)format,
(unsigned int)type, (void*)pixels);
}
// T -> .getBuffer()
template <typename T>
inline void glReadPixels_4J(int x, int y, int width, int height, int format,
int type, T* pixels) {
::glReadPixels(x, y, width, height, (unsigned int)format,
(unsigned int)type, pixels->getBuffer());
}
void glBeginQuery_4J_Helper(unsigned int target, unsigned int id);
void glEndQuery_4J_Helper(unsigned int target);
void glGenQueries_4J_Helper(unsigned int* id);
void glGetQueryObjectu_4J_Helper(unsigned int id, unsigned int pname,
unsigned int* val);
// redirect the functions to my own implementation, no more 2.1 funcs
#define glGenTextures(...) glGenTextures_4J(__VA_ARGS__)
#define glDeleteTextures(...) glDeleteTextures_4J(__VA_ARGS__)
#define glTexCoordPointer(a, b, c) glTexCoordPointer_4J(a, b, c)
#define glNormalPointer(a, b) glNormalPointer_4J(a, b)
#define glColorPointer(a, b, c, d) glColorPointer_4J(a, b, c, d)
#define glVertexPointer(a, b, c) glVertexPointer_4J(a, b, c)
#define glTexImage2D(a, b, c, d, e, f, g, h, i) \
glTexImage2D_4J(a, b, c, d, e, f, g, h, i)
#define glCallLists(x) glCallLists_4J(x)
#define glGenQueriesARB(x) glGenQueries_4J(x)
#define glGetQueryObjectuARB(a, b, c) glGetQueryObjectu_4J(a, b, c)
#define glReadPixels(a, b, c, d, e, f, g) glReadPixels_4J(a, b, c, d, e, f, g)
#define glFog(a, b) glFog_4J(a, b)
#define glLight(a, b, c) glLight_4J(a, b, c)
#define glLightModel(a, b) glLightModel_4J(a, b)
#define glTexGen(a, b, c) glTexGen_4J(a, b, c)
+227
View File
@@ -0,0 +1,227 @@
#include "Storage.h"
#include <stdlib.h>
#include <cstring>
#include <string>
#include <vector>
C4JStorage StorageManager;
static XMARKETPLACE_CONTENTOFFER_INFO s_dummyOffer = {};
static XCONTENT_DATA s_dummyContentData = {};
C4JStorage::C4JStorage() : m_pStringTable(nullptr) {}
void C4JStorage::Tick(void) {}
C4JStorage::EMessageResult C4JStorage::RequestMessageBox(
unsigned int uiTitle, unsigned int uiText, unsigned int* uiOptionA,
unsigned int uiOptionC, unsigned int pad,
int (*Func)(void*, int, const C4JStorage::EMessageResult), void* lpParam,
C4JStringTable* pStringTable, wchar_t* pwchFormatString,
unsigned int focusButton) {
return EMessage_ResultAccept;
}
C4JStorage::EMessageResult C4JStorage::GetMessageBoxResult() {
return EMessage_Undefined;
}
bool C4JStorage::SetSaveDevice(int (*Func)(void*, const bool), void* lpParam,
bool bForceResetOfSaveDevice) {
return true;
}
void C4JStorage::Init(unsigned int uiSaveVersion,
const wchar_t* pwchDefaultSaveName, char* pszSavePackName,
int iMinimumSaveSize,
int (*Func)(void*, const ESavingMessage, int),
void* lpParam, const char* szGroupID) {}
void C4JStorage::ResetSaveData() {}
void C4JStorage::SetDefaultSaveNameForKeyboardDisplay(
const wchar_t* pwchDefaultSaveName) {}
void C4JStorage::SetSaveTitle(const wchar_t* pwchDefaultSaveName) {}
bool C4JStorage::GetSaveUniqueNumber(int* piVal) {
if (piVal) *piVal = 0;
return true;
}
bool C4JStorage::GetSaveUniqueFilename(char* pszName) {
if (pszName) pszName[0] = '\0';
return true;
}
void C4JStorage::SetSaveUniqueFilename(char* szFilename) {}
void C4JStorage::SetState(ESaveGameControlState eControlState,
int (*Func)(void*, const bool), void* lpParam) {}
void C4JStorage::SetSaveDisabled(bool bDisable) {}
bool C4JStorage::GetSaveDisabled(void) { return false; }
unsigned int C4JStorage::GetSaveSize() { return 0; }
void C4JStorage::GetSaveData(void* pvData, unsigned int* puiBytes) {
if (puiBytes) *puiBytes = 0;
}
void* C4JStorage::AllocateSaveData(unsigned int uiBytes) {
return malloc(uiBytes);
}
void C4JStorage::SetSaveImages(std::uint8_t* pbThumbnail,
unsigned int thumbnailBytes,
std::uint8_t* pbImage, unsigned int imageBytes,
std::uint8_t* pbTextData,
unsigned int textDataBytes) {}
C4JStorage::ESaveGameState C4JStorage::SaveSaveData(int (*Func)(void*,
const bool),
void* lpParam) {
return ESaveGame_Idle;
}
void C4JStorage::CopySaveDataToNewSave(std::uint8_t* pbThumbnail,
unsigned int cbThumbnail,
wchar_t* wchNewName,
int (*Func)(void* lpParam, bool),
void* lpParam) {}
void C4JStorage::SetSaveDeviceSelected(unsigned int uiPad, bool bSelected) {}
bool C4JStorage::GetSaveDeviceSelected(unsigned int iPad) { return true; }
C4JStorage::ESaveGameState C4JStorage::DoesSaveExist(bool* pbExists) {
if (pbExists) *pbExists = false;
return ESaveGame_Idle;
}
bool C4JStorage::EnoughSpaceForAMinSaveGame() { return true; }
void C4JStorage::SetSaveMessageVPosition(float fY) {}
C4JStorage::ESaveGameState C4JStorage::GetSavesInfo(
int iPad,
int (*Func)(void* lpParam, SAVE_DETAILS* pSaveDetails, const bool),
void* lpParam, char* pszSavePackName) {
return ESaveGame_Idle;
}
PSAVE_DETAILS C4JStorage::ReturnSavesInfo() { return nullptr; }
void C4JStorage::ClearSavesInfo() {}
C4JStorage::ESaveGameState C4JStorage::LoadSaveDataThumbnail(
PSAVE_INFO pSaveInfo,
int (*Func)(void* lpParam, std::uint8_t* thumbnailData,
unsigned int thumbnailBytes),
void* lpParam) {
return ESaveGame_Idle;
}
void C4JStorage::GetSaveCacheFileInfo(unsigned int fileIndex,
XCONTENT_DATA& xContentData) {
memset(&xContentData, 0, sizeof(xContentData));
}
void C4JStorage::GetSaveCacheFileInfo(unsigned int fileIndex,
std::uint8_t** ppbImageData,
unsigned int* pImageBytes) {
if (ppbImageData) *ppbImageData = nullptr;
if (pImageBytes) *pImageBytes = 0;
}
C4JStorage::ESaveGameState C4JStorage::LoadSaveData(
PSAVE_INFO pSaveInfo, int (*Func)(void* lpParam, const bool, const bool),
void* lpParam) {
return ESaveGame_Idle;
}
C4JStorage::ESaveGameState C4JStorage::DeleteSaveData(PSAVE_INFO pSaveInfo,
int (*Func)(void* lpParam,
const bool),
void* lpParam) {
return ESaveGame_Idle;
}
void C4JStorage::RegisterMarketplaceCountsCallback(
int (*Func)(void* lpParam, C4JStorage::DLC_TMS_DETAILS*, int),
void* lpParam) {}
void C4JStorage::SetDLCPackageRoot(char* pszDLCRoot) {}
C4JStorage::EDLCStatus C4JStorage::GetDLCOffers(
int iPad, int (*Func)(void*, int, std::uint32_t, int), void* lpParam,
std::uint32_t dwOfferTypesBitmask) {
return EDLC_NoOffers;
}
unsigned int C4JStorage::CancelGetDLCOffers() { return 0; }
void C4JStorage::ClearDLCOffers() {}
XMARKETPLACE_CONTENTOFFER_INFO& C4JStorage::GetOffer(unsigned int dw) {
return s_dummyOffer;
}
int C4JStorage::GetOfferCount() { return 0; }
unsigned int C4JStorage::InstallOffer(int iOfferIDC, std::uint64_t* ullOfferIDA,
int (*Func)(void*, int, int),
void* lpParam, bool bTrial) {
return 0;
}
unsigned int C4JStorage::GetAvailableDLCCount(int iPad) { return 0; }
C4JStorage::EDLCStatus C4JStorage::GetInstalledDLC(int iPad,
int (*Func)(void*, int, int),
void* lpParam) {
if (Func) {
Func(lpParam, 0, iPad);
}
return EDLC_NoInstalledDLC;
}
XCONTENT_DATA& C4JStorage::GetDLC(unsigned int dw) {
return s_dummyContentData;
}
std::uint32_t C4JStorage::MountInstalledDLC(
int iPad, std::uint32_t dwDLC,
int (*Func)(void*, int, std::uint32_t, std::uint32_t), void* lpParam,
const char* szMountDrive) {
return 0;
}
unsigned int C4JStorage::UnmountInstalledDLC(const char* szMountDrive) {
return 0;
}
void C4JStorage::GetMountedDLCFileList(const char* szMountDrive,
std::vector<std::string>& fileList) {
fileList.clear();
}
std::string C4JStorage::GetMountedPath(std::string szMount) { return ""; }
C4JStorage::ETMSStatus C4JStorage::ReadTMSFile(
int iQuadrant, eGlobalStorage eStorageFacility,
C4JStorage::eTMS_FileType eFileType, wchar_t* pwchFilename,
std::uint8_t** ppBuffer, unsigned int* pBufferSize,
int (*Func)(void*, wchar_t*, int, bool, int), void* lpParam, int iAction) {
return ETMSStatus_Fail;
}
bool C4JStorage::WriteTMSFile(int iQuadrant, eGlobalStorage eStorageFacility,
wchar_t* pwchFilename, std::uint8_t* pBuffer,
unsigned int bufferSize) {
return false;
}
bool C4JStorage::DeleteTMSFile(int iQuadrant, eGlobalStorage eStorageFacility,
wchar_t* pwchFilename) {
return false;
}
void C4JStorage::StoreTMSPathName(wchar_t* pwchName) {}
C4JStorage::ETMSStatus C4JStorage::TMSPP_ReadFile(
int iPad, C4JStorage::eGlobalStorage eStorageFacility,
C4JStorage::eTMS_FILETYPEVAL eFileTypeVal, const char* szFilename,
int (*Func)(void*, int, int, PTMSPP_FILEDATA, const char*), void* lpParam,
int iUserData) {
return ETMSStatus_Fail;
}
unsigned int C4JStorage::CRC(unsigned char* buf, int len) {
unsigned int crc = 0xFFFFFFFF;
for (int i = 0; i < len; i++) {
crc ^= buf[i];
for (int j = 0; j < 8; j++) {
crc = (crc >> 1) ^ (0xEDB88320 & (-(crc & 1)));
}
}
return ~crc;
}
int C4JStorage::AddSubfile(int regionIndex) {
(void)regionIndex;
return 0;
}
unsigned int C4JStorage::GetSubfileCount() { return 0; }
void C4JStorage::GetSubfileDetails(unsigned int i, int* regionIndex,
void** data, unsigned int* size) {
(void)i;
if (regionIndex) *regionIndex = 0;
if (data) *data = 0;
if (size) *size = 0;
}
void C4JStorage::ResetSubfiles() {}
void C4JStorage::UpdateSubfile(int index, void* data, unsigned int size) {
(void)index;
(void)data;
(void)size;
}
void C4JStorage::SaveSubfiles(int (*Func)(void*, const bool), void* param) {
if (Func) Func(param, true);
}
C4JStorage::ESaveGameState C4JStorage::GetSaveState() { return ESaveGame_Idle; }
void C4JStorage::ContinueIncompleteOperation() {}
+284
View File
@@ -0,0 +1,284 @@
#pragma once
#include <cstdint>
#include <ctime>
#include <string>
#include <vector>
// #include <xtms.h>
#include "../../4J.Common/4J_Compat.h"
#include "../IPlatformStorage.h"
class C4JStringTable;
#define MAX_DISPLAYNAME_LENGTH 128 // CELL_SAVEDATA_SYSP_SUBTITLE_SIZE on PS3
#define MAX_DETAILS_LENGTH 128 // CELL_SAVEDATA_SYSP_SUBTITLE_SIZE on PS3
#define MAX_SAVEFILENAME_LENGTH 32 // CELL_SAVEDATA_DIRNAME_SIZE
struct CONTAINER_METADATA {
time_t modifiedTime;
unsigned int dataSize;
unsigned int thumbnailSize;
};
struct SAVE_INFO {
char UTF8SaveFilename[MAX_SAVEFILENAME_LENGTH];
char UTF8SaveTitle[MAX_DISPLAYNAME_LENGTH];
CONTAINER_METADATA metaData;
std::uint8_t* thumbnailData;
};
using PSAVE_INFO = SAVE_INFO*;
struct SAVE_DETAILS {
int iSaveC;
PSAVE_INFO SaveInfoA;
};
using PSAVE_DETAILS = SAVE_DETAILS*;
typedef std::vector<PXMARKETPLACE_CONTENTOFFER_INFO> OfferDataArray;
typedef std::vector<PXCONTENT_DATA> XContentDataArray;
// typedef std::vector <PSAVE_DETAILS> SaveDetailsArray;
// Current version of the dlc data creator
#define CURRENT_DLC_VERSION_NUM 3
class C4JStorage : public IPlatformStorage {
public:
struct DLC_FILE_DETAILS {
unsigned int uiFileSize;
std::uint32_t dwType;
std::uint32_t dwWchCount;
wchar_t wchFile[1];
};
using PDLC_FILE_DETAILS = DLC_FILE_DETAILS*;
struct DLC_FILE_PARAM {
std::uint32_t dwType;
std::uint32_t dwWchCount;
wchar_t wchData[1];
};
using PDLC_FILE_PARAM = DLC_FILE_PARAM*;
struct CACHEINFOSTRUCT {
wchar_t wchDisplayName[XCONTENT_MAX_DISPLAYNAME_LENGTH];
char szFileName[XCONTENT_MAX_FILENAME_LENGTH];
std::uint32_t dwImageOffset;
std::uint32_t dwImageBytes;
};
enum eGTS_FileTypes { eGTS_Type_Skin = 0, eGTS_Type_Cape, eGTS_Type_MAX };
enum ELoadGameStatus {
ELoadGame_Idle = 0,
ELoadGame_InProgress,
ELoadGame_NoSaves,
ELoadGame_ChangedDevice,
ELoadGame_DeviceRemoved
};
enum EDeleteGameStatus {
EDeleteGame_Idle = 0,
EDeleteGame_InProgress,
};
enum ESGIStatus {
ESGIStatus_Error = 0,
ESGIStatus_Idle,
ESGIStatus_ReadInProgress,
ESGIStatus_NoSaves,
};
enum eTMS_UGCTYPE { TMS_UGCTYPE_NONE, TMS_UGCTYPE_IMAGE, TMS_UGCTYPE_MAX };
struct TMSPP_FILE_DETAILS {
char szFilename[256];
int iFileSize;
eTMS_FILETYPEVAL eFileTypeVal;
};
using PTMSPP_FILE_DETAILS = TMSPP_FILE_DETAILS*;
struct TMSPP_FILE_LIST {
int iCount;
PTMSPP_FILE_DETAILS FileDetailsA;
};
using PTMSPP_FILE_LIST = TMSPP_FILE_LIST*;
C4JStorage();
void Tick(void);
// Messages
C4JStorage::EMessageResult RequestMessageBox(
unsigned int uiTitle, unsigned int uiText, unsigned int* uiOptionA,
unsigned int uiOptionC, unsigned int pad = XUSER_INDEX_ANY,
int (*Func)(void*, int, const C4JStorage::EMessageResult) = nullptr,
void* lpParam = nullptr, C4JStringTable* pStringTable = nullptr,
wchar_t* pwchFormatString = nullptr, unsigned int focusButton = 0);
C4JStorage::EMessageResult GetMessageBoxResult();
// save device
bool SetSaveDevice(int (*Func)(void*, const bool), void* lpParam,
bool bForceResetOfSaveDevice = false);
// savegame
void Init(unsigned int uiSaveVersion, const wchar_t* pwchDefaultSaveName,
char* pszSavePackName, int iMinimumSaveSize,
int (*Func)(void*, const ESavingMessage, int), void* lpParam,
const char* szGroupID);
void ResetSaveData(); // Call before a new save to clear out stored save
// file name
void SetDefaultSaveNameForKeyboardDisplay(
const wchar_t* pwchDefaultSaveName);
void SetSaveTitle(const wchar_t* pwchDefaultSaveName);
bool GetSaveUniqueNumber(int* piVal);
bool GetSaveUniqueFilename(char* pszName);
void SetSaveUniqueFilename(char* szFilename);
void SetState(ESaveGameControlState eControlState,
int (*Func)(void*, const bool), void* lpParam);
void SetSaveDisabled(bool bDisable);
bool GetSaveDisabled(void);
unsigned int GetSaveSize();
void GetSaveData(void* pvData, unsigned int* puiBytes);
void* AllocateSaveData(unsigned int uiBytes);
void SetSaveImages(
std::uint8_t* pbThumbnail, unsigned int thumbnailBytes,
std::uint8_t* pbImage, unsigned int imageBytes,
std::uint8_t* pbTextData,
unsigned int textDataBytes); // Sets the thumbnail & image for the
// save, optionally setting the
// metadata in the png
C4JStorage::ESaveGameState SaveSaveData(int (*Func)(void*, const bool),
void* lpParam);
void CopySaveDataToNewSave(std::uint8_t* pbThumbnail,
unsigned int cbThumbnail, wchar_t* wchNewName,
int (*Func)(void* lpParam, bool), void* lpParam);
void SetSaveDeviceSelected(unsigned int uiPad, bool bSelected);
bool GetSaveDeviceSelected(unsigned int iPad);
C4JStorage::ESaveGameState DoesSaveExist(bool* pbExists);
bool EnoughSpaceForAMinSaveGame();
void SetSaveMessageVPosition(
float fY); // The 'Saving' message will display at a default position
// unless changed
// Get the info for the saves
C4JStorage::ESaveGameState GetSavesInfo(
int iPad,
int (*Func)(void* lpParam, SAVE_DETAILS* pSaveDetails, const bool),
void* lpParam, char* pszSavePackName);
PSAVE_DETAILS ReturnSavesInfo();
void ClearSavesInfo(); // Clears results
C4JStorage::ESaveGameState LoadSaveDataThumbnail(
PSAVE_INFO pSaveInfo,
int (*Func)(void* lpParam, std::uint8_t* thumbnailData,
unsigned int thumbnailBytes),
void* lpParam); // Get the thumbnail for an individual save referenced
// by pSaveInfo
void GetSaveCacheFileInfo(unsigned int fileIndex,
XCONTENT_DATA& xContentData);
void GetSaveCacheFileInfo(unsigned int fileIndex,
std::uint8_t** ppbImageData,
unsigned int* pImageBytes);
// Load the save. Need to call GetSaveData once the callback is called
C4JStorage::ESaveGameState LoadSaveData(PSAVE_INFO pSaveInfo,
int (*Func)(void* lpParam,
const bool, const bool),
void* lpParam);
C4JStorage::ESaveGameState DeleteSaveData(PSAVE_INFO pSaveInfo,
int (*Func)(void* lpParam,
const bool),
void* lpParam);
// DLC
void RegisterMarketplaceCountsCallback(
int (*Func)(void* lpParam, C4JStorage::DLC_TMS_DETAILS*, int),
void* lpParam);
void SetDLCPackageRoot(char* pszDLCRoot);
C4JStorage::EDLCStatus GetDLCOffers(
int iPad, int (*Func)(void*, int, std::uint32_t, int), void* lpParam,
std::uint32_t dwOfferTypesBitmask = XMARKETPLACE_OFFERING_TYPE_CONTENT);
unsigned int CancelGetDLCOffers();
void ClearDLCOffers();
XMARKETPLACE_CONTENTOFFER_INFO& GetOffer(unsigned int dw);
int GetOfferCount();
unsigned int InstallOffer(int iOfferIDC, std::uint64_t* ullOfferIDA,
int (*Func)(void*, int, int), void* lpParam,
bool bTrial = false);
unsigned int GetAvailableDLCCount(int iPad);
C4JStorage::EDLCStatus GetInstalledDLC(int iPad,
int (*Func)(void*, int, int),
void* lpParam);
XCONTENT_DATA& GetDLC(unsigned int dw);
std::uint32_t MountInstalledDLC(int iPad, std::uint32_t dwDLC,
int (*Func)(void*, int, std::uint32_t,
std::uint32_t),
void* lpParam,
const char* szMountDrive = nullptr);
unsigned int UnmountInstalledDLC(const char* szMountDrive = nullptr);
void GetMountedDLCFileList(const char* szMountDrive,
std::vector<std::string>& fileList);
std::string GetMountedPath(std::string szMount);
// Global title storage
C4JStorage::ETMSStatus ReadTMSFile(
int iQuadrant, eGlobalStorage eStorageFacility,
C4JStorage::eTMS_FileType eFileType, wchar_t* pwchFilename,
std::uint8_t** ppBuffer, unsigned int* pBufferSize,
int (*Func)(void*, wchar_t*, int, bool, int) = nullptr,
void* lpParam = nullptr, int iAction = 0);
bool WriteTMSFile(int iQuadrant, eGlobalStorage eStorageFacility,
wchar_t* pwchFilename, std::uint8_t* pBuffer,
unsigned int bufferSize);
bool DeleteTMSFile(int iQuadrant, eGlobalStorage eStorageFacility,
wchar_t* pwchFilename);
void StoreTMSPathName(wchar_t* pwchName = nullptr);
// TMS++
#ifdef _XBOX
C4JStorage::ETMSStatus WriteTMSFile(
int iPad, C4JStorage::eGlobalStorage eStorageFacility,
C4JStorage::eTMS_FileType eFileType, char* pchFilePath, char* pchBuffer,
unsigned int bufferSize, TMSCLIENT_CALLBACK Func, void* lpParam);
int GetUserQuotaInfo(int iPad, TMSCLIENT_CALLBACK Func, void* lpParam);
#endif
// Older TMS++ write/quota entry points were kept in platform-specific
// implementations and are intentionally not part of this shared API.
C4JStorage::ETMSStatus TMSPP_ReadFile(
int iPad, C4JStorage::eGlobalStorage eStorageFacility,
C4JStorage::eTMS_FILETYPEVAL eFileTypeVal, const char* szFilename,
int (*Func)(void*, int, int, PTMSPP_FILEDATA, const char*) = nullptr,
void* lpParam = nullptr, int iUserData = 0);
// Older TMS++ list/delete helpers stayed platform-specific. The shared
// surface keeps the read path plus CRC/subfile helpers below.
// enum eXBLWS
// {
// eXBLWS_GET,
// eXBLWS_POST,
// eXBLWS_PUT,
// eXBLWS_DELETE,
// };
// bool
// XBLWS_Command(eXBLWS eCommand);
unsigned int CRC(unsigned char* buf, int len);
int AddSubfile(int regionIndex);
unsigned int GetSubfileCount();
void GetSubfileDetails(unsigned int i, int* regionIndex, void** data,
unsigned int* size);
void ResetSubfiles();
void UpdateSubfile(int index, void* data, unsigned int size);
void SaveSubfiles(int (*Func)(void*, const bool), void* param);
ESaveGameState GetSaveState();
void ContinueIncompleteOperation();
C4JStringTable* m_pStringTable;
};
extern C4JStorage StorageManager;
+48
View File
@@ -0,0 +1,48 @@
#pragma once
#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES 1
#endif
#include <GL/gl.h>
#include <GL/glext.h>
#include <SDL2/SDL.h>
#include <cstdio>
#ifndef GL_ARRAY_BUFFER
#define GL_ARRAY_BUFFER 0x8892
#endif
#ifndef GL_ELEMENT_ARRAY_BUFFER
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
#endif
#ifndef GL_STATIC_DRAW
#define GL_STATIC_DRAW 0x88B4
#endif
#ifndef GL_VERTEX_SHADER
#define GL_VERTEX_SHADER 0x8B31
#endif
#ifndef GL_FRAGMENT_SHADER
#define GL_FRAGMENT_SHADER 0x8B30
#endif
#ifndef GL_QUADS
#define GL_QUADS 0x0007
#endif
static inline bool gl3_load() {
const char* ver = (const char*)glGetString(GL_VERSION);
if (!ver) {
fprintf(stderr, "[gl3_loader] ERROR: No active GL context found.\n");
return false;
}
int major = 0, minor = 0;
if (sscanf(ver, "%d.%d", &major, &minor) >= 2) {
if (major < 3 || (major == 3 && minor < 3)) {
fprintf(stderr,
"[gl3_loader] ERROR: Need GL 3.3, but system provides %s\n",
ver);
return false;
}
}
fprintf(
stderr,
"[gl3_loader] GL Version: %s, it's all okay!! until android support.\n",
ver);
return true;
}
+44
View File
@@ -0,0 +1,44 @@
#include "Render.h"
// Command Buffers
void C4JRender::CBuffLockStaticCreations() {}
int C4JRender::CBuffSize(int) { return 0; }
void C4JRender::CBuffTick() {}
void C4JRender::CBuffDeferredModeStart() {}
void C4JRender::CBuffDeferredModeEnd() {}
// Render States
void C4JRender::StateSetLightEnable(int, bool) {}
void C4JRender::StateSetEnableViewportClipPlanes(bool) {}
void C4JRender::StateSetForceLOD(int) {}
void C4JRender::StateSetTexGenCol(int, float, float, float, float, bool) {}
// Textures
void C4JRender::TextureDynamicUpdateStart() {}
void C4JRender::TextureDynamicUpdateEnd() {}
void C4JRender::TextureGetStats() {}
void* C4JRender::TextureGetTexture(int) { return nullptr; }
int C4JRender::SaveTextureData(const char*, D3DXIMAGE_INFO*, int*) { return 0; }
int C4JRender::SaveTextureDataToMemory(void*, int, int*, int, int, int*) {
return 0;
}
// Screen/Image Capturing
void C4JRender::DoScreenGrabOnNextPresent() {}
void C4JRender::CaptureThumbnail(ImageFileBuffer*) {}
void C4JRender::CaptureScreen(ImageFileBuffer*, XSOCIAL_PREVIEWIMAGE*) {}
// Conditional Rendering & Events
void C4JRender::BeginConditionalSurvey(int) {}
void C4JRender::EndConditionalSurvey() {}
void C4JRender::BeginConditionalRendering(int) {}
void C4JRender::EndConditionalRendering() {}
void C4JRender::BeginEvent(const wchar_t*) {}
void C4JRender::EndEvent() {}
void C4JRender::Tick() {}
// Lifecycle
void C4JRender::Suspend() {}
bool C4JRender::Suspended() { return false; }
void C4JRender::Resume() {}