2024-01-08 10:54:14 +08:00
|
|
|
import ctypes, os, sys, typing
|
2023-11-02 22:02:39 +08:00
|
|
|
|
|
|
|
#region Type Defines
|
|
|
|
|
2023-11-04 21:58:58 +08:00
|
|
|
class BMapException(Exception):
|
|
|
|
"""
|
|
|
|
The exception thrown by BMap bindings.
|
|
|
|
"""
|
|
|
|
pass
|
|
|
|
|
2023-11-02 22:02:39 +08:00
|
|
|
bm_CKSTRING = ctypes.c_char_p
|
|
|
|
bm_CKSTRING_p = ctypes.POINTER(bm_CKSTRING)
|
|
|
|
bm_CKDWORD = ctypes.c_uint32
|
|
|
|
bm_CKDWORD_p = ctypes.POINTER(bm_CKDWORD)
|
2023-11-03 10:43:06 +08:00
|
|
|
bm_CKDWORD_pp = ctypes.POINTER(bm_CKDWORD_p)
|
2023-11-02 22:02:39 +08:00
|
|
|
bm_CKWORD = ctypes.c_uint16
|
|
|
|
bm_CKWORD_p = ctypes.POINTER(bm_CKWORD)
|
2023-11-03 10:43:06 +08:00
|
|
|
bm_CKWORD_pp = ctypes.POINTER(bm_CKWORD_p)
|
2023-11-02 22:02:39 +08:00
|
|
|
bm_CKID = ctypes.c_uint32
|
|
|
|
bm_CKID_p = ctypes.POINTER(bm_CKID)
|
2023-11-03 10:43:06 +08:00
|
|
|
bm_CKID_pp = ctypes.POINTER(bm_CKID_p)
|
2023-11-02 22:02:39 +08:00
|
|
|
bm_CKFLOAT = ctypes.c_float
|
|
|
|
bm_CKFLOAT_p = ctypes.POINTER(bm_CKFLOAT)
|
2023-11-03 10:43:06 +08:00
|
|
|
bm_CKINT = ctypes.c_int32
|
|
|
|
bm_CKBYTE = ctypes.c_uint8
|
|
|
|
bm_CKBYTE_p = ctypes.POINTER(bm_CKBYTE)
|
2023-11-02 22:02:39 +08:00
|
|
|
|
|
|
|
bm_enum = bm_CKDWORD
|
2023-11-03 10:43:06 +08:00
|
|
|
bm_enum_p = ctypes.POINTER(bm_enum)
|
2023-11-02 22:02:39 +08:00
|
|
|
bm_bool = ctypes.c_bool
|
2023-11-03 10:43:06 +08:00
|
|
|
bm_bool_p = ctypes.POINTER(bm_bool)
|
2023-11-02 22:02:39 +08:00
|
|
|
bm_void_p = ctypes.c_void_p
|
2023-11-03 10:43:06 +08:00
|
|
|
bm_void_pp = ctypes.POINTER(ctypes.c_void_p)
|
2023-11-02 22:02:39 +08:00
|
|
|
|
2023-11-15 21:47:58 +08:00
|
|
|
bm_callback = ctypes.CFUNCTYPE(None, bm_CKSTRING)
|
|
|
|
|
2023-11-02 22:02:39 +08:00
|
|
|
class bm_VxVector2(ctypes.Structure):
|
|
|
|
_fields_ = [
|
|
|
|
('x', bm_CKFLOAT),
|
|
|
|
('y', bm_CKFLOAT),
|
|
|
|
]
|
|
|
|
bm_VxVector2_p = ctypes.POINTER(bm_VxVector2)
|
2023-11-03 10:43:06 +08:00
|
|
|
bm_VxVector2_pp = ctypes.POINTER(bm_VxVector2_p)
|
2023-11-02 22:02:39 +08:00
|
|
|
class bm_VxVector3(ctypes.Structure):
|
|
|
|
_fields_ = [
|
|
|
|
('x', bm_CKFLOAT),
|
|
|
|
('y', bm_CKFLOAT),
|
|
|
|
('z', bm_CKFLOAT),
|
|
|
|
]
|
|
|
|
bm_VxVector3_p = ctypes.POINTER(bm_VxVector3)
|
2023-11-10 12:23:03 +08:00
|
|
|
bm_VxVector3_pp = ctypes.POINTER(bm_VxVector3_p)
|
2023-11-03 10:43:06 +08:00
|
|
|
class bm_VxColor(ctypes.Structure):
|
|
|
|
_fields_ = [
|
|
|
|
('r', bm_CKFLOAT),
|
|
|
|
('g', bm_CKFLOAT),
|
|
|
|
('b', bm_CKFLOAT),
|
|
|
|
('a', bm_CKFLOAT),
|
|
|
|
]
|
|
|
|
bm_VxColor_p = ctypes.POINTER(bm_VxColor)
|
2023-11-02 22:02:39 +08:00
|
|
|
class bm_VxMatrix(ctypes.Structure):
|
|
|
|
_fields_ = list(
|
|
|
|
(f'i{idx}', bm_CKFLOAT) for idx in range(16)
|
|
|
|
)
|
2023-11-03 10:43:06 +08:00
|
|
|
bm_VxMatrix_p = ctypes.POINTER(bm_VxMatrix)
|
2023-11-02 22:02:39 +08:00
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region BMap Loader
|
|
|
|
|
2023-11-16 21:11:36 +08:00
|
|
|
_g_BMapLibName: str
|
|
|
|
|
|
|
|
if sys.platform.startswith('win32') or sys.platform.startswith('cygwin'):
|
|
|
|
_g_BMapLibName = "BMap.dll"
|
|
|
|
elif sys.platform.startswith('linux') or sys.platform.startswith('freebsd'):
|
|
|
|
_g_BMapLibName = "BMap.so"
|
|
|
|
elif sys.platform.startswith('darwin'):
|
|
|
|
_g_BMapLibName = "BMap.dylib"
|
|
|
|
else:
|
|
|
|
_g_BMapLibName = "BMap.bin"
|
|
|
|
|
2023-12-03 18:15:05 +08:00
|
|
|
_g_BMapModule: ctypes.CDLL | None = None
|
2023-11-02 22:02:39 +08:00
|
|
|
try:
|
|
|
|
_g_BMapModule = ctypes.cdll.LoadLibrary(
|
2023-11-16 21:11:36 +08:00
|
|
|
os.path.join(os.path.dirname(__file__), _g_BMapLibName)
|
2023-11-02 22:02:39 +08:00
|
|
|
)
|
|
|
|
except:
|
|
|
|
_g_BMapModule = None
|
|
|
|
|
|
|
|
def is_bmap_available() -> bool:
|
|
|
|
return _g_BMapModule is not None
|
|
|
|
|
2024-01-08 10:54:14 +08:00
|
|
|
def _bmap_error_check(result: bool, func, args):
|
2023-11-05 10:44:11 +08:00
|
|
|
if not result:
|
2023-11-04 21:58:58 +08:00
|
|
|
raise BMapException("BMap operation failed.")
|
|
|
|
return result
|
|
|
|
|
2024-01-08 10:54:14 +08:00
|
|
|
def _create_bmap_func(fct_name: str, fct_params: list[typing.Any]) -> typing.Callable[..., bm_bool]:
|
2023-11-02 22:02:39 +08:00
|
|
|
if _g_BMapModule is None: return None
|
|
|
|
|
2024-01-08 10:54:14 +08:00
|
|
|
cache: typing.Callable[..., bm_bool] = getattr(_g_BMapModule, fct_name)
|
2023-11-02 22:02:39 +08:00
|
|
|
cache.argtypes = fct_params
|
|
|
|
cache.restype = bm_bool
|
2023-11-04 21:58:58 +08:00
|
|
|
cache.errcheck = _bmap_error_check
|
2023-11-02 22:02:39 +08:00
|
|
|
return cache
|
|
|
|
|
|
|
|
#endregion
|