mirror of
https://github.com/CDevJoud/Minecraft-Community-Edition.git
synced 2026-07-18 01:41:15 +00:00
This commit is contained in:
168
Minecraft-Community-Edition/Mod/ModLoader.cpp
Normal file
168
Minecraft-Community-Edition/Mod/ModLoader.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
#include "ModLoader.h"
|
||||
|
||||
static XIDevice* g_device;
|
||||
static XIContext* g_ctx;
|
||||
static XIExports g_exp;
|
||||
eastl::unordered_map<Xuint64, Xvoid*> registeries;
|
||||
Xuint64 hash_str(Xcstr str) {
|
||||
Xuint64 h = 0xcbf29ce484222325ULL; // FNV offset basis
|
||||
|
||||
while (*str) {
|
||||
h ^= (Xuint8)(*str++);
|
||||
h *= 0x100000001b3ULL; // FNV prime
|
||||
}
|
||||
|
||||
// Final mixing (improves avalanche)
|
||||
h ^= h >> 33;
|
||||
h *= 0xff51afd7ed558ccdULL;
|
||||
h ^= h >> 33;
|
||||
h *= 0xc4ceb9fe1a85ec53ULL;
|
||||
h ^= h >> 33;
|
||||
|
||||
return h;
|
||||
}
|
||||
typedef struct {
|
||||
XIDevice iface;
|
||||
Xint32 ref;
|
||||
Xint32 handle;
|
||||
}DeviceImpl;
|
||||
|
||||
typedef struct {
|
||||
XIContext iface;
|
||||
Xint32 ref;
|
||||
}ContextImpl;
|
||||
|
||||
Xvoid mce_device_addref(XIDevice* device) {
|
||||
((DeviceImpl*)device)->ref++;
|
||||
}
|
||||
|
||||
Xvoid mce_device_release(XIDevice* device) {
|
||||
DeviceImpl* self = (DeviceImpl*)device;
|
||||
if (--self->ref == 0) {
|
||||
//printf("[Engine] Device destroyed\n");
|
||||
}
|
||||
}
|
||||
|
||||
Xint32 mce_device_createQEventBus(XIDevice* device, XHQEventBus* qBus, XQEventBusDescriptor desc) {
|
||||
|
||||
Xuint64 hash = hash_str(desc.name);
|
||||
auto it = registeries.find(hash);
|
||||
if (it == registeries.end()) {
|
||||
registeries[hash] = new mce::core::QEventBus(desc.name);
|
||||
qBus->idx = hash;
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
qBus->idx = it->first;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
Xvoid mce_device_setXIExports(XIDevice* device, XIExports exp) {
|
||||
g_exp = exp;
|
||||
}
|
||||
|
||||
Xvoid mce_ctx_addRef(XIContext* ctx) {
|
||||
((ContextImpl*)ctx)->ref++;
|
||||
}
|
||||
|
||||
Xvoid mce_ctx_release(XIContext* device) {
|
||||
ContextImpl* self = (ContextImpl*)device;
|
||||
if (--self->ref == 0) {
|
||||
//printf("[Engine] Context destroyed\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Xuint32 mce_ctx_postEvent(XHQEventBus* qBus, Xvoid* event, Xconst Xuint64 type) {
|
||||
auto it = registeries.find(qBus->idx);
|
||||
if (it != registeries.end()) {
|
||||
mce::core::QEventBus* _qBus = reinterpret_cast<mce::core::QEventBus*>(it->second);
|
||||
|
||||
if (type == XE_EVENT_TYPE_LOG) {
|
||||
XSEventLog* XAPI_eventLog = reinterpret_cast<XSEventLog*>(event);
|
||||
mce::event::Log log;
|
||||
log.channel = XAPI_eventLog->channel;
|
||||
log.msg = XAPI_eventLog->msg;
|
||||
log.severity = static_cast<mce::event::Log::Severity>(XAPI_eventLog->severity);
|
||||
_qBus->post(log);
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return XE_ERROR;
|
||||
}
|
||||
|
||||
void zMem(void*& mem, size_t size) {
|
||||
char* _mem = (char*)mem;
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
_mem[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Xvoid setGlobalQEventBus(mce::core::QEventBus* qBus) {
|
||||
//auto num = hash_str("mce.core.event.logger_output");
|
||||
Xuint64 hash = hash_str(qBus->getNamespace().data());
|
||||
auto it = registeries.find(hash);
|
||||
|
||||
if (it == registeries.end()) {
|
||||
registeries[hash] = qBus;
|
||||
}
|
||||
}
|
||||
|
||||
Xint32 mce_createDeviceAndContext(XIDevice** device, XIContext** ctx) {
|
||||
if ((*device) != nullptr && (*ctx) != nullptr) {
|
||||
return XE_ERROR;
|
||||
}
|
||||
|
||||
*device = new XIDevice();
|
||||
*ctx = new XIContext();
|
||||
|
||||
XIDeviceVTable* device_vtbl = new XIDeviceVTable();
|
||||
XIContextVTable* ctx_vtbl = new XIContextVTable();
|
||||
|
||||
//ZeroMemory(device_vtbl, sizeof(XIDeviceVTable));
|
||||
|
||||
//memset(device_vtbl, 0, sizeof(XIDeviceVTable));
|
||||
|
||||
if (!device_vtbl && !ctx_vtbl) {
|
||||
return XE_ERROR;
|
||||
}
|
||||
const_cast<XIDeviceVTable*>(device_vtbl)->addRef = mce_device_addref;
|
||||
const_cast<XIDeviceVTable*>(device_vtbl)->addRef = mce_device_release;
|
||||
const_cast<XIDeviceVTable*>(device_vtbl)->createQEventBus = mce_device_createQEventBus;
|
||||
const_cast<XIDeviceVTable*>(device_vtbl)->setXIExports = mce_device_setXIExports;
|
||||
|
||||
const_cast<XIContextVTable*>(ctx_vtbl)->addRef = mce_ctx_addRef;
|
||||
const_cast<XIContextVTable*>(ctx_vtbl)->release = mce_ctx_release;
|
||||
//const_cast<XIContextVTable*>(ctx_vtbl)->setXIExports = mce_ctx_setXIExports;
|
||||
const_cast<XIContextVTable*>(ctx_vtbl)->postEvent = mce_ctx_postEvent;
|
||||
|
||||
(*device)->vtbl = device_vtbl;
|
||||
(*ctx)->vtbl = ctx_vtbl;
|
||||
|
||||
g_device = (*device);
|
||||
g_ctx = (*ctx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
Xint32 mce_destroyDeviceAndContext(XIDevice** device, XIContext** ctx) {
|
||||
if ((*device) == nullptr || (*ctx) == nullptr) {
|
||||
return XE_ERROR;
|
||||
}
|
||||
|
||||
delete (*device)->vtbl;
|
||||
delete (*ctx)->vtbl;
|
||||
|
||||
delete* device;
|
||||
delete* ctx;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Xconst XIExports mce_pullSessionsExports() {
|
||||
return g_exp;
|
||||
}
|
||||
11
Minecraft-Community-Edition/Mod/ModLoader.h
Normal file
11
Minecraft-Community-Edition/Mod/ModLoader.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#define XAPI_USE_V1_0_0
|
||||
#include "XAPI.h"
|
||||
#include <Core/QEventBus.hpp>
|
||||
|
||||
Xvoid setGlobalQEventBus(mce::core::QEventBus* qBus);
|
||||
|
||||
Xint32 mce_createDeviceAndContext(XIDevice** device, XIContext** ctx);
|
||||
Xint32 mce_destroyDeviceAndContext(XIDevice** device, XIContext** ctx);
|
||||
|
||||
Xconst XIExports mce_pullSessionsExports();
|
||||
141
Minecraft-Community-Edition/Mod/XAPI.h
Normal file
141
Minecraft-Community-Edition/Mod/XAPI.h
Normal file
@@ -0,0 +1,141 @@
|
||||
///---------------------------------------------------------------------------------\\\
|
||||
/// MIT License \\\
|
||||
/// \\\
|
||||
/// Copyright(c) 2026 Joud Kandeel \\\
|
||||
/// \\\
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy \\\
|
||||
/// of this software and associated documentation files(the "Software"), to deal \\\
|
||||
/// in the Software without restriction, including without limitation the rights \\\
|
||||
/// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell \\\
|
||||
/// copies of the Software, and to permit persons to whom the Software is \\\
|
||||
/// furnished to do so, subject to the following conditions : \\\
|
||||
/// \\\
|
||||
/// The above copyright notice and this permission notice shall be included in all\\\
|
||||
/// copies or substantial portions of the Software. \\\
|
||||
/// \\\
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR \\\
|
||||
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, \\\
|
||||
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE \\\
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER \\\
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \\\
|
||||
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE \\\
|
||||
/// SOFTWARE. \\\
|
||||
///---------------------------------------------------------------------------------\\\
|
||||
|
||||
#pragma once
|
||||
#ifdef XAPI_USE_V1_0_0
|
||||
#ifndef XAPI_HEADER
|
||||
#define XAPI_HEADER
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef __cplusplus
|
||||
#define XAPI_EXPORT __declspec(dllexport) extern "C"
|
||||
#define XAPI_LOCAL
|
||||
#else
|
||||
#define XAPI_EXPORT __declspec(dllexport)
|
||||
#define XAPI_LOCAL
|
||||
#endif
|
||||
#else
|
||||
#define XAPI_EXPORT __attribute__((visibility("default")))
|
||||
#define XAPI_LOCAL __attribute__((visibility("hidden")))
|
||||
#endif
|
||||
|
||||
#define XAPI_LOCAL
|
||||
#define XAPI_STDCALL __stdcall
|
||||
|
||||
#define XAPI_VERSION 0x01000000u
|
||||
#define XAPI_NULL (Xvoid*)0
|
||||
|
||||
#define XE_ERROR 0xDEADBEEF
|
||||
|
||||
#define XE_EVENT_TYPE_LOG 0xA2942192B2001D9E //mce.core.event.logger_output
|
||||
|
||||
#define XE_EVENT_LOG_DEBUG 0x07
|
||||
|
||||
#define Xconst const
|
||||
#define Xconstptr const*
|
||||
#define XInterface struct
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef char Xint8;
|
||||
typedef short Xint16;
|
||||
typedef int Xint32;
|
||||
typedef long long Xint64;
|
||||
|
||||
typedef unsigned char Xuint8;
|
||||
typedef unsigned short Xuint16;
|
||||
typedef unsigned int Xuint32;
|
||||
typedef unsigned long long Xuint64;
|
||||
|
||||
typedef Xconst char Xconstptr Xcstrcp;
|
||||
typedef Xconst char* Xcstr;
|
||||
|
||||
typedef void Xvoid;
|
||||
|
||||
typedef XInterface XIDevice XIDevice;
|
||||
typedef XInterface XIContext XIContext;
|
||||
typedef Xconst Xint32(XAPI_STDCALL* XI_createDeviceAndContextFn)(XIDevice**, XIContext**);
|
||||
typedef Xconst Xint32(XAPI_STDCALL* XI_destroyDeviceAndContextFn)(XIDevice**, XIContext**);
|
||||
|
||||
typedef struct {
|
||||
Xcstrcp name;
|
||||
Xcstrcp author;
|
||||
Xint32 version;
|
||||
Xcstrcp language;// programming language
|
||||
Xcstrcp sdkName;
|
||||
Xcstrcp dependencies;
|
||||
}XAPIDescriptor;
|
||||
|
||||
typedef struct {
|
||||
Xint64 idx;
|
||||
}XHQEventBus;
|
||||
|
||||
typedef struct {
|
||||
Xcstr name;
|
||||
Xuint16 maxSize;
|
||||
}XQEventBusDescriptor;
|
||||
|
||||
typedef struct {
|
||||
Xcstr channel;
|
||||
Xcstr msg;
|
||||
Xuint8 severity;
|
||||
}XSEventLog;
|
||||
|
||||
typedef struct {
|
||||
Xint32(*onShutdown)(Xvoid);
|
||||
Xint32(*onUpdate)(Xvoid);
|
||||
Xint32(*onInit)(Xvoid);
|
||||
}XIExports;
|
||||
|
||||
typedef struct {
|
||||
Xvoid(*addRef)(XIDevice* device);
|
||||
Xvoid(*release)(XIDevice* device);
|
||||
Xint32(*createQEventBus)(XIDevice* device, XHQEventBus* qBus, XQEventBusDescriptor desc);
|
||||
Xvoid(*setXIExports)(XIDevice* device, XIExports exp);
|
||||
}XIDeviceVTable;
|
||||
|
||||
XInterface XIDevice{
|
||||
Xconst XIDeviceVTable Xconstptr vtbl;
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
Xvoid(*addRef)(XIContext* ctx);
|
||||
Xvoid(*release)(XIContext* ctx);
|
||||
//Xvoid(*setXIExports)(XIExports exp);
|
||||
Xuint32(*postEvent)(XHQEventBus* qBus, Xvoid* event, Xconst Xuint64 type);
|
||||
Xuint32(*subscribeEvent)(XHQEventBus* qBus, Xconst Xuint64 type, Xconst Xvoid Xconstptr fn);
|
||||
}XIContextVTable;
|
||||
|
||||
XInterface XIContext{
|
||||
Xconst XIContextVTable Xconstptr vtbl;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
321
Minecraft-Community-Edition/Mod/readme.md
Normal file
321
Minecraft-Community-Edition/Mod/readme.md
Normal file
@@ -0,0 +1,321 @@
|
||||
-- -
|
||||
|
||||
# XAPI — Cross - Engine Modding ABI
|
||||
|
||||
XAPI is a **C ABI - based modding interface** designed for voxel / sandbox - style engines.
|
||||
It provides a **stable, low - level contract** between engine and mods, enabling binary compatibility across different builds, forks, and even entirely separate engines.
|
||||
|
||||
-- -
|
||||
|
||||
## ✨ Overview
|
||||
|
||||
XAPI is not tied to a specific engine implementation.
|
||||
|
||||
Instead, it defines a **strict binary interface(ABI)** that any engine can implement and any mod can target.
|
||||
|
||||
This allows:
|
||||
|
||||
- Mods compiled once to run across multiple engines
|
||||
- Different codebases to share the same mod ecosystem
|
||||
- Language - agnostic bindings via C ABI
|
||||
|
||||
-- -
|
||||
|
||||
## 🧠 Design Philosophy
|
||||
|
||||
- **C ABI first** — maximum portability and language interoperability
|
||||
- **No engine pointers exposed**— mods operate on handles, not raw memory
|
||||
- **Explicit lifecycle**— no hidden initialization or runtime magic
|
||||
- **Event - driven communication**— decoupled interaction via event buses
|
||||
- **Stable contracts over implementations**— behavior defined by spec, not engine internals
|
||||
|
||||
-- -
|
||||
|
||||
## 🧩 Core Concepts
|
||||
|
||||
### 1. Entry Points
|
||||
|
||||
Every XAPI module exports three functions :
|
||||
|
||||
```c
|
||||
XAPI_EXPORT XAPIDescriptor XI_query(Xvoid);
|
||||
XAPI_EXPORT Xint32 XI_main(Xvoid* pParam);
|
||||
XAPI_EXPORT Xint32 XI_terminate(Xvoid* pParam);
|
||||
````
|
||||
|
||||
* `XI_query` → returns mod metadata
|
||||
* `XI_main` → initializes the module
|
||||
* `XI_terminate` → cleans up resources
|
||||
|
||||
-- -
|
||||
|
||||
### 2. Device & Context
|
||||
|
||||
The engine provides :
|
||||
|
||||
* `XIDevice` → resource and system access
|
||||
* `XIContext` → runtime interaction(events, callbacks)
|
||||
|
||||
Mods never construct these manually — they are provided by the engine.
|
||||
|
||||
-- -
|
||||
|
||||
### 3. Function Table(VTable)
|
||||
|
||||
All engine interaction is done through function tables :
|
||||
|
||||
```c
|
||||
device->vtbl->createQEventBus(...)
|
||||
ctx->vtbl->postEvent(...)
|
||||
```
|
||||
|
||||
This ensures :
|
||||
|
||||
* ABI stability
|
||||
* no direct linking against engine internals
|
||||
|
||||
-- -
|
||||
|
||||
### 4. Event System
|
||||
|
||||
XAPI uses an **event - driven architecture**:
|
||||
|
||||
* Mods post events via `postEvent`
|
||||
* Systems subscribe via `subscribeEvent`
|
||||
* Communication is decoupled and asynchronous
|
||||
|
||||
Example :
|
||||
|
||||
```c
|
||||
XSEventLog log;
|
||||
log.channel = "default";
|
||||
log.msg = "Hello World";
|
||||
log.severity = XE_EVENT_LOG_DEBUG;
|
||||
|
||||
ctx->vtbl->postEvent(NULL, &log, XE_EVENT_TYPE_LOG);
|
||||
```
|
||||
|
||||
-- -
|
||||
|
||||
### 5. Handles Instead of Pointers
|
||||
|
||||
All engine - side objects are represented as **handles**, not pointers:
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
Xint64 idx;
|
||||
} XHQEventBus;
|
||||
```
|
||||
|
||||
This ensures :
|
||||
|
||||
* memory safety across modules
|
||||
* engine - side ownership control
|
||||
* compatibility across implementations
|
||||
|
||||
-- -
|
||||
|
||||
## 🔄 Module Lifecycle
|
||||
|
||||
1. Engine loads module(`.dll`)
|
||||
2. Calls `XI_query` → retrieves metadata
|
||||
3. Calls `XI_main`
|
||||
|
||||
* provides function pointer to create device / context
|
||||
* mod initializes and registers callbacks
|
||||
4. Engine drives execution via callbacks :
|
||||
|
||||
* `onInit`
|
||||
* `onUpdate`
|
||||
* `onShutdown`
|
||||
5. Engine calls `XI_terminate` on unload
|
||||
|
||||
-- -
|
||||
|
||||
## 🧱 CXAPI(C Wrapper)
|
||||
|
||||
CXAPI is a thin helper layer built on top of XAPI to simplify usage in C.
|
||||
|
||||
It provides :
|
||||
|
||||
* global state management
|
||||
* callback registration
|
||||
* utility functions(logging, event posting)
|
||||
|
||||
Example:
|
||||
|
||||
```c
|
||||
CXAPI_setOnInitCB(onInit);
|
||||
CXAPI_setOnUpdateCB(onUpdate);
|
||||
CXAPI_setOnShutdownCB(onShutdown);
|
||||
```
|
||||
|
||||
-- -
|
||||
|
||||
## 🌍 Multi - Language Support
|
||||
|
||||
Because XAPI is pure C ABI, it can be used from many languages.
|
||||
|
||||
Bindings can be created by the community for:
|
||||
|
||||
* C / C++ (native)
|
||||
* Rust
|
||||
* Zig
|
||||
* Nim
|
||||
* Go
|
||||
* C# (AOT)
|
||||
* Python(via C API / Cython)
|
||||
* JavaScript / Lua(via embedded runtimes)
|
||||
|
||||
The core project focuses on :
|
||||
|
||||
> **C/C++ reference implementation and wrappers**
|
||||
|
||||
-- -
|
||||
|
||||
## 🔐 Safety Model
|
||||
|
||||
* Mods never receive raw engine pointers
|
||||
* All access goes through validated interfaces
|
||||
* Engine retains full ownership of resources
|
||||
* Invalid operations return error codes(`XE_ERROR`)
|
||||
|
||||
-- -
|
||||
|
||||
## 🔢 Versioning
|
||||
|
||||
XAPI uses explicit versioning:
|
||||
|
||||
```c
|
||||
#define XAPI_VERSION 1
|
||||
```
|
||||
|
||||
Future versions must maintain :
|
||||
|
||||
* backward compatibility where possible
|
||||
* strict ABI guarantees
|
||||
|
||||
-- -
|
||||
|
||||
## 🎯 Goals
|
||||
|
||||
* Provide a **portable modding standard**
|
||||
* Enable **cross - engine compatibility**
|
||||
* Keep the core **minimal, stable, and predictable**
|
||||
* Allow higher - level systems to be built on top
|
||||
|
||||
-- -
|
||||
|
||||
## 🚀 Example(Minimal Mod)
|
||||
|
||||
```c
|
||||
//Globals
|
||||
XAPIDescriptor desc;
|
||||
XIExports exports;
|
||||
XHQEventBus qBus;
|
||||
XI_createDeviceAndContextFn XI_createDeviceAndContext;
|
||||
XI_destroyDeviceAndContextFn XI_destroyDeviceAndContext;
|
||||
|
||||
XAPI_LOCAL Xint32 onUpdate(Xvoid) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
XAPI_LOCAL Xint32 onInit(Xvoid) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
XAPI_LOCAL Xint32 onShutdown(Xvoid) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
XAPI_EXPORT Xconst XAPIDescriptor XI_query(Xvoid) {
|
||||
XAPIDescriptor desc;
|
||||
desc.author = "CDevJoud";
|
||||
desc.language = "C";
|
||||
desc.name = "My Mod!";
|
||||
desc.version = 1;
|
||||
desc.dependencies = "xapi.sys.q_eventBus";
|
||||
desc.sdkName = "CXAPI";
|
||||
return desc;
|
||||
}
|
||||
|
||||
XAPI_EXPORT Xint32 XI_main(Xvoid* pParam) {
|
||||
XI_createDeviceAndContext = (XI_createDeviceAndContextFn)pParam;
|
||||
Xconst Xint32 ret = XI_createDeviceAndContext(&device, &ctx);
|
||||
|
||||
if (ret != XE_ERROR) {
|
||||
// request for the APP QEventBus
|
||||
if (device->vtbl->createQEventBus != XAPI_NULL) {
|
||||
XQEventBusDescriptor qBusdesc;
|
||||
qBusdesc.name = "APP";
|
||||
qBusdesc.maxSize = 0xFFFF;
|
||||
Xint32 res = device->vtbl->createQEventBus(device, &qBus, qBusdesc);
|
||||
}
|
||||
else {
|
||||
return XE_ERROR; //Fatal Error!
|
||||
}
|
||||
|
||||
exports.onInit = onInit;
|
||||
exports.onShutdown = onShutdown;
|
||||
exports.onUpdate = onUpdate;
|
||||
|
||||
if (device->vtbl->setXIExports != XAPI_NULL) {
|
||||
device->vtbl->setXIExports(&device, exports);
|
||||
}
|
||||
else {
|
||||
return XE_ERROR; //Fatal Error!
|
||||
}
|
||||
}
|
||||
XSEventLog log;
|
||||
log.channel = "default";
|
||||
log.msg = "Running XAPI!";
|
||||
log.severity = XE_EVENT_LOG_DEBUG;
|
||||
ctx->vtbl->postEvent(&qBus, &log, XE_EVENT_TYPE_LOG);
|
||||
return ret != XE_ERROR;
|
||||
}
|
||||
|
||||
XAPI_EXPORT Xint32 XI_terminate(Xvoid* pParam) {
|
||||
XI_destroyDeviceAndContext = (XI_destroyDeviceAndContextFn)pParam;
|
||||
return XI_destroyDeviceAndContext(&device, &ctx) != XE_ERROR;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📌 Summary
|
||||
|
||||
XAPI is :
|
||||
|
||||
* a **specification**, not just an implementation
|
||||
* a **binary contract**, not a framework
|
||||
* a **foundation layer** for building mod ecosystems
|
||||
|
||||
---
|
||||
|
||||
**XAPI is an open specification. Anyone is free to implement it in their own engine or create language bindings.**
|
||||
|
||||
## 📄 License
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Joud Kandeel
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
BIN
Minecraft-Community-Edition/assets/images/jj.jpg
Normal file
BIN
Minecraft-Community-Edition/assets/images/jj.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
120
SampleMod/CXAPI.c
Normal file
120
SampleMod/CXAPI.c
Normal file
@@ -0,0 +1,120 @@
|
||||
#include "CXAPI.h"
|
||||
|
||||
XAPIDescriptor desc;
|
||||
XI_createDeviceAndContextFn XI_createDeviceAndContext;
|
||||
XI_destroyDeviceAndContextFn XI_destroyDeviceAndContext;
|
||||
XIDevice* device;
|
||||
XIContext* ctx;
|
||||
XIExports exports, cxapiExports;
|
||||
XHQEventBus qBus;
|
||||
|
||||
XAPI_LOCAL Xint32 CXAPI_onUpdate(Xvoid) {
|
||||
if (cxapiExports.onUpdate != XAPI_NULL) {
|
||||
cxapiExports.onUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
XAPI_LOCAL Xint32 CXAPI_onInit(Xvoid) {
|
||||
if (cxapiExports.onInit != XAPI_NULL) {
|
||||
cxapiExports.onInit();
|
||||
}
|
||||
}
|
||||
|
||||
XAPI_LOCAL Xint32 CXAPI_onShutdown(Xvoid) {
|
||||
if (cxapiExports.onShutdown != XAPI_NULL) {
|
||||
cxapiExports.onShutdown();
|
||||
}
|
||||
}
|
||||
|
||||
XAPI_EXPORT Xconst XAPIDescriptor XI_query(Xvoid) {
|
||||
desc = queryCXAPIDescriptor();
|
||||
desc.sdkName = "CXAPI";
|
||||
return desc;
|
||||
}
|
||||
|
||||
XAPI_EXPORT Xint32 XI_main(Xvoid* pParam){
|
||||
XI_createDeviceAndContext = (XI_createDeviceAndContextFn)pParam;
|
||||
|
||||
Xconst Xint32 ret = XI_createDeviceAndContext(&device, &ctx);
|
||||
|
||||
if (ret != XE_ERROR) {
|
||||
initCXAPI();
|
||||
// request for the APP QEventBus
|
||||
if (device->vtbl->createQEventBus != XAPI_NULL) {
|
||||
XQEventBusDescriptor qBusdesc;
|
||||
qBusdesc.name = "APP";
|
||||
Xint32 res = device->vtbl->createQEventBus(device, &qBus, qBusdesc);
|
||||
}
|
||||
else {
|
||||
return XE_ERROR; //Fatal Error!
|
||||
}
|
||||
|
||||
CXAPI_logDebug("CXAPI running XAPI on version: 1.0.0, instantiating the mod loading phase!");
|
||||
|
||||
exports.onInit = CXAPI_onInit;
|
||||
exports.onShutdown = CXAPI_onShutdown;
|
||||
exports.onUpdate = CXAPI_onUpdate;
|
||||
|
||||
if (device->vtbl->setXIExports != XAPI_NULL) {
|
||||
device->vtbl->setXIExports(&device, exports);
|
||||
}
|
||||
else {
|
||||
return XE_ERROR; //Fatal Error!
|
||||
}
|
||||
}
|
||||
|
||||
CXAPI_logDebug("CXAPI has been instantiated!");
|
||||
return ret != XE_ERROR;
|
||||
}
|
||||
|
||||
XAPI_EXPORT Xint32 XI_terminate(Xvoid* pParam) {
|
||||
XI_destroyDeviceAndContext = (XI_destroyDeviceAndContextFn)pParam;
|
||||
return XI_destroyDeviceAndContext(&device, &ctx) != XE_ERROR;
|
||||
}
|
||||
|
||||
XAPI_LOCAL Xvoid CXAPI_setOnShutdownCB(onShutdownCB cb) {
|
||||
cxapiExports.onShutdown = cb;
|
||||
}
|
||||
|
||||
XAPI_LOCAL Xvoid CXAPI_setOnInitCB(onInitCB cb) {
|
||||
cxapiExports.onInit = cb;
|
||||
}
|
||||
|
||||
XAPI_LOCAL Xvoid CXAPI_setOnUpdateCB(onUpdateCB cb) {
|
||||
cxapiExports.onUpdate = cb;
|
||||
}
|
||||
|
||||
XAPI_LOCAL Xvoid CXAPI_logDebug(Xcstr msg) {
|
||||
XSEventLog log;
|
||||
log.channel = "default";
|
||||
log.msg = msg;
|
||||
log.severity = XE_EVENT_LOG_DEBUG;
|
||||
CXAPI_postEvent(XAPI_NULL, &log, XE_EVENT_TYPE_LOG);
|
||||
}
|
||||
|
||||
XHQEventBus CXAPI_createQEventBus(Xcstr name) {
|
||||
XHQEventBus qBus;
|
||||
if (device->vtbl->createQEventBus != XAPI_NULL) {
|
||||
XQEventBusDescriptor qBusdesc;
|
||||
qBusdesc.name = name;
|
||||
qBusdesc.maxSize = 0xFFFF;
|
||||
device->vtbl->createQEventBus(device, &qBus, qBusdesc);
|
||||
}
|
||||
else {
|
||||
qBus.idx = 0;
|
||||
}
|
||||
return qBus;
|
||||
}
|
||||
|
||||
Xuint32 CXAPI_postEvent(XHQEventBus* _qBus, Xvoid* event, Xconst Xuint64 type) {
|
||||
XHQEventBus thisQbus;
|
||||
if (_qBus == XAPI_NULL) {
|
||||
thisQbus.idx = qBus.idx;
|
||||
}
|
||||
else {
|
||||
thisQbus.idx = _qBus->idx;
|
||||
}
|
||||
return (ctx->vtbl->postEvent != XAPI_NULL) ? ctx->vtbl->postEvent(&thisQbus, event, type) : XE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
19
SampleMod/CXAPI.h
Normal file
19
SampleMod/CXAPI.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#define XAPI_USE_V1_0_0
|
||||
#include "XAPI.h"
|
||||
|
||||
typedef Xint32(XAPI_STDCALL onShutdownCB)(Xvoid);
|
||||
typedef Xint32(XAPI_STDCALL onInitCB)(Xvoid);
|
||||
typedef Xint32(XAPI_STDCALL onUpdateCB)(Xvoid);
|
||||
XAPI_LOCAL Xvoid initCXAPI();
|
||||
XAPI_LOCAL XAPIDescriptor queryCXAPIDescriptor();
|
||||
|
||||
XAPI_LOCAL XHQEventBus CXAPI_createQEventBus(Xcstr name);
|
||||
XAPI_LOCAL Xuint32 CXAPI_postEvent(XHQEventBus* qBus, Xvoid* event, Xconst Xuint64 type);
|
||||
|
||||
XAPI_LOCAL Xvoid CXAPI_logDebug(Xcstr msg);
|
||||
|
||||
XAPI_LOCAL Xvoid CXAPI_setOnShutdownCB(onShutdownCB cb);
|
||||
XAPI_LOCAL Xvoid CXAPI_setOnInitCB(onInitCB cb);
|
||||
XAPI_LOCAL Xvoid CXAPI_setOnUpdateCB(onUpdateCB cb);
|
||||
|
||||
34
SampleMod/MyMod.c
Normal file
34
SampleMod/MyMod.c
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "CXAPI.h"
|
||||
|
||||
XAPI_LOCAL Xint32 onInit(Xvoid);
|
||||
XAPI_LOCAL Xint32 onUpdate(Xvoid);
|
||||
XAPI_LOCAL Xint32 onShutdown(Xvoid);
|
||||
|
||||
XAPI_LOCAL XAPIDescriptor queryCXAPIDescriptor() {
|
||||
XAPIDescriptor desc;
|
||||
desc.author = "CDevJoud";
|
||||
desc.language = "C";
|
||||
desc.name = "My Mod!";
|
||||
desc.version = 1;
|
||||
desc.dependencies = "mce.core.*";
|
||||
return desc;
|
||||
}
|
||||
|
||||
XAPI_LOCAL Xvoid initCXAPI() {
|
||||
CXAPI_setOnInitCB(onInit);
|
||||
CXAPI_setOnUpdateCB(onUpdate);
|
||||
CXAPI_setOnShutdownCB(onShutdown);
|
||||
}
|
||||
|
||||
XAPI_LOCAL Xint32 onInit(Xvoid) {
|
||||
CXAPI_logDebug("Hello From MyMod!Joud!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
XAPI_LOCAL Xint32 onUpdate(Xvoid) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
XAPI_LOCAL Xint32 onShutdown(Xvoid) {
|
||||
return 1;
|
||||
}
|
||||
164
SampleMod/SampleMod.vcxproj
Normal file
164
SampleMod/SampleMod.vcxproj
Normal file
@@ -0,0 +1,164 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CXAPI.c" />
|
||||
<ClCompile Include="MyMod.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CXAPI.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{43a5cfef-b842-465d-94e5-b2af0bbaceae}</ProjectGuid>
|
||||
<RootNamespace>SampleMod</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IncludePath>$(SolutionDir)\Minecraft-Community-Edition\Mod\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IncludePath>$(SolutionDir)\Minecraft-Community-Edition\Mod\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IncludePath>$(SolutionDir)\Minecraft-Community-Edition\Mod\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>$(SolutionDir)\Minecraft-Community-Edition\Mod\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;SAMPLEMOD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;SAMPLEMOD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;SAMPLEMOD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp23</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;SAMPLEMOD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
30
SampleMod/SampleMod.vcxproj.filters
Normal file
30
SampleMod/SampleMod.vcxproj.filters
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CXAPI.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MyMod.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CXAPI.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
15
SampleModC#/SampleModC#.csproj
Normal file
15
SampleModC#/SampleModC#.csproj
Normal file
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseUwp>true</UseUwp>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<IsAotCompatible>true</IsAotCompatible>
|
||||
<DisableRuntimeMarshalling>true</DisableRuntimeMarshalling>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<BaseOutputPath>Z:\mce\x64</BaseOutputPath>
|
||||
<IlcExportUnmanagedEntrypoints>true</IlcExportUnmanagedEntrypoints>
|
||||
<PublishAot>true</PublishAot>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
254
SampleModC#/XAPI.cs
Normal file
254
SampleModC#/XAPI.cs
Normal file
@@ -0,0 +1,254 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
#pragma warning disable CS8500
|
||||
|
||||
// ==========================
|
||||
// BASIC TYPES
|
||||
// ==========================
|
||||
using Xint8 = System.SByte;
|
||||
using Xint16 = System.Int16;
|
||||
using Xint32 = System.Int32;
|
||||
using Xint64 = System.Int64;
|
||||
|
||||
using Xuint8 = System.Byte;
|
||||
using Xuint16 = System.UInt16;
|
||||
using Xuint32 = System.UInt32;
|
||||
using Xuint64 = System.UInt64;
|
||||
|
||||
// ==========================
|
||||
// CONSTANTS
|
||||
// ==========================
|
||||
public static class XE {
|
||||
public const Xuint32 ERROR = 0xDEADBEEF;
|
||||
public const Xuint64 EVENT_TYPE_LOG = 0xA2942192B2001D9E;
|
||||
public const Xuint8 EVENT_LOG_DEBUG = 0x07;
|
||||
}
|
||||
|
||||
// ==========================
|
||||
// STRUCTS
|
||||
// ==========================
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct XHQEventBus {
|
||||
public Xint64 idx;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct XQEventBusDescriptor {
|
||||
public Xint8* name;
|
||||
public Xuint16 maxSize;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct XSEventLog {
|
||||
public Xint8* channel;
|
||||
public Xint8* msg;
|
||||
public Xuint8 severity;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct XAPIDescriptor {
|
||||
public Xint8* name;
|
||||
public Xint8* author;
|
||||
public Xint32 version;
|
||||
public Xint8* language;
|
||||
public Xint8* sdkName;
|
||||
public Xint8* dependencies;
|
||||
}
|
||||
|
||||
// ==========================
|
||||
// FORWARD TYPES
|
||||
// ==========================
|
||||
public unsafe struct XIDevice {
|
||||
public XIDeviceVTable* vtbl;
|
||||
}
|
||||
|
||||
public unsafe struct XIContext {
|
||||
public XIContextVTable* vtbl;
|
||||
}
|
||||
|
||||
// ==========================
|
||||
// VTABLES
|
||||
// ==========================
|
||||
public unsafe struct XIDeviceVTable {
|
||||
public delegate* unmanaged[Stdcall]<XIDevice*, void> addRef;
|
||||
public delegate* unmanaged[Stdcall]<XIDevice*, void> release;
|
||||
public delegate* unmanaged[Stdcall]<XIDevice*, XHQEventBus*, XQEventBusDescriptor, Xint32> createQEventBus;
|
||||
public delegate* unmanaged[Stdcall]<XIDevice*, XIExports, void> setXIExports;
|
||||
|
||||
}
|
||||
|
||||
public unsafe struct XIContextVTable {
|
||||
public delegate* unmanaged[Stdcall]<XIContext*, void> addRef;
|
||||
public delegate* unmanaged[Stdcall]<XIContext*, void> release;
|
||||
|
||||
//public delegate* unmanaged[Stdcall]<XIExports, void> setXIExports;
|
||||
|
||||
public delegate* unmanaged[Stdcall]<XHQEventBus*, void*, Xuint64, Xuint32> postEvent;
|
||||
|
||||
public delegate* unmanaged[Stdcall]<XHQEventBus*, Xuint64, void*, Xuint32> subscribeEvent;
|
||||
}
|
||||
|
||||
// ==========================
|
||||
// EXPORT CALLBACKS
|
||||
// ==========================
|
||||
public unsafe struct XIExports {
|
||||
public delegate* unmanaged[Stdcall]<int> onShutdown;
|
||||
public delegate* unmanaged[Stdcall]<int> onUpdate;
|
||||
public delegate* unmanaged[Stdcall]<int> onInit;
|
||||
}
|
||||
|
||||
// ==========================
|
||||
// FUNCTION POINTER TYPES
|
||||
// ==========================
|
||||
public unsafe class XAPIFunctions {
|
||||
public delegate* unmanaged[Stdcall]<XIDevice**, XIContext**, Xint32> CreateDeviceAndContext;
|
||||
|
||||
public delegate* unmanaged[Stdcall]<XIDevice**, XIContext**, Xint32> DestroyDeviceAndContext;
|
||||
}
|
||||
|
||||
// ==========================
|
||||
// GLOBAL STATE
|
||||
// ==========================
|
||||
public unsafe static class CSX {
|
||||
public static XIDevice* device;
|
||||
public static XIContext* ctx;
|
||||
public static XHQEventBus qBus;
|
||||
|
||||
// ======================
|
||||
// INIT
|
||||
// ======================
|
||||
public static void Init(void* fn) {
|
||||
var create = (delegate* unmanaged[Stdcall]<XIDevice**, XIContext**, int>)fn;
|
||||
|
||||
XIDevice* dev = null;
|
||||
XIContext* context = null;
|
||||
|
||||
int ret = create(&dev, &context);
|
||||
if (ret == XE.ERROR)
|
||||
return;
|
||||
|
||||
// create default event bus
|
||||
XQEventBusDescriptor desc;
|
||||
desc.name = CString("APP");
|
||||
desc.maxSize = 0xFFFF;
|
||||
|
||||
device = dev;
|
||||
ctx = context;
|
||||
|
||||
XHQEventBus hQEventBus;
|
||||
|
||||
if (device != null) {
|
||||
if (device->vtbl != null) {
|
||||
if (device->vtbl->createQEventBus != null) {
|
||||
device->vtbl->createQEventBus(device, &hQEventBus, desc);
|
||||
qBus = hQEventBus;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ======================
|
||||
// LOGGING
|
||||
// ======================
|
||||
public static void LogDebug(string msg) {
|
||||
XSEventLog log;
|
||||
|
||||
log.channel = CString("default");
|
||||
log.msg = CString(msg);
|
||||
log.severity = XE.EVENT_LOG_DEBUG;
|
||||
|
||||
PostEvent(null, &log, XE.EVENT_TYPE_LOG);
|
||||
}
|
||||
|
||||
// ======================
|
||||
// EVENTS
|
||||
// ======================
|
||||
public static Xuint32 PostEvent(XHQEventBus* bus, void* ev, Xuint64 type) {
|
||||
XHQEventBus target;
|
||||
|
||||
if (bus == null)
|
||||
target = qBus;
|
||||
else
|
||||
target = *bus;
|
||||
|
||||
return ctx->vtbl->postEvent(&target, ev, type);
|
||||
}
|
||||
|
||||
// ======================
|
||||
// STRING HELPER
|
||||
// ======================
|
||||
public static sbyte* CString(string s) {
|
||||
byte[] bytes = Encoding.ASCII.GetBytes(s + "\0");
|
||||
fixed (byte* p = bytes)
|
||||
return (sbyte*)p;
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================
|
||||
// EXAMPLE MOD IMPLEMENTATION
|
||||
// ==========================
|
||||
public unsafe static class MyMod {
|
||||
// callbacks
|
||||
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })]
|
||||
public static int OnInit() {
|
||||
CSX.LogDebug("Hello from C# XAPI mod!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })]
|
||||
public static int OnUpdate() {
|
||||
//CSX.LogDebug("This is Update");
|
||||
return 1;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })]
|
||||
public static int OnShutdown() {
|
||||
return 1;
|
||||
}
|
||||
static XIExports exp;
|
||||
// ======================
|
||||
// EXPORTS
|
||||
// ======================
|
||||
[UnmanagedCallersOnly(EntryPoint = "XI_main")]
|
||||
public static int XI_main(void* p) {
|
||||
CSX.Init(p);
|
||||
|
||||
exp.onInit = &OnInit;
|
||||
exp.onUpdate = &OnUpdate;
|
||||
exp.onShutdown = &OnShutdown;
|
||||
|
||||
CSX.device->vtbl->setXIExports(CSX.device, exp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly(EntryPoint = "XI_query", CallConvs = new[] { typeof(CallConvStdcall) })]
|
||||
public static XAPIDescriptor XI_query() {
|
||||
XAPIDescriptor desc;
|
||||
|
||||
desc.name = CSX.CString("C# Mod");
|
||||
desc.author = CSX.CString("CDevJoud");
|
||||
desc.version = 1;
|
||||
desc.language = CSX.CString("C#");
|
||||
desc.sdkName = CSX.CString("XAPI-CS");
|
||||
desc.dependencies = CSX.CString("mce.core.*");
|
||||
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly(EntryPoint = "XI_terminate")]
|
||||
public static void XI_terminate(void* p) {
|
||||
var destroy = (delegate* unmanaged[Stdcall]<XIDevice**, XIContext**, int>)p;
|
||||
XIDevice* dev = null;
|
||||
XIContext* context = null;
|
||||
destroy(&dev, &context);
|
||||
|
||||
CSX.device = dev;
|
||||
CSX.ctx = context;
|
||||
}
|
||||
}
|
||||
28
SampleModCpp/MyMod.cpp
Normal file
28
SampleModCpp/MyMod.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "XPP.hpp"
|
||||
|
||||
class MyMod : public IXPP {
|
||||
public:
|
||||
MyMod();
|
||||
~MyMod();
|
||||
XAPIDescriptor query() override {
|
||||
return XAPIDescriptor();
|
||||
}
|
||||
int onInit() override {
|
||||
XPP::logDebug("Hello C++");
|
||||
return 1;
|
||||
}
|
||||
int onUpdate() override {
|
||||
return 1;
|
||||
}
|
||||
int onShutdown() override {
|
||||
return 1;
|
||||
}
|
||||
}mod;
|
||||
|
||||
MyMod::MyMod() {
|
||||
XPP::initXPP(&mod);
|
||||
}
|
||||
|
||||
MyMod::~MyMod() {
|
||||
|
||||
}
|
||||
155
SampleModCpp/SampleModCpp.vcxproj
Normal file
155
SampleModCpp/SampleModCpp.vcxproj
Normal file
@@ -0,0 +1,155 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="MyMod.cpp" />
|
||||
<ClCompile Include="XPP.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="XPP.hpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{62121dc8-0ebd-43f8-8d30-85db30a3574d}</ProjectGuid>
|
||||
<RootNamespace>SampleModCpp</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IncludePath>$(SolutionDir)\Minecraft-Community-Edition\Mod\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IncludePath>$(SolutionDir)\Minecraft-Community-Edition\Mod\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;SAMPLEMODCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;SAMPLEMODCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;SAMPLEMODCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp23</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;SAMPLEMODCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp23</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
30
SampleModCpp/SampleModCpp.vcxproj.filters
Normal file
30
SampleModCpp/SampleModCpp.vcxproj.filters
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="MyMod.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="XPP.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="XPP.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
124
SampleModCpp/XPP.cpp
Normal file
124
SampleModCpp/XPP.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include "XPP.hpp"
|
||||
|
||||
IXPP* XPP::_instance;
|
||||
XI_createDeviceAndContextFn XI_createDeviceAndContext;
|
||||
XI_destroyDeviceAndContextFn XI_destroyDeviceAndContext;
|
||||
XHQEventBus qBus;
|
||||
XIDevice* device;
|
||||
XIContext* ctx;
|
||||
XIExports exports;
|
||||
|
||||
XPP& XPP::getSingleton() {
|
||||
static XPP xpp;
|
||||
return xpp;
|
||||
}
|
||||
|
||||
void XPP::initXPP(IXPP* instance) {
|
||||
_instance = instance;
|
||||
}
|
||||
|
||||
void XPP::logDebug(const std::string& msg) {
|
||||
XSEventLog log;
|
||||
log.channel = "default";
|
||||
log.msg = msg.c_str();
|
||||
log.severity = XE_EVENT_LOG_DEBUG;
|
||||
XPP::postEvent(nullptr, &log, XE_EVENT_TYPE_LOG);
|
||||
}
|
||||
|
||||
IXPP* XPP::getModInstance() {
|
||||
return _instance;
|
||||
}
|
||||
XHQEventBus CXAPI_createQEventBus(Xcstr name) {
|
||||
XHQEventBus qBus;
|
||||
if (device->vtbl->createQEventBus != XAPI_NULL) {
|
||||
XQEventBusDescriptor qBusdesc;
|
||||
qBusdesc.name = name;
|
||||
qBusdesc.maxSize = 0xFFFF;
|
||||
device->vtbl->createQEventBus(device, &qBus, qBusdesc);
|
||||
}
|
||||
else {
|
||||
qBus.idx = 0;
|
||||
}
|
||||
return qBus;
|
||||
}
|
||||
XHQEventBus XPP::createQEventBus(const std::string& name) {
|
||||
XHQEventBus qBus;
|
||||
if (device->vtbl->createQEventBus != XAPI_NULL) {
|
||||
XQEventBusDescriptor qBusDesc;
|
||||
qBusDesc.name = name.c_str();
|
||||
qBusDesc.maxSize = 0xFFFF;
|
||||
device->vtbl->createQEventBus(device, &qBus, qBusDesc);
|
||||
}
|
||||
else {
|
||||
qBus.idx = 0;
|
||||
}
|
||||
return qBus;
|
||||
}
|
||||
|
||||
int XPP::postEvent(XHQEventBus* _qBus, Xvoid* event, Xconst Xuint64 type) {
|
||||
XHQEventBus thisQbus;
|
||||
if (_qBus == XAPI_NULL) {
|
||||
thisQbus.idx = qBus.idx;
|
||||
}
|
||||
else {
|
||||
thisQbus.idx = _qBus->idx;
|
||||
}
|
||||
return (ctx->vtbl->postEvent != XAPI_NULL) ? ctx->vtbl->postEvent(&thisQbus, event, type) : XE_ERROR;
|
||||
}
|
||||
|
||||
extern "C" XAPI_EXPORT XAPIDescriptor XI_query(Xvoid) {
|
||||
auto& instance = XPP::getSingleton();
|
||||
auto desc = instance.getModInstance()->query();
|
||||
desc.sdkName = "XPP";
|
||||
return desc;
|
||||
}
|
||||
|
||||
extern "C" XAPI_EXPORT Xint32 XI_main(Xvoid* pParam) {
|
||||
XI_createDeviceAndContext = (XI_createDeviceAndContextFn)pParam;
|
||||
Xconst Xint32 ret = XI_createDeviceAndContext(&device, &ctx);
|
||||
|
||||
if (ret != XE_ERROR) {
|
||||
|
||||
if (device != XAPI_NULL && ctx != XAPI_NULL) {
|
||||
if (device->vtbl != XAPI_NULL && ctx->vtbl != XAPI_NULL) {
|
||||
if (device->vtbl->createQEventBus != XAPI_NULL) {
|
||||
XQEventBusDescriptor desc{};
|
||||
desc.maxSize = 0xFFFF;
|
||||
desc.name = "APP";
|
||||
device->vtbl->createQEventBus(device, &qBus, desc);
|
||||
}
|
||||
else {
|
||||
return XE_ERROR;
|
||||
}
|
||||
|
||||
exports.onInit = []() -> Xint32 {return XPP::getSingleton().getModInstance()->onInit(); };
|
||||
exports.onUpdate = []() -> Xint32 {return XPP::getSingleton().getModInstance()->onUpdate(); };
|
||||
exports.onShutdown = []() -> Xint32 {return XPP::getSingleton().getModInstance()->onShutdown(); };
|
||||
|
||||
if (device->vtbl->setXIExports != XAPI_NULL) {
|
||||
device->vtbl->setXIExports(device, exports);
|
||||
}
|
||||
else {
|
||||
return XE_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return XE_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return XE_ERROR;
|
||||
}
|
||||
}
|
||||
XPP::getSingleton().logDebug("XPP loaded up successfully! XAPI version v1.0.0");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
extern "C" XAPI_EXPORT Xint32 XI_terminate(Xvoid* pParam) {
|
||||
XI_destroyDeviceAndContext = (XI_destroyDeviceAndContextFn)pParam;
|
||||
|
||||
auto ret = XI_destroyDeviceAndContext(&device, &ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
28
SampleModCpp/XPP.hpp
Normal file
28
SampleModCpp/XPP.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#define XAPI_USE_V1_0_0
|
||||
#include "XAPI.h"
|
||||
#include <string>
|
||||
|
||||
class IXPP {
|
||||
public:
|
||||
virtual ~IXPP() {
|
||||
|
||||
}
|
||||
virtual XAPIDescriptor query() = 0;
|
||||
virtual int onInit() = 0;
|
||||
virtual int onUpdate() = 0;
|
||||
virtual int onShutdown() = 0;
|
||||
};
|
||||
|
||||
class XPP {
|
||||
public:
|
||||
static XPP& getSingleton();
|
||||
static void initXPP(IXPP* instance);
|
||||
static void logDebug(const std::string& msg);
|
||||
static IXPP* getModInstance();
|
||||
static XHQEventBus createQEventBus(const std::string& name);
|
||||
static int postEvent(XHQEventBus* _qBus, Xvoid* event, Xconst Xuint64 type);
|
||||
private:
|
||||
static IXPP* _instance;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user