Decouple 4J libs for extraction to 4jlibs

This commit is contained in:
MatthewBeshay 2026-03-20 11:08:45 +11:00
parent f0b898b75d
commit 1845c64ad4
23 changed files with 639 additions and 186 deletions

7
.gitignore vendored
View file

@ -6,15 +6,22 @@
!/.github/
!/.github-assets/
!/4J.Input/
!/4J.Common/
!/4J.Profile/
!/4J.Render/
!/4J.Storage/
!/4jlibs/
!/docs/
!/Minecraft.Assets/
!/Minecraft.Client/
!/Minecraft.World/
!/scripts/
!/subprojects/
/subprojects/*
!/subprojects/*.wrap
!/subprojects/4jlibs/
!/subprojects/4jlibs/**
/scripts/__pycache__/
!/.clang-format
!/.git-blame-ignore-revs
!/.gitattributes

129
4J.Common/4J_Compat.h Normal file
View file

@ -0,0 +1,129 @@
#pragma once
#include <cstdint>
// The extracted 4J public headers only need the generic Linux/Windows-style
// compatibility surface. Console backends still own their platform-specific
// identity/content definitions elsewhere.
#if !defined(__ORBIS__) && !defined(__PS3__) && !defined(__PSVITA__) && \
!defined(_DURANGO)
#ifndef XUSER_INDEX_ANY
inline constexpr int XUSER_INDEX_ANY = 255;
#endif
#ifndef XUSER_MAX_COUNT
inline constexpr int XUSER_MAX_COUNT = 4;
#endif
#ifndef XUSER_NAME_SIZE
inline constexpr int XUSER_NAME_SIZE = 32;
#endif
#ifndef XUSER_INDEX_FOCUS
inline constexpr int XUSER_INDEX_FOCUS = 254;
#endif
#ifndef FOURJ_COMMON_PLAYER_UID_DEFINED
#define FOURJ_COMMON_PLAYER_UID_DEFINED
using PlayerUID = unsigned long long;
using PPlayerUID = PlayerUID*;
#endif
#endif
class CXuiStringTable;
#if !defined(__ORBIS__) && !defined(__PS3__) && !defined(__PSVITA__) && \
!defined(_DURANGO)
#ifndef XCONTENT_MAX_DISPLAYNAME_LENGTH
inline constexpr int XCONTENT_MAX_DISPLAYNAME_LENGTH = 256;
#endif
#ifndef XCONTENT_MAX_FILENAME_LENGTH
inline constexpr int XCONTENT_MAX_FILENAME_LENGTH = 256;
#endif
#ifndef FOURJ_COMMON_XCONTENT_DATA_DEFINED
#define FOURJ_COMMON_XCONTENT_DATA_DEFINED
using XCONTENTDEVICEID = int;
struct XCONTENT_DATA {
XCONTENTDEVICEID DeviceID;
std::uint32_t dwContentType;
wchar_t szDisplayName[XCONTENT_MAX_DISPLAYNAME_LENGTH];
char szFileName[XCONTENT_MAX_FILENAME_LENGTH];
};
using PXCONTENT_DATA = XCONTENT_DATA*;
#endif
#ifndef XMARKETPLACE_CONTENT_ID_LEN
inline constexpr int XMARKETPLACE_CONTENT_ID_LEN = 4;
#endif
#ifndef FOURJ_COMMON_XMARKETPLACE_DEFINED
#define FOURJ_COMMON_XMARKETPLACE_DEFINED
struct XMARKETPLACE_CONTENTOFFER_INFO {
std::uint64_t qwOfferID;
std::uint64_t qwPreviewOfferID;
std::uint32_t dwOfferNameLength;
wchar_t* wszOfferName;
std::uint32_t dwOfferType;
std::uint8_t contentId[XMARKETPLACE_CONTENT_ID_LEN];
bool fIsUnrestrictedLicense;
std::uint32_t dwLicenseMask;
std::uint32_t dwTitleID;
std::uint32_t dwContentCategory;
std::uint32_t dwTitleNameLength;
wchar_t* wszTitleName;
bool fUserHasPurchased;
std::uint32_t dwPackageSize;
std::uint32_t dwInstallSize;
std::uint32_t dwSellTextLength;
wchar_t* wszSellText;
std::uint32_t dwAssetID;
std::uint32_t dwPurchaseQuantity;
std::uint32_t dwPointsPrice;
};
using PXMARKETPLACE_CONTENTOFFER_INFO = XMARKETPLACE_CONTENTOFFER_INFO*;
#endif
#ifndef XMARKETPLACE_OFFERING_TYPE_CONTENT
inline constexpr std::uint32_t XMARKETPLACE_OFFERING_TYPE_CONTENT =
0x00000002;
#endif
#ifndef XMARKETPLACE_OFFERING_TYPE_GAME_DEMO
inline constexpr std::uint32_t XMARKETPLACE_OFFERING_TYPE_GAME_DEMO =
0x00000020;
#endif
#ifndef XMARKETPLACE_OFFERING_TYPE_GAME_TRAILER
inline constexpr std::uint32_t XMARKETPLACE_OFFERING_TYPE_GAME_TRAILER =
0x00000040;
#endif
#ifndef XMARKETPLACE_OFFERING_TYPE_THEME
inline constexpr std::uint32_t XMARKETPLACE_OFFERING_TYPE_THEME = 0x00000080;
#endif
#ifndef XMARKETPLACE_OFFERING_TYPE_TILE
inline constexpr std::uint32_t XMARKETPLACE_OFFERING_TYPE_TILE = 0x00000800;
#endif
#ifndef XMARKETPLACE_OFFERING_TYPE_ARCADE
inline constexpr std::uint32_t XMARKETPLACE_OFFERING_TYPE_ARCADE = 0x00002000;
#endif
#ifndef XMARKETPLACE_OFFERING_TYPE_VIDEO
inline constexpr std::uint32_t XMARKETPLACE_OFFERING_TYPE_VIDEO = 0x00004000;
#endif
#ifndef XMARKETPLACE_OFFERING_TYPE_CONSUMABLE
inline constexpr std::uint32_t XMARKETPLACE_OFFERING_TYPE_CONSUMABLE =
0x00010000;
#endif
#ifndef XMARKETPLACE_OFFERING_TYPE_AVATARITEM
inline constexpr std::uint32_t XMARKETPLACE_OFFERING_TYPE_AVATARITEM =
0x00100000;
#endif
#endif

View file

@ -0,0 +1,59 @@
#pragma once
enum EControllerActions {
ACTION_MENU_A,
ACTION_MENU_B,
ACTION_MENU_X,
ACTION_MENU_Y,
ACTION_MENU_UP,
ACTION_MENU_DOWN,
ACTION_MENU_RIGHT,
ACTION_MENU_LEFT,
ACTION_MENU_PAGEUP,
ACTION_MENU_PAGEDOWN,
ACTION_MENU_RIGHT_SCROLL,
ACTION_MENU_LEFT_SCROLL,
ACTION_MENU_STICK_PRESS,
ACTION_MENU_OTHER_STICK_PRESS,
ACTION_MENU_OTHER_STICK_UP,
ACTION_MENU_OTHER_STICK_DOWN,
ACTION_MENU_OTHER_STICK_LEFT,
ACTION_MENU_OTHER_STICK_RIGHT,
ACTION_MENU_PAUSEMENU,
ACTION_MENU_OK,
ACTION_MENU_CANCEL,
ACTION_MAX_MENU = ACTION_MENU_CANCEL + 1,
MINECRAFT_ACTION_JUMP,
MINECRAFT_ACTION_FORWARD,
MINECRAFT_ACTION_BACKWARD,
MINECRAFT_ACTION_LEFT,
MINECRAFT_ACTION_RIGHT,
MINECRAFT_ACTION_LOOK_LEFT,
MINECRAFT_ACTION_LOOK_RIGHT,
MINECRAFT_ACTION_LOOK_UP,
MINECRAFT_ACTION_LOOK_DOWN,
MINECRAFT_ACTION_USE,
MINECRAFT_ACTION_ACTION,
MINECRAFT_ACTION_LEFT_SCROLL,
MINECRAFT_ACTION_RIGHT_SCROLL,
MINECRAFT_ACTION_INVENTORY,
MINECRAFT_ACTION_PAUSEMENU,
MINECRAFT_ACTION_DROP,
MINECRAFT_ACTION_SNEAK_TOGGLE,
MINECRAFT_ACTION_SPRINT,
MINECRAFT_ACTION_CRAFTING,
MINECRAFT_ACTION_RENDER_THIRD_PERSON,
MINECRAFT_ACTION_GAME_INFO,
MINECRAFT_ACTION_DPAD_LEFT,
MINECRAFT_ACTION_DPAD_RIGHT,
MINECRAFT_ACTION_DPAD_UP,
MINECRAFT_ACTION_DPAD_DOWN,
MINECRAFT_ACTION_MAX,
MINECRAFT_ACTION_SPAWN_CREEPER,
MINECRAFT_ACTION_CHANGE_SKIN,
MINECRAFT_ACTION_FLY_TOGGLE,
MINECRAFT_ACTION_RENDER_DEBUG
};

View file

@ -0,0 +1,26 @@
#pragma once
#include <cstdint>
inline constexpr int TUTORIAL_PROFILE_STORAGE_BITS = 512;
inline constexpr int TUTORIAL_PROFILE_STORAGE_BYTES =
TUTORIAL_PROFILE_STORAGE_BITS / 8;
inline constexpr int MAX_FAVORITE_SKINS = 10;
inline constexpr std::uint32_t GAMESETTING_CLOUDS = 0x00000001;
inline constexpr std::uint32_t GAMESETTING_ONLINE = 0x00000002;
inline constexpr std::uint32_t GAMESETTING_FRIENDSOFFRIENDS = 0x00000008;
inline constexpr std::uint32_t GAMESETTING_DISPLAYUPDATEMSG = 0x00000030;
inline constexpr std::uint32_t GAMESETTING_BEDROCKFOG = 0x00000040;
inline constexpr std::uint32_t GAMESETTING_DISPLAYHUD = 0x00000080;
inline constexpr std::uint32_t GAMESETTING_DISPLAYHAND = 0x00000100;
inline constexpr std::uint32_t GAMESETTING_CUSTOMSKINANIM = 0x00000200;
inline constexpr std::uint32_t GAMESETTING_DEATHMESSAGES = 0x00000400;
inline constexpr std::uint32_t GAMESETTING_UISIZE = 0x00001800;
inline constexpr std::uint32_t GAMESETTING_UISIZE_SPLITSCREEN = 0x00006000;
inline constexpr std::uint32_t GAMESETTING_ANIMATEDCHARACTER = 0x00008000;
inline constexpr std::uint32_t GAMESETTING_PS3EULAREAD = 0x00010000;
inline constexpr std::uint32_t GAMESETTING_PSVITANETWORKMODEADHOC = 0x00020000;
inline constexpr unsigned char MINECRAFT_LANGUAGE_DEFAULT = 0x00;

View file

@ -1,6 +1,5 @@
#include "4J_Input.h"
#include "../Minecraft.Client/Platform/Common/App_enums.h"
#include "../4J.Render/4J_Render.h"
#include "../4J.Common/4J_InputActions.h"
#include <SDL2/SDL.h>
#include <math.h>
#include <string.h>

View file

@ -1,5 +1,7 @@
#pragma once
#include <cstdint>
#define MAP_STYLE_0 0
#define MAP_STYLE_1 1
#define MAP_STYLE_2 2
@ -54,7 +56,7 @@ enum EKeyboardResult {
typedef struct _STRING_VERIFY_RESPONSE {
std::uint16_t wNumStrings;
HRESULT* pStringResult;
int* pStringResult;
} STRING_VERIFY_RESPONSE;
class C_4JInput {
@ -112,14 +114,8 @@ public:
int GetHotbarSlotPressed(int iPad);
int GetScrollDelta();
// EKeyboardResult RequestKeyboard(UINT uiTitle, UINT uiText, UINT
// uiDesc, DWORD dwPad, WCHAR *pwchResult, UINT uiResultSize,int(
// *Func)(LPVOID,const bool),LPVOID lpParam,EKeyboardMode
// eMode,C4JStringTable *pStringTable=NULL); EKeyboardResult
// RequestKeyboard(UINT uiTitle, LPCWSTR pwchDefault, UINT uiDesc, DWORD
// dwPad, WCHAR *pwchResult, UINT uiResultSize,int( *Func)(LPVOID,const
// bool),LPVOID lpParam, EKeyboardMode eMode,C4JStringTable
// *pStringTable=NULL);
// 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),
@ -160,7 +156,7 @@ public:
int GetMouseX();
int GetMouseY();
// bool InputDetected(DWORD dwUserIndex,WCHAR *pwchInput);
// bool InputDetected(int userIndex, wchar_t* inputText);
};
// Singleton

View file

@ -1,8 +1,6 @@
#ifndef _4J_INPUT_STADAFX_H
#define _4J_INPUT_STADAFX_H
#ifdef __linux__
#include "../Minecraft.Client/Platform/Linux/Stubs/LinuxStubs.h"
#endif
#include "../4J.Common/4J_Compat.h"
#endif //_4J_INPUT_STADAFX_H
#endif //_4J_INPUT_STADAFX_H

View file

@ -1,6 +1,5 @@
#include "4J_Profile.h"
#include "../Minecraft.Client/Platform/Common/App_Defines.h"
#include "../Minecraft.Client/Platform/Common/Tutorial/TutorialEnum.h"
#include "../4J.Common/4J_ProfileConstants.h"
#include <cstdio>
#include <cstring>
@ -177,7 +176,7 @@ void C_4JProfile::AllowedPlayerCreatedContent(int iPad, bool thisQuadrantOnly,
if (friendsAllowed) *friendsAllowed = true;
}
bool C_4JProfile::CanViewPlayerCreatedContent(int iPad, bool thisQuadrantOnly,
PPlayerUID pXuids,
PlayerUID* pXuids,
unsigned int xuidCount) {
return true;
}
@ -212,7 +211,7 @@ void C_4JProfile::SetNotificationsCallback(void (*Func)(void*, std::uint32_t,
void* lpParam) {}
bool C_4JProfile::RegionIsNorthAmerica(void) { return false; }
bool C_4JProfile::LocaleIsUSorCanada(void) { return false; }
HRESULT C_4JProfile::GetLiveConnectionStatus() { return S_OK; }
int C_4JProfile::GetLiveConnectionStatus() { return 0; }
bool C_4JProfile::IsSystemUIDisplayed() { return false; }
void C_4JProfile::SetProfileReadErrorCallback(void (*Func)(void*),
void* lpParam) {}

View file

@ -1,6 +1,9 @@
#pragma once
#include <cstdint>
#include <string>
#include "../4J.Common/4J_Compat.h"
enum eAwardType {
eAwardType_Achievement = 0,
@ -77,7 +80,8 @@ public:
void AllowedPlayerCreatedContent(int iPad, bool thisQuadrantOnly,
bool* allAllowed, bool* friendsAllowed);
bool CanViewPlayerCreatedContent(int iPad, bool thisQuadrantOnly,
PPlayerUID pXuids, unsigned int xuidCount);
PlayerUID* pXuids,
unsigned int xuidCount);
void ShowProfileCard(int iPad, PlayerUID targetUid);
bool GetProfileAvatar(int iPad,
int (*Func)(void* lpParam,
@ -99,7 +103,7 @@ public:
void* lpParam);
bool RegionIsNorthAmerica(void);
bool LocaleIsUSorCanada(void);
HRESULT GetLiveConnectionStatus();
int GetLiveConnectionStatus();
bool IsSystemUIDisplayed();
void SetProfileReadErrorCallback(void (*Func)(void*), void* lpParam);
@ -124,9 +128,10 @@ public:
void RegisterAward(int iAwardNumber, int iGamerconfigID, eAwardType eType,
bool bLeaderboardAffected = false,
CXuiStringTable* pStringTable = NULL, int iTitleStr = -1,
CXuiStringTable* pStringTable = nullptr,
int iTitleStr = -1,
int iTextStr = -1, int iAcceptStr = -1,
char* pszThemeName = NULL,
char* pszThemeName = nullptr,
unsigned int uiThemeSize = 0L);
int GetAwardId(int iAwardNumber);
eAwardType GetAwardType(int iAwardNumber);

View file

@ -1,10 +1,6 @@
#ifndef _4J_PROFILE_STADAFX_H
#define _4J_PROFILE_STADAFX_H
#ifdef __linux__
#include "../Minecraft.Client/Platform/Linux/Stubs/LinuxStubs.h"
#endif
#include "../4J.Common/4J_Compat.h"
#include "../Minecraft.World/Platform/x64headers/extraX64.h"
#endif //_4J_PROFILE_STADAFX_H
#endif //_4J_PROFILE_STADAFX_H

View file

@ -654,8 +654,8 @@ void C4JRender::Tick() {}
void C4JRender::UpdateGamma(unsigned short) {}
// Converts RGBA data to the format expected by the texture loader.
static HRESULT LoadFromSTB(unsigned char* data, int width, int height,
D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut) {
static int LoadFromSTB(unsigned char* data, int width, int height,
D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut) {
int pixelCount = width * height;
int* pixels = new int[pixelCount];
@ -675,45 +675,45 @@ static HRESULT LoadFromSTB(unsigned char* data, int width, int height,
}
*ppDataOut = pixels;
return S_OK;
return 0;
}
HRESULT C4JRender::LoadTextureData(const char* szFilename,
D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut) {
int C4JRender::LoadTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo,
int** ppDataOut) {
int width, height, channels;
unsigned char* data = stbi_load(szFilename, &width, &height, &channels, 4);
if (!data) return E_FAIL;
if (!data) return -1;
HRESULT hr = LoadFromSTB(data, width, height, pSrcInfo, ppDataOut);
const int hr = LoadFromSTB(data, width, height, pSrcInfo, ppDataOut);
stbi_image_free(data);
return hr;
}
HRESULT C4JRender::LoadTextureData(std::uint8_t* pbData,
std::uint32_t byteCount,
D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut) {
int C4JRender::LoadTextureData(std::uint8_t* pbData,
std::uint32_t byteCount,
D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut) {
int width, height, channels;
unsigned char* data =
stbi_load_from_memory(pbData, byteCount, &width, &height, &channels, 4);
if (!data) return E_FAIL;
if (!data) return -1;
HRESULT hr = LoadFromSTB(data, width, height, pSrcInfo, ppDataOut);
const int hr = LoadFromSTB(data, width, height, pSrcInfo, ppDataOut);
stbi_image_free(data);
return hr;
}
HRESULT C4JRender::SaveTextureData(const char* szFilename,
D3DXIMAGE_INFO* pSrcInfo, int* ppDataOut) {
return S_OK;
int C4JRender::SaveTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo,
int* ppDataOut) {
return 0;
}
HRESULT C4JRender::SaveTextureDataToMemory(void* pOutput, int outputCapacity,
int* outputLength, int width,
int height, int* ppDataIn) {
return S_OK;
int C4JRender::SaveTextureDataToMemory(void* pOutput, int outputCapacity,
int* outputLength, int width,
int height, int* ppDataIn) {
return 0;
}
void C4JRender::TextureGetStats() {}
void* C4JRender::TextureGetTexture(int idx) { return nullptr; }
@ -910,7 +910,7 @@ void C4JRender::StateSetStencil(int Function, uint8_t stencil_ref,
void C4JRender::StateSetForceLOD(int LOD) {} // No LOD bias in legacy GL path
void C4JRender::BeginEvent(LPCWSTR eventName) {}
void C4JRender::BeginEvent(const wchar_t* eventName) {}
void C4JRender::EndEvent() {}
void C4JRender::Suspend() {}
bool C4JRender::Suspended() { return false; }

View file

@ -1,10 +1,7 @@
#pragma once
#ifdef __linux__
#include "../Minecraft.Client/Platform/Linux/Stubs/LinuxStubs.h"
#endif
#include <cstdint>
#include <cstdlib>
class ImageFileBuffer {
public:
@ -18,10 +15,10 @@ public:
void* GetBufferPointer() { return m_pBuffer; }
int GetBufferSize() { return m_bufferSize; }
void Release() {
free(m_pBuffer);
m_pBuffer = NULL;
std::free(m_pBuffer);
m_pBuffer = nullptr;
}
bool Allocated() { return m_pBuffer != NULL; }
bool Allocated() { return m_pBuffer != nullptr; }
};
typedef struct {
@ -84,7 +81,7 @@ public:
typedef enum {
VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1, // Position 3 x float, texture 2 x
// float, colour 4 x byte, normal 4 x
// byte, padding 1 DWORD
// byte, padding 1 32-bit word
VERTEX_TYPE_COMPRESSED, // Compressed format - see comment at top of
// VS_PS3_TS2_CS1.hlsl for description of
// layout
@ -169,15 +166,15 @@ public:
void TextureSetParam(int param, int value);
void TextureDynamicUpdateStart();
void TextureDynamicUpdateEnd();
HRESULT LoadTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo,
int** ppDataOut);
HRESULT LoadTextureData(std::uint8_t* pbData, std::uint32_t byteCount,
D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut);
HRESULT SaveTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo,
int* ppDataOut);
HRESULT SaveTextureDataToMemory(void* pOutput, int outputCapacity,
int* outputLength, int width, int height,
int* ppDataIn);
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 TextureGetStats();
void* TextureGetTexture(int idx);
@ -212,12 +209,13 @@ public:
void StateSetEnableViewportClipPlanes(bool enable);
void StateSetTexGenCol(int col, float x, float y, float z, float w,
bool eyeSpace);
void StateSetStencil(int Function, uint8_t stencil_ref,
uint8_t stencil_func_mask, uint8_t stencil_write_mask);
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);
// Event tracking
void BeginEvent(LPCWSTR eventName);
void BeginEvent(const wchar_t* eventName);
void EndEvent();
// PLM event handling

View file

@ -1,8 +1,6 @@
#ifndef _4J_RENDER_STADAFX_H
#define _4J_RENDER_STADAFX_H
#ifdef __linux__
#include "../Minecraft.Client/Platform/Linux/Stubs/LinuxStubs.h"
#endif
#include "../4J.Common/4J_Compat.h"
#endif //_4J_RENDER_STADAFX_H
#endif //_4J_RENDER_STADAFX_H

View file

@ -16,7 +16,7 @@ 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* pwchFormatString,
C4JStringTable* pStringTable, wchar_t* pwchFormatString,
unsigned int focusButton) {
return EMessage_ResultAccept;
}
@ -30,15 +30,16 @@ bool C4JStorage::SetSaveDevice(int (*Func)(void*, const bool), void* lpParam,
return true;
}
void C4JStorage::Init(unsigned int uiSaveVersion, LPCWSTR pwchDefaultSaveName,
void C4JStorage::Init(unsigned int uiSaveVersion,
const wchar_t* pwchDefaultSaveName,
char* pszSavePackName, int iMinimumSaveSize,
int (*Func)(void*, const ESavingMessage, int),
void* lpParam, LPCSTR szGroupID) {}
void* lpParam, const char* szGroupID) {}
void C4JStorage::ResetSaveData() {}
void C4JStorage::SetDefaultSaveNameForKeyboardDisplay(
LPCWSTR pwchDefaultSaveName) {}
void C4JStorage::SetSaveTitle(LPCWSTR pwchDefaultSaveName) {}
bool C4JStorage::GetSaveUniqueNumber(INT* piVal) {
const wchar_t* pwchDefaultSaveName) {}
void C4JStorage::SetSaveTitle(const wchar_t* pwchDefaultSaveName) {}
bool C4JStorage::GetSaveUniqueNumber(int* piVal) {
if (piVal) *piVal = 0;
return true;
}
@ -55,7 +56,7 @@ unsigned int C4JStorage::GetSaveSize() { return 0; }
void C4JStorage::GetSaveData(void* pvData, unsigned int* puiBytes) {
if (puiBytes) *puiBytes = 0;
}
PVOID C4JStorage::AllocateSaveData(unsigned int uiBytes) {
void* C4JStorage::AllocateSaveData(unsigned int uiBytes) {
return malloc(uiBytes);
}
void C4JStorage::SetSaveImages(std::uint8_t* pbThumbnail,
@ -71,7 +72,7 @@ C4JStorage::ESaveGameState C4JStorage::SaveSaveData(int (*Func)(void*,
}
void C4JStorage::CopySaveDataToNewSave(std::uint8_t* pbThumbnail,
unsigned int cbThumbnail,
WCHAR* wchNewName,
wchar_t* wchNewName,
int (*Func)(void* lpParam, bool),
void* lpParam) {}
void C4JStorage::SetSaveDeviceSelected(unsigned int uiPad, bool bSelected) {}
@ -129,11 +130,9 @@ C4JStorage::EDLCStatus C4JStorage::GetDLCOffers(
}
unsigned int C4JStorage::CancelGetDLCOffers() { return 0; }
void C4JStorage::ClearDLCOffers() {}
XMARKETPLACE_CONTENTOFFER_INFO& C4JStorage::GetOffer(unsigned int dw) {
return s_dummyOffer;
}
XMARKETPLACE_CONTENTOFFER_INFO& C4JStorage::GetOffer(unsigned int dw) { return s_dummyOffer; }
int C4JStorage::GetOfferCount() { return 0; }
unsigned int C4JStorage::InstallOffer(int iOfferIDC, __uint64* ullOfferIDA,
unsigned int C4JStorage::InstallOffer(int iOfferIDC, std::uint64_t* ullOfferIDA,
int (*Func)(void*, int, int),
void* lpParam, bool bTrial) {
return 0;
@ -151,10 +150,12 @@ 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,
LPCSTR szMountDrive) {
const char* szMountDrive) {
return 0;
}
unsigned int C4JStorage::UnmountInstalledDLC(const char* szMountDrive) {
return 0;
}
unsigned int C4JStorage::UnmountInstalledDLC(LPCSTR szMountDrive) { return 0; }
void C4JStorage::GetMountedDLCFileList(const char* szMountDrive,
std::vector<std::string>& fileList) {
fileList.clear();
@ -162,25 +163,26 @@ void C4JStorage::GetMountedDLCFileList(const char* szMountDrive,
std::string C4JStorage::GetMountedPath(std::string szMount) { return ""; }
C4JStorage::ETMSStatus C4JStorage::ReadTMSFile(
int iQuadrant, eGlobalStorage eStorageFacility,
C4JStorage::eTMS_FileType eFileType, WCHAR* pwchFilename,
C4JStorage::eTMS_FileType eFileType, wchar_t* pwchFilename,
std::uint8_t** ppBuffer, unsigned int* pBufferSize,
int (*Func)(void*, WCHAR*, int, bool, int), void* lpParam, int iAction) {
int (*Func)(void*, wchar_t*, int, bool, int), void* lpParam,
int iAction) {
return ETMSStatus_Fail;
}
bool C4JStorage::WriteTMSFile(int iQuadrant, eGlobalStorage eStorageFacility,
WCHAR* pwchFilename, std::uint8_t* pBuffer,
wchar_t* pwchFilename, std::uint8_t* pBuffer,
unsigned int bufferSize) {
return false;
}
bool C4JStorage::DeleteTMSFile(int iQuadrant, eGlobalStorage eStorageFacility,
WCHAR* pwchFilename) {
wchar_t* pwchFilename) {
return false;
}
void C4JStorage::StoreTMSPathName(WCHAR* pwchName) {}
void C4JStorage::StoreTMSPathName(wchar_t* pwchName) {}
C4JStorage::ETMSStatus C4JStorage::TMSPP_ReadFile(
int iPad, C4JStorage::eGlobalStorage eStorageFacility,
C4JStorage::eTMS_FILETYPEVAL eFileTypeVal, LPCSTR szFilename,
int (*Func)(void*, int, int, PTMSPP_FILEDATA, LPCSTR), void* lpParam,
C4JStorage::eTMS_FILETYPEVAL eFileTypeVal, const char* szFilename,
int (*Func)(void*, int, int, PTMSPP_FILEDATA, const char*), void* lpParam,
int iUserData) {
return ETMSStatus_Fail;
}

View file

@ -1,9 +1,13 @@
#pragma once
#include <cstdint>
#include <ctime>
#include <string>
#include <vector>
// #include <xtms.h>
#include "../4J.Common/4J_Compat.h"
class C4JStringTable;
#define MAX_DISPLAYNAME_LENGTH 128 // CELL_SAVEDATA_SYSP_SUBTITLE_SIZE on PS3
@ -38,23 +42,23 @@ typedef std::vector<PXCONTENT_DATA> XContentDataArray;
class C4JStorage {
public:
// Structs defined in the DLC_Creator, but added here to be used in the app
typedef struct {
unsigned int uiFileSize;
std::uint32_t dwType;
std::uint32_t dwWchCount; // count of WCHAR in next array
WCHAR wchFile[1];
} DLC_FILE_DETAILS, *PDLC_FILE_DETAILS;
typedef struct {
unsigned int uiFileSize;
std::uint32_t dwType;
std::uint32_t dwWchCount; // count of wchar_t in next array
wchar_t wchFile[1];
} DLC_FILE_DETAILS, *PDLC_FILE_DETAILS;
typedef struct {
std::uint32_t dwType;
std::uint32_t dwWchCount; // count of WCHAR in next array;
WCHAR wchData[1]; // will be an array of size dwBytes
} DLC_FILE_PARAM, *PDLC_FILE_PARAM;
typedef struct {
std::uint32_t dwType;
std::uint32_t dwWchCount; // count of wchar_t in next array;
wchar_t wchData[1]; // will be an array of size dwBytes
} DLC_FILE_PARAM, *PDLC_FILE_PARAM;
// End of DLC_Creator structs
typedef struct {
WCHAR wchDisplayName[XCONTENT_MAX_DISPLAYNAME_LENGTH];
CHAR szFileName[XCONTENT_MAX_FILENAME_LENGTH];
wchar_t wchDisplayName[XCONTENT_MAX_DISPLAYNAME_LENGTH];
char szFileName[XCONTENT_MAX_FILENAME_LENGTH];
std::uint32_t dwImageOffset;
std::uint32_t dwImageBytes;
} CACHEINFOSTRUCT;
@ -178,7 +182,7 @@ public:
enum eTMS_UGCTYPE { TMS_UGCTYPE_NONE, TMS_UGCTYPE_IMAGE, TMS_UGCTYPE_MAX };
typedef struct {
CHAR szFilename[256];
char szFilename[256];
int iFileSize;
eTMS_FILETYPEVAL eFileTypeVal;
} TMSPP_FILE_DETAILS, *PTMSPP_FILE_DETAILS;
@ -201,9 +205,9 @@ public:
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) = NULL,
void* lpParam = NULL, C4JStringTable* pStringTable = NULL,
WCHAR* pwchFormatString = NULL, unsigned int focusButton = 0);
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();
@ -212,15 +216,16 @@ public:
bool bForceResetOfSaveDevice = false);
// savegame
void Init(unsigned int uiSaveVersion, LPCWSTR pwchDefaultSaveName,
void Init(unsigned int uiSaveVersion, const wchar_t* pwchDefaultSaveName,
char* pszSavePackName, int iMinimumSaveSize,
int (*Func)(void*, const ESavingMessage, int), void* lpParam,
LPCSTR szGroupID);
const char* szGroupID);
void ResetSaveData(); // Call before a new save to clear out stored save
// file name
void SetDefaultSaveNameForKeyboardDisplay(LPCWSTR pwchDefaultSaveName);
void SetSaveTitle(LPCWSTR pwchDefaultSaveName);
bool GetSaveUniqueNumber(INT* piVal);
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,
@ -229,7 +234,7 @@ public:
bool GetSaveDisabled(void);
unsigned int GetSaveSize();
void GetSaveData(void* pvData, unsigned int* puiBytes);
PVOID AllocateSaveData(unsigned int uiBytes);
void* AllocateSaveData(unsigned int uiBytes);
void SetSaveImages(
std::uint8_t* pbThumbnail, unsigned int thumbnailBytes,
std::uint8_t* pbImage, unsigned int imageBytes,
@ -240,7 +245,7 @@ public:
C4JStorage::ESaveGameState SaveSaveData(int (*Func)(void*, const bool),
void* lpParam);
void CopySaveDataToNewSave(std::uint8_t* pbThumbnail,
unsigned int cbThumbnail, WCHAR* wchNewName,
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);
@ -292,7 +297,7 @@ public:
void ClearDLCOffers();
XMARKETPLACE_CONTENTOFFER_INFO& GetOffer(unsigned int dw);
int GetOfferCount();
unsigned int InstallOffer(int iOfferIDC, __uint64* ullOfferIDA,
unsigned int InstallOffer(int iOfferIDC, std::uint64_t* ullOfferIDA,
int (*Func)(void*, int, int), void* lpParam,
bool bTrial = false);
unsigned int GetAvailableDLCCount(int iPad);
@ -304,8 +309,9 @@ public:
std::uint32_t MountInstalledDLC(int iPad, std::uint32_t dwDLC,
int (*Func)(void*, int, std::uint32_t,
std::uint32_t),
void* lpParam, LPCSTR szMountDrive = NULL);
unsigned int UnmountInstalledDLC(LPCSTR szMountDrive = NULL);
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);
@ -313,49 +319,36 @@ public:
// Global title storage
C4JStorage::ETMSStatus ReadTMSFile(
int iQuadrant, eGlobalStorage eStorageFacility,
C4JStorage::eTMS_FileType eFileType, WCHAR* pwchFilename,
C4JStorage::eTMS_FileType eFileType, wchar_t* pwchFilename,
std::uint8_t** ppBuffer, unsigned int* pBufferSize,
int (*Func)(void*, WCHAR*, int, bool, int) = NULL, void* lpParam = NULL,
int iAction = 0);
int (*Func)(void*, wchar_t*, int, bool, int) = nullptr,
void* lpParam = nullptr, int iAction = 0);
bool WriteTMSFile(int iQuadrant, eGlobalStorage eStorageFacility,
WCHAR* pwchFilename, std::uint8_t* pBuffer,
wchar_t* pwchFilename, std::uint8_t* pBuffer,
unsigned int bufferSize);
bool DeleteTMSFile(int iQuadrant, eGlobalStorage eStorageFacility,
WCHAR* pwchFilename);
void StoreTMSPathName(WCHAR* pwchName = NULL);
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, LPVOID lpParam);
HRESULT GetUserQuotaInfo(int iPad, TMSCLIENT_CALLBACK Func, LPVOID lpParam);
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
// C4JStorage::ETMSStatus TMSPP_WriteFile(int
// iPad,C4JStorage::eGlobalStorage
// eStorageFacility,C4JStorage::eTMS_FILETYPEVAL
// eFileTypeVal,C4JStorage::eTMS_UGCTYPE eUGCType,CHAR *pchFilePath,CHAR
// *pchBuffer,DWORD dwBufferSize,int( *Func)(LPVOID,int,int)=NULL,LPVOID
// lpParam=NULL, int iUserData=0); C4JStorage::ETMSStatus
// TMSPP_GetUserQuotaInfo(int iPad,TMSCLIENT_CALLBACK Func,LPVOID lpParam,
// int iUserData=0);
// 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, LPCSTR szFilename,
int (*Func)(void*, int, int, PTMSPP_FILEDATA, LPCSTR) = NULL,
void* lpParam = NULL, int iUserData = 0);
// C4JStorage::ETMSStatus TMSPP_ReadFileList(int
// iPad,C4JStorage::eGlobalStorage eStorageFacility,CHAR *pchFilePath,int(
// *Func)(LPVOID,int,int,PTMSPP_FILE_LIST)=NULL,LPVOID lpParam=NULL, int
// iUserData=0); C4JStorage::ETMSStatus
// TMSPP_DeleteFile(int iPad,LPCSTR szFilePath,C4JStorage::eTMS_FILETYPEVAL
// eFileTypeVal,int( *Func)(LPVOID,int,int),LPVOID lpParam=NULL, int
// iUserData=0); bool
// TMSPP_InFileList(eGlobalStorage eStorageFacility, int iPad,const
// std::wstring &Filename); unsigned int
// CRC(unsigned char *buf, int len);
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
// {

View file

@ -1,10 +1,6 @@
#ifndef _4J_STORAGE_STADAFX_H
#define _4J_STORAGE_STADAFX_H
#ifdef __linux__
#include "../Minecraft.Client/Platform/Linux/Stubs/LinuxStubs.h"
#endif
#include "../4J.Common/4J_Compat.h"
#include "../Minecraft.World/Platform/x64headers/extraX64.h"
#endif //_4J_STORAGE_STADAFX_H
#endif //_4J_STORAGE_STADAFX_H

View file

@ -0,0 +1,6 @@
#include "../../4J.Input/4J_Input.h"
#include "../../4J.Profile/4J_Profile.h"
#include "../../4J.Render/4J_Render.h"
#include "../../4J.Storage/4J_Storage.h"
int main() { return 0; }

127
4jlibs/builddef/meson.build Normal file
View file

@ -0,0 +1,127 @@
gl_dep = dependency('gl', required: false)
sdl2_dep = dependency('sdl2', required: false)
thread_dep = dependency('threads')
fourj_cpp_args = [
'-fpermissive',
'-Wshift-count-overflow',
'-pipe',
]
fourj_cpp_defs = [
'-DSPLIT_SAVES',
'-D_LARGE_WORLDS',
'-D_EXTENDED_ACHIEVEMENTS',
'-D_DEBUG_MENUS_ENABLED',
'-D_DEBUG',
'-DDEBUG',
]
if host_machine.system() == 'linux'
fourj_cpp_defs += [
'-Dlinux',
'-D__linux',
'-D__linux__',
]
endif
render_inc = include_directories('../../4J.Render', '../../4J.Common')
render_sources = files('../../4J.Render/4J_Render.cpp', '../../4J.Render/stdafx.cpp')
lib_render = static_library(
'4J_Render',
render_sources,
include_directories: render_inc,
dependencies: [sdl2_dep, gl_dep, thread_dep],
cpp_args: fourj_cpp_args + fourj_cpp_defs + [
'-include', meson.current_source_dir() / '../../4J.Render/stdafx.h',
],
)
render_dep = declare_dependency(
link_with: lib_render,
include_directories: render_inc,
dependencies: [sdl2_dep, gl_dep, thread_dep],
)
input_inc = include_directories('../../4J.Input', '../../4J.Common')
input_sources = files(
'../../4J.Input/4J_Input.cpp',
'../../4J.Input/INP_ForceFeedback.cpp',
'../../4J.Input/INP_Keyboard.cpp',
'../../4J.Input/INP_Main.cpp',
'../../4J.Input/INP_StringCheck.cpp',
'../../4J.Input/stdafx.cpp',
)
lib_input = static_library(
'4J_Input',
input_sources,
include_directories: input_inc,
dependencies: [sdl2_dep],
cpp_args: fourj_cpp_args + fourj_cpp_defs + [
'-include', meson.current_source_dir() / '../../4J.Input/stdafx.h',
],
)
input_dep = declare_dependency(
link_with: lib_input,
include_directories: input_inc,
dependencies: [sdl2_dep],
)
profile_inc = include_directories('../../4J.Profile', '../../4J.Common')
profile_sources = files(
'../../4J.Profile/4J_Profile.cpp',
'../../4J.Profile/PRO_AwardManager.cpp',
'../../4J.Profile/PRO_Data.cpp',
'../../4J.Profile/PRO_Main.cpp',
'../../4J.Profile/PRO_RichPresence.cpp',
'../../4J.Profile/PRO_Sys.cpp',
'../../4J.Profile/stdafx.cpp',
)
lib_profile = static_library(
'4J_Profile',
profile_sources,
include_directories: profile_inc,
cpp_args: fourj_cpp_args + fourj_cpp_defs + [
'-include', meson.current_source_dir() / '../../4J.Profile/stdafx.h',
],
)
profile_dep = declare_dependency(
link_with: lib_profile,
include_directories: profile_inc,
)
storage_inc = include_directories('../../4J.Storage', '../../4J.Common')
storage_sources = files(
'../../4J.Storage/4J_Storage.cpp',
'../../4J.Storage/stdafx.cpp',
'../../4J.Storage/STO_DLC.cpp',
'../../4J.Storage/STO_Main.cpp',
'../../4J.Storage/STO_SaveGame.cpp',
)
lib_storage = static_library(
'4J_Storage',
storage_sources,
include_directories: storage_inc,
cpp_args: fourj_cpp_args + fourj_cpp_defs + [
'-include', meson.current_source_dir() / '../../4J.Storage/stdafx.h',
],
)
storage_dep = declare_dependency(
link_with: lib_storage,
include_directories: storage_inc,
)
meson.override_dependency('4j-render', render_dep)
meson.override_dependency('4j-input', input_dep)
meson.override_dependency('4j-profile', profile_dep)
meson.override_dependency('4j-storage', storage_dep)
if meson.project_name() == '4jlibs'
smoke_inc = include_directories('../..')
header_smoke = executable(
'4j-header-smoke',
'header_smoke.cpp',
include_directories: smoke_inc,
build_by_default: false,
)
test('4j-header-smoke', header_smoke)
endif

15
4jlibs/meson.build Normal file
View file

@ -0,0 +1,15 @@
project(
'4jlibs',
['c', 'cpp'],
version: '0.1.0',
meson_version: '>=1.1',
default_options: [
'cpp_std=c++23',
'warning_level=0',
'buildtype=debug',
'unity=on',
'unity_size=8',
'b_pch=true',
],
)
subdir('builddef')

View file

@ -5,6 +5,7 @@
#include <functional>
#include <cstdint>
#include <limits>
#include "../../../4J.Common/4J_Compat.h"
#include "../../../Minecraft.Client/Rendering/Models/SkinBox.h"
@ -13,14 +14,10 @@
#define MULTITHREAD_ENABLE
typedef unsigned char byte;
const int XUSER_INDEX_ANY = 255;
const int XUSER_INDEX_FOCUS = 254;
#ifdef __PSVITA__
const int XUSER_MAX_COUNT = 1;
constexpr int MINECRAFT_NET_MAX_PLAYERS = 4;
#else
const int XUSER_MAX_COUNT = 4;
constexpr int MINECRAFT_NET_MAX_PLAYERS = 8;
#endif
@ -65,16 +62,12 @@ typedef ULONGLONG SessionID;
typedef ULONGLONG GameSessionUID;
typedef DQRNetworkManager::SessionInfo INVITE_INFO;
#else
typedef ULONGLONG PlayerUID;
typedef ULONGLONG SessionID;
typedef PlayerUID GameSessionUID;
class INVITE_INFO;
#endif // __PS3__
#ifndef _DURANGO
typedef PlayerUID* PPlayerUID;
#endif
typedef struct _XUIOBJ* HXUIOBJ;
typedef struct _XUICLASS* HXUICLASS;
typedef struct _XUIBRUSH* HXUIBRUSH;
@ -189,8 +182,6 @@ const int XN_SYS_STORAGEDEVICESCHANGED = 3;
#define VK_PAD_RTHUMB_DOWNRIGHT 0x5836
#define VK_PAD_RTHUMB_DOWNLEFT 0x5837
const int XUSER_NAME_SIZE = 32;
class IQNetPlayer {
public:
BYTE GetSmallId();
@ -339,23 +330,12 @@ const int INVALID_XUID = 0;
// HRESULT *pStringResult;
// } STRING_VERIFY_RESPONSE;
const int XCONTENT_MAX_DISPLAYNAME_LENGTH = 256;
const int XCONTENT_MAX_FILENAME_LENGTH = 256;
typedef int XCONTENTDEVICEID;
#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(_DURANGO) && \
!defined(__PSVITA__)
typedef struct _XCONTENT_DATA {
XCONTENTDEVICEID DeviceID;
DWORD dwContentType;
WCHAR szDisplayName[XCONTENT_MAX_DISPLAYNAME_LENGTH];
CHAR szFileName[XCONTENT_MAX_FILENAME_LENGTH];
} XCONTENT_DATA, *PXCONTENT_DATA;
!defined(__PSVITA__) && !defined(FOURJ_COMMON_XCONTENT_DATA_DEFINED)
typedef int XCONTENTDEVICEID;
#endif //__PS3__
static const int XMARKETPLACE_CONTENT_ID_LEN = 4;
#ifndef _DURANGO
#if !defined(_DURANGO) && !defined(FOURJ_COMMON_XMARKETPLACE_DEFINED)
typedef struct _XMARKETPLACE_CONTENTOFFER_INFO {
ULONGLONG qwOfferID;
ULONGLONG qwPreviewOfferID;

View file

@ -48,10 +48,15 @@ if host_machine.system() == 'linux'
]
endif
subdir('4J.Render')
subdir('4J.Input')
subdir('4J.Profile')
subdir('4J.Storage')
render_dep = dependency('4j-render', required: false)
input_dep = dependency('4j-input', required: false)
profile_dep = dependency('4j-profile', required: false)
storage_dep = dependency('4j-storage', required: false)
if not render_dep.found() or not input_dep.found() or not profile_dep.found() or not storage_dep.found()
subdir('4jlibs/builddef')
endif
subdir('Minecraft.Assets')
subdir('Minecraft.World')
subdir('Minecraft.Client')

113
scripts/extract_4jlibs.py Normal file
View file

@ -0,0 +1,113 @@
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import shutil
import subprocess
import sys
from pathlib import Path
PATHS_TO_KEEP = [
"4J.Common",
"4J.Input",
"4J.Profile",
"4J.Render",
"4J.Storage",
"4jlibs",
]
def run(cmd: list[str], cwd: Path | None = None) -> None:
subprocess.run(cmd, cwd=cwd, check=True)
def require_clean_destination(dest: Path) -> None:
if dest.exists():
raise SystemExit(f"Destination already exists: {dest}")
def ensure_filter_repo() -> None:
try:
run(["git", "filter-repo", "--help"])
except subprocess.CalledProcessError as exc:
raise SystemExit(
"git-filter-repo is required. Install it first and rerun this script."
) from exc
def clone_source(source: Path, dest: Path) -> None:
run(["git", "clone", "--no-local", str(source), str(dest)])
def filter_history(dest: Path) -> None:
cmd = ["git", "filter-repo", "--force"]
for path in PATHS_TO_KEEP:
cmd.extend(["--path", path])
run(cmd, cwd=dest)
def rewrite_staged_layout(dest: Path) -> None:
staged_root = dest / "4jlibs"
meson_src = staged_root / "meson.build"
builddef_src = staged_root / "builddef"
if not meson_src.exists() or not builddef_src.exists():
raise SystemExit("Filtered tree is missing the staged 4jlibs Meson files.")
shutil.move(str(meson_src), str(dest / "meson.build"))
shutil.move(str(builddef_src), str(dest / "builddef"))
try:
staged_root.rmdir()
except OSError:
pass
builddef_meson = dest / "builddef" / "meson.build"
builddef_smoke = dest / "builddef" / "header_smoke.cpp"
builddef_meson.write_text(
builddef_meson.read_text(encoding="utf-8").replace("../../", "../"),
encoding="utf-8",
)
builddef_smoke.write_text(
builddef_smoke.read_text(encoding="utf-8").replace("../../", "../"),
encoding="utf-8",
)
def main() -> int:
parser = argparse.ArgumentParser(
description=(
"Create a filtered 4jlibs bootstrap repo from the current 4jcraft tree."
)
)
parser.add_argument(
"destination",
type=Path,
help="Path to create the filtered 4jlibs clone in",
)
parser.add_argument(
"--source",
type=Path,
default=Path.cwd(),
help="Source 4jcraft repo to clone from (default: current working directory)",
)
args = parser.parse_args()
source = args.source.resolve()
destination = args.destination.resolve()
require_clean_destination(destination)
ensure_filter_repo()
clone_source(source, destination)
filter_history(destination)
rewrite_staged_layout(destination)
print(f"Created filtered 4jlibs bootstrap repo at: {destination}")
return 0
if __name__ == "__main__":
sys.exit(main())

6
subprojects/4jlibs.wrap Normal file
View file

@ -0,0 +1,6 @@
[wrap-git]
url = https://github.com/4jcraft/4jlibs.git
revision = main
[provide]
dependency_names = 4j-render, 4j-input, 4j-profile, 4j-storage