Merge pull request #1946 from RadWolfie/line-ending-renormalize

Setup Force Source Files to LF Line Ending and Renormalize
This commit is contained in:
Luke Usher 2020-08-23 14:58:19 +01:00 committed by GitHub
commit ffe3b95323
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
136 changed files with 49428 additions and 49428 deletions

20
.gitattributes vendored
View File

@ -1,11 +1,3 @@
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
@ -18,5 +10,13 @@
*.rtf diff=astextplain
*.RTF diff=astextplain
[Cc][Mm]ake[Ll]ists.txt text=lf
*.bat text=lf
* text=auto
[Cc][Mm]ake[Ll]ists.txt text eol=lf
*.bat text eol=lf
*.c text eol=lf
*.h text eol=lf
*.cpp text eol=lf
*.hpp text eol=lf
*.unused-patches text eol=lf
*.rc text eol=lf

View File

@ -1,220 +1,220 @@
// ******************************************************************
// *
// * proj : OpenXDK
// *
// * desc : Open Source XBox Development Kit
// *
// * file : ob.h
// *
// * note : XBox Kernel *Object Manager* Declarations
// *
// ******************************************************************
#ifndef XBOXKRNL_OB_H
#define XBOXKRNL_OB_H
#define OBJ_NAME_PATH_SEPARATOR ((CHAR)L'\\')
#define OB_NUMBER_HASH_BUCKETS 11
typedef struct _OBJECT_DIRECTORY {
struct _OBJECT_HEADER_NAME_INFO *HashBuckets[OB_NUMBER_HASH_BUCKETS];
} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;
typedef struct _OBJECT_SYMBOLIC_LINK {
PVOID LinkTargetObject;
OBJECT_STRING LinkTarget;
} OBJECT_SYMBOLIC_LINK, *POBJECT_SYMBOLIC_LINK;
typedef struct _OBJECT_HEADER_NAME_INFO {
struct _OBJECT_HEADER_NAME_INFO *ChainLink;
struct _OBJECT_DIRECTORY *Directory;
OBJECT_STRING Name;
} OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;
#define ObDosDevicesDirectory() ((HANDLE)-3)
#define ObWin32NamedObjectsDirectory() ((HANDLE)-4)
#define ObpIsFlagSet(flagset, flag) (((flagset) & (flag)) != 0)
#define ObpIsFlagClear(flagset, flag) (((flagset) & (flag)) == 0)
#define ObpEncodeFreeHandleLink(Link) (((ULONG_PTR)(Link)) | 1)
#define ObpDecodeFreeHandleLink(Link) (((ULONG_PTR)(Link)) & (~1))
#define ObpIsFreeHandleLink(Link) (((ULONG_PTR)(Link)) & 1)
#define ObpGetTableByteOffsetFromHandle(Handle) (HandleToUlong(Handle) & (OB_HANDLES_PER_TABLE * sizeof(PVOID) - 1))
#define ObpGetTableFromHandle(Handle) ObpObjectHandleTable.RootTable[HandleToUlong(Handle) >> (OB_HANDLES_PER_TABLE_SHIFT + 2)]
#define ObpGetHandleContentsPointer(Handle) ((PVOID*)((PUCHAR)ObpGetTableFromHandle(Handle) + ObpGetTableByteOffsetFromHandle(Handle)))
#define ObpMaskOffApplicationBits(Handle) ((HANDLE)(((ULONG_PTR)(Handle)) & ~(sizeof(ULONG) - 1)))
#define OB_FLAG_NAMED_OBJECT 0x01
#define OB_FLAG_PERMANENT_OBJECT 0x02
#define OB_FLAG_ATTACHED_OBJECT 0x04
#define OBJECT_TO_OBJECT_HEADER(Object) CONTAINING_RECORD(Object, OBJECT_HEADER, Body)
#define OBJECT_TO_OBJECT_HEADER_NAME_INFO(Object) ((POBJECT_HEADER_NAME_INFO)OBJECT_TO_OBJECT_HEADER(Object) - 1)
#define OBJECT_HEADER_NAME_INFO_TO_OBJECT_HEADER(ObjectHeaderNameInfo) ((POBJECT_HEADER)((POBJECT_HEADER_NAME_INFO)(ObjectHeaderNameInfo)+1))
#define OBJECT_HEADER_TO_OBJECT_HEADER_NAME_INFO(ObjectHeader) ((POBJECT_HEADER_NAME_INFO)(ObjectHeader)-1)
#define OBJECT_HEADER_NAME_INFO_TO_OBJECT(ObjectHeaderNameInfo) (&OBJECT_HEADER_NAME_INFO_TO_OBJECT_HEADER(ObjectHeaderNameInfo)->Body)
HANDLE ObpCreateObjectHandle(PVOID Object);
BOOLEAN ObpCreatePermanentDirectoryObject(
IN POBJECT_STRING DirectoryName OPTIONAL,
OUT POBJECT_DIRECTORY *DirectoryObject
);
NTSTATUS ObpReferenceObjectByName(
IN HANDLE RootDirectoryHandle,
IN POBJECT_STRING ObjectName,
IN ULONG Attributes,
IN POBJECT_TYPE ObjectType,
IN OUT PVOID ParseContext OPTIONAL,
OUT PVOID *ReturnedObject
);
#define XB_InitializeObjectAttributes(p, n, a, r, s){\
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
}
BOOLEAN ObInitSystem();
BOOLEAN ObpExtendObjectHandleTable();
VOID ObDissectName(OBJECT_STRING Path, POBJECT_STRING FirstName, POBJECT_STRING RemainingName);
PVOID ObpGetObjectHandleContents(HANDLE Handle);
PVOID ObpGetObjectHandleReference(HANDLE Handle);
ULONG FASTCALL ObpComputeHashIndex(IN POBJECT_STRING ElementName);
BOOLEAN ObpLookupElementNameInDirectory(
IN POBJECT_DIRECTORY Directory,
IN POBJECT_STRING ElementName,
IN BOOLEAN ResolveSymbolicLink,
OUT PVOID *ReturnedObject
);
// ******************************************************************
// * 0x00EF - ObCreateObject()
// ******************************************************************
XBSYSAPI EXPORTNUM(239) NTSTATUS NTAPI ObCreateObject
(
IN POBJECT_TYPE ObjectType,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN ULONG ObjectBodySize,
OUT PVOID *Object
);
// ******************************************************************
// * 0x00F0 - ObDirectoryObjectType
// ******************************************************************
XBSYSAPI EXPORTNUM(240) OBJECT_TYPE ObDirectoryObjectType;
// ******************************************************************
// * 0x00F1 - ObInsertObject()
// ******************************************************************
XBSYSAPI EXPORTNUM(241) NTSTATUS NTAPI ObInsertObject
(
IN PVOID Object,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN ULONG ObjectPointerBias,
OUT PHANDLE Handle
);
// ******************************************************************
// * 0x00F2 - ObMakeTemporaryObject()
// ******************************************************************
XBSYSAPI EXPORTNUM(242) VOID NTAPI ObMakeTemporaryObject
(
IN PVOID Object
);
// ******************************************************************
// * 0x00F3 - ObOpenObjectByName()
// ******************************************************************
XBSYSAPI EXPORTNUM(243) NTSTATUS NTAPI ObOpenObjectByName
(
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN POBJECT_TYPE ObjectType,
IN OUT PVOID ParseContext OPTIONAL,
OUT PHANDLE Handle
);
// ******************************************************************
// * 0x00F4 - ObOpenObjectByPointer()
// ******************************************************************
XBSYSAPI EXPORTNUM(244) NTSTATUS NTAPI ObOpenObjectByPointer
(
IN PVOID Object,
IN POBJECT_TYPE ObjectType,
OUT PHANDLE Handle
);
#define OB_HANDLES_PER_TABLE_SHIFT 6
#define OB_HANDLES_PER_TABLE (1 << OB_HANDLES_PER_TABLE_SHIFT)
#define OB_TABLES_PER_SEGMENT 8
#define OB_HANDLES_PER_SEGMENT (OB_TABLES_PER_SEGMENT * OB_HANDLES_PER_TABLE)
typedef struct _OBJECT_HANDLE_TABLE {
LONG HandleCount;
LONG_PTR FirstFreeTableEntry;
HANDLE NextHandleNeedingPool;
PVOID **RootTable;
PVOID *BuiltinRootTable[OB_TABLES_PER_SEGMENT];
} OBJECT_HANDLE_TABLE, *POBJECT_HANDLE_TABLE;
// ******************************************************************
// * 0x00F5 - ObpObjectHandleTable
// ******************************************************************
XBSYSAPI EXPORTNUM(245) OBJECT_HANDLE_TABLE ObpObjectHandleTable;
// ******************************************************************
// * 0x00F6 - ObReferenceObjectByHandle()
// ******************************************************************
XBSYSAPI EXPORTNUM(246) NTSTATUS NTAPI ObReferenceObjectByHandle
(
IN HANDLE Handle,
IN POBJECT_TYPE ObjectType OPTIONAL,
OUT PVOID *ReturnedObject
);
// ******************************************************************
// * 0x00F7 - ObReferenceObjectByName()
// ******************************************************************
XBSYSAPI EXPORTNUM(247) NTSTATUS NTAPI ObReferenceObjectByName
(
IN POBJECT_STRING ObjectName,
IN ULONG Attributes,
IN POBJECT_TYPE ObjectType,
IN OUT PVOID ParseContext OPTIONAL,
OUT PVOID *Object
);
// ******************************************************************
// * 0x00F8 - ObReferenceObjectByPointer()
// ******************************************************************
XBSYSAPI EXPORTNUM(248) NTSTATUS NTAPI ObReferenceObjectByPointer
(
IN PVOID Object,
IN POBJECT_TYPE ObjectType
);
// ******************************************************************
// * 0x00F9 - ObSymbolicLinkObjectType
// ******************************************************************
XBSYSAPI EXPORTNUM(249) OBJECT_TYPE ObSymbolicLinkObjectType;
// ******************************************************************
// * 0x00FA - ObfDereferenceObject()
// ******************************************************************
XBSYSAPI EXPORTNUM(250) VOID FASTCALL ObfDereferenceObject
(
IN PVOID Object
);
// ******************************************************************
// * 0x00FB - ObfReferenceObject()
// ******************************************************************
XBSYSAPI EXPORTNUM(251) VOID FASTCALL ObfReferenceObject
(
IN PVOID Object
);
#endif
// ******************************************************************
// *
// * proj : OpenXDK
// *
// * desc : Open Source XBox Development Kit
// *
// * file : ob.h
// *
// * note : XBox Kernel *Object Manager* Declarations
// *
// ******************************************************************
#ifndef XBOXKRNL_OB_H
#define XBOXKRNL_OB_H
#define OBJ_NAME_PATH_SEPARATOR ((CHAR)L'\\')
#define OB_NUMBER_HASH_BUCKETS 11
typedef struct _OBJECT_DIRECTORY {
struct _OBJECT_HEADER_NAME_INFO *HashBuckets[OB_NUMBER_HASH_BUCKETS];
} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;
typedef struct _OBJECT_SYMBOLIC_LINK {
PVOID LinkTargetObject;
OBJECT_STRING LinkTarget;
} OBJECT_SYMBOLIC_LINK, *POBJECT_SYMBOLIC_LINK;
typedef struct _OBJECT_HEADER_NAME_INFO {
struct _OBJECT_HEADER_NAME_INFO *ChainLink;
struct _OBJECT_DIRECTORY *Directory;
OBJECT_STRING Name;
} OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;
#define ObDosDevicesDirectory() ((HANDLE)-3)
#define ObWin32NamedObjectsDirectory() ((HANDLE)-4)
#define ObpIsFlagSet(flagset, flag) (((flagset) & (flag)) != 0)
#define ObpIsFlagClear(flagset, flag) (((flagset) & (flag)) == 0)
#define ObpEncodeFreeHandleLink(Link) (((ULONG_PTR)(Link)) | 1)
#define ObpDecodeFreeHandleLink(Link) (((ULONG_PTR)(Link)) & (~1))
#define ObpIsFreeHandleLink(Link) (((ULONG_PTR)(Link)) & 1)
#define ObpGetTableByteOffsetFromHandle(Handle) (HandleToUlong(Handle) & (OB_HANDLES_PER_TABLE * sizeof(PVOID) - 1))
#define ObpGetTableFromHandle(Handle) ObpObjectHandleTable.RootTable[HandleToUlong(Handle) >> (OB_HANDLES_PER_TABLE_SHIFT + 2)]
#define ObpGetHandleContentsPointer(Handle) ((PVOID*)((PUCHAR)ObpGetTableFromHandle(Handle) + ObpGetTableByteOffsetFromHandle(Handle)))
#define ObpMaskOffApplicationBits(Handle) ((HANDLE)(((ULONG_PTR)(Handle)) & ~(sizeof(ULONG) - 1)))
#define OB_FLAG_NAMED_OBJECT 0x01
#define OB_FLAG_PERMANENT_OBJECT 0x02
#define OB_FLAG_ATTACHED_OBJECT 0x04
#define OBJECT_TO_OBJECT_HEADER(Object) CONTAINING_RECORD(Object, OBJECT_HEADER, Body)
#define OBJECT_TO_OBJECT_HEADER_NAME_INFO(Object) ((POBJECT_HEADER_NAME_INFO)OBJECT_TO_OBJECT_HEADER(Object) - 1)
#define OBJECT_HEADER_NAME_INFO_TO_OBJECT_HEADER(ObjectHeaderNameInfo) ((POBJECT_HEADER)((POBJECT_HEADER_NAME_INFO)(ObjectHeaderNameInfo)+1))
#define OBJECT_HEADER_TO_OBJECT_HEADER_NAME_INFO(ObjectHeader) ((POBJECT_HEADER_NAME_INFO)(ObjectHeader)-1)
#define OBJECT_HEADER_NAME_INFO_TO_OBJECT(ObjectHeaderNameInfo) (&OBJECT_HEADER_NAME_INFO_TO_OBJECT_HEADER(ObjectHeaderNameInfo)->Body)
HANDLE ObpCreateObjectHandle(PVOID Object);
BOOLEAN ObpCreatePermanentDirectoryObject(
IN POBJECT_STRING DirectoryName OPTIONAL,
OUT POBJECT_DIRECTORY *DirectoryObject
);
NTSTATUS ObpReferenceObjectByName(
IN HANDLE RootDirectoryHandle,
IN POBJECT_STRING ObjectName,
IN ULONG Attributes,
IN POBJECT_TYPE ObjectType,
IN OUT PVOID ParseContext OPTIONAL,
OUT PVOID *ReturnedObject
);
#define XB_InitializeObjectAttributes(p, n, a, r, s){\
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
}
BOOLEAN ObInitSystem();
BOOLEAN ObpExtendObjectHandleTable();
VOID ObDissectName(OBJECT_STRING Path, POBJECT_STRING FirstName, POBJECT_STRING RemainingName);
PVOID ObpGetObjectHandleContents(HANDLE Handle);
PVOID ObpGetObjectHandleReference(HANDLE Handle);
ULONG FASTCALL ObpComputeHashIndex(IN POBJECT_STRING ElementName);
BOOLEAN ObpLookupElementNameInDirectory(
IN POBJECT_DIRECTORY Directory,
IN POBJECT_STRING ElementName,
IN BOOLEAN ResolveSymbolicLink,
OUT PVOID *ReturnedObject
);
// ******************************************************************
// * 0x00EF - ObCreateObject()
// ******************************************************************
XBSYSAPI EXPORTNUM(239) NTSTATUS NTAPI ObCreateObject
(
IN POBJECT_TYPE ObjectType,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN ULONG ObjectBodySize,
OUT PVOID *Object
);
// ******************************************************************
// * 0x00F0 - ObDirectoryObjectType
// ******************************************************************
XBSYSAPI EXPORTNUM(240) OBJECT_TYPE ObDirectoryObjectType;
// ******************************************************************
// * 0x00F1 - ObInsertObject()
// ******************************************************************
XBSYSAPI EXPORTNUM(241) NTSTATUS NTAPI ObInsertObject
(
IN PVOID Object,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN ULONG ObjectPointerBias,
OUT PHANDLE Handle
);
// ******************************************************************
// * 0x00F2 - ObMakeTemporaryObject()
// ******************************************************************
XBSYSAPI EXPORTNUM(242) VOID NTAPI ObMakeTemporaryObject
(
IN PVOID Object
);
// ******************************************************************
// * 0x00F3 - ObOpenObjectByName()
// ******************************************************************
XBSYSAPI EXPORTNUM(243) NTSTATUS NTAPI ObOpenObjectByName
(
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN POBJECT_TYPE ObjectType,
IN OUT PVOID ParseContext OPTIONAL,
OUT PHANDLE Handle
);
// ******************************************************************
// * 0x00F4 - ObOpenObjectByPointer()
// ******************************************************************
XBSYSAPI EXPORTNUM(244) NTSTATUS NTAPI ObOpenObjectByPointer
(
IN PVOID Object,
IN POBJECT_TYPE ObjectType,
OUT PHANDLE Handle
);
#define OB_HANDLES_PER_TABLE_SHIFT 6
#define OB_HANDLES_PER_TABLE (1 << OB_HANDLES_PER_TABLE_SHIFT)
#define OB_TABLES_PER_SEGMENT 8
#define OB_HANDLES_PER_SEGMENT (OB_TABLES_PER_SEGMENT * OB_HANDLES_PER_TABLE)
typedef struct _OBJECT_HANDLE_TABLE {
LONG HandleCount;
LONG_PTR FirstFreeTableEntry;
HANDLE NextHandleNeedingPool;
PVOID **RootTable;
PVOID *BuiltinRootTable[OB_TABLES_PER_SEGMENT];
} OBJECT_HANDLE_TABLE, *POBJECT_HANDLE_TABLE;
// ******************************************************************
// * 0x00F5 - ObpObjectHandleTable
// ******************************************************************
XBSYSAPI EXPORTNUM(245) OBJECT_HANDLE_TABLE ObpObjectHandleTable;
// ******************************************************************
// * 0x00F6 - ObReferenceObjectByHandle()
// ******************************************************************
XBSYSAPI EXPORTNUM(246) NTSTATUS NTAPI ObReferenceObjectByHandle
(
IN HANDLE Handle,
IN POBJECT_TYPE ObjectType OPTIONAL,
OUT PVOID *ReturnedObject
);
// ******************************************************************
// * 0x00F7 - ObReferenceObjectByName()
// ******************************************************************
XBSYSAPI EXPORTNUM(247) NTSTATUS NTAPI ObReferenceObjectByName
(
IN POBJECT_STRING ObjectName,
IN ULONG Attributes,
IN POBJECT_TYPE ObjectType,
IN OUT PVOID ParseContext OPTIONAL,
OUT PVOID *Object
);
// ******************************************************************
// * 0x00F8 - ObReferenceObjectByPointer()
// ******************************************************************
XBSYSAPI EXPORTNUM(248) NTSTATUS NTAPI ObReferenceObjectByPointer
(
IN PVOID Object,
IN POBJECT_TYPE ObjectType
);
// ******************************************************************
// * 0x00F9 - ObSymbolicLinkObjectType
// ******************************************************************
XBSYSAPI EXPORTNUM(249) OBJECT_TYPE ObSymbolicLinkObjectType;
// ******************************************************************
// * 0x00FA - ObfDereferenceObject()
// ******************************************************************
XBSYSAPI EXPORTNUM(250) VOID FASTCALL ObfDereferenceObject
(
IN PVOID Object
);
// ******************************************************************
// * 0x00FB - ObfReferenceObject()
// ******************************************************************
XBSYSAPI EXPORTNUM(251) VOID FASTCALL ObfReferenceObject
(
IN PVOID Object
);
#endif

View File

@ -415,41 +415,41 @@ XBSYSAPI EXPORTNUM(350) ULONG NTAPI XcCryptService
);
/* Function pointers which point to all the kernel crypto functions. Used by PCRYPTO_VECTOR. */
typedef VOID(NTAPI *pfXcSHAInit)(PUCHAR pbSHAContext);
typedef VOID(NTAPI *pfXcSHAUpdate)(PUCHAR pbSHAContext, PUCHAR pbInput, ULONG dwInputLength);
typedef VOID(NTAPI *pfXcSHAFinal)(PUCHAR pbSHAContext, PUCHAR pbDigest);
typedef VOID(NTAPI *pfXcRC4Key)(PUCHAR pbKeyStruct, ULONG dwKeyLength, PUCHAR pbKey);
typedef VOID(NTAPI *pfXcRC4Crypt)(PUCHAR pbKeyStruct, ULONG dwInputLength, PUCHAR pbInput);
typedef VOID(NTAPI *pfXcHMAC)(PBYTE pbKeyMaterial, ULONG cbKeyMaterial, PBYTE pbData, ULONG cbData, PBYTE pbData2, ULONG cbData2, PBYTE HmacData);
typedef ULONG(NTAPI *pfXcPKEncPublic)(PUCHAR pbPubKey, PUCHAR pbInput, PUCHAR pbOutput);
typedef ULONG(NTAPI *pfXcPKDecPrivate)(PUCHAR pbPrvKey, PUCHAR pbInput, PUCHAR pbOutput);
typedef ULONG(NTAPI *pfXcPKGetKeyLen)(PUCHAR pbPubKey);
typedef BOOLEAN(NTAPI *pfXcVerifyPKCS1Signature)(PUCHAR pbSig, PUCHAR pbPubKey, PUCHAR pbDigest);
typedef ULONG(NTAPI *pfXcModExp)(LPDWORD pA, LPDWORD pB, LPDWORD pC, LPDWORD pD, ULONG dwN);
typedef VOID(NTAPI *pfXcDESKeyParity)(PUCHAR pbKey, ULONG dwKeyLength);
typedef VOID(NTAPI *pfXcKeyTable)(ULONG dwCipher, PUCHAR pbKeyTable, PUCHAR pbKey);
typedef VOID(NTAPI *pfXcBlockCrypt)(ULONG dwCipher, PUCHAR pbOutput, PUCHAR pbInput, PUCHAR pbKeyTable, ULONG dwOp);
typedef VOID(NTAPI *pfXcBlockCryptCBC)(ULONG dwCipher, ULONG dwInputLength, PUCHAR pbOutput, PUCHAR pbInput, PUCHAR pbKeyTable, ULONG dwOp, PUCHAR pbFeedback);
typedef VOID(NTAPI *pfXcSHAInit)(PUCHAR pbSHAContext);
typedef VOID(NTAPI *pfXcSHAUpdate)(PUCHAR pbSHAContext, PUCHAR pbInput, ULONG dwInputLength);
typedef VOID(NTAPI *pfXcSHAFinal)(PUCHAR pbSHAContext, PUCHAR pbDigest);
typedef VOID(NTAPI *pfXcRC4Key)(PUCHAR pbKeyStruct, ULONG dwKeyLength, PUCHAR pbKey);
typedef VOID(NTAPI *pfXcRC4Crypt)(PUCHAR pbKeyStruct, ULONG dwInputLength, PUCHAR pbInput);
typedef VOID(NTAPI *pfXcHMAC)(PBYTE pbKeyMaterial, ULONG cbKeyMaterial, PBYTE pbData, ULONG cbData, PBYTE pbData2, ULONG cbData2, PBYTE HmacData);
typedef ULONG(NTAPI *pfXcPKEncPublic)(PUCHAR pbPubKey, PUCHAR pbInput, PUCHAR pbOutput);
typedef ULONG(NTAPI *pfXcPKDecPrivate)(PUCHAR pbPrvKey, PUCHAR pbInput, PUCHAR pbOutput);
typedef ULONG(NTAPI *pfXcPKGetKeyLen)(PUCHAR pbPubKey);
typedef BOOLEAN(NTAPI *pfXcVerifyPKCS1Signature)(PUCHAR pbSig, PUCHAR pbPubKey, PUCHAR pbDigest);
typedef ULONG(NTAPI *pfXcModExp)(LPDWORD pA, LPDWORD pB, LPDWORD pC, LPDWORD pD, ULONG dwN);
typedef VOID(NTAPI *pfXcDESKeyParity)(PUCHAR pbKey, ULONG dwKeyLength);
typedef VOID(NTAPI *pfXcKeyTable)(ULONG dwCipher, PUCHAR pbKeyTable, PUCHAR pbKey);
typedef VOID(NTAPI *pfXcBlockCrypt)(ULONG dwCipher, PUCHAR pbOutput, PUCHAR pbInput, PUCHAR pbKeyTable, ULONG dwOp);
typedef VOID(NTAPI *pfXcBlockCryptCBC)(ULONG dwCipher, ULONG dwInputLength, PUCHAR pbOutput, PUCHAR pbInput, PUCHAR pbKeyTable, ULONG dwOp, PUCHAR pbFeedback);
typedef ULONG(NTAPI *pfXcCryptService)(ULONG dwOp, PVOID pArgs);
/* Struct which contains all the pointers to the crypto functions */
typedef struct {
pfXcSHAInit pXcSHAInit;
pfXcSHAUpdate pXcSHAUpdate;
pfXcSHAFinal pXcSHAFinal;
pfXcRC4Key pXcRC4Key;
pfXcRC4Crypt pXcRC4Crypt;
pfXcHMAC pXcHMAC;
pfXcPKEncPublic pXcPKEncPublic;
pfXcPKDecPrivate pXcPKDecPrivate;
pfXcPKGetKeyLen pXcPKGetKeyLen;
pfXcVerifyPKCS1Signature pXcVerifyPKCS1Signature;
pfXcModExp pXcModExp;
pfXcDESKeyParity pXcDESKeyParity;
pfXcKeyTable pXcKeyTable;
pfXcBlockCrypt pXcBlockCrypt;
pfXcBlockCryptCBC pXcBlockCryptCBC;
pfXcCryptService pXcCryptService;
typedef struct {
pfXcSHAInit pXcSHAInit;
pfXcSHAUpdate pXcSHAUpdate;
pfXcSHAFinal pXcSHAFinal;
pfXcRC4Key pXcRC4Key;
pfXcRC4Crypt pXcRC4Crypt;
pfXcHMAC pXcHMAC;
pfXcPKEncPublic pXcPKEncPublic;
pfXcPKDecPrivate pXcPKDecPrivate;
pfXcPKGetKeyLen pXcPKGetKeyLen;
pfXcVerifyPKCS1Signature pXcVerifyPKCS1Signature;
pfXcModExp pXcModExp;
pfXcDESKeyParity pXcDESKeyParity;
pfXcKeyTable pXcKeyTable;
pfXcBlockCrypt pXcBlockCrypt;
pfXcBlockCryptCBC pXcBlockCryptCBC;
pfXcCryptService pXcCryptService;
} CRYPTO_VECTOR, *PCRYPTO_VECTOR;
// ******************************************************************

View File

@ -174,7 +174,7 @@ typedef long NTSTATUS;
// * Registry value types
// ******************************************************************
// Used in ExQueryNonVolatileSetting and ExSaveNonVolatileSetting
#ifndef _WIN32 // Avoid "warning C4005: 'REG_NONE': macro redefinition" (conflicting with winnt.h)
#ifndef _WIN32 // Avoid "warning C4005: 'REG_NONE': macro redefinition" (conflicting with winnt.h)
#define REG_NONE ( 0 ) // No defined value type.
#define REG_SZ ( 1 ) // A null - terminated string. This will be either a Unicode or an ANSI string, depending on whether you use the Unicode or ANSI functions.
#define REG_EXPAND_SZ ( 2 ) // A null - terminated string that contains unexpanded references to environment variables (for example, "%PATH%"). It will be a Unicode or ANSI string depending on whether you use the Unicode or ANSI functions. To expand the environment variable references, use the ExpandEnvironmentStrings function.
@ -187,7 +187,7 @@ typedef long NTSTATUS;
#define REG_RESOURCE_LIST ( 8 ) // Resource list in the resource map
#define REG_FULL_RESOURCE_DESCRIPTOR ( 9 ) // Resource list in the hardware description
#define REG_RESOURCE_REQUIREMENTS_LIST ( 10 )
#endif
#endif
// ******************************************************************
// * calling conventions
@ -352,13 +352,13 @@ typedef struct _SINGLE_LIST_ENTRY {
struct _SINGLE_LIST_ENTRY *Next;
} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY, SLIST_ENTRY, *PSLIST_ENTRY;
typedef union _SLIST_HEADER {
ULONGLONG Alignment;
struct {
SINGLE_LIST_ENTRY Next;
USHORT Depth;
USHORT Sequence;
};
typedef union _SLIST_HEADER {
ULONGLONG Alignment;
struct {
SINGLE_LIST_ENTRY Next;
USHORT Depth;
USHORT Sequence;
};
} SLIST_HEADER, *PSLIST_HEADER;
#define QUERY_DEPTH_SLIST(_listhead_) (USHORT)(_listhead_)->Depth
@ -642,9 +642,9 @@ XBOX_REFURB_INFO, *PXBOX_REFURB_INFO;
#define EXCEPTION_MAXIMUM_PARAMETERS 15 // maximum number of exception parameters
#define ALIGN_DOWN(length, type) ((ULONG)(length) & ~(sizeof(type) - 1))
#define ALIGN_UP(length, type) (ALIGN_DOWN(((ULONG)(length) + sizeof(type) - 1), type))
#define ALIGN_DOWN_POINTER(address, type) ((PVOID)((ULONG_PTR)(address) & ~((ULONG_PTR)sizeof(type) - 1)))
#define ALIGN_DOWN(length, type) ((ULONG)(length) & ~(sizeof(type) - 1))
#define ALIGN_UP(length, type) (ALIGN_DOWN(((ULONG)(length) + sizeof(type) - 1), type))
#define ALIGN_DOWN_POINTER(address, type) ((PVOID)((ULONG_PTR)(address) & ~((ULONG_PTR)sizeof(type) - 1)))
#define ALIGN_UP_POINTER(address, type) (ALIGN_DOWN_POINTER(((ULONG_PTR)(address) + sizeof(type) - 1), type))
// ******************************************************************
@ -1535,11 +1535,11 @@ KDPC, *PKDPC;
// ******************************************************************
// * DPC queue entry structure
// ******************************************************************
typedef struct _DPC_QUEUE_ENTRY
{
PKDPC Dpc;
PKDEFERRED_ROUTINE Routine;
PVOID Context;
typedef struct _DPC_QUEUE_ENTRY
{
PKDPC Dpc;
PKDEFERRED_ROUTINE Routine;
PVOID Context;
}
DPC_QUEUE_ENTRY, *PDPC_QUEUE_ENTRY;
@ -1644,7 +1644,7 @@ KINTERRUPT_MODE;
#define APC_LEVEL 1
#define DISPATCH_LEVEL 2
#define PROFILE_LEVEL 26
#define CLOCK1_LEVEL 28
#define CLOCK1_LEVEL 28
#define CLOCK2_LEVEL 28
#define SYNC_LEVEL 28
#define IPI_LEVEL 29
@ -2616,43 +2616,43 @@ typedef struct _IO_COMPLETION_BASIC_INFORMATION {
LONG Depth;
} IO_COMPLETION_BASIC_INFORMATION, *PIO_COMPLETION_BASIC_INFORMATION;
typedef VOID(*PIDE_INTERRUPT_ROUTINE) (void);
typedef VOID(*PIDE_FINISHIO_ROUTINE) (void);
typedef BOOLEAN(*PIDE_POLL_RESET_COMPLETE_ROUTINE) (void);
typedef VOID(*PIDE_TIMEOUT_EXPIRED_ROUTINE) (void);
typedef VOID(*PIDE_START_PACKET_ROUTINE) (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
typedef VOID(*PIDE_INTERRUPT_ROUTINE) (void);
typedef VOID(*PIDE_FINISHIO_ROUTINE) (void);
typedef BOOLEAN(*PIDE_POLL_RESET_COMPLETE_ROUTINE) (void);
typedef VOID(*PIDE_TIMEOUT_EXPIRED_ROUTINE) (void);
typedef VOID(*PIDE_START_PACKET_ROUTINE) (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
typedef VOID(*PIDE_START_NEXT_PACKET_ROUTINE) (void);
typedef struct _IDE_CHANNEL_OBJECT
{
PIDE_INTERRUPT_ROUTINE InterruptRoutine;
PIDE_FINISHIO_ROUTINE FinishIoRoutine;
PIDE_POLL_RESET_COMPLETE_ROUTINE PollResetCompleteRoutine;
PIDE_TIMEOUT_EXPIRED_ROUTINE TimeoutExpiredRoutine;
PIDE_START_PACKET_ROUTINE StartPacketRoutine;
PIDE_START_NEXT_PACKET_ROUTINE StartNextPacketRoutine;
KIRQL InterruptIrql;
BOOLEAN ExpectingBusMasterInterrupt;
BOOLEAN StartPacketBusy;
BOOLEAN StartPacketRequested;
UCHAR Timeout;
UCHAR IoRetries;
UCHAR MaximumIoRetries;
PIRP CurrentIrp;
KDEVICE_QUEUE DeviceQueue;
ULONG PhysicalRegionDescriptorTablePhysical;
KDPC TimerDpc;
KDPC FinishDpc;
KTIMER Timer;
KINTERRUPT InterruptObject;
typedef struct _IDE_CHANNEL_OBJECT
{
PIDE_INTERRUPT_ROUTINE InterruptRoutine;
PIDE_FINISHIO_ROUTINE FinishIoRoutine;
PIDE_POLL_RESET_COMPLETE_ROUTINE PollResetCompleteRoutine;
PIDE_TIMEOUT_EXPIRED_ROUTINE TimeoutExpiredRoutine;
PIDE_START_PACKET_ROUTINE StartPacketRoutine;
PIDE_START_NEXT_PACKET_ROUTINE StartNextPacketRoutine;
KIRQL InterruptIrql;
BOOLEAN ExpectingBusMasterInterrupt;
BOOLEAN StartPacketBusy;
BOOLEAN StartPacketRequested;
UCHAR Timeout;
UCHAR IoRetries;
UCHAR MaximumIoRetries;
PIRP CurrentIrp;
KDEVICE_QUEUE DeviceQueue;
ULONG PhysicalRegionDescriptorTablePhysical;
KDPC TimerDpc;
KDPC FinishDpc;
KTIMER Timer;
KINTERRUPT InterruptObject;
} IDE_CHANNEL_OBJECT, *PIDE_CHANNEL_OBJECT;
// ******************************************************************

View File

@ -1,26 +1,26 @@
@echo off
REM Cxbx-Reloaded setup script
REM
REM Depends on git, cmake and Visual Studio being installed.
echo Pulling latest version from git...
REM git clone --recurse-submodules https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/
git pull --recurse-submodules
REM echo Synchronizing submodules...
REM git submodule update --init --recursive
echo Initializing most recent Visual Studio build environment...
@call "%VS140COMNTOOLS%vsvars32.bat"
echo Generating solution...
mkdir build
cd build
REM cmake .. -G "Visual Studio 16 2019" -A Win32
cmake .. -A Win32
echo Building solution...
cmake --build . -j %NUMBER_OF_PROCESSORS%
echo Done! Enjoy using Cxbx-Reloaded!
@echo off
REM Cxbx-Reloaded setup script
REM
REM Depends on git, cmake and Visual Studio being installed.
echo Pulling latest version from git...
REM git clone --recurse-submodules https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/
git pull --recurse-submodules
REM echo Synchronizing submodules...
REM git submodule update --init --recursive
echo Initializing most recent Visual Studio build environment...
@call "%VS140COMNTOOLS%vsvars32.bat"
echo Generating solution...
mkdir build
cd build
REM cmake .. -G "Visual Studio 16 2019" -A Win32
cmake .. -A Win32
echo Building solution...
cmake --build . -j %NUMBER_OF_PROCESSORS%
echo Done! Enjoy using Cxbx-Reloaded!

View File

@ -1,75 +1,75 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * .,-::::: .,:: .::::::::. .,:: .:
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
// * $$$ Y$$$P $$""""Y$$ Y$$$P
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx is free software; you can redistribute it
// * and/or modify it under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2017-2019 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
// CxbxEmulator.cpp : Defines the exported functions for the DLL application.
#include "stdafx.h"
#include "Cxbx.h"
DWORD WINAPI Emulate()
{
FUNC_EXPORTS
/*! verify Cxbx-Loader.exe is loaded to base address 0x00010000 */
if ((UINT_PTR)GetModuleHandle(nullptr) != CXBX_BASE_ADDR)
{
/*! CXBX_BASE_ADDR is defined as 0x00010000, which is the base address of
the Cxbx-Loader.exe host executable.
Set in Cxbx-Loader.exe Project options, Linker, Advanced, Base Address */
MessageBox(NULL, "Cxbx-Loader.exe was not loaded to base address 0x00010000 (which is a requirement for Xbox emulation)", "Cxbx-Reloaded", MB_OK);
return 1;
}
/* Initialize Cxbx File Paths */
CxbxInitFilePaths();
/*! initialize shared memory */
if (!EmuShared::Init()) {
MessageBox(NULL, "Could not map shared memory!", "Cxbx-Reloaded", MB_OK);
return 1;
}
LPSTR CommandLine = GetCommandLine();
int argc;
PCHAR *argv = CommandLineToArgvA(CommandLine, &argc);
CxbxKrnlMain(argc, argv);
LocalFree(argv);
/*! cleanup shared memory */
EmuShared::Cleanup();
return 0;
}
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * .,-::::: .,:: .::::::::. .,:: .:
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
// * $$$ Y$$$P $$""""Y$$ Y$$$P
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx is free software; you can redistribute it
// * and/or modify it under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2017-2019 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
// CxbxEmulator.cpp : Defines the exported functions for the DLL application.
#include "stdafx.h"
#include "Cxbx.h"
DWORD WINAPI Emulate()
{
FUNC_EXPORTS
/*! verify Cxbx-Loader.exe is loaded to base address 0x00010000 */
if ((UINT_PTR)GetModuleHandle(nullptr) != CXBX_BASE_ADDR)
{
/*! CXBX_BASE_ADDR is defined as 0x00010000, which is the base address of
the Cxbx-Loader.exe host executable.
Set in Cxbx-Loader.exe Project options, Linker, Advanced, Base Address */
MessageBox(NULL, "Cxbx-Loader.exe was not loaded to base address 0x00010000 (which is a requirement for Xbox emulation)", "Cxbx-Reloaded", MB_OK);
return 1;
}
/* Initialize Cxbx File Paths */
CxbxInitFilePaths();
/*! initialize shared memory */
if (!EmuShared::Init()) {
MessageBox(NULL, "Could not map shared memory!", "Cxbx-Reloaded", MB_OK);
return 1;
}
LPSTR CommandLine = GetCommandLine();
int argc;
PCHAR *argv = CommandLineToArgvA(CommandLine, &argc);
CxbxKrnlMain(argc, argv);
LocalFree(argv);
/*! cleanup shared memory */
EmuShared::Cleanup();
return 0;
}

View File

@ -1,5 +1,5 @@
#include <Windows.h>
// Default to High Performance Mode on machines with dual graphics
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; // AMD
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; // NVIDIA
#include <Windows.h>
// Default to High Performance Mode on machines with dual graphics
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; // AMD
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; // NVIDIA

View File

@ -180,7 +180,7 @@ xboxkrnl::XBOX_EEPROM *CxbxRestoreEEPROM(char *szFilePath_EEPROM_bin)
}
// Read the HDD (and eventually also the online) keys stored in the eeprom file. Users can input them in the eeprom menu
memcpy(xboxkrnl::XboxHDKey, pEEPROM->EncryptedSettings.HDKey, xboxkrnl::XBOX_KEY_LENGTH);
memcpy(xboxkrnl::XboxHDKey, pEEPROM->EncryptedSettings.HDKey, xboxkrnl::XBOX_KEY_LENGTH);
// Verify the checksum of the eeprom header
UCHAR Checksum[20] = { 0 };
@ -230,22 +230,22 @@ void EmuEEPROMReset(xboxkrnl::XBOX_EEPROM* eeprom)
std::string serial = "";
for (int i = 0; i < 12; i++) {
serial += std::to_string(serialDis(gen));
}
}
memset(eeprom->FactorySettings.SerialNumber, 0, 12);
strncpy((char*)eeprom->FactorySettings.SerialNumber, serial.c_str(), 12);
// Generate a random mac address
eeprom->FactorySettings.EthernetAddr[0] = 0x00;
eeprom->FactorySettings.EthernetAddr[1] = 0x50;
eeprom->FactorySettings.EthernetAddr[0] = 0x00;
eeprom->FactorySettings.EthernetAddr[1] = 0x50;
eeprom->FactorySettings.EthernetAddr[2] = 0xF2;
for (int i = 3; i < 6; i++) {
eeprom->FactorySettings.EthernetAddr[i] = macOnlineDis(gen);
}
// Generate a random Online Key
for (int i = 0; i < 16; i++) {
eeprom->FactorySettings.OnlineKey[i] = macOnlineDis(gen);
}
}
// TODO: TimeZone Settings
}

View File

@ -27,119 +27,119 @@
#include <windows.h> // for PULONG
#include "Logging.h"
#include "common\Settings.hpp"
#include "Logging.h"
#include "common\Settings.hpp"
#include "EmuShared.h"
// For thread_local, see : https://en.cppreference.com/w/cpp/language/storage_duration
// TODO : Use Boost.Format https://www.boost.org/doc/libs/1_53_0/libs/format/index.html
thread_local std::string _logThreadPrefix;
std::atomic_bool g_EnabledModules[to_underlying(CXBXR_MODULE::MAX)] = { false };
const char* g_EnumModules2String[to_underlying(CXBXR_MODULE::MAX)] = {
"CXBXR ",
"XBE ",
"INIT ",
"VMEM ",
"PMEM ",
"GUI ",
"EEPR ",
"RSA ",
"POOLMEM ",
"D3D8 ",
"D3DST ",
"D3DCVT ",
"DSOUND ",
"XAPI ",
"XACT ",
"XGRP ",
"XONLINE ",
"FS ",
"PSHB ",
"PXSH ",
"VTXSH ",
"VSHCACHE",
"VTXB ",
"DINP ",
"XINP ",
"SDL ",
"FILE ",
"X86 ",
"HLE ",
"NET ",
"MCPX ",
"NV2A ",
"SMC ",
"OHCI ",
"USB ",
"HUB ",
"XIDCTRL ",
"ADM ",
"INPSYS ",
"DSBUFFER",
"DSSTREAM",
"DS3DCALC",
"XMO ",
"KRNL ",
"LOG ",
"XBOX ",
"XBDM ",
"AV ",
"DBG ",
"EX ",
"FSC ",
"HAL ",
"IO ",
"KD ",
"KE ",
"KI ",
"MM ",
"NT ",
"OB ",
"PS ",
"RTL ",
"XC ",
"XE ",
};
std::atomic_int g_CurrentLogLevel = to_underlying(LOG_LEVEL::INFO);
std::atomic_bool g_CurrentLogPopupTestCase = true;
static bool g_disablePopupMessages = false;
const char log_debug[] = "DEBUG: ";
const char log_info[] = "INFO : ";
const char log_warn[] = "WARN : ";
const char log_error[] = "ERROR: ";
const char log_fatal[] = "FATAL: ";
const char log_unkwn[] = "???? : ";
// Do not use EmuLogOutput function outside of this file.
void EmuLogOutput(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWarningMessage, const va_list argp)
thread_local std::string _logThreadPrefix;
std::atomic_bool g_EnabledModules[to_underlying(CXBXR_MODULE::MAX)] = { false };
const char* g_EnumModules2String[to_underlying(CXBXR_MODULE::MAX)] = {
"CXBXR ",
"XBE ",
"INIT ",
"VMEM ",
"PMEM ",
"GUI ",
"EEPR ",
"RSA ",
"POOLMEM ",
"D3D8 ",
"D3DST ",
"D3DCVT ",
"DSOUND ",
"XAPI ",
"XACT ",
"XGRP ",
"XONLINE ",
"FS ",
"PSHB ",
"PXSH ",
"VTXSH ",
"VSHCACHE",
"VTXB ",
"DINP ",
"XINP ",
"SDL ",
"FILE ",
"X86 ",
"HLE ",
"NET ",
"MCPX ",
"NV2A ",
"SMC ",
"OHCI ",
"USB ",
"HUB ",
"XIDCTRL ",
"ADM ",
"INPSYS ",
"DSBUFFER",
"DSSTREAM",
"DS3DCALC",
"XMO ",
"KRNL ",
"LOG ",
"XBOX ",
"XBDM ",
"AV ",
"DBG ",
"EX ",
"FSC ",
"HAL ",
"IO ",
"KD ",
"KE ",
"KI ",
"MM ",
"NT ",
"OB ",
"PS ",
"RTL ",
"XC ",
"XE ",
};
std::atomic_int g_CurrentLogLevel = to_underlying(LOG_LEVEL::INFO);
std::atomic_bool g_CurrentLogPopupTestCase = true;
static bool g_disablePopupMessages = false;
const char log_debug[] = "DEBUG: ";
const char log_info[] = "INFO : ";
const char log_warn[] = "WARN : ";
const char log_error[] = "ERROR: ";
const char log_fatal[] = "FATAL: ";
const char log_unkwn[] = "???? : ";
// Do not use EmuLogOutput function outside of this file.
void EmuLogOutput(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWarningMessage, const va_list argp)
{
LOG_THREAD_INIT;
const char* level_str;
LOG_THREAD_INIT;
const char* level_str;
switch (level) {
default:
level_str = log_unkwn;
default:
level_str = log_unkwn;
break;
case LOG_LEVEL::DEBUG:
level_str = log_debug;
case LOG_LEVEL::DEBUG:
level_str = log_debug;
break;
case LOG_LEVEL::INFO:
level_str = log_info;
case LOG_LEVEL::INFO:
level_str = log_info;
break;
case LOG_LEVEL::WARNING:
level_str = log_warn;
break;
case LOG_LEVEL::ERROR2:
level_str = log_error;
case LOG_LEVEL::WARNING:
level_str = log_warn;
break;
case LOG_LEVEL::FATAL:
level_str = log_fatal;
case LOG_LEVEL::ERROR2:
level_str = log_error;
break;
case LOG_LEVEL::FATAL:
level_str = log_fatal;
break;
}
std::cout << _logThreadPrefix << level_str
std::cout << _logThreadPrefix << level_str
<< g_EnumModules2String[to_underlying(cxbxr_module)];
vfprintf(stdout, szWarningMessage, argp);
@ -147,23 +147,23 @@ void EmuLogOutput(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWarn
fprintf(stdout, "\n");
fflush(stdout);
}
inline void EmuLogOutputEx(const CXBXR_MODULE cxbxr_module, const LOG_LEVEL level, const char *szWarningMessage, ...)
}
inline void EmuLogOutputEx(const CXBXR_MODULE cxbxr_module, const LOG_LEVEL level, const char *szWarningMessage, ...)
{
va_list argp;
va_start(argp, szWarningMessage);
EmuLogOutput(cxbxr_module, level, szWarningMessage, argp);
va_end(argp);
}
// print out a custom message to the console or kernel debug log file
void NTAPI EmuLogEx(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWarningMessage, ...)
}
// print out a custom message to the console or kernel debug log file
void NTAPI EmuLogEx(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWarningMessage, ...)
{
if (szWarningMessage == NULL) {
return;
}
LOG_CHECK_ENABLED_EX(cxbxr_module, level) {
LOG_CHECK_ENABLED_EX(cxbxr_module, level) {
if (g_bPrintfOn) {
LOG_THREAD_INIT;
@ -174,11 +174,11 @@ void NTAPI EmuLogEx(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWa
EmuLogOutput(cxbxr_module, level, szWarningMessage, argp);
va_end(argp);
}
}
}
}
void NTAPI EmuLogInit(LOG_LEVEL level, const char *szWarningMessage, ...)
}
void NTAPI EmuLogInit(LOG_LEVEL level, const char *szWarningMessage, ...)
{
if (szWarningMessage == NULL) {
return;
@ -190,56 +190,56 @@ void NTAPI EmuLogInit(LOG_LEVEL level, const char *szWarningMessage, ...)
EmuLogOutput(CXBXR_MODULE::INIT, level, szWarningMessage, argp);
va_end(argp);
}
// Set up the logging variables for the GUI process
inline void log_get_settings()
{
}
// Set up the logging variables for the GUI process
inline void log_get_settings()
{
log_set_config(g_Settings->m_core.LogLevel, g_Settings->m_core.LoggedModules, g_Settings->m_core.bLogPopupTestCase);
}
inline void log_sync_config()
{
int LogLevel;
unsigned int LoggedModules[NUM_INTEGERS_LOG];
bool LogPopupTestCase;
g_EmuShared->GetLogLv(&LogLevel);
g_EmuShared->GetLogModules(LoggedModules);
g_EmuShared->GetLogPopupTestCase(&LogPopupTestCase);
}
inline void log_sync_config()
{
int LogLevel;
unsigned int LoggedModules[NUM_INTEGERS_LOG];
bool LogPopupTestCase;
g_EmuShared->GetLogLv(&LogLevel);
g_EmuShared->GetLogModules(LoggedModules);
g_EmuShared->GetLogPopupTestCase(&LogPopupTestCase);
log_set_config(LogLevel, LoggedModules, LogPopupTestCase);
}
void log_set_config(int LogLevel, unsigned int* LoggedModules, bool LogPopupTestCase)
{
g_CurrentLogLevel = LogLevel;
for (unsigned int index = to_underlying(CXBXR_MODULE::CXBXR); index < to_underlying(CXBXR_MODULE::MAX); index++) {
if (LoggedModules[index / 32] & (1 << (index % 32))) {
g_EnabledModules[index] = true;
}
else {
g_EnabledModules[index] = false;
}
}
void log_set_config(int LogLevel, unsigned int* LoggedModules, bool LogPopupTestCase)
{
g_CurrentLogLevel = LogLevel;
for (unsigned int index = to_underlying(CXBXR_MODULE::CXBXR); index < to_underlying(CXBXR_MODULE::MAX); index++) {
if (LoggedModules[index / 32] & (1 << (index % 32))) {
g_EnabledModules[index] = true;
}
else {
g_EnabledModules[index] = false;
}
}
g_CurrentLogPopupTestCase = LogPopupTestCase;
}
// Generate active log filter output.
void log_generate_active_filter_output(const CXBXR_MODULE cxbxr_module)
}
// Generate active log filter output.
void log_generate_active_filter_output(const CXBXR_MODULE cxbxr_module)
{
LOG_THREAD_INIT;
std::string generic_output_str = _logThreadPrefix + log_info + g_EnumModules2String[to_underlying(cxbxr_module)];
std::cout << generic_output_str << "Current log level: " << g_CurrentLogLevel << std::endl;
generic_output_str.append("Active log filter: ");
for (unsigned int index = to_underlying(CXBXR_MODULE::CXBXR); index < to_underlying(CXBXR_MODULE::MAX); index++) {
if (g_EnabledModules[index]) {
std::cout << generic_output_str << g_EnumModules2String[index] << "\n";
}
}
LOG_THREAD_INIT;
std::string generic_output_str = _logThreadPrefix + log_info + g_EnumModules2String[to_underlying(cxbxr_module)];
std::cout << generic_output_str << "Current log level: " << g_CurrentLogLevel << std::endl;
generic_output_str.append("Active log filter: ");
for (unsigned int index = to_underlying(CXBXR_MODULE::CXBXR); index < to_underlying(CXBXR_MODULE::MAX); index++) {
if (g_EnabledModules[index]) {
std::cout << generic_output_str << g_EnumModules2String[index] << "\n";
}
}
std::cout << std::flush;
}
}
// Use kernel managed environment
void log_init_popup_msg()
{
@ -250,10 +250,10 @@ void log_init_popup_msg()
// TODO: Move PopupPlatformHandler into common GUI's window source code or use imgui in the future.
// PopupPlatformHandler is intended to be use as internal wrapper function.
static PopupReturn PopupPlatformHandler(const char* msg, const PopupReturn ret_default, const UINT uType, const HWND hWnd)
{
int ret = MessageBox(hWnd, msg, /*lpCaption=*/TEXT("Cxbx-Reloaded"), uType);
static PopupReturn PopupPlatformHandler(const char* msg, const PopupReturn ret_default, const UINT uType, const HWND hWnd)
{
int ret = MessageBox(hWnd, msg, /*lpCaption=*/TEXT("Cxbx-Reloaded"), uType);
switch (ret) {
default:
case IDCANCEL:
@ -271,73 +271,73 @@ static PopupReturn PopupPlatformHandler(const char* msg, const PopupReturn ret_d
case IDNO:
return PopupReturn::No;
}
}
PopupReturn PopupCustomEx(const void* hwnd, const CXBXR_MODULE cxbxr_module, const LOG_LEVEL level, const PopupIcon icon, const PopupButtons buttons, const PopupReturn ret_default, const char *message, ...)
{
UINT uType = MB_TOPMOST | MB_SETFOREGROUND;
// Make assert whenever the format string is null pointer which isn't allow in here.
assert(message != nullptr);
switch (icon) {
case PopupIcon::Warning: {
uType |= MB_ICONWARNING;
break;
}
case PopupIcon::Error: {
uType |= MB_ICONERROR; // Note : MB_ICONERROR == MB_ICONSTOP == MB_ICONHAND
break;
}
case PopupIcon::Info: {
uType |= MB_ICONINFORMATION;
break;
}
case PopupIcon::Question:
case PopupIcon::Unknown:
default: {
uType |= MB_ICONQUESTION;
break;
}
}
switch (buttons) {
default:
case PopupButtons::Ok:
uType |= MB_OK;
break;
case PopupButtons::OkCancel:
uType |= MB_OKCANCEL;
break;
case PopupButtons::AbortRetryIgnore:
uType |= MB_RETRYCANCEL;
break;
case PopupButtons::YesNoCancel:
uType |= MB_YESNOCANCEL;
break;
case PopupButtons::YesNo:
uType |= MB_YESNO;
break;
case PopupButtons::RetryCancel:
uType |= MB_RETRYCANCEL;
break;
}
va_list argp;
va_start(argp, message);
// allocate predicted buffer size then write to buffer afterward.
std::vector<char> Buffer(1+std::vsnprintf(nullptr, 0, message, argp));
vsnprintf(Buffer.data(), Buffer.size(), message, argp);
va_end(argp);
EmuLogOutputEx(cxbxr_module, level, "Popup : %s", Buffer);
// If user is using exclusive fullscreen, we need to refrain all popups.
if (g_disablePopupMessages) {
return ret_default;
}
return PopupPlatformHandler(Buffer.data(), ret_default, uType, (const HWND)hwnd);
}
PopupReturn PopupCustomEx(const void* hwnd, const CXBXR_MODULE cxbxr_module, const LOG_LEVEL level, const PopupIcon icon, const PopupButtons buttons, const PopupReturn ret_default, const char *message, ...)
{
UINT uType = MB_TOPMOST | MB_SETFOREGROUND;
// Make assert whenever the format string is null pointer which isn't allow in here.
assert(message != nullptr);
switch (icon) {
case PopupIcon::Warning: {
uType |= MB_ICONWARNING;
break;
}
case PopupIcon::Error: {
uType |= MB_ICONERROR; // Note : MB_ICONERROR == MB_ICONSTOP == MB_ICONHAND
break;
}
case PopupIcon::Info: {
uType |= MB_ICONINFORMATION;
break;
}
case PopupIcon::Question:
case PopupIcon::Unknown:
default: {
uType |= MB_ICONQUESTION;
break;
}
}
switch (buttons) {
default:
case PopupButtons::Ok:
uType |= MB_OK;
break;
case PopupButtons::OkCancel:
uType |= MB_OKCANCEL;
break;
case PopupButtons::AbortRetryIgnore:
uType |= MB_RETRYCANCEL;
break;
case PopupButtons::YesNoCancel:
uType |= MB_YESNOCANCEL;
break;
case PopupButtons::YesNo:
uType |= MB_YESNO;
break;
case PopupButtons::RetryCancel:
uType |= MB_RETRYCANCEL;
break;
}
va_list argp;
va_start(argp, message);
// allocate predicted buffer size then write to buffer afterward.
std::vector<char> Buffer(1+std::vsnprintf(nullptr, 0, message, argp));
vsnprintf(Buffer.data(), Buffer.size(), message, argp);
va_end(argp);
EmuLogOutputEx(cxbxr_module, level, "Popup : %s", Buffer);
// If user is using exclusive fullscreen, we need to refrain all popups.
if (g_disablePopupMessages) {
return ret_default;
}
return PopupPlatformHandler(Buffer.data(), ret_default, uType, (const HWND)hwnd);
}
const bool needs_escape(const wint_t _char)
@ -453,7 +453,7 @@ LOG_SANITIZE_HEADER(sanitized_char_pointer, char *)
while (*v && max_length--) {
os << *v++;
}
}
}
return os << "\"";
}
@ -467,7 +467,7 @@ LOG_SANITIZE_HEADER(sanitized_wchar_pointer, wchar_t *)
return os << "NULL";
bool needsEscaping = false;
int max_length = container.max;
int max_length = container.max;
while (*v && max_length--)
if (needs_escape(*v++))
{

View File

@ -17,7 +17,7 @@
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2016 Patrick van Logchem <pvanlogchem@gmail.com>
// * (c) 2016 Patrick van Logchem <pvanlogchem@gmail.com>
// * (c) 2019 ergo720
// *
// * All rights reserved
@ -29,112 +29,112 @@
#include <windows.h> // For DWORD
#include <sstream> // For std::stringstream
#include <iostream> // For std::cout
#include <iomanip> // For std::setw
#include <iomanip> // For std::setw
#include <atomic> // For atomic_bool and atomic_uint
#include "common\util\CxbxUtil.h" // For g_bPrintfOn and to_underlying
// NOTE: using ERROR2 since windows.h imports an ERROR macro which would conflict otherwise
typedef enum class _LOG_LEVEL {
DEBUG = 0,
INFO,
WARNING,
ERROR2,
FATAL,
MAX,
#include "common\util\CxbxUtil.h" // For g_bPrintfOn and to_underlying
// NOTE: using ERROR2 since windows.h imports an ERROR macro which would conflict otherwise
typedef enum class _LOG_LEVEL {
DEBUG = 0,
INFO,
WARNING,
ERROR2,
FATAL,
MAX,
}LOG_LEVEL;
typedef enum class _CXBXR_MODULE: unsigned int {
// general
CXBXR = 0,
XBE,
INIT,
VMEM,
PMEM,
GUI,
EEPR,
RSA,
POOLMEM,
D3D8,
D3DST,
D3DCVT,
DSOUND,
XAPI,
XACT,
XGRP,
XONLINE,
FS,
PSHB,
PXSH,
VTXSH,
VSHCACHE,
VTXB,
DINP,
XINP,
SDL,
FILE,
X86,
HLE,
NET,
MCPX,
NV2A,
SMC,
OHCI,
USB,
HUB,
XIDCTRL,
ADM,
INPSYS,
DSBUFFER,
DSSTREAM,
DS3DCALC,
XMO,
// kernel
KRNL,
LOG,
XBOX,
XBDM,
AV,
DBG,
EX,
FSC,
HAL,
IO,
KD,
KE,
KI,
MM,
NT,
OB,
PS,
RTL,
XC,
XE,
// max
MAX,
}CXBXR_MODULE;
extern std::atomic_bool g_EnabledModules[to_underlying(CXBXR_MODULE::MAX)];
extern const char* g_EnumModules2String[to_underlying(CXBXR_MODULE::MAX)];
extern std::atomic_int g_CurrentLogLevel;
extern std::atomic_bool g_CurrentLogPopupTestCase;
typedef enum class _CXBXR_MODULE: unsigned int {
// general
CXBXR = 0,
XBE,
INIT,
VMEM,
PMEM,
GUI,
EEPR,
RSA,
POOLMEM,
D3D8,
D3DST,
D3DCVT,
DSOUND,
XAPI,
XACT,
XGRP,
XONLINE,
FS,
PSHB,
PXSH,
VTXSH,
VSHCACHE,
VTXB,
DINP,
XINP,
SDL,
FILE,
X86,
HLE,
NET,
MCPX,
NV2A,
SMC,
OHCI,
USB,
HUB,
XIDCTRL,
ADM,
INPSYS,
DSBUFFER,
DSSTREAM,
DS3DCALC,
XMO,
// kernel
KRNL,
LOG,
XBOX,
XBDM,
AV,
DBG,
EX,
FSC,
HAL,
IO,
KD,
KE,
KI,
MM,
NT,
OB,
PS,
RTL,
XC,
XE,
// max
MAX,
}CXBXR_MODULE;
// print out a log message to the console or kernel debug log file if level is high enough
void NTAPI EmuLogEx(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWarningMessage, ...);
void NTAPI EmuLogInit(LOG_LEVEL level, const char *szWarningMessage, ...);
#define EmuLog(level, fmt, ...) EmuLogEx(LOG_PREFIX, level, fmt, ##__VA_ARGS__)
extern inline void log_get_settings();
extern inline void log_sync_config();
void log_set_config(int LogLevel, unsigned int* LoggedModules, bool LogPopupTestCase);
void log_generate_active_filter_output(const CXBXR_MODULE cxbxr_module);
// Use emulation environment to manage popup messages
// If log_init_popup_msg is not called at earliest point of emulation.
// Then users will have a chance of popup message appear during start of emulation in full screen.
extern std::atomic_bool g_EnabledModules[to_underlying(CXBXR_MODULE::MAX)];
extern const char* g_EnumModules2String[to_underlying(CXBXR_MODULE::MAX)];
extern std::atomic_int g_CurrentLogLevel;
extern std::atomic_bool g_CurrentLogPopupTestCase;
// print out a log message to the console or kernel debug log file if level is high enough
void NTAPI EmuLogEx(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWarningMessage, ...);
void NTAPI EmuLogInit(LOG_LEVEL level, const char *szWarningMessage, ...);
#define EmuLog(level, fmt, ...) EmuLogEx(LOG_PREFIX, level, fmt, ##__VA_ARGS__)
extern inline void log_get_settings();
extern inline void log_sync_config();
void log_set_config(int LogLevel, unsigned int* LoggedModules, bool LogPopupTestCase);
void log_generate_active_filter_output(const CXBXR_MODULE cxbxr_module);
// Use emulation environment to manage popup messages
// If log_init_popup_msg is not called at earliest point of emulation.
// Then users will have a chance of popup message appear during start of emulation in full screen.
void log_init_popup_msg();
typedef enum class _PopupIcon {
@ -164,7 +164,7 @@ typedef enum class _PopupReturn {
Ignore,
Yes,
No
} PopupReturn;
} PopupReturn;
PopupReturn PopupCustomEx(const void* hwnd, const CXBXR_MODULE cxbxr_module, const LOG_LEVEL level, const PopupIcon icon, const PopupButtons buttons, const PopupReturn ret_default, const char* message, ...);
@ -173,11 +173,11 @@ PopupReturn PopupCustomEx(const void* hwnd, const CXBXR_MODULE cxbxr_module, con
#define PopupQuestion(hwnd, fmt, ...) PopupQuestionEx(hwnd, LOG_LEVEL::INFO, PopupButtons::YesNoCancel, PopupReturn::Cancel, fmt, ## __VA_ARGS__)
#define PopupInfoEx(hwnd, buttons, ret_default, fmt, ...) PopupCustom(hwnd, LOG_LEVEL::INFO, PopupIcon::Info, buttons, ret_default, fmt, ## __VA_ARGS__)
#define PopupInfo(hwnd, fmt, ...) (void)PopupInfoEx(hwnd, PopupButtons::Ok, PopupReturn::Ok, fmt, ## __VA_ARGS__)
#define PopupWarningEx(hwnd, buttons, ret_default, fmt, ...) PopupCustom(hwnd, LOG_LEVEL::WARNING, PopupIcon::Warning, buttons, ret_default, fmt, ## __VA_ARGS__)
#define PopupWarningEx(hwnd, buttons, ret_default, fmt, ...) PopupCustom(hwnd, LOG_LEVEL::WARNING, PopupIcon::Warning, buttons, ret_default, fmt, ## __VA_ARGS__)
#define PopupWarning(hwnd, fmt, ...) (void)PopupWarningEx(hwnd, PopupButtons::Ok, PopupReturn::Ok, fmt, ## __VA_ARGS__)
#define PopupErrorEx(hwnd, buttons, ret_default, fmt, ...) PopupCustom(hwnd, LOG_LEVEL::ERROR2, PopupIcon::Error, buttons, ret_default, fmt, ## __VA_ARGS__)
#define PopupError(hwnd, fmt, ...) (void)PopupErrorEx(hwnd, PopupButtons::Ok, PopupReturn::Ok, fmt, ## __VA_ARGS__)
#define PopupFatalEx(hwnd, buttons, ret_default, fmt, ...) PopupCustom(hwnd, LOG_LEVEL::FATAL, PopupIcon::Error, buttons, ret_default, fmt, ## __VA_ARGS__)
#define PopupErrorEx(hwnd, buttons, ret_default, fmt, ...) PopupCustom(hwnd, LOG_LEVEL::ERROR2, PopupIcon::Error, buttons, ret_default, fmt, ## __VA_ARGS__)
#define PopupError(hwnd, fmt, ...) (void)PopupErrorEx(hwnd, PopupButtons::Ok, PopupReturn::Ok, fmt, ## __VA_ARGS__)
#define PopupFatalEx(hwnd, buttons, ret_default, fmt, ...) PopupCustom(hwnd, LOG_LEVEL::FATAL, PopupIcon::Error, buttons, ret_default, fmt, ## __VA_ARGS__)
#define PopupFatal(hwnd, fmt, ...) (void)PopupFatalEx(hwnd, PopupButtons::Ok, PopupReturn::Ok, fmt, ## __VA_ARGS__)
// For LOG_TEST_CASE
@ -199,7 +199,7 @@ extern inline void EmuLogOutputEx(const CXBXR_MODULE cxbxr_module, const LOG_LEV
EmuLogOutputEx(LOG_PREFIX, LOG_LEVEL::INFO, "Please report that %s shows the following message:\nLOG_TEST_CASE: %s\nIn %s (%s line %d)", \
CxbxKrnl_Xbe->m_szAsciiTitle, message, __func__, __FILE__, __LINE__); \
} while (0)
// was g_pCertificate->wszTitleName
// was g_pCertificate->wszTitleName
//
// __FILENAME__
@ -257,12 +257,12 @@ inline const char * _log_sanitize(BOOL value, int ignored_length = 0)
#define LOG_SANITIZE_HEADER(C, T) \
std::ostream& operator<<( \
std::ostream& os, \
const Sane##C& container) \
const Sane##C& container) \
#define LOG_SANITIZE(C, T) \
struct Sane##C \
{ \
T value; \
T value; \
int max; \
Sane##C(T _v, int _m = 80) : value(_v), max(_m) { } \
}; \
@ -328,14 +328,14 @@ constexpr const char* remove_emupatch_prefix(const char* str) {
// For thread_local, see : https://en.cppreference.com/w/cpp/language/storage_duration
// TODO : Use Boost.Format https://www.boost.org/doc/libs/1_53_0/libs/format/index.html
extern thread_local std::string _logThreadPrefix;
// Checks if this log should be printed or not
#define LOG_CHECK_ENABLED_EX(cxbxr_module, level) \
if (g_EnabledModules[to_underlying(cxbxr_module)] && to_underlying(level) >= g_CurrentLogLevel)
// Checks if this log should be printed or not
#define LOG_CHECK_ENABLED(level) \
LOG_CHECK_ENABLED_EX(LOG_PREFIX, level)
// Checks if this log should be printed or not
#define LOG_CHECK_ENABLED_EX(cxbxr_module, level) \
if (g_EnabledModules[to_underlying(cxbxr_module)] && to_underlying(level) >= g_CurrentLogLevel)
// Checks if this log should be printed or not
#define LOG_CHECK_ENABLED(level) \
LOG_CHECK_ENABLED_EX(LOG_PREFIX, level)
#define LOG_THREAD_INIT \
if (_logThreadPrefix.length() == 0) { \
@ -366,7 +366,7 @@ extern thread_local std::string _logThreadPrefix;
msg << _logThreadPrefix << _logFuncPrefix << "(";
#define LOG_FUNC_BEGIN \
LOG_INIT \
LOG_INIT \
LOG_CHECK_ENABLED(LOG_LEVEL::DEBUG) { \
LOG_FUNC_BEGIN_NO_INIT
@ -388,9 +388,9 @@ extern thread_local std::string _logThreadPrefix;
// LOG_FUNC_END closes off function and optional argument logging
#define LOG_FUNC_END \
if (_had_arg) msg << "\n"; \
msg << ");\n"; \
msg << ");\n"; \
std::cout << msg.str(); \
} } while (0); \
} } while (0); \
}
#define LOG_FUNC_BEGIN_ARG_RESULT_NO_INIT \
@ -441,23 +441,23 @@ extern thread_local std::string _logThreadPrefix;
// LOG_FORWARD indicates that an api is implemented by a forward to another API
#define LOG_FORWARD(api) \
LOG_INIT \
LOG_INIT \
LOG_CHECK_ENABLED(LOG_LEVEL::DEBUG) { \
do { if(g_bPrintfOn) { \
std::cout << _logThreadPrefix << _logFuncPrefix << " forwarding to "#api"...\n"; \
} } while (0); \
} } while (0); \
}
// LOG_IGNORED indicates that Cxbx consiously ignores an api
#define LOG_IGNORED() \
do { \
static bool b_echoOnce = true; \
if(g_bPrintfOn && b_echoOnce) { \
if(g_bPrintfOn && b_echoOnce) { \
LOG_CHECK_ENABLED(LOG_LEVEL::INFO) { \
LOG_THREAD_INIT \
LOG_FUNC_INIT(__func__) \
std::cout << _logThreadPrefix << "WARN: " << _logFuncPrefix << " ignored!\n"; \
b_echoOnce = false; \
b_echoOnce = false; \
} \
} \
} while(0)
@ -466,12 +466,12 @@ extern thread_local std::string _logThreadPrefix;
#define LOG_UNIMPLEMENTED() \
do { \
static bool b_echoOnce = true; \
if(g_bPrintfOn && b_echoOnce) { \
if(g_bPrintfOn && b_echoOnce) { \
LOG_CHECK_ENABLED(LOG_LEVEL::INFO) { \
LOG_THREAD_INIT \
LOG_FUNC_INIT(__func__) \
std::cout << _logThreadPrefix << "WARN: " << _logFuncPrefix << " unimplemented!\n"; \
b_echoOnce = false; \
b_echoOnce = false; \
} \
} \
} while(0)
@ -480,12 +480,12 @@ extern thread_local std::string _logThreadPrefix;
#define LOG_INCOMPLETE() \
do { \
static bool b_echoOnce = true; \
if(g_bPrintfOn && b_echoOnce) { \
if(g_bPrintfOn && b_echoOnce) { \
LOG_CHECK_ENABLED(LOG_LEVEL::INFO) { \
LOG_THREAD_INIT \
LOG_FUNC_INIT(__func__) \
std::cout << _logThreadPrefix << "WARN: " << _logFuncPrefix << " incomplete!\n"; \
b_echoOnce = false; \
b_echoOnce = false; \
} \
} \
} while(0)
@ -494,12 +494,12 @@ extern thread_local std::string _logThreadPrefix;
#define LOG_NOT_SUPPORTED() \
do { \
static bool b_echoOnce = true; \
if(g_bPrintfOn && b_echoOnce) { \
if(g_bPrintfOn && b_echoOnce) { \
LOG_CHECK_ENABLED(LOG_LEVEL::INFO) { \
LOG_THREAD_INIT \
LOG_FUNC_INIT(__func__) \
std::cout << _logThreadPrefix << "WARN: " << _logFuncPrefix << " not supported!\n"; \
b_echoOnce = false; \
b_echoOnce = false; \
} \
} \
} while(0)
@ -626,6 +626,6 @@ LOGRENDER_HEADER_BY_REF(Type) \
// An example type rendering, for PVOID
//
LOGRENDER_HEADER_BY_REF(PVOID);
LOGRENDER_HEADER_BY_REF(PVOID);
#endif _LOGGING_H

View File

@ -52,4 +52,4 @@ unsigned char virtual_memory_placeholder[VM_PLACEHOLDER_SIZE]; // = { OPCODE_NOP
#endif
#endif
#endif // RESERVEDMEMORY_H
#endif // RESERVEDMEMORY_H

View File

@ -82,7 +82,7 @@ static struct {
const char* RecentXbeFiles = "RecentXbeFiles";
const char* DataStorageToggle = "DataStorageToggle";
const char* DataCustomLocation = "DataCustomLocation";
const char* IgnoreInvalidXbeSig = "IgnoreInvalidXbeSig";
const char* IgnoreInvalidXbeSig = "IgnoreInvalidXbeSig";
const char *IgnoreInvalidXbeSec = "IgnoreInvalidXbeSec";
} sect_gui_keys;
@ -316,7 +316,7 @@ bool Settings::LoadConfig()
index++;
}
m_gui.bIgnoreInvalidXbeSig = m_si.GetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSig, /*Default=*/false);
m_gui.bIgnoreInvalidXbeSig = m_si.GetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSig, /*Default=*/false);
m_gui.bIgnoreInvalidXbeSec = m_si.GetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSec, /*Default=*/false);
// ==== GUI End =============
@ -453,17 +453,17 @@ bool Settings::LoadConfig()
// ==== Input Profile Begin ====
std::array<std::vector<std::string>, to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)> control_names;
for (int device = 0; device < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX); device++) {
for (int device = 0; device < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX); device++) {
if (dev_num_buttons[device] == 0) {
continue;
}
}
for (int i = 0; i < dev_num_buttons[device]; i++) {
char control_name[30];
std::sprintf(control_name, sect_input_profiles.control, button_xbox_ctrl_names[i][0]);
control_names[device].push_back(control_name);
}
}
}
// TODO: add the control names of the other devices
@ -519,7 +519,7 @@ bool Settings::Save(std::string file_path)
m_si.SetValue(section_gui, sect_gui_keys.RecentXbeFiles, m_gui.szRecentXbeFiles[i].c_str(), nullptr, false);
}
m_si.SetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSig, m_gui.bIgnoreInvalidXbeSig, nullptr, true);
m_si.SetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSig, m_gui.bIgnoreInvalidXbeSig, nullptr, true);
m_si.SetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSec, m_gui.bIgnoreInvalidXbeSec, nullptr, true);
// ==== GUI End =============
@ -598,16 +598,16 @@ bool Settings::Save(std::string file_path)
// ==== Input Profile Begin ====
std::array<std::vector<std::string>, to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)> control_names;
for (int device = 0; device < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX); device++) {
for (int device = 0; device < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX); device++) {
if (dev_num_buttons[device] == 0) {
continue;
}
}
for (int i = 0; i < dev_num_buttons[device]; i++) {
char control_name[30];
std::sprintf(control_name, sect_input_profiles.control, button_xbox_ctrl_names[i][0]);
control_names[device].push_back(control_name);
}
}
}
// TODO: add the control names of the other devices

View File

@ -18,7 +18,7 @@
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// * (c) 2017-2018 RadWolfie
// * (c) 2017-2018 RadWolfie
// * (c) 2019 ergo720
// *
// * All rights reserved
@ -28,21 +28,21 @@
#define SETTINGS_HPP
#include "Cxbx.h"
#include "SimpleIni.h"
#include "input\InputDevice.h"
#include "SimpleIni.h"
#include "input\InputDevice.h"
#include "common\util\CxbxUtil.h"
#include <string>
#include <array>
#include <string>
#include <array>
extern std::string g_exec_filepath;
// Individual library version
extern uint16_t g_LibVersion_D3D8;
// Individual library version
extern uint16_t g_LibVersion_D3D8;
extern uint16_t g_LibVersion_DSOUND;
#define szSettings_alloc_error "ERROR: Unable to allocate Settings class."
#define assert_check_shared_memory(type) \
"Invalid "#type" size, please verify structure is align, not adding new member, or is using placeholder reserves." \
"Invalid "#type" size, please verify structure is align, not adding new member, or is using placeholder reserves." \
" Otherwise, please perform versioning upgrade and update "#type" sizeof check."
// Cxbx-Reloaded's data storage location.
@ -51,12 +51,12 @@ typedef enum _CXBX_DATA {
CXBX_DATA_APPDATA = 0,
CXBX_DATA_EXECDIR = 1,
CXBX_DATA_CUSTOM = 2,
} CXBX_DATA;
} CXBX_DATA;
// ******************************************************************
// * Define number of integers required to store logging settings
// ******************************************************************
#define NUM_INTEGERS_LOG 2
#define NUM_INTEGERS_LOG 2
enum {
LLE_NONE = 0,
@ -88,18 +88,18 @@ public:
std::string szRecentXbeFiles[10];
unsigned int DataStorageToggle;
std::string szCustomLocation = "";
bool bIgnoreInvalidXbeSig;
bool bIgnoreInvalidXbeSig;
bool bIgnoreInvalidXbeSec;
} m_gui;
// Core settings
struct s_core {
struct s_core {
unsigned int Revision;
unsigned int FlagsLLE;
DebugMode KrnlDebugMode;
char szKrnlDebug[MAX_PATH] = "";
char szStorageLocation[MAX_PATH] = "";
unsigned int LoggedModules[NUM_INTEGERS_LOG];
unsigned int LoggedModules[NUM_INTEGERS_LOG];
int LogLevel = 1;
bool bUseLoaderExec;
bool allowAdminPrivilege;
@ -116,7 +116,7 @@ public:
unsigned int direct3DDevice;
bool bVSync;
bool bFullScreen;
bool bHardwareYUV;
bool bHardwareYUV;
bool Reserved3;
int renderScaleFactor = 1;
int Reserved99[9] = { 0 };
@ -133,34 +133,34 @@ public:
int Reserved99[14] = { 0 };
} m_audio;
static_assert(sizeof(s_audio) == 0x4C, assert_check_shared_memory(s_audio));
struct s_input {
int Type;
std::string DeviceName;
std::string ProfileName;
};
std::array<s_input, 4> m_input;
struct s_input_profiles {
int Type;
std::string ProfileName;
std::string DeviceName;
std::vector<std::string> ControlList;
};
std::array<std::vector<s_input_profiles>, to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)> m_input_profiles;
struct s_input {
int Type;
std::string DeviceName;
std::string ProfileName;
};
std::array<s_input, 4> m_input;
struct s_input_profiles {
int Type;
std::string ProfileName;
std::string DeviceName;
std::vector<std::string> ControlList;
};
std::array<std::vector<s_input_profiles>, to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)> m_input_profiles;
// Network settings
struct s_network {
char adapter_name[MAX_PATH] = "";
} m_network;
static_assert(sizeof(s_network) == 0x104, assert_check_shared_memory(s_network));
// Hack settings
// NOTE: When removing fields, replace them with place-holders
// The size and order of this structure should *not* be allowed to change
// Hack settings
// NOTE: When removing fields, replace them with place-holders
// The size and order of this structure should *not* be allowed to change
// TODO: Fix IPC/Shared Memory so this isn't necessary
struct s_hack {
bool DisablePixelShaders;
bool DisablePixelShaders;
bool Reserved2;
bool UseAllCores;
bool SkipRdtscPatching;
@ -172,7 +172,7 @@ public:
} m_hacks;
static_assert(sizeof(s_hack) == 0x28, assert_check_shared_memory(s_hack));
private:
private:
void RemoveLegacyConfigs(unsigned int CurrentRevision);
std::string m_file_path = "";
CSimpleIniA m_si;

View File

@ -24,32 +24,32 @@
// * All rights reserved
// *
// ******************************************************************
#ifdef _WIN32
#include <windows.h>
#include <windows.h>
#endif
#include <thread>
#include <vector>
#include <vector>
#include <mutex>
#include "Timer.h"
#include "common\util\CxbxUtil.h"
#include "common\util\CxbxUtil.h"
#include "core\kernel\init\CxbxKrnl.h"
#ifdef __linux__
#include <time.h>
#endif
// Virtual clocks will probably become useful once LLE CPU is implemented, but for now we don't need them.
// Virtual clocks will probably become useful once LLE CPU is implemented, but for now we don't need them.
// See the QEMUClockType QEMU_CLOCK_VIRTUAL of XQEMU for more info.
#define CLOCK_REALTIME 0
//#define CLOCK_VIRTUALTIME 1
// Vector storing all the timers created
static std::vector<TimerObject*> TimerList;
static std::vector<TimerObject*> TimerList;
// The frequency of the high resolution clock of the host
uint64_t HostClockFrequency;
// Lock to acquire when accessing TimerList
uint64_t HostClockFrequency;
// Lock to acquire when accessing TimerList
std::mutex TimerMtx;
@ -61,8 +61,8 @@ uint64_t GetTime_NS(TimerObject* Timer)
QueryPerformanceCounter(&li);
uint64_t Ret = Muldiv64(li.QuadPart, SCALE_S_IN_NS, (uint32_t)HostClockFrequency);
#elif __linux__
static struct timespec ts;
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
static struct timespec ts;
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
uint64_t Ret = Muldiv64(ts.tv_sec, SCALE_S_IN_NS, 1) + ts.tv_nsec;
#else
#error "Unsupported OS"
@ -79,16 +79,16 @@ static inline uint64_t GetNextExpireTime(TimerObject* Timer)
// Deallocates the memory of the timer
void Timer_Destroy(TimerObject* Timer)
{
unsigned int index, i;
std::lock_guard<std::mutex>lock(TimerMtx);
unsigned int index, i;
std::lock_guard<std::mutex>lock(TimerMtx);
index = TimerList.size();
for (i = 0; i < index; i++) {
if (Timer == TimerList[i]) {
index = i;
}
}
assert(index != TimerList.size());
delete Timer;
TimerList.erase(TimerList.begin() + index);
@ -96,12 +96,12 @@ void Timer_Destroy(TimerObject* Timer)
// Thread that runs the timer
void ClockThread(TimerObject* Timer)
{
uint64_t NewExpireTime;
{
uint64_t NewExpireTime;
if (!Timer->Name.empty()) {
CxbxSetThreadName(Timer->Name.c_str());
}
}
if (Timer->CpuAffinity != nullptr) {
InitXboxThread(*Timer->CpuAffinity);
}
@ -115,7 +115,7 @@ void ClockThread(TimerObject* Timer)
}
Timer->Callback(Timer->Opaque);
NewExpireTime = GetNextExpireTime(Timer);
}
}
Sleep(1); // prevent burning the cpu
}
}
@ -134,22 +134,22 @@ void Timer_Exit(TimerObject* Timer)
// Allocates the memory for the timer object
TimerObject* Timer_Create(TimerCB Callback, void* Arg, std::string Name, unsigned long* Affinity)
{
{
std::lock_guard<std::mutex>lock(TimerMtx);
TimerObject* pTimer = new TimerObject;
pTimer->Type = CLOCK_REALTIME;
pTimer->Callback = Callback;
pTimer->ExpireTime_MS.store(0);
pTimer->Exit.store(false);
pTimer->Opaque = Arg;
Name.empty() ? pTimer->Name = "Unnamed thread" : pTimer->Name = Name;
pTimer->Opaque = Arg;
Name.empty() ? pTimer->Name = "Unnamed thread" : pTimer->Name = Name;
pTimer->CpuAffinity = Affinity;
TimerList.emplace_back(pTimer);
return pTimer;
}
// Starts the timer
// Starts the timer
// Expire_MS must be expressed in NS
void Timer_Start(TimerObject* Timer, uint64_t Expire_MS)
{

View File

@ -28,13 +28,13 @@
#ifndef TIMER_H
#define TIMER_H
#include <atomic>
#include <atomic>
#define SCALE_S_IN_NS 1000000000
#define SCALE_MS_IN_NS 1000000
#define SCALE_US_IN_NS 1000
#define SCALE_NS_IN_NS 1
#define SCALE_NS_IN_NS 1
#define SCALE_S_IN_US 1000000
#define SCALE_MS_IN_US 1000
#define SCALE_US_IN_US 1
@ -47,8 +47,8 @@ typedef struct _TimerObject
std::atomic_uint64_t ExpireTime_MS; // when the timer expires (ms)
std::atomic_bool Exit; // indicates that the timer should be destroyed
TimerCB Callback; // function to call when the timer expires
void* Opaque; // opaque argument to pass to the callback
std::string Name; // the name of the timer thread (if any)
void* Opaque; // opaque argument to pass to the callback
std::string Name; // the name of the timer thread (if any)
unsigned long* CpuAffinity; // the cpu affinity of the timer thread (if any)
}
TimerObject;

File diff suppressed because it is too large Load Diff

View File

@ -23,42 +23,42 @@
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef EMUDES_H
#define EMUDES_H
#define MBEDTLS_DES_KEY_SIZE 8
#define MBEDTLS_DES_ENCRYPT 1
#define MBEDTLS_DES_DECRYPT 0
#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */
/**
* \brief DES context structure
*/
typedef struct
{
uint32_t sk[32]; /*!< DES subkeys */
}
mbedtls_des_context;
/**
* \brief Triple-DES context structure
*/
typedef struct
{
uint32_t sk[96]; /*!< 3DES subkeys */
}
mbedtls_des3_context;
void mbedtls_des_key_set_parity(unsigned char* Key, unsigned long KeyLenght);
void mbedtls_des_setkey_enc(mbedtls_des_context* ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]);
void mbedtls_des_crypt_ecb(mbedtls_des_context* ctx, const unsigned char input[8], unsigned char output[8], unsigned long encrypt);
int mbedtls_des_crypt_cbc(mbedtls_des_context* ctx, unsigned long mode, unsigned long length, unsigned char iv[8], const unsigned char* input, unsigned char* output);
void mbedtls_des3_set3key_enc(mbedtls_des3_context* ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]);
void mbedtls_des3_crypt_ecb(mbedtls_des3_context* ctx, const unsigned char input[8], unsigned char output[8], unsigned long encrypt);
int mbedtls_des3_crypt_cbc(mbedtls_des3_context* ctx, unsigned long mode, unsigned long length, unsigned char iv[8], const unsigned char *input, unsigned char *output);
#endif EMUDES_H
// ******************************************************************
#ifndef EMUDES_H
#define EMUDES_H
#define MBEDTLS_DES_KEY_SIZE 8
#define MBEDTLS_DES_ENCRYPT 1
#define MBEDTLS_DES_DECRYPT 0
#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */
/**
* \brief DES context structure
*/
typedef struct
{
uint32_t sk[32]; /*!< DES subkeys */
}
mbedtls_des_context;
/**
* \brief Triple-DES context structure
*/
typedef struct
{
uint32_t sk[96]; /*!< 3DES subkeys */
}
mbedtls_des3_context;
void mbedtls_des_key_set_parity(unsigned char* Key, unsigned long KeyLenght);
void mbedtls_des_setkey_enc(mbedtls_des_context* ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]);
void mbedtls_des_crypt_ecb(mbedtls_des_context* ctx, const unsigned char input[8], unsigned char output[8], unsigned long encrypt);
int mbedtls_des_crypt_cbc(mbedtls_des_context* ctx, unsigned long mode, unsigned long length, unsigned char iv[8], const unsigned char* input, unsigned char* output);
void mbedtls_des3_set3key_enc(mbedtls_des3_context* ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]);
void mbedtls_des3_crypt_ecb(mbedtls_des3_context* ctx, const unsigned char input[8], unsigned char output[8], unsigned long encrypt);
int mbedtls_des3_crypt_cbc(mbedtls_des3_context* ctx, unsigned long mode, unsigned long length, unsigned char iv[8], const unsigned char *input, unsigned char *output);
#endif EMUDES_H

View File

@ -1,161 +1,161 @@
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2018 ergo720
// * (c) 2019 Jannik Vogel
// *
// * All rights reserved
// *
// ******************************************************************
// Acknowledgment:
// verify_hash, RSApkcs1paddingtable and RSA_PUBLIC_KEY are from the
// file xboxlib.c of the xbedump tool (and that file only, GPLv2).
// https://github.com/XboxDev/xbedump/blob/master/xboxlib.c
// mbedtls_swap_endianness is extracted from mbedtls_mpi_read_binary used in the file bignum.h of ReactOS
// https://github.com/reactos/reactos
// xboxlib.c license
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/**
* \file bignum.h
*
* \brief Multi-precision integer library
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#define LOG_PREFIX CXBXR_MODULE::RSA
#include "EmuRsa.h"
#include "core\kernel\support\Emu.h" // For EmuLog
#include "tomcrypt.h"
#include "tommath.h"
#define CHK_MP_RET(x) do { int ret = (x); if (ret != MP_OKAY) return false; } while(0)
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2018 ergo720
// * (c) 2019 Jannik Vogel
// *
// * All rights reserved
// *
// ******************************************************************
// Acknowledgment:
// verify_hash, RSApkcs1paddingtable and RSA_PUBLIC_KEY are from the
// file xboxlib.c of the xbedump tool (and that file only, GPLv2).
// https://github.com/XboxDev/xbedump/blob/master/xboxlib.c
// mbedtls_swap_endianness is extracted from mbedtls_mpi_read_binary used in the file bignum.h of ReactOS
// https://github.com/reactos/reactos
// xboxlib.c license
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/**
* \file bignum.h
*
* \brief Multi-precision integer library
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#define LOG_PREFIX CXBXR_MODULE::RSA
#include "EmuRsa.h"
#include "core\kernel\support\Emu.h" // For EmuLog
#include "tomcrypt.h"
#include "tommath.h"
#define CHK_MP_RET(x) do { int ret = (x); if (ret != MP_OKAY) return false; } while(0)
const unsigned char RSApkcs1paddingtable[3][16] = {
{ 0x0F, 0x14,0x04,0x00,0x05,0x1A,0x02,0x03,0x0E,0x2B,0x05,0x06,0x09,0x30,0x21,0x30 },
{ 0x0D, 0x14,0x04,0x1A,0x02,0x03,0x0E,0x2B,0x05,0x06,0x07,0x30,0x1F,0x30,0x00,0x00 },
{ 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }
};
// Move this to CxbxUtil.h if it's ever needed in other places of the emu as well
void mbedtls_swap_endianness(const unsigned char* in_buf, unsigned char* out_buf, size_t size)
{
size_t i, j, n;
uint32_t* out_buf_uint = (uint32_t*)out_buf;
memset(out_buf_uint, 0, size);
for (n = 0; n < size; n++)
if (in_buf[n] != 0)
break;
for (i = size, j = 0; i > n; i--, j++) {
out_buf_uint[j / 4] |= ((uint32_t)in_buf[i - 1]) << ((j % 4) << 3);
}
}
void init_tom_lib()
{
// NOTE: init_LTM has been deprecated in favor to crypt_mp_init("L"). However, in the latest master branch crypt_mp_init
// is still undefined.
static bool need_init = true;
if (need_init) {
init_LTM();
need_init = false;
}
}
bool xbox_exp_mod(unsigned char* pA, const unsigned char* pB, const unsigned char* pC, const unsigned char* pD,
size_t a_size, size_t b_size, size_t c_size, size_t d_size)
{
mp_int a, b, c, d;
CHK_MP_RET(mp_init(&a));
CHK_MP_RET(mp_init(&b));
CHK_MP_RET(mp_init(&c));
CHK_MP_RET(mp_init(&d));
CHK_MP_RET(mp_import(&b, 1, -1, b_size, 0, 0, pB));
CHK_MP_RET(mp_import(&c, 1, -1, c_size, 0, 0, pC));
CHK_MP_RET(mp_import(&d, 1, -1, d_size, 0, 0, pD));
CHK_MP_RET(mp_exptmod(&b, &c, &d, &a));
CHK_MP_RET(mp_export(pA, NULL, -1, a_size, 0, 0, &a));
return true;
}
bool xbox_rsa_public(const unsigned char* in_buf, unsigned char* out_buf, RSA_PUBLIC_KEY key)
{
rsa_key tom_key;
unsigned char in_buf_be[256] = { 0 };
unsigned char out_buf_be[256] = { 0 };
unsigned long out_len = 256;
unsigned char modulus_be[256] = { 0 };
unsigned char exp_be[4] = { 0 };
// We must swap the data since libtom expects the data to be in big endian
mbedtls_swap_endianness (key.KeyData.Modulus, modulus_be, 256);
mbedtls_swap_endianness (key.KeyData.Exponent, exp_be, 4);
mbedtls_swap_endianness (in_buf, in_buf_be, 256);
if (rsa_set_key(modulus_be, 256, exp_be, 4, NULL, 0, &tom_key) != CRYPT_OK) {
EmuLog(LOG_LEVEL::WARNING, "Failed to load rsa key");
return false;
}
if (rsa_exptmod(in_buf_be, 256, out_buf_be, &out_len, PK_PUBLIC, &tom_key) != CRYPT_OK) {
EmuLog(LOG_LEVEL::WARNING, "rsa_exptmod failed");
return false;
}
mbedtls_swap_endianness(out_buf_be, out_buf, 256);
return true;
}
bool verify_hash(const unsigned char* hash, const unsigned char* decryptBuffer, RSA_PUBLIC_KEY key)
{
};
// Move this to CxbxUtil.h if it's ever needed in other places of the emu as well
void mbedtls_swap_endianness(const unsigned char* in_buf, unsigned char* out_buf, size_t size)
{
size_t i, j, n;
uint32_t* out_buf_uint = (uint32_t*)out_buf;
memset(out_buf_uint, 0, size);
for (n = 0; n < size; n++)
if (in_buf[n] != 0)
break;
for (i = size, j = 0; i > n; i--, j++) {
out_buf_uint[j / 4] |= ((uint32_t)in_buf[i - 1]) << ((j % 4) << 3);
}
}
void init_tom_lib()
{
// NOTE: init_LTM has been deprecated in favor to crypt_mp_init("L"). However, in the latest master branch crypt_mp_init
// is still undefined.
static bool need_init = true;
if (need_init) {
init_LTM();
need_init = false;
}
}
bool xbox_exp_mod(unsigned char* pA, const unsigned char* pB, const unsigned char* pC, const unsigned char* pD,
size_t a_size, size_t b_size, size_t c_size, size_t d_size)
{
mp_int a, b, c, d;
CHK_MP_RET(mp_init(&a));
CHK_MP_RET(mp_init(&b));
CHK_MP_RET(mp_init(&c));
CHK_MP_RET(mp_init(&d));
CHK_MP_RET(mp_import(&b, 1, -1, b_size, 0, 0, pB));
CHK_MP_RET(mp_import(&c, 1, -1, c_size, 0, 0, pC));
CHK_MP_RET(mp_import(&d, 1, -1, d_size, 0, 0, pD));
CHK_MP_RET(mp_exptmod(&b, &c, &d, &a));
CHK_MP_RET(mp_export(pA, NULL, -1, a_size, 0, 0, &a));
return true;
}
bool xbox_rsa_public(const unsigned char* in_buf, unsigned char* out_buf, RSA_PUBLIC_KEY key)
{
rsa_key tom_key;
unsigned char in_buf_be[256] = { 0 };
unsigned char out_buf_be[256] = { 0 };
unsigned long out_len = 256;
unsigned char modulus_be[256] = { 0 };
unsigned char exp_be[4] = { 0 };
// We must swap the data since libtom expects the data to be in big endian
mbedtls_swap_endianness (key.KeyData.Modulus, modulus_be, 256);
mbedtls_swap_endianness (key.KeyData.Exponent, exp_be, 4);
mbedtls_swap_endianness (in_buf, in_buf_be, 256);
if (rsa_set_key(modulus_be, 256, exp_be, 4, NULL, 0, &tom_key) != CRYPT_OK) {
EmuLog(LOG_LEVEL::WARNING, "Failed to load rsa key");
return false;
}
if (rsa_exptmod(in_buf_be, 256, out_buf_be, &out_len, PK_PUBLIC, &tom_key) != CRYPT_OK) {
EmuLog(LOG_LEVEL::WARNING, "rsa_exptmod failed");
return false;
}
mbedtls_swap_endianness(out_buf_be, out_buf, 256);
return true;
}
bool verify_hash(const unsigned char* hash, const unsigned char* decryptBuffer, RSA_PUBLIC_KEY key)
{
unsigned char cmphash[20];
int a;
int zero_position = 20;
@ -192,5 +192,5 @@ bool verify_hash(const unsigned char* hash, const unsigned char* decryptBuffer,
if (decryptBuffer[i] != 0xff) return false;
}
return true;
}
return true;
}

View File

@ -1,55 +1,55 @@
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2018-2019 ergo720
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef EMURSA_H
#define EMURSA_H
#include <cstdlib> // For size_t
#pragma pack(4)
typedef union _RSA_PUBLIC_KEY
{
unsigned char Default[284];
struct {
char Magic[4]; // "RSA1"
unsigned int Bloblen; // 264 (Modulus + Exponent + Modulussize)
unsigned char Bitlen[4]; // 2048
unsigned int ModulusSize; // 255 (bytes in the Modulus)
unsigned char Exponent[4]; // Public exponent
unsigned char Modulus[256]; // Bit endian style
unsigned char Unknown[8]; // ?
}KeyData;
} RSA_PUBLIC_KEY;
#pragma pack()
void init_tom_lib();
bool xbox_exp_mod(unsigned char* pA, const unsigned char* pB, const unsigned char* pC, const unsigned char* pD,
size_t a_size, size_t b_size, size_t c_size, size_t d_size);
bool xbox_rsa_public(const unsigned char* in_buf, unsigned char* out_buf, RSA_PUBLIC_KEY key);
bool verify_hash(const unsigned char* hash, const unsigned char* decryptBuffer, RSA_PUBLIC_KEY key);
#endif
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2018-2019 ergo720
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef EMURSA_H
#define EMURSA_H
#include <cstdlib> // For size_t
#pragma pack(4)
typedef union _RSA_PUBLIC_KEY
{
unsigned char Default[284];
struct {
char Magic[4]; // "RSA1"
unsigned int Bloblen; // 264 (Modulus + Exponent + Modulussize)
unsigned char Bitlen[4]; // 2048
unsigned int ModulusSize; // 255 (bytes in the Modulus)
unsigned char Exponent[4]; // Public exponent
unsigned char Modulus[256]; // Bit endian style
unsigned char Unknown[8]; // ?
}KeyData;
} RSA_PUBLIC_KEY;
#pragma pack()
void init_tom_lib();
bool xbox_exp_mod(unsigned char* pA, const unsigned char* pB, const unsigned char* pC, const unsigned char* pD,
size_t a_size, size_t b_size, size_t c_size, size_t d_size);
bool xbox_rsa_public(const unsigned char* in_buf, unsigned char* out_buf, RSA_PUBLIC_KEY key);
bool verify_hash(const unsigned char* hash, const unsigned char* decryptBuffer, RSA_PUBLIC_KEY key);
#endif

View File

@ -43,7 +43,7 @@ A million repetitions of "a"
/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
/* #define SHA1HANDSOFF * Copies data before messing with it. */
// Acknowledgment: Steve Reid
// Acknowledgment: Steve Reid
// https://github.com/clibs/sha1
#define SHA1HANDSOFF

View File

@ -35,7 +35,7 @@ EmuDevice::EmuDevice(int type, HWND hwnd)
{
switch (type)
{
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE):
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE):
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
m_hwnd = hwnd;
for (size_t i = 0; i < ARRAY_SIZE(button_xbox_ctrl_id); i++) {

View File

@ -25,9 +25,9 @@
// *
// ******************************************************************
// Acknowledgment: Muldiv64 is from qemu-common.h which doesn't have a license header, iovector functions are from iov.c file.
// Both files were originally taken from XQEMU (GPLv2)
// https://xqemu.com/
// Acknowledgment: Muldiv64 is from qemu-common.h which doesn't have a license header, iovector functions are from iov.c file.
// Both files were originally taken from XQEMU (GPLv2)
// https://xqemu.com/
/*
* Helpers for getting linearized buffers from iov / filling buffers into iovs
@ -49,15 +49,15 @@
// The intent of this file is to add general functions which are not kernel specific (for those CxbxKrnl.h should be used instead)
#include <cstring> // For memcpy
#include "common\util\CxbxUtil.h"
#include "core\kernel\init\CxbxKrnl.h"
#include "common\util\CxbxUtil.h"
#include "core\kernel\init\CxbxKrnl.h"
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#endif
// Disable a compiler warning relative to uint64_t -> uint32_t conversions in Muldiv64. This function is taken from
// QEMU so it should be safe regardless
@ -150,133 +150,133 @@ size_t IoVecFromBuffer(const IoVec* iov, unsigned int iov_cnt, size_t offset, vo
// Read an array of DWORDs in memory
bool GetDwords(xbaddr Paddr, uint32_t* Buffer, int Number)
{
for (int i = 0; i < Number; i++, Buffer++, Paddr += sizeof(*Buffer)) {
// dropped little -> big endian conversion from XQEMU
for (int i = 0; i < Number; i++, Buffer++, Paddr += sizeof(*Buffer)) {
// dropped little -> big endian conversion from XQEMU
if (Memory_R(reinterpret_cast<void*>(Paddr), Buffer, 4)) {
return true;
}
}
}
return false;
}
// Write an array of DWORDs in memory
bool WriteDwords(xbaddr Paddr, uint32_t* Buffer, int Number)
{
for (int i = 0; i < Number; i++, Buffer++, Paddr += sizeof(*Buffer)) {
// dropped big -> little endian conversion from XQEMU
for (int i = 0; i < Number; i++, Buffer++, Paddr += sizeof(*Buffer)) {
// dropped big -> little endian conversion from XQEMU
if (Memory_W(reinterpret_cast<void*>(Paddr), Buffer, 4)) {
return true;
}
}
}
return false;
}
// Read an array of WORDs in memory
bool GetWords(xbaddr Paddr, uint16_t* Buffer, int Number)
{
for (int i = 0; i < Number; i++, Buffer++, Paddr += sizeof(*Buffer)) {
// dropped little -> big endian conversion from XQEMU
for (int i = 0; i < Number; i++, Buffer++, Paddr += sizeof(*Buffer)) {
// dropped little -> big endian conversion from XQEMU
if (Memory_R(reinterpret_cast<void*>(Paddr), Buffer, 2)) {
return true;
}
}
}
return false;
}
// Write an array of WORDs in memory
bool WriteWords(xbaddr Paddr, uint16_t* Buffer, int Number)
{
for (int i = 0; i < Number; i++, Buffer++, Paddr += sizeof(*Buffer)) {
// dropped big -> little endian conversion from XQEMU
for (int i = 0; i < Number; i++, Buffer++, Paddr += sizeof(*Buffer)) {
// dropped big -> little endian conversion from XQEMU
if (Memory_W(reinterpret_cast<void*>(Paddr), Buffer, 2)) {
return true;
}
}
}
return false;
}
bool Memory_R(void* Addr, void* Buf, size_t Num)
}
bool Memory_R(void* Addr, void* Buf, size_t Num)
{
bool Error = false;
bool Error = false;
if (Num != 0) {
if (Addr == nullptr) {
Error = true;
}
}
else {
std::memcpy(Buf, Addr, Num);
}
}
}
return Error;
}
bool Memory_W(void* Addr, void* Buf, size_t Num)
}
bool Memory_W(void* Addr, void* Buf, size_t Num)
{
bool Error = false;
bool Error = false;
if (Num != 0) {
if (Addr == nullptr) {
Error = true;
}
}
else {
std::memcpy(Addr, Buf, Num);
}
}
}
return Error;
}
bool Memory_RW(void* Addr, void* Buf, size_t Num, bool bIsWrite)
}
bool Memory_RW(void* Addr, void* Buf, size_t Num, bool bIsWrite)
{
if (bIsWrite) {
if (bIsWrite) {
return Memory_W(Addr, Buf, Num);
}
else {
else {
return Memory_R(Addr, Buf, Num);
}
}
// Converts LF to CRLF line endings
void unix2dos(std::string& string)
{
size_t position = 0;
while (true) {
position = string.find('\n', position);
if (position == std::string::npos) {
break;
}
if (position != 0 && string.compare(position - 1, 2U, "\r\n") == 0) {
position++;
continue;
}
string.insert(position, 1, '\r');
position += 2;
}
}
// Converts LF to CRLF line endings
void unix2dos(std::string& string)
{
size_t position = 0;
while (true) {
position = string.find('\n', position);
if (position == std::string::npos) {
break;
}
if (position != 0 && string.compare(position - 1, 2U, "\r\n") == 0) {
position++;
continue;
}
string.insert(position, 1, '\r');
position += 2;
}
}
// Copyright 2008 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file of Dolphin at https://github.com/dolphin-emu/dolphin/blob/master/license.txt.
// Source: StringUtil.cpp of Dolphin emulator
std::string StripChars(const std::string& str, const char* strip_chars)
{
const size_t s = str.find_first_not_of(strip_chars);
if (str.npos != s) {
return str.substr(s, str.find_last_not_of(strip_chars) - s + 1);
}
else {
return "";
}
}
/* Turns " hello " into "hello". Also handles tabs */
std::string StripSpaces(const std::string& str)
{
return StripChars(str, " \t\r\n");
}
std::string StripQuotes(const std::string& str)
{
return StripChars(str, "\"");
}
// Refer to the license.txt file of Dolphin at https://github.com/dolphin-emu/dolphin/blob/master/license.txt.
// Source: StringUtil.cpp of Dolphin emulator
std::string StripChars(const std::string& str, const char* strip_chars)
{
const size_t s = str.find_first_not_of(strip_chars);
if (str.npos != s) {
return str.substr(s, str.find_last_not_of(strip_chars) - s + 1);
}
else {
return "";
}
}
/* Turns " hello " into "hello". Also handles tabs */
std::string StripSpaces(const std::string& str)
{
return StripChars(str, " \t\r\n");
}
std::string StripQuotes(const std::string& str)
{
return StripChars(str, "\"");
}

View File

@ -17,7 +17,7 @@
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// * (c) 2018 ergo720
// *
// * All rights reserved
@ -26,13 +26,13 @@
#ifndef CXBXUTIL_H
#define CXBXUTIL_H
#include "Cxbx.h"
#include <stdint.h>
#include <assert.h>
#include <string>
#include "Cxbx.h"
#include <stdint.h>
#include <assert.h>
#include <string>
#include <type_traits>
#include "std_extend.hpp" // for ARRAY_SIZE
/* This is a linux struct for vectored I/O. See readv() and writev() */
struct IoVec
{
@ -58,24 +58,24 @@ size_t IoVecFromBuffer(const IoVec* iov, unsigned int iov_cnt, size_t offset, vo
bool WriteDwords(xbaddr Paddr, uint32_t* Buffer, int Number);
bool GetDwords(xbaddr Paddr, uint32_t* Buffer, int Number);
bool GetWords(xbaddr Paddr, uint16_t* Buffer, int Number);
bool WriteWords(xbaddr Paddr, uint16_t* Buffer, int Number);
bool Memory_R(void* Addr, void* Buf, size_t Num);
bool Memory_W(void* Addr, void* Buf, size_t Num);
bool Memory_RW(void* Addr, void* Buf, size_t Num, bool bIsWrite);
void unix2dos(std::string& string);
std::string StripSpaces(const std::string& str);
std::string StripQuotes(const std::string& str);
// Retrieves the underlying integer value of a scoped enumerator. It allows to avoid using static_cast every time
template <typename E>
constexpr typename std::underlying_type<E>::type to_underlying(E e) noexcept
{
return static_cast<std::underlying_type_t<E>>(e);
bool WriteWords(xbaddr Paddr, uint16_t* Buffer, int Number);
bool Memory_R(void* Addr, void* Buf, size_t Num);
bool Memory_W(void* Addr, void* Buf, size_t Num);
bool Memory_RW(void* Addr, void* Buf, size_t Num, bool bIsWrite);
void unix2dos(std::string& string);
std::string StripSpaces(const std::string& str);
std::string StripQuotes(const std::string& str);
// Retrieves the underlying integer value of a scoped enumerator. It allows to avoid using static_cast every time
template <typename E>
constexpr typename std::underlying_type<E>::type to_underlying(E e) noexcept
{
return static_cast<std::underlying_type_t<E>>(e);
}
#define GET_WORD_LOW(value) (uint8_t)((value) & 0xFF)
#define GET_WORD_HIGH(value) (uint8_t)(((value) >> 8) & 0xFF)
#define GET_WORD_HIGH(value) (uint8_t)(((value) >> 8) & 0xFF)
/*! round dwValue to the nearest multiple of dwMult */
static uint32_t RoundUp(uint32_t dwValue, uint32_t dwMult)
@ -87,6 +87,6 @@ static uint32_t RoundUp(uint32_t dwValue, uint32_t dwMult)
return dwValue;
return dwValue + dwMult - remainder;
}
}
#endif

View File

@ -199,11 +199,11 @@ void glo_context_destroy(GloContext *context)
free(context);
}
void glo_swap(GloContext *context)
{
if (!context) { return; }
SwapBuffers(context->hDC);
}
void glo_swap(GloContext *context)
{
if (!context) { return; }
SwapBuffers(context->hDC);
}

View File

@ -25,31 +25,31 @@
#ifndef EMUSHARED_H
#define EMUSHARED_H
#include "Cxbx.h"
#include "common\Settings.hpp"
#include "Mutex.h"
#include "common\IPCHybrid.hpp"
#include "common\input\Button.h"
#include "Cxbx.h"
#include "common\Settings.hpp"
#include "Mutex.h"
#include "common\IPCHybrid.hpp"
#include "common\input\Button.h"
#include <memory.h>
extern HMODULE hActiveModule; // Equals EXE Module handle in (GUI) Cxbx.exe / cxbxr.exe, equals DLL Module handle in cxbxr-emu.dll
extern HMODULE hActiveModule; // Equals EXE Module handle in (GUI) Cxbx.exe / cxbxr.exe, equals DLL Module handle in cxbxr-emu.dll
typedef enum _XBOX_LED_COLOUR: unsigned char {
XBOX_LED_COLOUR_OFF,
XBOX_LED_COLOUR_GREEN,
XBOX_LED_COLOUR_RED,
XBOX_LED_COLOUR_ORANGE,
} XBOX_LED_COLOUR;
// Kernel boot flags
enum {
BOOT_NONE = 0,
BOOT_EJECT_PENDING = 1 << 0,
BOOT_FATAL_ERROR = 1 << 1,
BOOT_SKIP_ANIMATION = 1 << 2,
BOOT_RUN_DASHBOARD = 1 << 3,
BOOT_QUICK_REBOOT = 1 << 4,
} XBOX_LED_COLOUR;
// Kernel boot flags
enum {
BOOT_NONE = 0,
BOOT_EJECT_PENDING = 1 << 0,
BOOT_FATAL_ERROR = 1 << 1,
BOOT_SKIP_ANIMATION = 1 << 2,
BOOT_RUN_DASHBOARD = 1 << 3,
BOOT_QUICK_REBOOT = 1 << 4,
};
// ******************************************************************
@ -85,7 +85,7 @@ class EmuShared : public Mutex
// * Check if parent process is emulating title
// ******************************************************************
void GetIsEmulating(bool *isEmulating) { Lock(); *isEmulating = m_bEmulating_status; Unlock(); }
void SetIsEmulating(const bool isEmulating) { Lock(); m_bEmulating_status = isEmulating; Unlock(); }
void SetIsEmulating(const bool isEmulating) { Lock(); m_bEmulating_status = isEmulating; Unlock(); }
// ******************************************************************
// * Each child process need to wait until parent process is ready
@ -115,38 +115,38 @@ class EmuShared : public Mutex
// * Xbox Audio Accessors
// ******************************************************************
void GetAudioSettings( Settings::s_audio *audio) { Lock(); *audio = m_audio; Unlock(); }
void SetAudioSettings(const Settings::s_audio *audio) { Lock(); m_audio = *audio; Unlock(); }
void SetAudioSettings(const Settings::s_audio *audio) { Lock(); m_audio = *audio; Unlock(); }
// ******************************************************************
// * Xbox Network Accessors
// ******************************************************************
void GetNetworkSettings(Settings::s_network *network) { Lock(); *network = m_network; Unlock(); }
void SetNetworkSettings(const Settings::s_network *network) { Lock(); m_network = *network; Unlock(); }
// ******************************************************************
// * Input config Accessors
// ******************************************************************
void GetInputDevTypeSettings(int* type, int port) { Lock(); *type = m_DeviceType[port]; Unlock(); }
void SetInputDevTypeSettings(const int* type, int port) { Lock(); m_DeviceType[port] = *type; Unlock(); }
void GetInputDevNameSettings(char* name, int port) { Lock(); strncpy(name, m_DeviceName[port], 50); Unlock(); }
void SetInputDevNameSettings(const char* name, int port) { Lock(); strncpy(m_DeviceName[port], name, 50); Unlock(); }
void GetInputBindingsSettings(char button_str[][30], int max_num_buttons, int port)
{
assert(max_num_buttons <= XBOX_CTRL_NUM_BUTTONS);
Lock();
for (int i = 0; i < max_num_buttons; i++) {
strncpy(button_str[i], m_DeviceControlNames[port][i], 30);
}
Unlock();
}
void SetInputBindingsSettings(const char button_str[][30], int max_num_buttons, int port)
{
assert(max_num_buttons <= XBOX_CTRL_NUM_BUTTONS);
Lock();
for (int i = 0; i < max_num_buttons; i++) {
strncpy(m_DeviceControlNames[port][i], button_str[i], 30);
}
Unlock();
// ******************************************************************
// * Input config Accessors
// ******************************************************************
void GetInputDevTypeSettings(int* type, int port) { Lock(); *type = m_DeviceType[port]; Unlock(); }
void SetInputDevTypeSettings(const int* type, int port) { Lock(); m_DeviceType[port] = *type; Unlock(); }
void GetInputDevNameSettings(char* name, int port) { Lock(); strncpy(name, m_DeviceName[port], 50); Unlock(); }
void SetInputDevNameSettings(const char* name, int port) { Lock(); strncpy(m_DeviceName[port], name, 50); Unlock(); }
void GetInputBindingsSettings(char button_str[][30], int max_num_buttons, int port)
{
assert(max_num_buttons <= XBOX_CTRL_NUM_BUTTONS);
Lock();
for (int i = 0; i < max_num_buttons; i++) {
strncpy(button_str[i], m_DeviceControlNames[port][i], 30);
}
Unlock();
}
void SetInputBindingsSettings(const char button_str[][30], int max_num_buttons, int port)
{
assert(max_num_buttons <= XBOX_CTRL_NUM_BUTTONS);
Lock();
for (int i = 0; i < max_num_buttons; i++) {
strncpy(m_DeviceControlNames[port][i], button_str[i], 30);
}
Unlock();
}
// ******************************************************************
@ -163,9 +163,9 @@ class EmuShared : public Mutex
// ******************************************************************
// * Hack Flag Accessors
// ******************************************************************
void GetHackSettings(Settings::s_hack *hacks) { Lock(); *hacks = m_hacks; Unlock(); }
void SetHackSettings(Settings::s_hack *hacks) { Lock(); m_hacks = *hacks; Unlock(); }
// ******************************************************************
void GetHackSettings(Settings::s_hack *hacks) { Lock(); *hacks = m_hacks; Unlock(); }
void SetHackSettings(Settings::s_hack *hacks) { Lock(); m_hacks = *hacks; Unlock(); }
void GetDisablePixelShaders(int* value) { Lock(); *value = m_hacks.DisablePixelShaders; Unlock(); }
void SetDisablePixelShaders(const int* value) { Lock(); m_hacks.DisablePixelShaders = *value; Unlock(); }
@ -173,37 +173,37 @@ class EmuShared : public Mutex
void SetUseAllCores(const int* value) { Lock(); m_hacks.UseAllCores = *value; Unlock(); }
void GetSkipRdtscPatching(int* value) { Lock(); *value = m_hacks.SkipRdtscPatching; Unlock(); }
void SetSkipRdtscPatching(const int* value) { Lock(); m_hacks.SkipRdtscPatching = *value; Unlock(); }
// ******************************************************************
// * FPS/Benchmark values Accessors
// ******************************************************************
void GetCurrentFPS(float *value) { Lock(); *value = m_FPS_status; Unlock(); }
void SetCurrentFPS(const float *value) { Lock(); m_FPS_status = *value; Unlock(); }
// ******************************************************************
// * FPS/Benchmark values Accessors
// ******************************************************************
void GetIsKrnlLogEnabled(bool *value) { Lock(); *value = m_Krnl_Log_enabled; Unlock(); }
// ******************************************************************
// * FPS/Benchmark values Accessors
// ******************************************************************
void GetCurrentFPS(float *value) { Lock(); *value = m_FPS_status; Unlock(); }
void SetCurrentFPS(const float *value) { Lock(); m_FPS_status = *value; Unlock(); }
// ******************************************************************
// * FPS/Benchmark values Accessors
// ******************************************************************
void GetIsKrnlLogEnabled(bool *value) { Lock(); *value = m_Krnl_Log_enabled; Unlock(); }
void SetIsKrnlLogEnabled(const bool value) { Lock(); m_Krnl_Log_enabled = value; Unlock(); }
// ******************************************************************
// * Debugging flag Accessors
// ******************************************************************
void GetDebuggingFlag(bool *value) { Lock(); *value = m_bDebugging; Unlock(); }
void SetDebuggingFlag(const bool *value) { Lock(); m_bDebugging = *value; Unlock(); }
#ifndef CXBX_LOADER // Temporary usage for cxbx.exe's emu
void SetDebuggingFlag(const bool *value) { Lock(); m_bDebugging = *value; Unlock(); }
#ifndef CXBX_LOADER // Temporary usage for cxbx.exe's emu
// ******************************************************************
// * Previous Memory Layout value Accessors
// ******************************************************************
void GetMmLayout(unsigned int* value) { Lock(); *value = m_PreviousMmLayout; Unlock(); }
void SetMmLayout(unsigned int* value) { Lock(); m_PreviousMmLayout = *value; Unlock(); }
#endif
void SetMmLayout(unsigned int* value) { Lock(); m_PreviousMmLayout = *value; Unlock(); }
#endif
// ******************************************************************
// * Log Level value Accessors
// ******************************************************************
void GetLogLv(int *value) { Lock(); *value = m_core.LogLevel; Unlock(); }
void SetLogLv(int *value) { Lock(); m_core.LogLevel = *value; Unlock(); }
void SetLogLv(int *value) { Lock(); m_core.LogLevel = *value; Unlock(); }
// ******************************************************************
// * Log modules value Accessors
// ******************************************************************
@ -222,41 +222,41 @@ class EmuShared : public Mutex
m_core.LoggedModules[i] = value[i];
}
Unlock();
}
}
// ******************************************************************
// * Log Level value Accessors
// ******************************************************************
void GetLogPopupTestCase(bool *value) { Lock(); *value = m_core.bLogPopupTestCase; Unlock(); }
void SetLogPopupTestCase(const bool value) { Lock(); m_core.bLogPopupTestCase = value; Unlock(); }
void SetLogPopupTestCase(const bool value) { Lock(); m_core.bLogPopupTestCase = value; Unlock(); }
// ******************************************************************
// * File storage location
// ******************************************************************
void GetStorageLocation(char *path) { Lock(); strncpy(path, m_core.szStorageLocation, MAX_PATH); Unlock(); }
// ******************************************************************
void GetStorageLocation(char *path) { Lock(); strncpy(path, m_core.szStorageLocation, MAX_PATH); Unlock(); }
void SetStorageLocation(const char *path) { Lock(); strncpy(m_core.szStorageLocation, path, MAX_PATH); Unlock(); }
// ******************************************************************
// * Reset specific variables to default for kernel mode.
// ******************************************************************
void ResetKrnl()
{
// ******************************************************************
void ResetKrnl()
{
Lock();
m_BootFlags_status = 0;
m_FPS_status = 0.0f;
Unlock();
m_BootFlags_status = 0;
m_FPS_status = 0.0f;
Unlock();
}
// ******************************************************************
// * Reset specific variables to default for gui mode.
// ******************************************************************
void Reset()
{
// ******************************************************************
void Reset()
{
Lock();
ResetKrnl();
m_bEmulating_status = 0;
m_dwKrnlProcID = 0;
Unlock();
ResetKrnl();
m_bEmulating_status = 0;
m_dwKrnlProcID = 0;
Unlock();
}
private:
@ -274,31 +274,31 @@ class EmuShared : public Mutex
float m_Reserved6;
float m_FPS_status; // NOTE: If move into ipc_send_gui_update will spam GUI's message system (one message per frame)
bool m_Krnl_Log_enabled; // Is require in order to preserve previous set for support multi-xbe.
bool m_bDebugging;
bool m_bReady_status;
bool m_bEmulating_status;
#ifndef CXBX_LOADER // Temporary usage for cxbx.exe's emu
unsigned int m_PreviousMmLayout;
int m_Reserved7[3];
#else
int m_Reserved7[4];
#endif
bool m_bFirstLaunch;
bool m_bReserved2;
bool m_bReserved3;
bool m_bReserved4;
unsigned int m_dwKrnlProcID; // Only used for kernel mode level.
int m_DeviceType[4];
char m_DeviceControlNames[4][XBOX_CTRL_NUM_BUTTONS][30]; // macro should be num of buttons of dev with highest num buttons
bool m_bDebugging;
bool m_bReady_status;
bool m_bEmulating_status;
#ifndef CXBX_LOADER // Temporary usage for cxbx.exe's emu
unsigned int m_PreviousMmLayout;
int m_Reserved7[3];
#else
int m_Reserved7[4];
#endif
bool m_bFirstLaunch;
bool m_bReserved2;
bool m_bReserved3;
bool m_bReserved4;
unsigned int m_dwKrnlProcID; // Only used for kernel mode level.
int m_DeviceType[4];
char m_DeviceControlNames[4][XBOX_CTRL_NUM_BUTTONS][30]; // macro should be num of buttons of dev with highest num buttons
char m_DeviceName[4][50];
int m_Reserved99[28]; // Reserve space
// Settings class in memory should not be tampered by third-party.
// Third-party program should only be allow to edit settings.ini file.
int m_Reserved99[28]; // Reserve space
// Settings class in memory should not be tampered by third-party.
// Third-party program should only be allow to edit settings.ini file.
Settings::s_core m_core;
Settings::s_video m_video;
Settings::s_audio m_audio;
Settings::s_network m_network;
Settings::s_video m_video;
Settings::s_audio m_audio;
Settings::s_network m_network;
Settings::s_hack m_hacks;
};

View File

@ -55,7 +55,7 @@ bool CxbxExec(bool useDebugger, HANDLE* hProcess, bool requestHandleProcess) {
if (!cli_config::GenCMD(szProcArgsBuffer)) {
return false;
}
// TODO: Set a configuration variable for this. For now it will be within the same folder as Cxbx.exe
if (useDebugger) {
szProcArgsBuffer = "cxbxr-debugger.exe " + szProcArgsBuffer;

File diff suppressed because it is too large Load Diff

View File

@ -1,397 +1,397 @@
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// * (c) 2017 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef XBE_H
#define XBE_H
#include "common\Error.h"
#include "common/xbox/Types.hpp"
#include <cstdio>
//#include <windef.h> // For MAX_PATH
// The above leads to 55 compile errors, so until we've sorted out why that happens, declare MAX_PATH ourselves for now :
#define MAX_PATH 260
#define XPR_IMAGE_WH 128
#define XPR_IMAGE_DATA_SIZE (XPR_IMAGE_WH * XPR_IMAGE_WH) / 2
#define XPR_IMAGE_HDR_SIZE 2048
namespace xboxkrnl
{
typedef struct _XBE_SECTION XBEIMAGE_SECTION, *PXBEIMAGE_SECTION;
}
// Xbe (Xbox Executable) file object
class Xbe : public Error
{
public:
// construct via Xbe file
Xbe(const char *x_szFilename, bool bFromGUI);
// deconstructor
~Xbe();
// find an section by name
void *FindSection(char *zsSectionName);
// Find a section by its definition
void* FindSection(xboxkrnl::PXBEIMAGE_SECTION section);
// export to Xbe file
void Export(const char *x_szXbeFilename);
// verify the integrity of the xbe header
bool CheckSignature();
// verify the integrity of an xbe section
bool CheckSectionIntegrity(uint32_t sectionIndex);
// import logo bitmap from raw monochrome data
void ImportLogoBitmap(const uint8_t x_Gray[100*17]);
// export logo bitmap to raw monochrome data
void ExportLogoBitmap(uint8_t x_Gray[100*17]);
// purge illegal characters in Windows filenames or other OS's
void PurgeBadChar(std::string& s, const std::string& illegalChars = "\\/:?\"<>|");
// Convert game region field to string
const char *GameRegionToString();
XbeType GetXbeType();
// Xbe header
#include "AlignPrefix1.h"
struct Header
{
uint32_t dwMagic; // 0x0000 - magic number [should be "XBEH"]
uint8_t pbDigitalSignature[256]; // 0x0004 - digital signature
uint32_t dwBaseAddr; // 0x0104 - base address
uint32_t dwSizeofHeaders; // 0x0108 - size of headers
uint32_t dwSizeofImage; // 0x010C - size of image
uint32_t dwSizeofImageHeader; // 0x0110 - size of image header
uint32_t dwTimeDate; // 0x0114 - timedate stamp
uint32_t dwCertificateAddr; // 0x0118 - certificate address
uint32_t dwSections; // 0x011C - number of sections
uint32_t dwSectionHeadersAddr; // 0x0120 - section headers address
typedef struct
{
uint32_t bMountUtilityDrive : 1; // mount utility drive flag
uint32_t bFormatUtilityDrive : 1; // format utility drive flag
uint32_t bLimit64MB : 1; // limit development kit run time memory to 64mb flag
uint32_t bDontSetupHarddisk : 1; // don't setup hard disk flag
uint32_t Unused : 4; // unused (or unknown)
uint32_t Unused_b1 : 8; // unused (or unknown)
uint32_t Unused_b2 : 8; // unused (or unknown)
uint32_t Unused_b3 : 8; // unused (or unknown)
} InitFlags;
union { // 0x0124 - initialization flags
InitFlags dwInitFlags;
uint32_t dwInitFlags_value;
};
uint32_t dwEntryAddr; // 0x0128 - entry point address
uint32_t dwTLSAddr; // 0x012C - thread local storage directory address
uint32_t dwPeStackCommit; // 0x0130 - size of stack commit
uint32_t dwPeHeapReserve; // 0x0134 - size of heap reserve
uint32_t dwPeHeapCommit; // 0x0138 - size of heap commit
uint32_t dwPeBaseAddr; // 0x013C - original base address
uint32_t dwPeSizeofImage; // 0x0140 - size of original image
uint32_t dwPeChecksum; // 0x0144 - original checksum
uint32_t dwPeTimeDate; // 0x0148 - original timedate stamp
uint32_t dwDebugPathnameAddr; // 0x014C - debug pathname address
uint32_t dwDebugFilenameAddr; // 0x0150 - debug filename address
uint32_t dwDebugUnicodeFilenameAddr; // 0x0154 - debug unicode filename address
uint32_t dwKernelImageThunkAddr; // 0x0158 - kernel image thunk address
uint32_t dwNonKernelImportDirAddr; // 0x015C - non kernel import directory address
uint32_t dwLibraryVersions; // 0x0160 - number of library versions
uint32_t dwLibraryVersionsAddr; // 0x0164 - library versions address
uint32_t dwKernelLibraryVersionAddr; // 0x0168 - kernel library version address
uint32_t dwXAPILibraryVersionAddr; // 0x016C - xapi library version address
uint32_t dwLogoBitmapAddr; // 0x0170 - logo bitmap address
uint32_t dwSizeofLogoBitmap; // 0x0174 - logo bitmap size
}
#include "AlignPosfix1.h"
m_Header;
// Xbe header extra byte (used to preserve unknown data)
char *m_HeaderEx;
uint32_t m_ExSize;
// Xbe certificate
#include "AlignPrefix1.h"
struct Certificate
{
uint32_t dwSize; // 0x0000 - size of certificate
uint32_t dwTimeDate; // 0x0004 - timedate stamp
uint32_t dwTitleId; // 0x0008 - title id
wchar_t wszTitleName[40]; // 0x000C - title name (unicode)
uint32_t dwAlternateTitleId[0x10]; // 0x005C - alternate title ids
uint32_t dwAllowedMedia; // 0x009C - allowed media types
uint32_t dwGameRegion; // 0x00A0 - game region
uint32_t dwGameRatings; // 0x00A4 - game ratings
uint32_t dwDiskNumber; // 0x00A8 - disk number
uint32_t dwVersion; // 0x00AC - version
uint8_t bzLanKey[16]; // 0x00B0 - lan key
uint8_t bzSignatureKey[16]; // 0x00C0 - signature key
// NOT ALL XBEs have these fields!
uint8_t bzTitleAlternateSignatureKey[16][16]; // 0x00D0 - alternate signature keys
uint32_t dwOriginalCertificateSize; // 0x01D0 - Original Certificate Size?
uint32_t dwOnlineService; // 0x01D4 - Online Service ID
uint32_t dwSecurityFlags; // 0x01D8 - Extra Security Flags
uint8_t bzCodeEncKey[16]; // 0x01DC - Code Encryption Key?
}
#include "AlignPosfix1.h"
m_Certificate;
// Xbe section header
#include "AlignPrefix1.h"
struct SectionHeader
{
typedef struct
{
uint32_t bWritable : 1; // writable flag
uint32_t bPreload : 1; // preload flag
uint32_t bExecutable : 1; // executable flag
uint32_t bInsertedFile : 1; // inserted file flag
uint32_t bHeadPageRO : 1; // head page read only flag
uint32_t bTailPageRO : 1; // tail page read only flag
uint32_t Unused_a1 : 1; // unused (or unknown)
uint32_t Unused_a2 : 1; // unused (or unknown)
uint32_t Unused_b1 : 8; // unused (or unknown)
uint32_t Unused_b2 : 8; // unused (or unknown)
uint32_t Unused_b3 : 8; // unused (or unknown)
} _Flags;
union {
_Flags dwFlags;
uint32_t dwFlags_value;
};
uint32_t dwVirtualAddr; // virtual address
uint32_t dwVirtualSize; // virtual size
uint32_t dwRawAddr; // file offset to raw data
uint32_t dwSizeofRaw; // size of raw data
uint32_t dwSectionNameAddr; // section name addr
uint32_t dwSectionRefCount; // section reference count
uint32_t dwHeadSharedRefCountAddr; // head shared page reference count address
uint32_t dwTailSharedRefCountAddr; // tail shared page reference count address
uint8_t bzSectionDigest[20]; // section digest
}
#include "AlignPosfix1.h"
*m_SectionHeader;
// Xbe library versions
#include "AlignPrefix1.h"
struct LibraryVersion
{
char szName[8]; // library name
uint16_t wMajorVersion; // major version
uint16_t wMinorVersion; // minor version
uint16_t wBuildVersion; // build version
typedef struct
{
uint16_t QFEVersion : 13; // QFE Version
uint16_t Approved : 2; // Approved? (0:no, 1:possibly, 2:yes)
uint16_t bDebugBuild : 1; // Is this a debug build?
} Flags;
union {
Flags wFlags;
uint16_t wFlags_value;
};
}
#include "AlignPosfix1.h"
*m_LibraryVersion;
// Xbe thread local storage
#include "AlignPrefix1.h"
struct TLS
{
uint32_t dwDataStartAddr; // raw start address
uint32_t dwDataEndAddr; // raw end address
uint32_t dwTLSIndexAddr; // tls index address
uint32_t dwTLSCallbackAddr; // tls callback address
uint32_t dwSizeofZeroFill; // size of zero fill
uint32_t dwCharacteristics; // characteristics
}
#include "AlignPosfix1.h"
*m_TLS;
// Xbe signature header
uint8_t* m_SignatureHeader;
// Xbe section names, stored null terminated
char (*m_szSectionName)[10];
// Xbe sections
uint8_t **m_bzSection;
// Xbe original path
char m_szPath[MAX_PATH];
// Xbe ascii title, translated from certificate title
char m_szAsciiTitle[40];
// retrieve thread local storage data address
uint8_t *GetTLSData() { if(m_TLS == 0) return 0; else return GetAddr(m_TLS->dwDataStartAddr); }
// retrieve thread local storage index address
uint32_t *GetTLSIndex() { if(m_TLS == 0) return 0; else return (uint32_t*)GetAddr(m_TLS->dwTLSIndexAddr); }
// return a modifiable pointer inside this structure that corresponds to a virtual address
uint8_t *GetAddr(uint32_t x_dwVirtualAddress);
const wchar_t *GetUnicodeFilenameAddr();
private:
// constructor initialization
void ConstructorInit();
// return a modifiable pointer to logo bitmap data
uint8_t *GetLogoBitmap(uint32_t x_dwSize);
// used to encode/decode logo bitmap data
union LogoRLE
{
struct Eight
{
uint32_t bType1 : 1;
uint32_t Len : 3;
uint32_t Data : 4;
}
m_Eight;
struct Sixteen
{
uint32_t bType1 : 1;
uint32_t bType2 : 1;
uint32_t Len : 10;
uint32_t Data : 4;
}
m_Sixteen;
};
public:
// used to decode game logo bitmap data
#include "AlignPrefix1.h"
struct X_D3DResourceLoc
{
uint32_t Common;
uint32_t Data;
uint32_t Lock;
uint32_t Format;
uint32_t Size;
}
#include "AlignPosfix1.h"
;
#include "AlignPrefix1.h"
// XPR structures
// Purpose:
// The XPR file format allows multiple graphics resources to be pre-defined
// and bundled together into one file. These resources can be copied into
// memory and then immediately used in-place as D3D objects such as textures
// and vertex buffers. The structure below defines the XPR header and the
// unique identifier for this file type.
struct XprHeader
{
uint32_t dwXprMagic; // 'XPR0' or 'XPR1'
uint32_t dwXprTotalSize;
uint32_t dwXprHeaderSize;
}
#include "AlignPosfix1.h"
*m_xprHeader;
#include "AlignPrefix1.h"
// Layout of SaveImage.xbx saved game image file
//
// File is XPR0 format. Since the XPR will always contain only a single
// 256x256 DXT1 image, we know exactly what the header portion will look like
struct XprImageHeader
{
XprHeader xprHeader; // Standard XPR struct
X_D3DResourceLoc d3dTexture; // Standard D3D texture struct
uint32_t dwEndOfHeader; // $FFFFFFFF
}
#include "AlignPosfix1.h"
*m_xprImageHeader;
#include "AlignPrefix1.h"
struct XprImage
{
XprImageHeader xprImageHeader;
char strPad[XPR_IMAGE_HDR_SIZE - sizeof(XprImageHeader)];
unsigned char pBits;
}
#include "AlignPosfix1.h"
*m_xprImage;
};
// debug/retail XOR keys
const uint32_t XOR_EP_DEBUG = 0x94859D4B; // Entry Point (Debug)
const uint32_t XOR_EP_RETAIL = 0xA8FC57AB; // Entry Point (Retail)
const uint32_t XOR_KT_DEBUG = 0xEFB1F152; // Kernel Thunk (Debug)
const uint32_t XOR_KT_RETAIL = 0x5B6D40B6; // Kernel Thunk (Retail)
// Sega Chihiro XOR keys
const uint32_t XOR_EP_CHIHIRO = 0x40B5C16E;
const uint32_t XOR_KT_CHIHIRO = 0x2290059D;
// game region flags for Xbe certificate
const uint32_t XBEIMAGE_GAME_REGION_NA = 0x00000001;
const uint32_t XBEIMAGE_GAME_REGION_JAPAN = 0x00000002;
const uint32_t XBEIMAGE_GAME_REGION_RESTOFWORLD = 0x00000004;
const uint32_t XBEIMAGE_GAME_REGION_MANUFACTURING = 0x80000000;
// media type flags for Xbe certificate
const uint32_t XBEIMAGE_MEDIA_TYPE_HARD_DISK = 0x00000001;
const uint32_t XBEIMAGE_MEDIA_TYPE_DVD_X2 = 0x00000002;
const uint32_t XBEIMAGE_MEDIA_TYPE_DVD_CD = 0x00000004;
const uint32_t XBEIMAGE_MEDIA_TYPE_CD = 0x00000008;
const uint32_t XBEIMAGE_MEDIA_TYPE_DVD_5_RO = 0x00000010;
const uint32_t XBEIMAGE_MEDIA_TYPE_DVD_9_RO = 0x00000020;
const uint32_t XBEIMAGE_MEDIA_TYPE_DVD_5_RW = 0x00000040;
const uint32_t XBEIMAGE_MEDIA_TYPE_DVD_9_RW = 0x00000080;
const uint32_t XBEIMAGE_MEDIA_TYPE_DONGLE = 0x00000100;
const uint32_t XBEIMAGE_MEDIA_TYPE_MEDIA_BOARD = 0x00000200;
const uint32_t XBEIMAGE_MEDIA_TYPE_NONSECURE_HARD_DISK = 0x40000000;
const uint32_t XBEIMAGE_MEDIA_TYPE_NONSECURE_MODE = 0x80000000;
const uint32_t XBEIMAGE_MEDIA_TYPE_MEDIA_MASK = 0x00FFFFFF;
// section type flags for Xbe
const uint32_t XBEIMAGE_SECTION_WRITEABLE = 0x00000001;
const uint32_t XBEIMAGE_SECTION_PRELOAD = 0x00000002;
const uint32_t XBEIMAGE_SECTION_EXECUTABLE = 0x00000004;
const uint32_t XBEIMAGE_SECTION_INSERTFILE = 0x00000008;
const uint32_t XBEIMAGE_SECTION_HEAD_PAGE_READONLY = 0x00000010;
const uint32_t XBEIMAGE_SECTION_TAIL_PAGE_READONLY = 0x00000020;
#endif
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// * (c) 2017 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef XBE_H
#define XBE_H
#include "common\Error.h"
#include "common/xbox/Types.hpp"
#include <cstdio>
//#include <windef.h> // For MAX_PATH
// The above leads to 55 compile errors, so until we've sorted out why that happens, declare MAX_PATH ourselves for now :
#define MAX_PATH 260
#define XPR_IMAGE_WH 128
#define XPR_IMAGE_DATA_SIZE (XPR_IMAGE_WH * XPR_IMAGE_WH) / 2
#define XPR_IMAGE_HDR_SIZE 2048
namespace xboxkrnl
{
typedef struct _XBE_SECTION XBEIMAGE_SECTION, *PXBEIMAGE_SECTION;
}
// Xbe (Xbox Executable) file object
class Xbe : public Error
{
public:
// construct via Xbe file
Xbe(const char *x_szFilename, bool bFromGUI);
// deconstructor
~Xbe();
// find an section by name
void *FindSection(char *zsSectionName);
// Find a section by its definition
void* FindSection(xboxkrnl::PXBEIMAGE_SECTION section);
// export to Xbe file
void Export(const char *x_szXbeFilename);
// verify the integrity of the xbe header
bool CheckSignature();
// verify the integrity of an xbe section
bool CheckSectionIntegrity(uint32_t sectionIndex);
// import logo bitmap from raw monochrome data
void ImportLogoBitmap(const uint8_t x_Gray[100*17]);
// export logo bitmap to raw monochrome data
void ExportLogoBitmap(uint8_t x_Gray[100*17]);
// purge illegal characters in Windows filenames or other OS's
void PurgeBadChar(std::string& s, const std::string& illegalChars = "\\/:?\"<>|");
// Convert game region field to string
const char *GameRegionToString();
XbeType GetXbeType();
// Xbe header
#include "AlignPrefix1.h"
struct Header
{
uint32_t dwMagic; // 0x0000 - magic number [should be "XBEH"]
uint8_t pbDigitalSignature[256]; // 0x0004 - digital signature
uint32_t dwBaseAddr; // 0x0104 - base address
uint32_t dwSizeofHeaders; // 0x0108 - size of headers
uint32_t dwSizeofImage; // 0x010C - size of image
uint32_t dwSizeofImageHeader; // 0x0110 - size of image header
uint32_t dwTimeDate; // 0x0114 - timedate stamp
uint32_t dwCertificateAddr; // 0x0118 - certificate address
uint32_t dwSections; // 0x011C - number of sections
uint32_t dwSectionHeadersAddr; // 0x0120 - section headers address
typedef struct
{
uint32_t bMountUtilityDrive : 1; // mount utility drive flag
uint32_t bFormatUtilityDrive : 1; // format utility drive flag
uint32_t bLimit64MB : 1; // limit development kit run time memory to 64mb flag
uint32_t bDontSetupHarddisk : 1; // don't setup hard disk flag
uint32_t Unused : 4; // unused (or unknown)
uint32_t Unused_b1 : 8; // unused (or unknown)
uint32_t Unused_b2 : 8; // unused (or unknown)
uint32_t Unused_b3 : 8; // unused (or unknown)
} InitFlags;
union { // 0x0124 - initialization flags
InitFlags dwInitFlags;
uint32_t dwInitFlags_value;
};
uint32_t dwEntryAddr; // 0x0128 - entry point address
uint32_t dwTLSAddr; // 0x012C - thread local storage directory address
uint32_t dwPeStackCommit; // 0x0130 - size of stack commit
uint32_t dwPeHeapReserve; // 0x0134 - size of heap reserve
uint32_t dwPeHeapCommit; // 0x0138 - size of heap commit
uint32_t dwPeBaseAddr; // 0x013C - original base address
uint32_t dwPeSizeofImage; // 0x0140 - size of original image
uint32_t dwPeChecksum; // 0x0144 - original checksum
uint32_t dwPeTimeDate; // 0x0148 - original timedate stamp
uint32_t dwDebugPathnameAddr; // 0x014C - debug pathname address
uint32_t dwDebugFilenameAddr; // 0x0150 - debug filename address
uint32_t dwDebugUnicodeFilenameAddr; // 0x0154 - debug unicode filename address
uint32_t dwKernelImageThunkAddr; // 0x0158 - kernel image thunk address
uint32_t dwNonKernelImportDirAddr; // 0x015C - non kernel import directory address
uint32_t dwLibraryVersions; // 0x0160 - number of library versions
uint32_t dwLibraryVersionsAddr; // 0x0164 - library versions address
uint32_t dwKernelLibraryVersionAddr; // 0x0168 - kernel library version address
uint32_t dwXAPILibraryVersionAddr; // 0x016C - xapi library version address
uint32_t dwLogoBitmapAddr; // 0x0170 - logo bitmap address
uint32_t dwSizeofLogoBitmap; // 0x0174 - logo bitmap size
}
#include "AlignPosfix1.h"
m_Header;
// Xbe header extra byte (used to preserve unknown data)
char *m_HeaderEx;
uint32_t m_ExSize;
// Xbe certificate
#include "AlignPrefix1.h"
struct Certificate
{
uint32_t dwSize; // 0x0000 - size of certificate
uint32_t dwTimeDate; // 0x0004 - timedate stamp
uint32_t dwTitleId; // 0x0008 - title id
wchar_t wszTitleName[40]; // 0x000C - title name (unicode)
uint32_t dwAlternateTitleId[0x10]; // 0x005C - alternate title ids
uint32_t dwAllowedMedia; // 0x009C - allowed media types
uint32_t dwGameRegion; // 0x00A0 - game region
uint32_t dwGameRatings; // 0x00A4 - game ratings
uint32_t dwDiskNumber; // 0x00A8 - disk number
uint32_t dwVersion; // 0x00AC - version
uint8_t bzLanKey[16]; // 0x00B0 - lan key
uint8_t bzSignatureKey[16]; // 0x00C0 - signature key
// NOT ALL XBEs have these fields!
uint8_t bzTitleAlternateSignatureKey[16][16]; // 0x00D0 - alternate signature keys
uint32_t dwOriginalCertificateSize; // 0x01D0 - Original Certificate Size?
uint32_t dwOnlineService; // 0x01D4 - Online Service ID
uint32_t dwSecurityFlags; // 0x01D8 - Extra Security Flags
uint8_t bzCodeEncKey[16]; // 0x01DC - Code Encryption Key?
}
#include "AlignPosfix1.h"
m_Certificate;
// Xbe section header
#include "AlignPrefix1.h"
struct SectionHeader
{
typedef struct
{
uint32_t bWritable : 1; // writable flag
uint32_t bPreload : 1; // preload flag
uint32_t bExecutable : 1; // executable flag
uint32_t bInsertedFile : 1; // inserted file flag
uint32_t bHeadPageRO : 1; // head page read only flag
uint32_t bTailPageRO : 1; // tail page read only flag
uint32_t Unused_a1 : 1; // unused (or unknown)
uint32_t Unused_a2 : 1; // unused (or unknown)
uint32_t Unused_b1 : 8; // unused (or unknown)
uint32_t Unused_b2 : 8; // unused (or unknown)
uint32_t Unused_b3 : 8; // unused (or unknown)
} _Flags;
union {
_Flags dwFlags;
uint32_t dwFlags_value;
};
uint32_t dwVirtualAddr; // virtual address
uint32_t dwVirtualSize; // virtual size
uint32_t dwRawAddr; // file offset to raw data
uint32_t dwSizeofRaw; // size of raw data
uint32_t dwSectionNameAddr; // section name addr
uint32_t dwSectionRefCount; // section reference count
uint32_t dwHeadSharedRefCountAddr; // head shared page reference count address
uint32_t dwTailSharedRefCountAddr; // tail shared page reference count address
uint8_t bzSectionDigest[20]; // section digest
}
#include "AlignPosfix1.h"
*m_SectionHeader;
// Xbe library versions
#include "AlignPrefix1.h"
struct LibraryVersion
{
char szName[8]; // library name
uint16_t wMajorVersion; // major version
uint16_t wMinorVersion; // minor version
uint16_t wBuildVersion; // build version
typedef struct
{
uint16_t QFEVersion : 13; // QFE Version
uint16_t Approved : 2; // Approved? (0:no, 1:possibly, 2:yes)
uint16_t bDebugBuild : 1; // Is this a debug build?
} Flags;
union {
Flags wFlags;
uint16_t wFlags_value;
};
}
#include "AlignPosfix1.h"
*m_LibraryVersion;
// Xbe thread local storage
#include "AlignPrefix1.h"
struct TLS
{
uint32_t dwDataStartAddr; // raw start address
uint32_t dwDataEndAddr; // raw end address
uint32_t dwTLSIndexAddr; // tls index address
uint32_t dwTLSCallbackAddr; // tls callback address
uint32_t dwSizeofZeroFill; // size of zero fill
uint32_t dwCharacteristics; // characteristics
}
#include "AlignPosfix1.h"
*m_TLS;
// Xbe signature header
uint8_t* m_SignatureHeader;
// Xbe section names, stored null terminated
char (*m_szSectionName)[10];
// Xbe sections
uint8_t **m_bzSection;
// Xbe original path
char m_szPath[MAX_PATH];
// Xbe ascii title, translated from certificate title
char m_szAsciiTitle[40];
// retrieve thread local storage data address
uint8_t *GetTLSData() { if(m_TLS == 0) return 0; else return GetAddr(m_TLS->dwDataStartAddr); }
// retrieve thread local storage index address
uint32_t *GetTLSIndex() { if(m_TLS == 0) return 0; else return (uint32_t*)GetAddr(m_TLS->dwTLSIndexAddr); }
// return a modifiable pointer inside this structure that corresponds to a virtual address
uint8_t *GetAddr(uint32_t x_dwVirtualAddress);
const wchar_t *GetUnicodeFilenameAddr();
private:
// constructor initialization
void ConstructorInit();
// return a modifiable pointer to logo bitmap data
uint8_t *GetLogoBitmap(uint32_t x_dwSize);
// used to encode/decode logo bitmap data
union LogoRLE
{
struct Eight
{
uint32_t bType1 : 1;
uint32_t Len : 3;
uint32_t Data : 4;
}
m_Eight;
struct Sixteen
{
uint32_t bType1 : 1;
uint32_t bType2 : 1;
uint32_t Len : 10;
uint32_t Data : 4;
}
m_Sixteen;
};
public:
// used to decode game logo bitmap data
#include "AlignPrefix1.h"
struct X_D3DResourceLoc
{
uint32_t Common;
uint32_t Data;
uint32_t Lock;
uint32_t Format;
uint32_t Size;
}
#include "AlignPosfix1.h"
;
#include "AlignPrefix1.h"
// XPR structures
// Purpose:
// The XPR file format allows multiple graphics resources to be pre-defined
// and bundled together into one file. These resources can be copied into
// memory and then immediately used in-place as D3D objects such as textures
// and vertex buffers. The structure below defines the XPR header and the
// unique identifier for this file type.
struct XprHeader
{
uint32_t dwXprMagic; // 'XPR0' or 'XPR1'
uint32_t dwXprTotalSize;
uint32_t dwXprHeaderSize;
}
#include "AlignPosfix1.h"
*m_xprHeader;
#include "AlignPrefix1.h"
// Layout of SaveImage.xbx saved game image file
//
// File is XPR0 format. Since the XPR will always contain only a single
// 256x256 DXT1 image, we know exactly what the header portion will look like
struct XprImageHeader
{
XprHeader xprHeader; // Standard XPR struct
X_D3DResourceLoc d3dTexture; // Standard D3D texture struct
uint32_t dwEndOfHeader; // $FFFFFFFF
}
#include "AlignPosfix1.h"
*m_xprImageHeader;
#include "AlignPrefix1.h"
struct XprImage
{
XprImageHeader xprImageHeader;
char strPad[XPR_IMAGE_HDR_SIZE - sizeof(XprImageHeader)];
unsigned char pBits;
}
#include "AlignPosfix1.h"
*m_xprImage;
};
// debug/retail XOR keys
const uint32_t XOR_EP_DEBUG = 0x94859D4B; // Entry Point (Debug)
const uint32_t XOR_EP_RETAIL = 0xA8FC57AB; // Entry Point (Retail)
const uint32_t XOR_KT_DEBUG = 0xEFB1F152; // Kernel Thunk (Debug)
const uint32_t XOR_KT_RETAIL = 0x5B6D40B6; // Kernel Thunk (Retail)
// Sega Chihiro XOR keys
const uint32_t XOR_EP_CHIHIRO = 0x40B5C16E;
const uint32_t XOR_KT_CHIHIRO = 0x2290059D;
// game region flags for Xbe certificate
const uint32_t XBEIMAGE_GAME_REGION_NA = 0x00000001;
const uint32_t XBEIMAGE_GAME_REGION_JAPAN = 0x00000002;
const uint32_t XBEIMAGE_GAME_REGION_RESTOFWORLD = 0x00000004;
const uint32_t XBEIMAGE_GAME_REGION_MANUFACTURING = 0x80000000;
// media type flags for Xbe certificate
const uint32_t XBEIMAGE_MEDIA_TYPE_HARD_DISK = 0x00000001;
const uint32_t XBEIMAGE_MEDIA_TYPE_DVD_X2 = 0x00000002;
const uint32_t XBEIMAGE_MEDIA_TYPE_DVD_CD = 0x00000004;
const uint32_t XBEIMAGE_MEDIA_TYPE_CD = 0x00000008;
const uint32_t XBEIMAGE_MEDIA_TYPE_DVD_5_RO = 0x00000010;
const uint32_t XBEIMAGE_MEDIA_TYPE_DVD_9_RO = 0x00000020;
const uint32_t XBEIMAGE_MEDIA_TYPE_DVD_5_RW = 0x00000040;
const uint32_t XBEIMAGE_MEDIA_TYPE_DVD_9_RW = 0x00000080;
const uint32_t XBEIMAGE_MEDIA_TYPE_DONGLE = 0x00000100;
const uint32_t XBEIMAGE_MEDIA_TYPE_MEDIA_BOARD = 0x00000200;
const uint32_t XBEIMAGE_MEDIA_TYPE_NONSECURE_HARD_DISK = 0x40000000;
const uint32_t XBEIMAGE_MEDIA_TYPE_NONSECURE_MODE = 0x80000000;
const uint32_t XBEIMAGE_MEDIA_TYPE_MEDIA_MASK = 0x00FFFFFF;
// section type flags for Xbe
const uint32_t XBEIMAGE_SECTION_WRITEABLE = 0x00000001;
const uint32_t XBEIMAGE_SECTION_PRELOAD = 0x00000002;
const uint32_t XBEIMAGE_SECTION_EXECUTABLE = 0x00000004;
const uint32_t XBEIMAGE_SECTION_INSERTFILE = 0x00000008;
const uint32_t XBEIMAGE_SECTION_HEAD_PAGE_READONLY = 0x00000010;
const uint32_t XBEIMAGE_SECTION_TAIL_PAGE_READONLY = 0x00000020;
#endif

View File

@ -31,7 +31,7 @@
#include <locale> // For ctime
#include <sstream> // For std::stringstream
#include <iomanip> // For std::setfill, std::uppercase, std::hex
#include "common/util/strConverter.hpp" // for utf16le_to_ascii
#include "common/util/strConverter.hpp" // for utf16le_to_ascii
extern std::string FormatTitleId(uint32_t title_id); // Exposed in Emu.cpp
@ -416,12 +416,12 @@ std::string XbePrinter::GenSectionHeaders()
text << "Section Reference Count : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwSectionRefCount << "\n";
text << "Head Shared Reference Count Addr : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwHeadSharedRefCountAddr << "\n";
text << "Tail Shared Reference Count Addr : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwTailSharedRefCountAddr << "\n";
text << GenSectionDigest(Xbe_to_print->m_SectionHeader[v]) << "\n";
if (Xbe_to_print->CheckSectionIntegrity(v)) {
text << "SHA hash check of section " << Xbe_to_print->m_szSectionName[v] << " successful" << "\n\n";
}
else {
text << "SHA hash of section " << Xbe_to_print->m_szSectionName[v] << " doesn't match, section is corrupted" << "\n\n";
text << GenSectionDigest(Xbe_to_print->m_SectionHeader[v]) << "\n";
if (Xbe_to_print->CheckSectionIntegrity(v)) {
text << "SHA hash check of section " << Xbe_to_print->m_szSectionName[v] << " successful" << "\n\n";
}
else {
text << "SHA hash of section " << Xbe_to_print->m_szSectionName[v] << " doesn't match, section is corrupted" << "\n\n";
}
}
return text.str();

View File

@ -5,8 +5,8 @@
#include <xboxkrnl/xboxkrnl.h> //#include <stdtypes.h>
#include "buffered_io.h"
#include "buffered_io.h"
using namespace xboxkrnl;
CONST CHAR *XDVDFS_Signature = "MICROSOFT*XBOX*MEDIA";
@ -155,4 +155,4 @@ extern DWORD XDVDFS_FileSeek(
int Delta,
DWORD SeekMode);
#endif // __XDVDFS_H__
#endif // __XDVDFS_H__

File diff suppressed because it is too large Load Diff

View File

@ -4043,95 +4043,95 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_GetViewportOffsetAndScale)
pScale->z = vScale[2];
pScale->w = vScale[3];
}
// ******************************************************************
// * patch: D3DDevice_GetVertexShaderDeclaration
// ******************************************************************
HRESULT WINAPI XTL::EMUPATCH(D3DDevice_GetVertexShaderDeclaration)
(
DWORD Handle,
PVOID pData,
DWORD *pSizeOfData
)
{
LOG_FUNC_BEGIN
LOG_FUNC_ARG(Handle)
LOG_FUNC_ARG(pData)
LOG_FUNC_ARG(pSizeOfData)
LOG_FUNC_END;
// Handle is always address of an Xbox VertexShader struct, or-ed with 1 (X_D3DFVF_RESERVED0)
// If the pData buffer pointer is given, pSizeOfData is the address of it's size (in bytes)
// If pData is null, pSizeOfData is still given (to receive the required data size)
// The VertexShader is converted back into the contained program and it's size.
// In any case, *pSizeOfData will be set to the program size.
// If the pData is null, no further action it taken.
// If the pData buffer pointer is given, but the given *pSizeOfData is smaller than the program size, an error is returned.
// Otherwise, the program is unbatched and copied into the pData buffer.
HRESULT hRet = D3DERR_INVALIDCALL;
if (pSizeOfData) {
CxbxVertexShader *pCxbxVertexShader = GetCxbxVertexShader(Handle);
if (pCxbxVertexShader) {
DWORD sizeOfData = pCxbxVertexShader->Declaration.XboxDeclarationCount * sizeof(DWORD);
if (*pSizeOfData < sizeOfData || !pData) {
*pSizeOfData = sizeOfData;
hRet = !pData ? D3D_OK : D3DERR_MOREDATA;
}
else {
memcpy(pData, pCxbxVertexShader->Declaration.pXboxDeclarationCopy, pCxbxVertexShader->Declaration.XboxDeclarationCount * sizeof(DWORD));
hRet = D3D_OK;
}
}
}
return hRet;
}
// ******************************************************************
// * patch: D3DDevice_GetVertexShaderFunction
// ******************************************************************
HRESULT WINAPI XTL::EMUPATCH(D3DDevice_GetVertexShaderFunction)
(
DWORD Handle,
PVOID *pData,
DWORD *pSizeOfData
)
{
LOG_FUNC_BEGIN
LOG_FUNC_ARG(Handle)
LOG_FUNC_ARG(pData)
LOG_FUNC_ARG(pSizeOfData)
LOG_FUNC_END;
// Handle is always address of an Xbox VertexShader struct, or-ed with 1 (X_D3DFVF_RESERVED0)
// If the pData buffer pointer is given, pSizeOfData is the address of it's size (in bytes)
// If pData is null, pSizeOfData is still given (to receive the required data size)
// The VertexShader is parsed and converted back into the underlying declaration and it's size.
// In any case, *pSizeOfData will be set to the declaration size.
// If the pData is null, no further action it taken.
// If the pData buffer pointer is given, but the given *pSizeOfData is smaller than the declaration size, an error is returned.
// Otherwise, the declaration is copied into the pData buffer.
HRESULT hRet = D3DERR_INVALIDCALL;
if(pSizeOfData) {
CxbxVertexShader *pCxbxVertexShader = GetCxbxVertexShader(Handle);
if (pCxbxVertexShader) {
if (*pSizeOfData < pCxbxVertexShader->XboxFunctionSize || !pData) {
*pSizeOfData = pCxbxVertexShader->XboxFunctionSize;
hRet = !pData ? D3D_OK : D3DERR_MOREDATA;
}
else {
memcpy(pData, pCxbxVertexShader->pXboxFunctionCopy, pCxbxVertexShader->XboxFunctionSize);
hRet = D3D_OK;
}
}
}
return hRet;
}
// ******************************************************************
// * patch: D3DDevice_GetVertexShaderDeclaration
// ******************************************************************
HRESULT WINAPI XTL::EMUPATCH(D3DDevice_GetVertexShaderDeclaration)
(
DWORD Handle,
PVOID pData,
DWORD *pSizeOfData
)
{
LOG_FUNC_BEGIN
LOG_FUNC_ARG(Handle)
LOG_FUNC_ARG(pData)
LOG_FUNC_ARG(pSizeOfData)
LOG_FUNC_END;
// Handle is always address of an Xbox VertexShader struct, or-ed with 1 (X_D3DFVF_RESERVED0)
// If the pData buffer pointer is given, pSizeOfData is the address of it's size (in bytes)
// If pData is null, pSizeOfData is still given (to receive the required data size)
// The VertexShader is converted back into the contained program and it's size.
// In any case, *pSizeOfData will be set to the program size.
// If the pData is null, no further action it taken.
// If the pData buffer pointer is given, but the given *pSizeOfData is smaller than the program size, an error is returned.
// Otherwise, the program is unbatched and copied into the pData buffer.
HRESULT hRet = D3DERR_INVALIDCALL;
if (pSizeOfData) {
CxbxVertexShader *pCxbxVertexShader = GetCxbxVertexShader(Handle);
if (pCxbxVertexShader) {
DWORD sizeOfData = pCxbxVertexShader->Declaration.XboxDeclarationCount * sizeof(DWORD);
if (*pSizeOfData < sizeOfData || !pData) {
*pSizeOfData = sizeOfData;
hRet = !pData ? D3D_OK : D3DERR_MOREDATA;
}
else {
memcpy(pData, pCxbxVertexShader->Declaration.pXboxDeclarationCopy, pCxbxVertexShader->Declaration.XboxDeclarationCount * sizeof(DWORD));
hRet = D3D_OK;
}
}
}
return hRet;
}
// ******************************************************************
// * patch: D3DDevice_GetVertexShaderFunction
// ******************************************************************
HRESULT WINAPI XTL::EMUPATCH(D3DDevice_GetVertexShaderFunction)
(
DWORD Handle,
PVOID *pData,
DWORD *pSizeOfData
)
{
LOG_FUNC_BEGIN
LOG_FUNC_ARG(Handle)
LOG_FUNC_ARG(pData)
LOG_FUNC_ARG(pSizeOfData)
LOG_FUNC_END;
// Handle is always address of an Xbox VertexShader struct, or-ed with 1 (X_D3DFVF_RESERVED0)
// If the pData buffer pointer is given, pSizeOfData is the address of it's size (in bytes)
// If pData is null, pSizeOfData is still given (to receive the required data size)
// The VertexShader is parsed and converted back into the underlying declaration and it's size.
// In any case, *pSizeOfData will be set to the declaration size.
// If the pData is null, no further action it taken.
// If the pData buffer pointer is given, but the given *pSizeOfData is smaller than the declaration size, an error is returned.
// Otherwise, the declaration is copied into the pData buffer.
HRESULT hRet = D3DERR_INVALIDCALL;
if(pSizeOfData) {
CxbxVertexShader *pCxbxVertexShader = GetCxbxVertexShader(Handle);
if (pCxbxVertexShader) {
if (*pSizeOfData < pCxbxVertexShader->XboxFunctionSize || !pData) {
*pSizeOfData = pCxbxVertexShader->XboxFunctionSize;
hRet = !pData ? D3D_OK : D3DERR_MOREDATA;
}
else {
memcpy(pData, pCxbxVertexShader->pXboxFunctionCopy, pCxbxVertexShader->XboxFunctionSize);
hRet = D3D_OK;
}
}
}
return hRet;
}

View File

@ -24,10 +24,10 @@
// ******************************************************************
#ifndef DIRECT3D9_H
#define DIRECT3D9_H
#include "core\hle\XAPI\Xapi.h" // For EMUPATCH
#include "core\hle\D3D8\XbD3D8Types.h"
#include "core\hle\D3D8\XbD3D8Types.h"
#define DIRECTDRAW_VERSION 0x0700
#include <ddraw.h>
@ -53,8 +53,8 @@ extern uint8_t *ConvertD3DTextureToARGB(
uint8_t *pSrc,
int *pWidth, int *pHeight,
int TextureStage = 0
);
);
void CxbxUpdateNativeD3DResources();
// initialize direct3d
@ -62,15 +62,15 @@ extern VOID EmuD3DInit();
// cleanup direct3d
extern VOID EmuD3DCleanup();
extern IDirect3DDevice *g_pD3DDevice;
extern IDirect3DDevice *g_pD3DDevice;
extern DWORD g_Xbox_VertexShader_Handle;
extern XTL::X_PixelShader *g_pXbox_PixelShader;
extern XTL::X_D3DBaseTexture *g_pXbox_SetTexture[XTL::X_D3DTS_STAGECOUNT];
namespace XTL {
// ******************************************************************
@ -2125,7 +2125,7 @@ VOID WINAPI EMUPATCH(D3DDevice_GetMaterial)
(
X_D3DMATERIAL8* pMaterial
);
} // end of namespace XTL
#endif

View File

@ -1,474 +1,474 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2019 Luke Usher
// *
// * All rights reserved
// *
// ******************************************************************
#define LOG_PREFIX CXBXR_MODULE::D3DST
#include "RenderStates.h"
#include "Logging.h"
#include "core/hle/D3D8/Direct3D9/Direct3D9.h" // For g_pD3DDevice
#include "core/hle/D3D8/XbConvert.h"
bool XboxRenderStateConverter::Init()
{
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2019 Luke Usher
// *
// * All rights reserved
// *
// ******************************************************************
#define LOG_PREFIX CXBXR_MODULE::D3DST
#include "RenderStates.h"
#include "Logging.h"
#include "core/hle/D3D8/Direct3D9/Direct3D9.h" // For g_pD3DDevice
#include "core/hle/D3D8/XbConvert.h"
bool XboxRenderStateConverter::Init()
{
if (g_SymbolAddresses.find("D3DDeferredRenderState") != g_SymbolAddresses.end()) {
D3D__RenderState = (uint32_t*)g_SymbolAddresses["D3DDeferredRenderState"];
} else {
return false;
}
// At this point, D3D__RenderState points to the first Deferred render state
// Do a little magic to verify that it's correct, then count back to determine the
// start offset of the entire structure
VerifyAndFixDeferredRenderStateOffset();
// Now use the verified Deferred offset to derive the D3D__RenderState offset
DeriveRenderStateOffsetFromDeferredRenderStateOffset();
// Build a mapping of Cxbx Render State indexes to indexes within the current XDK
BuildRenderStateMappingTable();
// Set Initial Values
StoreInitialValues();
} else {
return false;
}
// At this point, D3D__RenderState points to the first Deferred render state
// Do a little magic to verify that it's correct, then count back to determine the
// start offset of the entire structure
VerifyAndFixDeferredRenderStateOffset();
// Now use the verified Deferred offset to derive the D3D__RenderState offset
DeriveRenderStateOffsetFromDeferredRenderStateOffset();
// Build a mapping of Cxbx Render State indexes to indexes within the current XDK
BuildRenderStateMappingTable();
// Set Initial Values
StoreInitialValues();
return true;
}
bool IsRenderStateAvailableInCurrentXboxD3D8Lib(RenderStateInfo& aRenderStateInfo)
{
bool bIsRenderStateAvailable = (aRenderStateInfo.V <= g_LibVersion_D3D8);
if (aRenderStateInfo.R > 0) { // Applies to XTL::X_D3DRS_MULTISAMPLETYPE
// Note : X_D3DRS_MULTISAMPLETYPE seems the only render state that got
// removed (from 4039 onwards), so we check that limitation here as well
bIsRenderStateAvailable &= (g_LibVersion_D3D8 < aRenderStateInfo.R);
}
return bIsRenderStateAvailable;
}
void XboxRenderStateConverter::VerifyAndFixDeferredRenderStateOffset()
{
DWORD CullModeOffset = g_SymbolAddresses["D3DRS_CULLMODE"];
// If we found a valid CullMode offset, verify the symbol location
if (CullModeOffset == 0) {
EmuLog(LOG_LEVEL::WARNING, "D3DRS_CULLMODE could not be found. Please update the XbSymbolDatabase submodule");
return;
}
// Calculate index of D3DRS_CULLMODE for this XDK. We start counting from the first deferred state (D3DRS_FOGENABLE)
DWORD CullModeIndex = 0;
for (int i = XTL::X_D3DRS_DEFERRED_FIRST; i < XTL::X_D3DRS_CULLMODE; i++) {
auto RenderStateInfo = GetDxbxRenderStateInfo(i);
if (IsRenderStateAvailableInCurrentXboxD3D8Lib(RenderStateInfo)) {
CullModeIndex++;
}
}
// If the offset was incorrect, calculate the correct offset, log it, and fix it
if ((DWORD)(&D3D__RenderState[CullModeIndex]) != CullModeOffset) {
DWORD CorrectOffset = CullModeOffset - (CullModeIndex * sizeof(DWORD));
EmuLog(LOG_LEVEL::WARNING, "EmuD3DDeferredRenderState returned by XboxSymbolDatabase (0x%08X) was incorrect. Correcting to be 0x%08X.\nPlease file an issue with the XbSymbolDatabase project", D3D__RenderState, CorrectOffset);
D3D__RenderState = (uint32_t*)CorrectOffset;
}
}
void XboxRenderStateConverter::DeriveRenderStateOffsetFromDeferredRenderStateOffset()
{
// When this function is called. D3D__RenderState actually points to the first deferred render state
// (this is X_D3DRS_FOGENABLE). We can count back from this using our RenderStateInfo table to find
// the start of D3D__RenderStates.
// Count the number of render states (for this XDK) between 0 and the first deferred render state (D3DRS_FOGENABLE)
int FirstDeferredRenderStateOffset = 0;
for (unsigned int RenderState = XTL::X_D3DRS_FIRST; RenderState < XTL::X_D3DRS_DEFERRED_FIRST; RenderState++) {
// if the current renderstate exists in this XDK version, count it
auto RenderStateInfo = GetDxbxRenderStateInfo(RenderState);
if (IsRenderStateAvailableInCurrentXboxD3D8Lib(RenderStateInfo)) {
FirstDeferredRenderStateOffset++;
}
}
// At this point, FirstDeferredRenderStateOffset should point to the index of D3DRS_FOGENABLE for the given XDK
// This will be correct as long as our table DxbxRenderStateInfo is correct
// We can get the correct 0 offset by using a negative index
D3D__RenderState = &D3D__RenderState[-FirstDeferredRenderStateOffset];
}
void XboxRenderStateConverter::BuildRenderStateMappingTable()
{
EmuLog(LOG_LEVEL::INFO, "Building Cxbx to XDK Render State Mapping Table");
XboxRenderStateOffsets.fill(-1);
int XboxIndex = 0;
for (unsigned int RenderState = XTL::X_D3DRS_FIRST; RenderState <= XTL::X_D3DRS_LAST; RenderState++) {
auto RenderStateInfo = GetDxbxRenderStateInfo(RenderState);
if (IsRenderStateAvailableInCurrentXboxD3D8Lib(RenderStateInfo)) {
XboxRenderStateOffsets[RenderState] = XboxIndex;
EmuLog(LOG_LEVEL::INFO, "%s = %d", RenderStateInfo.S, XboxIndex);
XboxIndex++;
continue;
}
EmuLog(LOG_LEVEL::INFO, "%s Not Present", RenderStateInfo.S);
}
}
void XboxRenderStateConverter::SetDirty()
{
PreviousRenderStateValues.fill(-1);
}
void* XboxRenderStateConverter::GetPixelShaderRenderStatePointer()
{
return &D3D__RenderState[XTL::X_D3DRS_PS_FIRST];
}
bool XboxRenderStateConverter::XboxRenderStateExists(uint32_t State)
{
if (XboxRenderStateOffsets[State] >= 0) {
return true;
}
return false;
}
bool XboxRenderStateConverter::XboxRenderStateValueChanged(uint32_t State)
{
if (XboxRenderStateExists(State) && GetXboxRenderState(State) != PreviousRenderStateValues[State]) {
return true;
}
return false;
}
void XboxRenderStateConverter::SetXboxRenderState(uint32_t State, uint32_t Value)
{
if (!XboxRenderStateExists(State)) {
EmuLog(LOG_LEVEL::WARNING, "Attempt to write a Renderstate (%s) that does not exist in the current D3D8 XDK Version (%d)", GetDxbxRenderStateInfo(State).S, g_LibVersion_D3D8);
return;
}
D3D__RenderState[XboxRenderStateOffsets[State]] = Value;
}
uint32_t XboxRenderStateConverter::GetXboxRenderState(uint32_t State)
{
if (!XboxRenderStateExists(State)) {
EmuLog(LOG_LEVEL::WARNING, "Attempt to read a Renderstate (%s) that does not exist in the current D3D8 XDK Version (%d)", GetDxbxRenderStateInfo(State).S, g_LibVersion_D3D8);
return 0;
}
return D3D__RenderState[XboxRenderStateOffsets[State]];
}
void XboxRenderStateConverter::StoreInitialValues()
{
for (unsigned int RenderState = XTL::X_D3DRS_FIRST; RenderState <= XTL::X_D3DRS_LAST; RenderState++) {
// Skip Render States that don't exist within this XDK
if (!XboxRenderStateExists(RenderState)) {
continue;
}
PreviousRenderStateValues[RenderState] = GetXboxRenderState(RenderState);
}
}
void XboxRenderStateConverter::SetWireFrameMode(int wireframe)
{
WireFrameMode = wireframe;
// Wireframe mode changed, so we must force the Fill Mode renderstate to dirty
// At next call to Apply, the desired WireFrame mode will be set
PreviousRenderStateValues[XTL::X_D3DRS_FILLMODE] = -1;
}
void XboxRenderStateConverter::Apply()
{
// Iterate through each RenderState and set the associated host render state
// We start counting at X_D3DRS_SIMPLE_FIRST, to skip the pixel shader renderstates handled elsewhere
for (unsigned int RenderState = XTL::X_D3DRS_SIMPLE_FIRST; RenderState <= XTL::X_D3DRS_LAST; RenderState++) {
// Skip any renderstate that does not exist in the current XDK, or have not changed since the previous update call
// Also skip PSTextureModes, which is a special case used by Pixel Shaders
if (!XboxRenderStateExists(RenderState) || !XboxRenderStateValueChanged(RenderState) || RenderState == XTL::X_D3DRS_PSTEXTUREMODES) {
continue;
}
auto Value = GetXboxRenderState(RenderState);
EmuLog(LOG_LEVEL::DEBUG, "XboxRenderStateConverter::Apply(%s, %X)\n", GetDxbxRenderStateInfo(RenderState).S, Value);
if (RenderState <= XTL::X_D3DRS_SIMPLE_LAST) {
ApplySimpleRenderState(RenderState, Value);
} else if (RenderState <= XTL::X_D3DRS_DEFERRED_LAST) {
ApplyDeferredRenderState(RenderState, Value);
} else if (RenderState <= XTL::X_D3DRS_COMPLEX_LAST) {
ApplyComplexRenderState(RenderState, Value);
}
PreviousRenderStateValues[RenderState] = Value;
}
}
void XboxRenderStateConverter::ApplySimpleRenderState(uint32_t State, uint32_t Value)
{
auto RenderStateInfo = GetDxbxRenderStateInfo(State);
switch (State) {
case XTL::X_D3DRS_COLORWRITEENABLE: {
DWORD OrigValue = Value;
Value = 0;
if (OrigValue & (1L << 16)) {
Value |= D3DCOLORWRITEENABLE_RED;
}
if (OrigValue & (1L << 8)) {
Value |= D3DCOLORWRITEENABLE_GREEN;
}
if (OrigValue & (1L << 0)) {
Value |= D3DCOLORWRITEENABLE_BLUE;
}
if (OrigValue & (1L << 24)) {
Value |= D3DCOLORWRITEENABLE_ALPHA;
}
} break;
case XTL::X_D3DRS_SHADEMODE:
Value = EmuXB2PC_D3DSHADEMODE(Value);
break;
case XTL::X_D3DRS_BLENDOP:
Value = EmuXB2PC_D3DBLENDOP(Value);
break;
case XTL::X_D3DRS_SRCBLEND:
case XTL::X_D3DRS_DESTBLEND:
Value = EmuXB2PC_D3DBLEND(Value);
break;
case XTL::X_D3DRS_ZFUNC:
case XTL::X_D3DRS_ALPHAFUNC:
case XTL::X_D3DRS_STENCILFUNC:
Value = EmuXB2PC_D3DCMPFUNC(Value);
break;
case XTL::X_D3DRS_STENCILZFAIL:
case XTL::X_D3DRS_STENCILPASS:
Value = EmuXB2PC_D3DSTENCILOP(Value);
break;
case XTL::X_D3DRS_ALPHATESTENABLE:
if (g_LibVersion_D3D8 == 3925) {
// HACK: Many 3925 have missing polygons when this is true
// Until we find out the true underlying cause, and carry on
// Test Cases: Halo, Silent Hill 2.
LOG_TEST_CASE("Applying 3925 alpha test disable hack");
Value = false;
}
break;
case XTL::X_D3DRS_ALPHABLENDENABLE:
case XTL::X_D3DRS_BLENDCOLOR:
case XTL::X_D3DRS_ALPHAREF: case XTL::X_D3DRS_ZWRITEENABLE:
case XTL::X_D3DRS_DITHERENABLE: case XTL::X_D3DRS_STENCILREF:
case XTL::X_D3DRS_STENCILMASK: case XTL::X_D3DRS_STENCILWRITEMASK:
// These render states require no conversion, so we simply
// allow SetRenderState to be called with no changes
break;
default:
// Only log missing state if it has a PC counterpart
if (RenderStateInfo.PC != 0) {
EmuLog(LOG_LEVEL::WARNING, "ApplySimpleRenderState(%s, 0x%.08X) is unimplemented!", RenderStateInfo.S, Value);
}
return;
}
// Skip RenderStates that don't have a defined PC counterpart
if (RenderStateInfo.PC == 0) {
return;
}
g_pD3DDevice->SetRenderState((D3DRENDERSTATETYPE)(RenderStateInfo.PC), Value);
}
void XboxRenderStateConverter::ApplyDeferredRenderState(uint32_t State, uint32_t Value)
{
auto RenderStateInfo = GetDxbxRenderStateInfo(State);
// Convert from Xbox Data Formats to PC
switch (State) {
case XTL::X_D3DRS_FOGSTART:
case XTL::X_D3DRS_FOGEND: {
// HACK: If the fog start/fog-end are negative, make them positive
// This fixes Smashing Drive on non-nvidia hardware
// Cause appears to be non-nvidia drivers clamping values < 0 to 0
// Resulting in the fog formula becoming (0 - d) / 0, which breaks rendering
// This prevents that scenario for screen-space fog, *hopefully* without breaking eye-based fog also
float fogValue = *(float*)& Value;
if (fogValue < 0.0f) {
LOG_TEST_CASE("FOGSTART/FOGEND below 0");
fogValue = std::abs(fogValue);
Value = *(DWORD*)& fogValue;
}
} break;
case XTL::X_D3DRS_FOGENABLE:
if (g_LibVersion_D3D8 == 3925) {
// HACK: Many 3925 games only show a black screen if fog is enabled
// Initially, this was thought to be bad offsets, but it has been verified to be correct
// Until we find out the true underlying cause, disable fog and carry on
// Test Cases: Halo, Silent Hill 2.
LOG_TEST_CASE("Applying 3925 fog disable hack");
Value = false;
}
break;
case XTL::X_D3DRS_FOGTABLEMODE:
case XTL::X_D3DRS_FOGDENSITY:
case XTL::X_D3DRS_RANGEFOGENABLE:
case XTL::X_D3DRS_LIGHTING:
case XTL::X_D3DRS_SPECULARENABLE:
case XTL::X_D3DRS_LOCALVIEWER:
case XTL::X_D3DRS_COLORVERTEX:
case XTL::X_D3DRS_SPECULARMATERIALSOURCE:
case XTL::X_D3DRS_DIFFUSEMATERIALSOURCE:
case XTL::X_D3DRS_AMBIENTMATERIALSOURCE:
case XTL::X_D3DRS_EMISSIVEMATERIALSOURCE:
case XTL::X_D3DRS_AMBIENT:
case XTL::X_D3DRS_POINTSIZE:
case XTL::X_D3DRS_POINTSIZE_MIN:
case XTL::X_D3DRS_POINTSPRITEENABLE:
case XTL::X_D3DRS_POINTSCALEENABLE:
case XTL::X_D3DRS_POINTSCALE_A:
case XTL::X_D3DRS_POINTSCALE_B:
case XTL::X_D3DRS_POINTSCALE_C:
case XTL::X_D3DRS_POINTSIZE_MAX:
case XTL::X_D3DRS_PATCHEDGESTYLE:
case XTL::X_D3DRS_PATCHSEGMENTS:
// These render states require no conversion, so we can use them as-is
break;
case XTL::X_D3DRS_BACKSPECULARMATERIALSOURCE:
case XTL::X_D3DRS_BACKDIFFUSEMATERIALSOURCE:
case XTL::X_D3DRS_BACKAMBIENTMATERIALSOURCE:
case XTL::X_D3DRS_BACKEMISSIVEMATERIALSOURCE:
case XTL::X_D3DRS_BACKAMBIENT:
case XTL::X_D3DRS_SWAPFILTER:
// These states are unsupported by the host and are ignored (for now)
return;
case XTL::X_D3DRS_PRESENTATIONINTERVAL: {
// Store this as an override for our frame limiter
// Games can use this to limit certain scenes to a desired target framerate for a specific scene
// If this value is not set, or is set to 0, the default interval passed to CreateDevice is used
extern DWORD g_Xbox_PresentationInterval_Override;
g_Xbox_PresentationInterval_Override = Value;
} return;
case XTL::X_D3DRS_WRAP0:
case XTL::X_D3DRS_WRAP1:
case XTL::X_D3DRS_WRAP2:
case XTL::X_D3DRS_WRAP3: {
DWORD OldValue = Value;
Value = 0;
Value |= (OldValue & 0x00000010) ? D3DWRAPCOORD_0 : 0;
Value |= (OldValue & 0x00001000) ? D3DWRAPCOORD_1 : 0;
Value |= (OldValue & 0x00100000) ? D3DWRAPCOORD_2 : 0;
Value |= (OldValue & 0x01000000) ? D3DWRAPCOORD_3 : 0;
} break;
default:
// Only log missing state if it has a PC counterpart
if (RenderStateInfo.PC != 0) {
EmuLog(LOG_LEVEL::WARNING, "ApplyDeferredRenderState(%s, 0x%.08X) is unimplemented!", RenderStateInfo.S, Value);
}
return;
}
// Skip RenderStates that don't have a defined PC counterpart
if (RenderStateInfo.PC == 0) {
return;
}
g_pD3DDevice->SetRenderState(RenderStateInfo.PC, Value);
}
void XboxRenderStateConverter::ApplyComplexRenderState(uint32_t State, uint32_t Value)
{
auto RenderStateInfo = GetDxbxRenderStateInfo(State);
switch (State) {
case XTL::X_D3DRS_VERTEXBLEND:
// convert from Xbox direct3d to PC direct3d enumeration
if (Value <= 1) {
Value = Value;
} else if (Value == 3) {
Value = 2;
} else if (Value == 5) {
Value = 3;
} else {
LOG_TEST_CASE("Unsupported D3DVERTEXBLENDFLAGS (%d)");
return;
}
break;
case XTL::X_D3DRS_FILLMODE:
Value = EmuXB2PC_D3DFILLMODE(Value);
if (WireFrameMode > 0) {
if (WireFrameMode == 1) {
Value = D3DFILL_WIREFRAME;
} else {
Value = D3DFILL_POINT;
}
}
break;
case XTL::X_D3DRS_CULLMODE:
switch (Value) {
case XTL::X_D3DCULL_NONE: Value = D3DCULL_NONE; break;
case XTL::X_D3DCULL_CW: Value = D3DCULL_CW; break;
case XTL::X_D3DCULL_CCW: Value = D3DCULL_CCW;break;
default: LOG_TEST_CASE("EmuD3DDevice_SetRenderState_CullMode: Unknown Cullmode");
}
break;
case XTL::X_D3DRS_ZBIAS: {
FLOAT Biased = static_cast<FLOAT>(Value) * -0.000005f;
Value = *reinterpret_cast<const DWORD*>(&Biased);
} break;
// These states require no conversions, so can just be passed through to the host directly
case XTL::X_D3DRS_FOGCOLOR:
case XTL::X_D3DRS_NORMALIZENORMALS:
case XTL::X_D3DRS_ZENABLE:
case XTL::X_D3DRS_STENCILENABLE:
case XTL::X_D3DRS_STENCILFAIL:
case XTL::X_D3DRS_TEXTUREFACTOR:
case XTL::X_D3DRS_EDGEANTIALIAS:
case XTL::X_D3DRS_MULTISAMPLEANTIALIAS:
case XTL::X_D3DRS_MULTISAMPLEMASK:
break;
default:
// Only log missing state if it has a PC counterpart
if (RenderStateInfo.PC != 0) {
EmuLog(LOG_LEVEL::WARNING, "ApplyComplexRenderState(%s, 0x%.08X) is unimplemented!", RenderStateInfo.S, Value);
}
return;
}
// Skip RenderStates that don't have a defined PC counterpart
if (RenderStateInfo.PC == 0) {
return;
}
g_pD3DDevice->SetRenderState(RenderStateInfo.PC, Value);
}
}
bool IsRenderStateAvailableInCurrentXboxD3D8Lib(RenderStateInfo& aRenderStateInfo)
{
bool bIsRenderStateAvailable = (aRenderStateInfo.V <= g_LibVersion_D3D8);
if (aRenderStateInfo.R > 0) { // Applies to XTL::X_D3DRS_MULTISAMPLETYPE
// Note : X_D3DRS_MULTISAMPLETYPE seems the only render state that got
// removed (from 4039 onwards), so we check that limitation here as well
bIsRenderStateAvailable &= (g_LibVersion_D3D8 < aRenderStateInfo.R);
}
return bIsRenderStateAvailable;
}
void XboxRenderStateConverter::VerifyAndFixDeferredRenderStateOffset()
{
DWORD CullModeOffset = g_SymbolAddresses["D3DRS_CULLMODE"];
// If we found a valid CullMode offset, verify the symbol location
if (CullModeOffset == 0) {
EmuLog(LOG_LEVEL::WARNING, "D3DRS_CULLMODE could not be found. Please update the XbSymbolDatabase submodule");
return;
}
// Calculate index of D3DRS_CULLMODE for this XDK. We start counting from the first deferred state (D3DRS_FOGENABLE)
DWORD CullModeIndex = 0;
for (int i = XTL::X_D3DRS_DEFERRED_FIRST; i < XTL::X_D3DRS_CULLMODE; i++) {
auto RenderStateInfo = GetDxbxRenderStateInfo(i);
if (IsRenderStateAvailableInCurrentXboxD3D8Lib(RenderStateInfo)) {
CullModeIndex++;
}
}
// If the offset was incorrect, calculate the correct offset, log it, and fix it
if ((DWORD)(&D3D__RenderState[CullModeIndex]) != CullModeOffset) {
DWORD CorrectOffset = CullModeOffset - (CullModeIndex * sizeof(DWORD));
EmuLog(LOG_LEVEL::WARNING, "EmuD3DDeferredRenderState returned by XboxSymbolDatabase (0x%08X) was incorrect. Correcting to be 0x%08X.\nPlease file an issue with the XbSymbolDatabase project", D3D__RenderState, CorrectOffset);
D3D__RenderState = (uint32_t*)CorrectOffset;
}
}
void XboxRenderStateConverter::DeriveRenderStateOffsetFromDeferredRenderStateOffset()
{
// When this function is called. D3D__RenderState actually points to the first deferred render state
// (this is X_D3DRS_FOGENABLE). We can count back from this using our RenderStateInfo table to find
// the start of D3D__RenderStates.
// Count the number of render states (for this XDK) between 0 and the first deferred render state (D3DRS_FOGENABLE)
int FirstDeferredRenderStateOffset = 0;
for (unsigned int RenderState = XTL::X_D3DRS_FIRST; RenderState < XTL::X_D3DRS_DEFERRED_FIRST; RenderState++) {
// if the current renderstate exists in this XDK version, count it
auto RenderStateInfo = GetDxbxRenderStateInfo(RenderState);
if (IsRenderStateAvailableInCurrentXboxD3D8Lib(RenderStateInfo)) {
FirstDeferredRenderStateOffset++;
}
}
// At this point, FirstDeferredRenderStateOffset should point to the index of D3DRS_FOGENABLE for the given XDK
// This will be correct as long as our table DxbxRenderStateInfo is correct
// We can get the correct 0 offset by using a negative index
D3D__RenderState = &D3D__RenderState[-FirstDeferredRenderStateOffset];
}
void XboxRenderStateConverter::BuildRenderStateMappingTable()
{
EmuLog(LOG_LEVEL::INFO, "Building Cxbx to XDK Render State Mapping Table");
XboxRenderStateOffsets.fill(-1);
int XboxIndex = 0;
for (unsigned int RenderState = XTL::X_D3DRS_FIRST; RenderState <= XTL::X_D3DRS_LAST; RenderState++) {
auto RenderStateInfo = GetDxbxRenderStateInfo(RenderState);
if (IsRenderStateAvailableInCurrentXboxD3D8Lib(RenderStateInfo)) {
XboxRenderStateOffsets[RenderState] = XboxIndex;
EmuLog(LOG_LEVEL::INFO, "%s = %d", RenderStateInfo.S, XboxIndex);
XboxIndex++;
continue;
}
EmuLog(LOG_LEVEL::INFO, "%s Not Present", RenderStateInfo.S);
}
}
void XboxRenderStateConverter::SetDirty()
{
PreviousRenderStateValues.fill(-1);
}
void* XboxRenderStateConverter::GetPixelShaderRenderStatePointer()
{
return &D3D__RenderState[XTL::X_D3DRS_PS_FIRST];
}
bool XboxRenderStateConverter::XboxRenderStateExists(uint32_t State)
{
if (XboxRenderStateOffsets[State] >= 0) {
return true;
}
return false;
}
bool XboxRenderStateConverter::XboxRenderStateValueChanged(uint32_t State)
{
if (XboxRenderStateExists(State) && GetXboxRenderState(State) != PreviousRenderStateValues[State]) {
return true;
}
return false;
}
void XboxRenderStateConverter::SetXboxRenderState(uint32_t State, uint32_t Value)
{
if (!XboxRenderStateExists(State)) {
EmuLog(LOG_LEVEL::WARNING, "Attempt to write a Renderstate (%s) that does not exist in the current D3D8 XDK Version (%d)", GetDxbxRenderStateInfo(State).S, g_LibVersion_D3D8);
return;
}
D3D__RenderState[XboxRenderStateOffsets[State]] = Value;
}
uint32_t XboxRenderStateConverter::GetXboxRenderState(uint32_t State)
{
if (!XboxRenderStateExists(State)) {
EmuLog(LOG_LEVEL::WARNING, "Attempt to read a Renderstate (%s) that does not exist in the current D3D8 XDK Version (%d)", GetDxbxRenderStateInfo(State).S, g_LibVersion_D3D8);
return 0;
}
return D3D__RenderState[XboxRenderStateOffsets[State]];
}
void XboxRenderStateConverter::StoreInitialValues()
{
for (unsigned int RenderState = XTL::X_D3DRS_FIRST; RenderState <= XTL::X_D3DRS_LAST; RenderState++) {
// Skip Render States that don't exist within this XDK
if (!XboxRenderStateExists(RenderState)) {
continue;
}
PreviousRenderStateValues[RenderState] = GetXboxRenderState(RenderState);
}
}
void XboxRenderStateConverter::SetWireFrameMode(int wireframe)
{
WireFrameMode = wireframe;
// Wireframe mode changed, so we must force the Fill Mode renderstate to dirty
// At next call to Apply, the desired WireFrame mode will be set
PreviousRenderStateValues[XTL::X_D3DRS_FILLMODE] = -1;
}
void XboxRenderStateConverter::Apply()
{
// Iterate through each RenderState and set the associated host render state
// We start counting at X_D3DRS_SIMPLE_FIRST, to skip the pixel shader renderstates handled elsewhere
for (unsigned int RenderState = XTL::X_D3DRS_SIMPLE_FIRST; RenderState <= XTL::X_D3DRS_LAST; RenderState++) {
// Skip any renderstate that does not exist in the current XDK, or have not changed since the previous update call
// Also skip PSTextureModes, which is a special case used by Pixel Shaders
if (!XboxRenderStateExists(RenderState) || !XboxRenderStateValueChanged(RenderState) || RenderState == XTL::X_D3DRS_PSTEXTUREMODES) {
continue;
}
auto Value = GetXboxRenderState(RenderState);
EmuLog(LOG_LEVEL::DEBUG, "XboxRenderStateConverter::Apply(%s, %X)\n", GetDxbxRenderStateInfo(RenderState).S, Value);
if (RenderState <= XTL::X_D3DRS_SIMPLE_LAST) {
ApplySimpleRenderState(RenderState, Value);
} else if (RenderState <= XTL::X_D3DRS_DEFERRED_LAST) {
ApplyDeferredRenderState(RenderState, Value);
} else if (RenderState <= XTL::X_D3DRS_COMPLEX_LAST) {
ApplyComplexRenderState(RenderState, Value);
}
PreviousRenderStateValues[RenderState] = Value;
}
}
void XboxRenderStateConverter::ApplySimpleRenderState(uint32_t State, uint32_t Value)
{
auto RenderStateInfo = GetDxbxRenderStateInfo(State);
switch (State) {
case XTL::X_D3DRS_COLORWRITEENABLE: {
DWORD OrigValue = Value;
Value = 0;
if (OrigValue & (1L << 16)) {
Value |= D3DCOLORWRITEENABLE_RED;
}
if (OrigValue & (1L << 8)) {
Value |= D3DCOLORWRITEENABLE_GREEN;
}
if (OrigValue & (1L << 0)) {
Value |= D3DCOLORWRITEENABLE_BLUE;
}
if (OrigValue & (1L << 24)) {
Value |= D3DCOLORWRITEENABLE_ALPHA;
}
} break;
case XTL::X_D3DRS_SHADEMODE:
Value = EmuXB2PC_D3DSHADEMODE(Value);
break;
case XTL::X_D3DRS_BLENDOP:
Value = EmuXB2PC_D3DBLENDOP(Value);
break;
case XTL::X_D3DRS_SRCBLEND:
case XTL::X_D3DRS_DESTBLEND:
Value = EmuXB2PC_D3DBLEND(Value);
break;
case XTL::X_D3DRS_ZFUNC:
case XTL::X_D3DRS_ALPHAFUNC:
case XTL::X_D3DRS_STENCILFUNC:
Value = EmuXB2PC_D3DCMPFUNC(Value);
break;
case XTL::X_D3DRS_STENCILZFAIL:
case XTL::X_D3DRS_STENCILPASS:
Value = EmuXB2PC_D3DSTENCILOP(Value);
break;
case XTL::X_D3DRS_ALPHATESTENABLE:
if (g_LibVersion_D3D8 == 3925) {
// HACK: Many 3925 have missing polygons when this is true
// Until we find out the true underlying cause, and carry on
// Test Cases: Halo, Silent Hill 2.
LOG_TEST_CASE("Applying 3925 alpha test disable hack");
Value = false;
}
break;
case XTL::X_D3DRS_ALPHABLENDENABLE:
case XTL::X_D3DRS_BLENDCOLOR:
case XTL::X_D3DRS_ALPHAREF: case XTL::X_D3DRS_ZWRITEENABLE:
case XTL::X_D3DRS_DITHERENABLE: case XTL::X_D3DRS_STENCILREF:
case XTL::X_D3DRS_STENCILMASK: case XTL::X_D3DRS_STENCILWRITEMASK:
// These render states require no conversion, so we simply
// allow SetRenderState to be called with no changes
break;
default:
// Only log missing state if it has a PC counterpart
if (RenderStateInfo.PC != 0) {
EmuLog(LOG_LEVEL::WARNING, "ApplySimpleRenderState(%s, 0x%.08X) is unimplemented!", RenderStateInfo.S, Value);
}
return;
}
// Skip RenderStates that don't have a defined PC counterpart
if (RenderStateInfo.PC == 0) {
return;
}
g_pD3DDevice->SetRenderState((D3DRENDERSTATETYPE)(RenderStateInfo.PC), Value);
}
void XboxRenderStateConverter::ApplyDeferredRenderState(uint32_t State, uint32_t Value)
{
auto RenderStateInfo = GetDxbxRenderStateInfo(State);
// Convert from Xbox Data Formats to PC
switch (State) {
case XTL::X_D3DRS_FOGSTART:
case XTL::X_D3DRS_FOGEND: {
// HACK: If the fog start/fog-end are negative, make them positive
// This fixes Smashing Drive on non-nvidia hardware
// Cause appears to be non-nvidia drivers clamping values < 0 to 0
// Resulting in the fog formula becoming (0 - d) / 0, which breaks rendering
// This prevents that scenario for screen-space fog, *hopefully* without breaking eye-based fog also
float fogValue = *(float*)& Value;
if (fogValue < 0.0f) {
LOG_TEST_CASE("FOGSTART/FOGEND below 0");
fogValue = std::abs(fogValue);
Value = *(DWORD*)& fogValue;
}
} break;
case XTL::X_D3DRS_FOGENABLE:
if (g_LibVersion_D3D8 == 3925) {
// HACK: Many 3925 games only show a black screen if fog is enabled
// Initially, this was thought to be bad offsets, but it has been verified to be correct
// Until we find out the true underlying cause, disable fog and carry on
// Test Cases: Halo, Silent Hill 2.
LOG_TEST_CASE("Applying 3925 fog disable hack");
Value = false;
}
break;
case XTL::X_D3DRS_FOGTABLEMODE:
case XTL::X_D3DRS_FOGDENSITY:
case XTL::X_D3DRS_RANGEFOGENABLE:
case XTL::X_D3DRS_LIGHTING:
case XTL::X_D3DRS_SPECULARENABLE:
case XTL::X_D3DRS_LOCALVIEWER:
case XTL::X_D3DRS_COLORVERTEX:
case XTL::X_D3DRS_SPECULARMATERIALSOURCE:
case XTL::X_D3DRS_DIFFUSEMATERIALSOURCE:
case XTL::X_D3DRS_AMBIENTMATERIALSOURCE:
case XTL::X_D3DRS_EMISSIVEMATERIALSOURCE:
case XTL::X_D3DRS_AMBIENT:
case XTL::X_D3DRS_POINTSIZE:
case XTL::X_D3DRS_POINTSIZE_MIN:
case XTL::X_D3DRS_POINTSPRITEENABLE:
case XTL::X_D3DRS_POINTSCALEENABLE:
case XTL::X_D3DRS_POINTSCALE_A:
case XTL::X_D3DRS_POINTSCALE_B:
case XTL::X_D3DRS_POINTSCALE_C:
case XTL::X_D3DRS_POINTSIZE_MAX:
case XTL::X_D3DRS_PATCHEDGESTYLE:
case XTL::X_D3DRS_PATCHSEGMENTS:
// These render states require no conversion, so we can use them as-is
break;
case XTL::X_D3DRS_BACKSPECULARMATERIALSOURCE:
case XTL::X_D3DRS_BACKDIFFUSEMATERIALSOURCE:
case XTL::X_D3DRS_BACKAMBIENTMATERIALSOURCE:
case XTL::X_D3DRS_BACKEMISSIVEMATERIALSOURCE:
case XTL::X_D3DRS_BACKAMBIENT:
case XTL::X_D3DRS_SWAPFILTER:
// These states are unsupported by the host and are ignored (for now)
return;
case XTL::X_D3DRS_PRESENTATIONINTERVAL: {
// Store this as an override for our frame limiter
// Games can use this to limit certain scenes to a desired target framerate for a specific scene
// If this value is not set, or is set to 0, the default interval passed to CreateDevice is used
extern DWORD g_Xbox_PresentationInterval_Override;
g_Xbox_PresentationInterval_Override = Value;
} return;
case XTL::X_D3DRS_WRAP0:
case XTL::X_D3DRS_WRAP1:
case XTL::X_D3DRS_WRAP2:
case XTL::X_D3DRS_WRAP3: {
DWORD OldValue = Value;
Value = 0;
Value |= (OldValue & 0x00000010) ? D3DWRAPCOORD_0 : 0;
Value |= (OldValue & 0x00001000) ? D3DWRAPCOORD_1 : 0;
Value |= (OldValue & 0x00100000) ? D3DWRAPCOORD_2 : 0;
Value |= (OldValue & 0x01000000) ? D3DWRAPCOORD_3 : 0;
} break;
default:
// Only log missing state if it has a PC counterpart
if (RenderStateInfo.PC != 0) {
EmuLog(LOG_LEVEL::WARNING, "ApplyDeferredRenderState(%s, 0x%.08X) is unimplemented!", RenderStateInfo.S, Value);
}
return;
}
// Skip RenderStates that don't have a defined PC counterpart
if (RenderStateInfo.PC == 0) {
return;
}
g_pD3DDevice->SetRenderState(RenderStateInfo.PC, Value);
}
void XboxRenderStateConverter::ApplyComplexRenderState(uint32_t State, uint32_t Value)
{
auto RenderStateInfo = GetDxbxRenderStateInfo(State);
switch (State) {
case XTL::X_D3DRS_VERTEXBLEND:
// convert from Xbox direct3d to PC direct3d enumeration
if (Value <= 1) {
Value = Value;
} else if (Value == 3) {
Value = 2;
} else if (Value == 5) {
Value = 3;
} else {
LOG_TEST_CASE("Unsupported D3DVERTEXBLENDFLAGS (%d)");
return;
}
break;
case XTL::X_D3DRS_FILLMODE:
Value = EmuXB2PC_D3DFILLMODE(Value);
if (WireFrameMode > 0) {
if (WireFrameMode == 1) {
Value = D3DFILL_WIREFRAME;
} else {
Value = D3DFILL_POINT;
}
}
break;
case XTL::X_D3DRS_CULLMODE:
switch (Value) {
case XTL::X_D3DCULL_NONE: Value = D3DCULL_NONE; break;
case XTL::X_D3DCULL_CW: Value = D3DCULL_CW; break;
case XTL::X_D3DCULL_CCW: Value = D3DCULL_CCW;break;
default: LOG_TEST_CASE("EmuD3DDevice_SetRenderState_CullMode: Unknown Cullmode");
}
break;
case XTL::X_D3DRS_ZBIAS: {
FLOAT Biased = static_cast<FLOAT>(Value) * -0.000005f;
Value = *reinterpret_cast<const DWORD*>(&Biased);
} break;
// These states require no conversions, so can just be passed through to the host directly
case XTL::X_D3DRS_FOGCOLOR:
case XTL::X_D3DRS_NORMALIZENORMALS:
case XTL::X_D3DRS_ZENABLE:
case XTL::X_D3DRS_STENCILENABLE:
case XTL::X_D3DRS_STENCILFAIL:
case XTL::X_D3DRS_TEXTUREFACTOR:
case XTL::X_D3DRS_EDGEANTIALIAS:
case XTL::X_D3DRS_MULTISAMPLEANTIALIAS:
case XTL::X_D3DRS_MULTISAMPLEMASK:
break;
default:
// Only log missing state if it has a PC counterpart
if (RenderStateInfo.PC != 0) {
EmuLog(LOG_LEVEL::WARNING, "ApplyComplexRenderState(%s, 0x%.08X) is unimplemented!", RenderStateInfo.S, Value);
}
return;
}
// Skip RenderStates that don't have a defined PC counterpart
if (RenderStateInfo.PC == 0) {
return;
}
g_pD3DDevice->SetRenderState(RenderStateInfo.PC, Value);
}

View File

@ -1,66 +1,66 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2019 Luke Usher
// *
// * All rights reserved
// *
// ******************************************************************
#include <cstdint>
#include <array>
#include "EmuShared.h"
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2019 Luke Usher
// *
// * All rights reserved
// *
// ******************************************************************
#include <cstdint>
#include <array>
#include "EmuShared.h"
#include "core\kernel\init\CxbxKrnl.h"
#include "core\kernel\support\Emu.h"
#include "core\hle\Intercept.hpp"
#include "core\hle\D3D8\XbD3D8Types.h"
class XboxRenderStateConverter
{
public:
bool Init();
void Apply();
void* GetPixelShaderRenderStatePointer();
bool XboxRenderStateExists(uint32_t state);
void SetXboxRenderState(uint32_t State, uint32_t Value);
void SetWireFrameMode(int mode);
void SetDirty();
uint32_t GetXboxRenderState(uint32_t State);
private:
void VerifyAndFixDeferredRenderStateOffset();
void DeriveRenderStateOffsetFromDeferredRenderStateOffset();
void StoreInitialValues();
void BuildRenderStateMappingTable();
bool XboxRenderStateValueChanged(uint32_t State);
void ApplySimpleRenderState(uint32_t State, uint32_t Value);
void ApplyDeferredRenderState(uint32_t State, uint32_t Value);
void ApplyComplexRenderState(uint32_t State, uint32_t Value);
uint32_t* D3D__RenderState = nullptr;
int WireFrameMode = 0;
// NOTE: RenderStates are 32bit values, but using a 64bit value allows the upper bits to be used as a 'force dirty' flag
std::array<uint64_t, XTL::X_D3DRS_LAST + 1> PreviousRenderStateValues;
std::array<int, XTL::X_D3DRS_LAST + 1> XboxRenderStateOffsets;
};
#include "core\hle\Intercept.hpp"
#include "core\hle\D3D8\XbD3D8Types.h"
class XboxRenderStateConverter
{
public:
bool Init();
void Apply();
void* GetPixelShaderRenderStatePointer();
bool XboxRenderStateExists(uint32_t state);
void SetXboxRenderState(uint32_t State, uint32_t Value);
void SetWireFrameMode(int mode);
void SetDirty();
uint32_t GetXboxRenderState(uint32_t State);
private:
void VerifyAndFixDeferredRenderStateOffset();
void DeriveRenderStateOffsetFromDeferredRenderStateOffset();
void StoreInitialValues();
void BuildRenderStateMappingTable();
bool XboxRenderStateValueChanged(uint32_t State);
void ApplySimpleRenderState(uint32_t State, uint32_t Value);
void ApplyDeferredRenderState(uint32_t State, uint32_t Value);
void ApplyComplexRenderState(uint32_t State, uint32_t Value);
uint32_t* D3D__RenderState = nullptr;
int WireFrameMode = 0;
// NOTE: RenderStates are 32bit values, but using a 64bit value allows the upper bits to be used as a 'force dirty' flag
std::array<uint64_t, XTL::X_D3DRS_LAST + 1> PreviousRenderStateValues;
std::array<int, XTL::X_D3DRS_LAST + 1> XboxRenderStateOffsets;
};

View File

@ -1,275 +1,275 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2019 Luke Usher
// *
// * All rights reserved
// *
// ******************************************************************
#define LOG_PREFIX CXBXR_MODULE::D3DST
#include "TextureStates.h"
#include "core\kernel\init\CxbxKrnl.h"
#include "core\kernel\support\Emu.h"
#include "Logging.h"
#include "EmuShared.h"
#include "core/hle/Intercept.hpp"
#include "RenderStates.h"
#include "core/hle/D3D8/Direct3D9/Direct3D9.h" // For g_pD3DDevice
typedef struct {
char* S; // String representation.
bool IsSamplerState; // True if the state maps to a Sampler State instead of Texture Stage
DWORD PC; // PC Index
} TextureStateInfo;
TextureStateInfo CxbxTextureStateInfo[] = {
{ "D3DTSS_ADDRESSU", true, D3DSAMP_ADDRESSU },
{ "D3DTSS_ADDRESSV", true, D3DSAMP_ADDRESSV },
{ "D3DTSS_ADDRESSW", true, D3DSAMP_ADDRESSW },
{ "D3DTSS_MAGFILTER", true, D3DSAMP_MAGFILTER },
{ "D3DTSS_MINFILTER", true, D3DSAMP_MINFILTER },
{ "D3DTSS_MIPFILTER", true, D3DSAMP_MIPFILTER },
{ "D3DTSS_MIPMAPLODBIAS", true, D3DSAMP_MIPMAPLODBIAS },
{ "D3DTSS_MAXMIPLEVEL", true, D3DSAMP_MAXMIPLEVEL },
{ "D3DTSS_MAXANISOTROPY", true, D3DSAMP_MAXANISOTROPY },
{ "D3DTSS_COLORKEYOP", false, 0 },
{ "D3DTSS_COLORSIGN", false, 0 },
{ "D3DTSS_ALPHAKILL", false, 0 },
{ "D3DTSS_COLOROP", false, D3DTSS_COLOROP },
{ "D3DTSS_COLORARG0", false, D3DTSS_COLORARG0 },
{ "D3DTSS_COLORARG1", false, D3DTSS_COLORARG1 },
{ "D3DTSS_COLORARG2", false, D3DTSS_COLORARG2 },
{ "D3DTSS_ALPHAOP", false, D3DTSS_ALPHAOP },
{ "D3DTSS_ALPHAARG0", false, D3DTSS_ALPHAARG0 },
{ "D3DTSS_ALPHAARG1", false, D3DTSS_ALPHAARG1 },
{ "D3DTSS_ALPHAARG2", false, D3DTSS_ALPHAARG2 },
{ "D3DTSS_RESULTARG", false, D3DTSS_RESULTARG },
{ "D3DTSS_TEXTURETRANSFORMFLAGS", false, D3DTSS_TEXTURETRANSFORMFLAGS },
{ "D3DTSS_BUMPENVMAT00", false, D3DTSS_BUMPENVMAT00 },
{ "D3DTSS_BUMPENVMAT01", false, D3DTSS_BUMPENVMAT01 },
{ "D3DTSS_BUMPENVMAT11", false, D3DTSS_BUMPENVMAT11 },
{ "D3DTSS_BUMPENVMAT10", false, D3DTSS_BUMPENVMAT10 },
{ "D3DTSS_BUMPENVLSCALE", false, D3DTSS_BUMPENVLSCALE },
{ "D3DTSS_BUMPENVLOFFSET", false, D3DTSS_BUMPENVLOFFSET },
{ "D3DTSS_TEXCOORDINDEX", false, D3DTSS_TEXCOORDINDEX },
{ "D3DTSS_BORDERCOLOR", true, D3DSAMP_BORDERCOLOR },
{ "D3DTSS_COLORKEYCOLOR", false, 0 },
};
bool XboxTextureStateConverter::Init(XboxRenderStateConverter* pState)
{
// Deferred states start at 0, this menas that D3DDeferredTextureState IS D3D__TextureState
// No further works is required to derive the offset
if (g_SymbolAddresses.find("D3DDeferredTextureState") != g_SymbolAddresses.end()) {
D3D__TextureState = (uint32_t*)g_SymbolAddresses["D3DDeferredTextureState"];
} else {
return false;
}
// Build a mapping of Cxbx Texture State indexes to indexes within the current XDK
BuildTextureStateMappingTable();
// Store a handle to the Xbox Render State manager
// This is used to check for Point Sprites
pXboxRenderStates = pState;
return true;
}
void XboxTextureStateConverter::BuildTextureStateMappingTable()
{
EmuLog(LOG_LEVEL::INFO, "Building Cxbx to XDK Texture State Mapping Table");
for (int State = XTL::X_D3DTSS_FIRST; State <= XTL::X_D3DTSS_LAST; State++) {
int index = State;
// On early XDKs, we need to shuffle the values around a little
// TODO: Verify which XDK version this change occurred at
// Values range 0-9 (D3DTSS_COLOROP to D3DTSS_TEXTURETRANSFORMFLAGS) become 12-21
// Values 10-21 (D3DTSS_ADDRESSU to D3DTSS_ALPHAKILL) become 0-11
bool bOldOrder = g_LibVersion_D3D8 <= 3948; // Verfied old order in 3944, new order in 4039
if (bOldOrder) {
if (State <= 9) {
index += 12;
} else if (State <= 21) {
index -= 10;
}
}
EmuLog(LOG_LEVEL::INFO, "%s = %d", CxbxTextureStateInfo[State].S, index);
XboxTextureStateOffsets[State] = index;
}
}
DWORD XboxTextureStateConverter::GetHostTextureOpValue(DWORD Value)
{
bool bOldOrder = g_LibVersion_D3D8 <= 3948; // Verified old order in 3944, new order in 4039
switch (Value) {
case XTL::X_D3DTOP_DISABLE: return D3DTOP_DISABLE;
case XTL::X_D3DTOP_SELECTARG1: return D3DTOP_SELECTARG1;
case XTL::X_D3DTOP_SELECTARG2: return D3DTOP_SELECTARG2;
case XTL::X_D3DTOP_MODULATE: return D3DTOP_MODULATE;
case XTL::X_D3DTOP_MODULATE2X: return D3DTOP_MODULATE2X;
case XTL::X_D3DTOP_MODULATE4X: return D3DTOP_MODULATE4X;
case XTL::X_D3DTOP_ADD: return D3DTOP_ADD;
case XTL::X_D3DTOP_ADDSIGNED: return D3DTOP_ADDSIGNED;
case XTL::X_D3DTOP_ADDSIGNED2X: return D3DTOP_ADDSIGNED2X;
case XTL::X_D3DTOP_SUBTRACT: return D3DTOP_SUBTRACT;
case XTL::X_D3DTOP_ADDSMOOTH: return D3DTOP_ADDSMOOTH;
case XTL::X_D3DTOP_BLENDDIFFUSEALPHA: return D3DTOP_BLENDDIFFUSEALPHA;
case 0x0D/*XTL::X_D3DTOP_BLENDCURRENTALPHA */: return bOldOrder ? D3DTOP_BLENDTEXTUREALPHA : D3DTOP_BLENDCURRENTALPHA;
case 0x0E/*XTL::X_D3DTOP_BLENDTEXTUREALPHA */: return bOldOrder ? D3DTOP_BLENDFACTORALPHA : D3DTOP_BLENDTEXTUREALPHA;
case 0x0F/*XTL::X_D3DTOP_BLENDFACTORALPHA */: return bOldOrder ? D3DTOP_BLENDTEXTUREALPHAPM : D3DTOP_BLENDFACTORALPHA;
case 0x10/*XTL::X_D3DTOP_BLENDTEXTUREALPHAPM*/: return bOldOrder ? D3DTOP_BLENDCURRENTALPHA : D3DTOP_BLENDTEXTUREALPHAPM;
case XTL::X_D3DTOP_PREMODULATE: return D3DTOP_PREMODULATE;
case XTL::X_D3DTOP_MODULATEALPHA_ADDCOLOR: return D3DTOP_MODULATEALPHA_ADDCOLOR;
case XTL::X_D3DTOP_MODULATECOLOR_ADDALPHA: return D3DTOP_MODULATECOLOR_ADDALPHA;
case XTL::X_D3DTOP_MODULATEINVALPHA_ADDCOLOR: return D3DTOP_MODULATEINVALPHA_ADDCOLOR;
case XTL::X_D3DTOP_MODULATEINVCOLOR_ADDALPHA: return D3DTOP_MODULATEINVCOLOR_ADDALPHA;
case XTL::X_D3DTOP_DOTPRODUCT3: return D3DTOP_DOTPRODUCT3;
case XTL::X_D3DTOP_MULTIPLYADD: return D3DTOP_MULTIPLYADD;
case XTL::X_D3DTOP_LERP: return D3DTOP_LERP;
case XTL::X_D3DTOP_BUMPENVMAP: return D3DTOP_BUMPENVMAP;
case XTL::X_D3DTOP_BUMPENVMAPLUMINANCE: return D3DTOP_BUMPENVMAPLUMINANCE;
}
EmuLog(LOG_LEVEL::WARNING, "Unsupported D3DTOP Value (%d)", Value);
return D3DTOP_DISABLE;
}
void XboxTextureStateConverter::Apply()
{
// Iterate through all texture states/stages
// Track if we need to overwrite state 0 with 3 because of Point Sprites
// The Xbox NV2A uses only Stage 3 for point-sprites, so we emulate this
// by mapping Stage 3 to Stage 0, and disabling all stages > 0
bool pointSpriteOverride = false;
bool pointSpritesEnabled = pXboxRenderStates->GetXboxRenderState(XTL::X_D3DRS_POINTSPRITEENABLE);
if (pointSpritesEnabled) {
pointSpriteOverride = true;
}
for (int XboxStage = 0; XboxStage < XTL::X_D3DTS_STAGECOUNT; XboxStage++) {
// If point sprites are enabled, we need to overwrite our existing state 0 with State 3 also
DWORD HostStage = (pointSpriteOverride && XboxStage == 3) ? 0 : XboxStage;
for (int StateIndex = XTL::X_D3DTSS_FIRST; StateIndex <= XTL::X_D3DTSS_LAST; StateIndex++) {
// Read the value of the current stage/state from the Xbox data structure
DWORD Value = D3D__TextureState[(XboxStage * XTL::X_D3DTS_STAGESIZE) + StateIndex];
// Convert the index of the current state to an index that we can use
// This handles the case when XDKs have different state values
DWORD State = XboxTextureStateOffsets[StateIndex];
switch (State) {
// These types map 1:1 but have some unsupported values
case XTL::X_D3DTSS_ADDRESSU: case XTL::X_D3DTSS_ADDRESSV: case XTL::X_D3DTSS_ADDRESSW:
if (Value == XTL::X_D3DTADDRESS_CLAMPTOEDGE) {
EmuLog(LOG_LEVEL::WARNING, "D3DTADDRESS_CLAMPTOEDGE is unsupported");
// D3DTADDRESS_BORDER is the closest host match, CLAMPTOEDGE is identical
// Except it has additional restrictions.
Value = D3DTADDRESS_BORDER;
break;
}
break;
case XTL::X_D3DTSS_MAGFILTER: case XTL::X_D3DTSS_MINFILTER: case XTL::X_D3DTSS_MIPFILTER:
if (Value == XTL::X_D3DTEXF_QUINCUNX) {
EmuLog(LOG_LEVEL::WARNING, "D3DTEXF_QUINCUNX is unsupported");
// Fallback to D3DTEXF_ANISOTROPIC
Value = D3DTEXF_ANISOTROPIC;
break;
}
break;
case XTL::X_D3DTSS_TEXCOORDINDEX:
switch (Value) {
case 0x00040000:
// This value is TCI_OBJECT on Xbox,which is not supported by the host
// In this case, we reset to 0.
EmuLog(LOG_LEVEL::WARNING, "EmuD3DDevice_SetTextureState_TexCoordIndex: D3DTSS_TCI_OBJECT is unsupported", Value);
Value = 0;
break;
case 0x00050000:
// This value is TCI_SPHERE on Xbox, let's map it to D3DTSS_TCI_SPHEREMAP for the host
Value = D3DTSS_TCI_SPHEREMAP;
break;
}
break;
// These types require value remapping for all supported values
case XTL::X_D3DTSS_COLOROP: case XTL::X_D3DTSS_ALPHAOP:
Value = GetHostTextureOpValue(Value);
break;
// These types require no conversion, so we just pass through as-is
case XTL::X_D3DTSS_COLORARG0: case XTL::X_D3DTSS_COLORARG1: case XTL::X_D3DTSS_COLORARG2:
case XTL::X_D3DTSS_ALPHAARG0: case XTL::X_D3DTSS_ALPHAARG1: case XTL::X_D3DTSS_ALPHAARG2:
case XTL::X_D3DTSS_RESULTARG: case XTL::X_D3DTSS_TEXTURETRANSFORMFLAGS:
case XTL::X_D3DTSS_BUMPENVMAT00: case XTL::X_D3DTSS_BUMPENVMAT01:
case XTL::X_D3DTSS_BUMPENVMAT11: case XTL::X_D3DTSS_BUMPENVMAT10:
case XTL::X_D3DTSS_BUMPENVLSCALE: case XTL::X_D3DTSS_BUMPENVLOFFSET:
case XTL::X_D3DTSS_BORDERCOLOR: case XTL::X_D3DTSS_MIPMAPLODBIAS:
case XTL::X_D3DTSS_MAXMIPLEVEL: case XTL::X_D3DTSS_MAXANISOTROPY:
break;
default:
// Only log missing state if it has a PC counterpart
if (CxbxTextureStateInfo[State].PC != 0) {
EmuLog(LOG_LEVEL::WARNING, "XboxTextureStateConverter::Apply(%s, 0x%.08X) is unimplemented!", CxbxTextureStateInfo[State].S, Value);
}
break;
}
// Skip Texture States that don't have a defined PC counterpart
if (CxbxTextureStateInfo[State].PC == 0) {
continue;
}
if (CxbxTextureStateInfo[State].IsSamplerState) {
g_pD3DDevice->SetSamplerState(HostStage, (D3DSAMPLERSTATETYPE)CxbxTextureStateInfo[State].PC, Value);
} else {
g_pD3DDevice->SetTextureStageState(HostStage, (D3DTEXTURESTAGESTATETYPE)CxbxTextureStateInfo[State].PC, Value);
}
}
// Make sure we only do this once
if (pointSpriteOverride && XboxStage == 3) {
pointSpriteOverride = false;
XboxStage--;
}
}
if (pointSpritesEnabled) {
IDirect3DBaseTexture* pTexture;
// set the point sprites texture
g_pD3DDevice->GetTexture(3, &pTexture);
g_pD3DDevice->SetTexture(0, pTexture);
// Avoid a dangling reference that would lead to a memory leak
if (pTexture != nullptr)
pTexture->Release();
// disable all other stages
g_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
g_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
// no need to actually copy here, since it was handled in the loop above
}
}
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2019 Luke Usher
// *
// * All rights reserved
// *
// ******************************************************************
#define LOG_PREFIX CXBXR_MODULE::D3DST
#include "TextureStates.h"
#include "core\kernel\init\CxbxKrnl.h"
#include "core\kernel\support\Emu.h"
#include "Logging.h"
#include "EmuShared.h"
#include "core/hle/Intercept.hpp"
#include "RenderStates.h"
#include "core/hle/D3D8/Direct3D9/Direct3D9.h" // For g_pD3DDevice
typedef struct {
char* S; // String representation.
bool IsSamplerState; // True if the state maps to a Sampler State instead of Texture Stage
DWORD PC; // PC Index
} TextureStateInfo;
TextureStateInfo CxbxTextureStateInfo[] = {
{ "D3DTSS_ADDRESSU", true, D3DSAMP_ADDRESSU },
{ "D3DTSS_ADDRESSV", true, D3DSAMP_ADDRESSV },
{ "D3DTSS_ADDRESSW", true, D3DSAMP_ADDRESSW },
{ "D3DTSS_MAGFILTER", true, D3DSAMP_MAGFILTER },
{ "D3DTSS_MINFILTER", true, D3DSAMP_MINFILTER },
{ "D3DTSS_MIPFILTER", true, D3DSAMP_MIPFILTER },
{ "D3DTSS_MIPMAPLODBIAS", true, D3DSAMP_MIPMAPLODBIAS },
{ "D3DTSS_MAXMIPLEVEL", true, D3DSAMP_MAXMIPLEVEL },
{ "D3DTSS_MAXANISOTROPY", true, D3DSAMP_MAXANISOTROPY },
{ "D3DTSS_COLORKEYOP", false, 0 },
{ "D3DTSS_COLORSIGN", false, 0 },
{ "D3DTSS_ALPHAKILL", false, 0 },
{ "D3DTSS_COLOROP", false, D3DTSS_COLOROP },
{ "D3DTSS_COLORARG0", false, D3DTSS_COLORARG0 },
{ "D3DTSS_COLORARG1", false, D3DTSS_COLORARG1 },
{ "D3DTSS_COLORARG2", false, D3DTSS_COLORARG2 },
{ "D3DTSS_ALPHAOP", false, D3DTSS_ALPHAOP },
{ "D3DTSS_ALPHAARG0", false, D3DTSS_ALPHAARG0 },
{ "D3DTSS_ALPHAARG1", false, D3DTSS_ALPHAARG1 },
{ "D3DTSS_ALPHAARG2", false, D3DTSS_ALPHAARG2 },
{ "D3DTSS_RESULTARG", false, D3DTSS_RESULTARG },
{ "D3DTSS_TEXTURETRANSFORMFLAGS", false, D3DTSS_TEXTURETRANSFORMFLAGS },
{ "D3DTSS_BUMPENVMAT00", false, D3DTSS_BUMPENVMAT00 },
{ "D3DTSS_BUMPENVMAT01", false, D3DTSS_BUMPENVMAT01 },
{ "D3DTSS_BUMPENVMAT11", false, D3DTSS_BUMPENVMAT11 },
{ "D3DTSS_BUMPENVMAT10", false, D3DTSS_BUMPENVMAT10 },
{ "D3DTSS_BUMPENVLSCALE", false, D3DTSS_BUMPENVLSCALE },
{ "D3DTSS_BUMPENVLOFFSET", false, D3DTSS_BUMPENVLOFFSET },
{ "D3DTSS_TEXCOORDINDEX", false, D3DTSS_TEXCOORDINDEX },
{ "D3DTSS_BORDERCOLOR", true, D3DSAMP_BORDERCOLOR },
{ "D3DTSS_COLORKEYCOLOR", false, 0 },
};
bool XboxTextureStateConverter::Init(XboxRenderStateConverter* pState)
{
// Deferred states start at 0, this menas that D3DDeferredTextureState IS D3D__TextureState
// No further works is required to derive the offset
if (g_SymbolAddresses.find("D3DDeferredTextureState") != g_SymbolAddresses.end()) {
D3D__TextureState = (uint32_t*)g_SymbolAddresses["D3DDeferredTextureState"];
} else {
return false;
}
// Build a mapping of Cxbx Texture State indexes to indexes within the current XDK
BuildTextureStateMappingTable();
// Store a handle to the Xbox Render State manager
// This is used to check for Point Sprites
pXboxRenderStates = pState;
return true;
}
void XboxTextureStateConverter::BuildTextureStateMappingTable()
{
EmuLog(LOG_LEVEL::INFO, "Building Cxbx to XDK Texture State Mapping Table");
for (int State = XTL::X_D3DTSS_FIRST; State <= XTL::X_D3DTSS_LAST; State++) {
int index = State;
// On early XDKs, we need to shuffle the values around a little
// TODO: Verify which XDK version this change occurred at
// Values range 0-9 (D3DTSS_COLOROP to D3DTSS_TEXTURETRANSFORMFLAGS) become 12-21
// Values 10-21 (D3DTSS_ADDRESSU to D3DTSS_ALPHAKILL) become 0-11
bool bOldOrder = g_LibVersion_D3D8 <= 3948; // Verfied old order in 3944, new order in 4039
if (bOldOrder) {
if (State <= 9) {
index += 12;
} else if (State <= 21) {
index -= 10;
}
}
EmuLog(LOG_LEVEL::INFO, "%s = %d", CxbxTextureStateInfo[State].S, index);
XboxTextureStateOffsets[State] = index;
}
}
DWORD XboxTextureStateConverter::GetHostTextureOpValue(DWORD Value)
{
bool bOldOrder = g_LibVersion_D3D8 <= 3948; // Verified old order in 3944, new order in 4039
switch (Value) {
case XTL::X_D3DTOP_DISABLE: return D3DTOP_DISABLE;
case XTL::X_D3DTOP_SELECTARG1: return D3DTOP_SELECTARG1;
case XTL::X_D3DTOP_SELECTARG2: return D3DTOP_SELECTARG2;
case XTL::X_D3DTOP_MODULATE: return D3DTOP_MODULATE;
case XTL::X_D3DTOP_MODULATE2X: return D3DTOP_MODULATE2X;
case XTL::X_D3DTOP_MODULATE4X: return D3DTOP_MODULATE4X;
case XTL::X_D3DTOP_ADD: return D3DTOP_ADD;
case XTL::X_D3DTOP_ADDSIGNED: return D3DTOP_ADDSIGNED;
case XTL::X_D3DTOP_ADDSIGNED2X: return D3DTOP_ADDSIGNED2X;
case XTL::X_D3DTOP_SUBTRACT: return D3DTOP_SUBTRACT;
case XTL::X_D3DTOP_ADDSMOOTH: return D3DTOP_ADDSMOOTH;
case XTL::X_D3DTOP_BLENDDIFFUSEALPHA: return D3DTOP_BLENDDIFFUSEALPHA;
case 0x0D/*XTL::X_D3DTOP_BLENDCURRENTALPHA */: return bOldOrder ? D3DTOP_BLENDTEXTUREALPHA : D3DTOP_BLENDCURRENTALPHA;
case 0x0E/*XTL::X_D3DTOP_BLENDTEXTUREALPHA */: return bOldOrder ? D3DTOP_BLENDFACTORALPHA : D3DTOP_BLENDTEXTUREALPHA;
case 0x0F/*XTL::X_D3DTOP_BLENDFACTORALPHA */: return bOldOrder ? D3DTOP_BLENDTEXTUREALPHAPM : D3DTOP_BLENDFACTORALPHA;
case 0x10/*XTL::X_D3DTOP_BLENDTEXTUREALPHAPM*/: return bOldOrder ? D3DTOP_BLENDCURRENTALPHA : D3DTOP_BLENDTEXTUREALPHAPM;
case XTL::X_D3DTOP_PREMODULATE: return D3DTOP_PREMODULATE;
case XTL::X_D3DTOP_MODULATEALPHA_ADDCOLOR: return D3DTOP_MODULATEALPHA_ADDCOLOR;
case XTL::X_D3DTOP_MODULATECOLOR_ADDALPHA: return D3DTOP_MODULATECOLOR_ADDALPHA;
case XTL::X_D3DTOP_MODULATEINVALPHA_ADDCOLOR: return D3DTOP_MODULATEINVALPHA_ADDCOLOR;
case XTL::X_D3DTOP_MODULATEINVCOLOR_ADDALPHA: return D3DTOP_MODULATEINVCOLOR_ADDALPHA;
case XTL::X_D3DTOP_DOTPRODUCT3: return D3DTOP_DOTPRODUCT3;
case XTL::X_D3DTOP_MULTIPLYADD: return D3DTOP_MULTIPLYADD;
case XTL::X_D3DTOP_LERP: return D3DTOP_LERP;
case XTL::X_D3DTOP_BUMPENVMAP: return D3DTOP_BUMPENVMAP;
case XTL::X_D3DTOP_BUMPENVMAPLUMINANCE: return D3DTOP_BUMPENVMAPLUMINANCE;
}
EmuLog(LOG_LEVEL::WARNING, "Unsupported D3DTOP Value (%d)", Value);
return D3DTOP_DISABLE;
}
void XboxTextureStateConverter::Apply()
{
// Iterate through all texture states/stages
// Track if we need to overwrite state 0 with 3 because of Point Sprites
// The Xbox NV2A uses only Stage 3 for point-sprites, so we emulate this
// by mapping Stage 3 to Stage 0, and disabling all stages > 0
bool pointSpriteOverride = false;
bool pointSpritesEnabled = pXboxRenderStates->GetXboxRenderState(XTL::X_D3DRS_POINTSPRITEENABLE);
if (pointSpritesEnabled) {
pointSpriteOverride = true;
}
for (int XboxStage = 0; XboxStage < XTL::X_D3DTS_STAGECOUNT; XboxStage++) {
// If point sprites are enabled, we need to overwrite our existing state 0 with State 3 also
DWORD HostStage = (pointSpriteOverride && XboxStage == 3) ? 0 : XboxStage;
for (int StateIndex = XTL::X_D3DTSS_FIRST; StateIndex <= XTL::X_D3DTSS_LAST; StateIndex++) {
// Read the value of the current stage/state from the Xbox data structure
DWORD Value = D3D__TextureState[(XboxStage * XTL::X_D3DTS_STAGESIZE) + StateIndex];
// Convert the index of the current state to an index that we can use
// This handles the case when XDKs have different state values
DWORD State = XboxTextureStateOffsets[StateIndex];
switch (State) {
// These types map 1:1 but have some unsupported values
case XTL::X_D3DTSS_ADDRESSU: case XTL::X_D3DTSS_ADDRESSV: case XTL::X_D3DTSS_ADDRESSW:
if (Value == XTL::X_D3DTADDRESS_CLAMPTOEDGE) {
EmuLog(LOG_LEVEL::WARNING, "D3DTADDRESS_CLAMPTOEDGE is unsupported");
// D3DTADDRESS_BORDER is the closest host match, CLAMPTOEDGE is identical
// Except it has additional restrictions.
Value = D3DTADDRESS_BORDER;
break;
}
break;
case XTL::X_D3DTSS_MAGFILTER: case XTL::X_D3DTSS_MINFILTER: case XTL::X_D3DTSS_MIPFILTER:
if (Value == XTL::X_D3DTEXF_QUINCUNX) {
EmuLog(LOG_LEVEL::WARNING, "D3DTEXF_QUINCUNX is unsupported");
// Fallback to D3DTEXF_ANISOTROPIC
Value = D3DTEXF_ANISOTROPIC;
break;
}
break;
case XTL::X_D3DTSS_TEXCOORDINDEX:
switch (Value) {
case 0x00040000:
// This value is TCI_OBJECT on Xbox,which is not supported by the host
// In this case, we reset to 0.
EmuLog(LOG_LEVEL::WARNING, "EmuD3DDevice_SetTextureState_TexCoordIndex: D3DTSS_TCI_OBJECT is unsupported", Value);
Value = 0;
break;
case 0x00050000:
// This value is TCI_SPHERE on Xbox, let's map it to D3DTSS_TCI_SPHEREMAP for the host
Value = D3DTSS_TCI_SPHEREMAP;
break;
}
break;
// These types require value remapping for all supported values
case XTL::X_D3DTSS_COLOROP: case XTL::X_D3DTSS_ALPHAOP:
Value = GetHostTextureOpValue(Value);
break;
// These types require no conversion, so we just pass through as-is
case XTL::X_D3DTSS_COLORARG0: case XTL::X_D3DTSS_COLORARG1: case XTL::X_D3DTSS_COLORARG2:
case XTL::X_D3DTSS_ALPHAARG0: case XTL::X_D3DTSS_ALPHAARG1: case XTL::X_D3DTSS_ALPHAARG2:
case XTL::X_D3DTSS_RESULTARG: case XTL::X_D3DTSS_TEXTURETRANSFORMFLAGS:
case XTL::X_D3DTSS_BUMPENVMAT00: case XTL::X_D3DTSS_BUMPENVMAT01:
case XTL::X_D3DTSS_BUMPENVMAT11: case XTL::X_D3DTSS_BUMPENVMAT10:
case XTL::X_D3DTSS_BUMPENVLSCALE: case XTL::X_D3DTSS_BUMPENVLOFFSET:
case XTL::X_D3DTSS_BORDERCOLOR: case XTL::X_D3DTSS_MIPMAPLODBIAS:
case XTL::X_D3DTSS_MAXMIPLEVEL: case XTL::X_D3DTSS_MAXANISOTROPY:
break;
default:
// Only log missing state if it has a PC counterpart
if (CxbxTextureStateInfo[State].PC != 0) {
EmuLog(LOG_LEVEL::WARNING, "XboxTextureStateConverter::Apply(%s, 0x%.08X) is unimplemented!", CxbxTextureStateInfo[State].S, Value);
}
break;
}
// Skip Texture States that don't have a defined PC counterpart
if (CxbxTextureStateInfo[State].PC == 0) {
continue;
}
if (CxbxTextureStateInfo[State].IsSamplerState) {
g_pD3DDevice->SetSamplerState(HostStage, (D3DSAMPLERSTATETYPE)CxbxTextureStateInfo[State].PC, Value);
} else {
g_pD3DDevice->SetTextureStageState(HostStage, (D3DTEXTURESTAGESTATETYPE)CxbxTextureStateInfo[State].PC, Value);
}
}
// Make sure we only do this once
if (pointSpriteOverride && XboxStage == 3) {
pointSpriteOverride = false;
XboxStage--;
}
}
if (pointSpritesEnabled) {
IDirect3DBaseTexture* pTexture;
// set the point sprites texture
g_pD3DDevice->GetTexture(3, &pTexture);
g_pD3DDevice->SetTexture(0, pTexture);
// Avoid a dangling reference that would lead to a memory leak
if (pTexture != nullptr)
pTexture->Release();
// disable all other stages
g_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
g_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
// no need to actually copy here, since it was handled in the loop above
}
}

View File

@ -1,49 +1,49 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2019 Luke Usher
// *
// * All rights reserved
// *
// ******************************************************************
#include <cstdint>
#include <array>
#include "core\hle\D3D8\XbD3D8Types.h"
#define CXBX_D3DRS_UNSUPPORTED (XTL::X_D3DRS_LAST + 1)
class XboxRenderStateConverter;
class XboxTextureStateConverter
{
public:
bool Init(XboxRenderStateConverter* state);
void Apply();
private:
void BuildTextureStateMappingTable();
DWORD GetHostTextureOpValue(DWORD XboxTextureOp);
uint32_t* D3D__TextureState = nullptr;
std::array<int, XTL::X_D3DTSS_LAST + 1> XboxTextureStateOffsets;
XboxRenderStateConverter* pXboxRenderStates;
};
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2019 Luke Usher
// *
// * All rights reserved
// *
// ******************************************************************
#include <cstdint>
#include <array>
#include "core\hle\D3D8\XbD3D8Types.h"
#define CXBX_D3DRS_UNSUPPORTED (XTL::X_D3DRS_LAST + 1)
class XboxRenderStateConverter;
class XboxTextureStateConverter
{
public:
bool Init(XboxRenderStateConverter* state);
void Apply();
private:
void BuildTextureStateMappingTable();
DWORD GetHostTextureOpValue(DWORD XboxTextureOp);
uint32_t* D3D__TextureState = nullptr;
std::array<int, XTL::X_D3DTSS_LAST + 1> XboxTextureStateOffsets;
XboxRenderStateConverter* pXboxRenderStates;
};

View File

@ -5,10 +5,10 @@
#include "Logging.h"
#include "util/hasher.h"
#include "core/kernel/support/Emu.h"
VertexShaderSource g_VertexShaderSource = VertexShaderSource();
// FIXME : This should really be released and created in step with the D3D device lifecycle rather than being a thing on its own
// (And the ResetD3DDevice method should be removed)
VertexShaderSource g_VertexShaderSource = VertexShaderSource();
// FIXME : This should really be released and created in step with the D3D device lifecycle rather than being a thing on its own
// (And the ResetD3DDevice method should be removed)
ID3DBlob* AsyncCreateVertexShader(IntermediateVertexShader intermediateShader, ShaderKey key) {
// HACK set thread affinity every call to reduce interference with Xbox main thread
@ -44,14 +44,14 @@ ID3DBlob* AsyncCreateVertexShader(IntermediateVertexShader intermediateShader, S
// Create a new shader
// If the shader was already created, just increase its reference count
ShaderKey VertexShaderSource::CreateShader(const DWORD* pXboxFunction, DWORD *pXboxFunctionSize) {
IntermediateVertexShader intermediateShader;
IntermediateVertexShader intermediateShader;
// Parse into intermediate format
EmuParseVshFunction((DWORD*)pXboxFunction,
pXboxFunctionSize,
&intermediateShader);
// FIXME ignore shader header when creating key
// FIXME ignore shader header when creating key
ShaderKey key = ComputeHash((void*)pXboxFunction, *pXboxFunctionSize);
// Check if we need to create the shader

View File

@ -41,7 +41,7 @@ private:
bool VertexShaderSource::_FindShader(ShaderKey key, LazyVertexShader** ppLazyShader);
};
extern VertexShaderSource g_VertexShaderSource;
extern VertexShaderSource g_VertexShaderSource;
#endif

View File

@ -28,8 +28,8 @@
#define LOG_PREFIX CXBXR_MODULE::D3DCVT
#include "common\Settings.hpp" // for g_LibVersion_D3D8
#include "core\kernel\support\Emu.h"
#include "common\Settings.hpp" // for g_LibVersion_D3D8
#include "core\kernel\support\Emu.h"
#include "XbConvert.h"
@ -698,8 +698,8 @@ static __inline uint32_t Clamp(int32_t val) {
#define SIMD_ALIGNED(var) __declspec(align(16)) var
#define SIMD_ALIGNED32(var) __declspec(align(64)) var
typedef __declspec(align(32)) int16_t lvec16[16];
typedef __declspec(align(32)) int8_t lvec8[32];
#elif __GNUC__
typedef __declspec(align(32)) int8_t lvec8[32];
#elif __GNUC__
#define SIMD_ALIGNED(var) __attribute__((aligned(16)))var
#define SIMD_ALIGNED32(var) __attribute__((aligned(64))) var
typedef __attribute__((aligned(32))) int16_t lvec16[16];
@ -1054,7 +1054,7 @@ D3DFORMAT EmuXB2PC_D3DFormat(XTL::X_D3DFORMAT Format)
}
XTL::X_D3DFORMAT EmuPC2XB_D3DFormat(D3DFORMAT Format, bool bPreferLinear)
{
{
XTL::X_D3DFORMAT result;
switch(Format)
{
@ -1136,7 +1136,7 @@ XTL::X_D3DFORMAT EmuPC2XB_D3DFormat(D3DFORMAT Format, bool bPreferLinear)
}
DWORD EmuXB2PC_D3DLock(DWORD Flags)
{
{
DWORD NewFlags = 0;
// Need to convert the flags, TODO: fix the xbox extensions
@ -1189,11 +1189,11 @@ D3DMULTISAMPLE_TYPE EmuXB2PC_D3DMultiSampleFormat(DWORD Type)
// lookup table for converting vertex count to primitive count
const unsigned g_XboxPrimitiveTypeInfo[11][2] =
{
// First number is the starting number of vertices the draw requires
// Second number the number of vertices per primitive
{
// First number is the starting number of vertices the draw requires
// Second number the number of vertices per primitive
// Example : Triangle list, has no starting vertices, and uses 3 vertices for each triangle
// Example : Triangle strip, starts with 2 vertices, and adds 1 for each triangle
// Example : Triangle strip, starts with 2 vertices, and adds 1 for each triangle
{0, 0}, // NULL
{0, 1}, // X_D3DPT_POINTLIST
{0, 2}, // X_D3DPT_LINELIST
@ -1337,14 +1337,14 @@ void EmuUnswizzleBox
}
}
} // EmuUnswizzleBox NOPATCH
// Notes :
// * most renderstates were introduced in the (lowest known) XDK version : 3424
// * additional renderstates were introduced between 3434 and 4627
// * we MUST list exact versions for each of those, since their inserts impacts mapping!
// * renderstates were finalized in 4627 (so no change after that version)
// * renderstates after D3DRS_MULTISAMPLEMASK have no host mapping, thus no impact
// * D3DRS_MULTISAMPLETYPE seems the only renderstate that got removed (after 3944, before 4039)
// Notes :
// * most renderstates were introduced in the (lowest known) XDK version : 3424
// * additional renderstates were introduced between 3434 and 4627
// * we MUST list exact versions for each of those, since their inserts impacts mapping!
// * renderstates were finalized in 4627 (so no change after that version)
// * renderstates after D3DRS_MULTISAMPLEMASK have no host mapping, thus no impact
// * D3DRS_MULTISAMPLETYPE seems the only renderstate that got removed (after 3944, before 4039)
// * all renderstates marked 3424 are also verified present in 3944
const RenderStateInfo DxbxRenderStateInfo[] = {
@ -1444,40 +1444,40 @@ const RenderStateInfo DxbxRenderStateInfo[] = {
{ "D3DRS_SIMPLE_UNUSED2" /*= 90*/, 4627, xtDWORD, 0 }, // Verified absent in 4531, present in 4627 TODO : might be introduced in between?
{ "D3DRS_SIMPLE_UNUSED1" /*= 91*/, 4627, xtDWORD, 0 }, // Verified absent in 4531, present in 4627 TODO : might be introduced in between?
// End of "simple" render states, continuing with "deferred" render states :
// Verified as XDK 3911 Deferred RenderStates (3424 yet to do)
{ "D3DRS_FOGENABLE" /*= 92*/, 3424, xtBOOL, NV2A_FOG_ENABLE, D3DRS_FOGENABLE }, // TRUE to enable fog blending
{ "D3DRS_FOGTABLEMODE" /*= 93*/, 3424, xtD3DFOGMODE, NV2A_FOG_MODE, D3DRS_FOGTABLEMODE }, // D3DFOGMODE
{ "D3DRS_FOGSTART" /*= 94*/, 3424, xtFloat, NV2A_FOG_COORD_DIST, D3DRS_FOGSTART }, // float fog start (for both vertex and pixel fog)
{ "D3DRS_FOGEND" /*= 95*/, 3424, xtFloat, NV2A_FOG_MODE, D3DRS_FOGEND }, // float fog end
{ "D3DRS_FOGDENSITY" /*= 96*/, 3424, xtFloat, NV2A_FOG_EQUATION_CONSTANT, D3DRS_FOGDENSITY }, // float fog density // + NV2A_FOG_EQUATION_LINEAR + NV2A_FOG_EQUATION_QUADRATIC
{ "D3DRS_RANGEFOGENABLE" /*= 97*/, 3424, xtBOOL, NV2A_FOG_COORD_DIST, D3DRS_RANGEFOGENABLE }, // TRUE to enable range-based fog
{ "D3DRS_WRAP0" /*= 98*/, 3424, xtD3DWRAP, NV2A_TX_WRAP(0), D3DRS_WRAP0 }, // D3DWRAP* flags (D3DWRAP_U, D3DWRAPCOORD_0, etc.) for 1st texture coord.
{ "D3DRS_WRAP1" /*= 99*/, 3424, xtD3DWRAP, NV2A_TX_WRAP(1), D3DRS_WRAP1 }, // D3DWRAP* flags (D3DWRAP_U, D3DWRAPCOORD_0, etc.) for 2nd texture coord.
{ "D3DRS_WRAP2" /*= 100*/, 3424, xtD3DWRAP, NV2A_TX_WRAP(2), D3DRS_WRAP2 }, // D3DWRAP* flags (D3DWRAP_U, D3DWRAPCOORD_0, etc.) for 3rd texture coord.
{ "D3DRS_WRAP3" /*= 101*/, 3424, xtD3DWRAP, NV2A_TX_WRAP(3), D3DRS_WRAP3 }, // D3DWRAP* flags (D3DWRAP_U, D3DWRAPCOORD_0, etc.) for 4th texture coord.
{ "D3DRS_LIGHTING" /*= 102*/, 3424, xtBOOL, NV2A_LIGHT_MODEL, D3DRS_LIGHTING }, // TRUE to enable lighting // TODO : Needs push-buffer data conversion
{ "D3DRS_SPECULARENABLE" /*= 103*/, 3424, xtBOOL, NV2A_RC_FINAL0, D3DRS_SPECULARENABLE }, // TRUE to enable specular
{ "D3DRS_LOCALVIEWER" /*= 104*/, 3424, xtBOOL, 0, D3DRS_LOCALVIEWER }, // TRUE to enable camera-relative specular highlights
{ "D3DRS_COLORVERTEX" /*= 105*/, 3424, xtBOOL, 0, D3DRS_COLORVERTEX }, // TRUE to enable per-vertex color
{ "D3DRS_BACKSPECULARMATERIALSOURCE" /*= 106*/, 3424, xtD3DMCS, 0 }, // D3DMATERIALCOLORSOURCE (Xbox extension) nsp.
{ "D3DRS_BACKDIFFUSEMATERIALSOURCE" /*= 107*/, 3424, xtD3DMCS, 0 }, // D3DMATERIALCOLORSOURCE (Xbox extension) nsp.
{ "D3DRS_BACKAMBIENTMATERIALSOURCE" /*= 108*/, 3424, xtD3DMCS, 0 }, // D3DMATERIALCOLORSOURCE (Xbox extension) nsp.
{ "D3DRS_BACKEMISSIVEMATERIALSOURCE" /*= 109*/, 3424, xtD3DMCS, 0 }, // D3DMATERIALCOLORSOURCE (Xbox extension) nsp.
{ "D3DRS_SPECULARMATERIALSOURCE" /*= 110*/, 3424, xtD3DMCS, NV2A_COLOR_MATERIAL, D3DRS_SPECULARMATERIALSOURCE }, // D3DMATERIALCOLORSOURCE
{ "D3DRS_DIFFUSEMATERIALSOURCE" /*= 111*/, 3424, xtD3DMCS, 0, D3DRS_DIFFUSEMATERIALSOURCE }, // D3DMATERIALCOLORSOURCE
{ "D3DRS_AMBIENTMATERIALSOURCE" /*= 112*/, 3424, xtD3DMCS, 0, D3DRS_AMBIENTMATERIALSOURCE }, // D3DMATERIALCOLORSOURCE
{ "D3DRS_EMISSIVEMATERIALSOURCE" /*= 113*/, 3424, xtD3DMCS, 0, D3DRS_EMISSIVEMATERIALSOURCE }, // D3DMATERIALCOLORSOURCE
{ "D3DRS_BACKAMBIENT" /*= 114*/, 3424, xtD3DCOLOR, NV2A_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R }, // D3DCOLOR (Xbox extension) // ..NV2A_MATERIAL_FACTOR_BACK_B nsp. Was NV2A_LIGHT_MODEL_BACK_AMBIENT_R
{ "D3DRS_AMBIENT" /*= 115*/, 3424, xtD3DCOLOR, NV2A_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R, D3DRS_AMBIENT }, // D3DCOLOR // ..NV2A_LIGHT_MODEL_FRONT_AMBIENT_B + NV2A_MATERIAL_FACTOR_FRONT_R..NV2A_MATERIAL_FACTOR_FRONT_A Was NV2A_LIGHT_MODEL_FRONT_AMBIENT_R
{ "D3DRS_POINTSIZE" /*= 116*/, 3424, xtFloat, NV2A_POINT_PARAMETER(0), D3DRS_POINTSIZE }, // float point size
{ "D3DRS_POINTSIZE_MIN" /*= 117*/, 3424, xtFloat, 0, D3DRS_POINTSIZE_MIN }, // float point size min threshold
{ "D3DRS_POINTSPRITEENABLE" /*= 118*/, 3424, xtBOOL, NV2A_POINT_SMOOTH_ENABLE, D3DRS_POINTSPRITEENABLE }, // TRUE to enable point sprites
{ "D3DRS_POINTSCALEENABLE" /*= 119*/, 3424, xtBOOL, NV2A_POINT_PARAMETERS_ENABLE, D3DRS_POINTSCALEENABLE }, // TRUE to enable point size scaling
{ "D3DRS_POINTSCALE_A" /*= 120*/, 3424, xtFloat, 0, D3DRS_POINTSCALE_A }, // float point attenuation A value
{ "D3DRS_POINTSCALE_B" /*= 121*/, 3424, xtFloat, 0, D3DRS_POINTSCALE_B }, // float point attenuation B value
{ "D3DRS_POINTSCALE_C" /*= 122*/, 3424, xtFloat, 0, D3DRS_POINTSCALE_C }, // float point attenuation C value
{ "D3DRS_POINTSIZE_MAX" /*= 123*/, 3424, xtFloat, 0, D3DRS_POINTSIZE_MAX }, // float point size max threshold
{ "D3DRS_PATCHEDGESTYLE" /*= 124*/, 3424, xtDWORD, 0, D3DRS_PATCHEDGESTYLE }, // D3DPATCHEDGESTYLE
// Verified as XDK 3911 Deferred RenderStates (3424 yet to do)
{ "D3DRS_FOGENABLE" /*= 92*/, 3424, xtBOOL, NV2A_FOG_ENABLE, D3DRS_FOGENABLE }, // TRUE to enable fog blending
{ "D3DRS_FOGTABLEMODE" /*= 93*/, 3424, xtD3DFOGMODE, NV2A_FOG_MODE, D3DRS_FOGTABLEMODE }, // D3DFOGMODE
{ "D3DRS_FOGSTART" /*= 94*/, 3424, xtFloat, NV2A_FOG_COORD_DIST, D3DRS_FOGSTART }, // float fog start (for both vertex and pixel fog)
{ "D3DRS_FOGEND" /*= 95*/, 3424, xtFloat, NV2A_FOG_MODE, D3DRS_FOGEND }, // float fog end
{ "D3DRS_FOGDENSITY" /*= 96*/, 3424, xtFloat, NV2A_FOG_EQUATION_CONSTANT, D3DRS_FOGDENSITY }, // float fog density // + NV2A_FOG_EQUATION_LINEAR + NV2A_FOG_EQUATION_QUADRATIC
{ "D3DRS_RANGEFOGENABLE" /*= 97*/, 3424, xtBOOL, NV2A_FOG_COORD_DIST, D3DRS_RANGEFOGENABLE }, // TRUE to enable range-based fog
{ "D3DRS_WRAP0" /*= 98*/, 3424, xtD3DWRAP, NV2A_TX_WRAP(0), D3DRS_WRAP0 }, // D3DWRAP* flags (D3DWRAP_U, D3DWRAPCOORD_0, etc.) for 1st texture coord.
{ "D3DRS_WRAP1" /*= 99*/, 3424, xtD3DWRAP, NV2A_TX_WRAP(1), D3DRS_WRAP1 }, // D3DWRAP* flags (D3DWRAP_U, D3DWRAPCOORD_0, etc.) for 2nd texture coord.
{ "D3DRS_WRAP2" /*= 100*/, 3424, xtD3DWRAP, NV2A_TX_WRAP(2), D3DRS_WRAP2 }, // D3DWRAP* flags (D3DWRAP_U, D3DWRAPCOORD_0, etc.) for 3rd texture coord.
{ "D3DRS_WRAP3" /*= 101*/, 3424, xtD3DWRAP, NV2A_TX_WRAP(3), D3DRS_WRAP3 }, // D3DWRAP* flags (D3DWRAP_U, D3DWRAPCOORD_0, etc.) for 4th texture coord.
{ "D3DRS_LIGHTING" /*= 102*/, 3424, xtBOOL, NV2A_LIGHT_MODEL, D3DRS_LIGHTING }, // TRUE to enable lighting // TODO : Needs push-buffer data conversion
{ "D3DRS_SPECULARENABLE" /*= 103*/, 3424, xtBOOL, NV2A_RC_FINAL0, D3DRS_SPECULARENABLE }, // TRUE to enable specular
{ "D3DRS_LOCALVIEWER" /*= 104*/, 3424, xtBOOL, 0, D3DRS_LOCALVIEWER }, // TRUE to enable camera-relative specular highlights
{ "D3DRS_COLORVERTEX" /*= 105*/, 3424, xtBOOL, 0, D3DRS_COLORVERTEX }, // TRUE to enable per-vertex color
{ "D3DRS_BACKSPECULARMATERIALSOURCE" /*= 106*/, 3424, xtD3DMCS, 0 }, // D3DMATERIALCOLORSOURCE (Xbox extension) nsp.
{ "D3DRS_BACKDIFFUSEMATERIALSOURCE" /*= 107*/, 3424, xtD3DMCS, 0 }, // D3DMATERIALCOLORSOURCE (Xbox extension) nsp.
{ "D3DRS_BACKAMBIENTMATERIALSOURCE" /*= 108*/, 3424, xtD3DMCS, 0 }, // D3DMATERIALCOLORSOURCE (Xbox extension) nsp.
{ "D3DRS_BACKEMISSIVEMATERIALSOURCE" /*= 109*/, 3424, xtD3DMCS, 0 }, // D3DMATERIALCOLORSOURCE (Xbox extension) nsp.
{ "D3DRS_SPECULARMATERIALSOURCE" /*= 110*/, 3424, xtD3DMCS, NV2A_COLOR_MATERIAL, D3DRS_SPECULARMATERIALSOURCE }, // D3DMATERIALCOLORSOURCE
{ "D3DRS_DIFFUSEMATERIALSOURCE" /*= 111*/, 3424, xtD3DMCS, 0, D3DRS_DIFFUSEMATERIALSOURCE }, // D3DMATERIALCOLORSOURCE
{ "D3DRS_AMBIENTMATERIALSOURCE" /*= 112*/, 3424, xtD3DMCS, 0, D3DRS_AMBIENTMATERIALSOURCE }, // D3DMATERIALCOLORSOURCE
{ "D3DRS_EMISSIVEMATERIALSOURCE" /*= 113*/, 3424, xtD3DMCS, 0, D3DRS_EMISSIVEMATERIALSOURCE }, // D3DMATERIALCOLORSOURCE
{ "D3DRS_BACKAMBIENT" /*= 114*/, 3424, xtD3DCOLOR, NV2A_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R }, // D3DCOLOR (Xbox extension) // ..NV2A_MATERIAL_FACTOR_BACK_B nsp. Was NV2A_LIGHT_MODEL_BACK_AMBIENT_R
{ "D3DRS_AMBIENT" /*= 115*/, 3424, xtD3DCOLOR, NV2A_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R, D3DRS_AMBIENT }, // D3DCOLOR // ..NV2A_LIGHT_MODEL_FRONT_AMBIENT_B + NV2A_MATERIAL_FACTOR_FRONT_R..NV2A_MATERIAL_FACTOR_FRONT_A Was NV2A_LIGHT_MODEL_FRONT_AMBIENT_R
{ "D3DRS_POINTSIZE" /*= 116*/, 3424, xtFloat, NV2A_POINT_PARAMETER(0), D3DRS_POINTSIZE }, // float point size
{ "D3DRS_POINTSIZE_MIN" /*= 117*/, 3424, xtFloat, 0, D3DRS_POINTSIZE_MIN }, // float point size min threshold
{ "D3DRS_POINTSPRITEENABLE" /*= 118*/, 3424, xtBOOL, NV2A_POINT_SMOOTH_ENABLE, D3DRS_POINTSPRITEENABLE }, // TRUE to enable point sprites
{ "D3DRS_POINTSCALEENABLE" /*= 119*/, 3424, xtBOOL, NV2A_POINT_PARAMETERS_ENABLE, D3DRS_POINTSCALEENABLE }, // TRUE to enable point size scaling
{ "D3DRS_POINTSCALE_A" /*= 120*/, 3424, xtFloat, 0, D3DRS_POINTSCALE_A }, // float point attenuation A value
{ "D3DRS_POINTSCALE_B" /*= 121*/, 3424, xtFloat, 0, D3DRS_POINTSCALE_B }, // float point attenuation B value
{ "D3DRS_POINTSCALE_C" /*= 122*/, 3424, xtFloat, 0, D3DRS_POINTSCALE_C }, // float point attenuation C value
{ "D3DRS_POINTSIZE_MAX" /*= 123*/, 3424, xtFloat, 0, D3DRS_POINTSIZE_MAX }, // float point size max threshold
{ "D3DRS_PATCHEDGESTYLE" /*= 124*/, 3424, xtDWORD, 0, D3DRS_PATCHEDGESTYLE }, // D3DPATCHEDGESTYLE
{ "D3DRS_PATCHSEGMENTS" /*= 125*/, 3424, xtDWORD, 0 }, // DWORD number of segments per edge when drawing patches, nsp (D3DRS_PATCHSEGMENTS exists in Direct3D 8, but not in 9)
// TODO -oDxbx : Is X_D3DRS_SWAPFILTER really a xtD3DMULTISAMPLE_TYPE?
{ "D3DRS_SWAPFILTER" /*= 126*/, 4039, xtD3DMULTISAMPLE_TYPE, 0, D3DRS_UNSUPPORTED, "D3DTEXF_LINEAR etc. filter to use for Swap" }, // nsp. Verified absent in 3944, present in 4039 TODO : Might be introduced in 4034?
@ -1509,7 +1509,7 @@ const RenderStateInfo DxbxRenderStateInfo[] = {
{ "D3DRS_EDGEANTIALIAS" /*= 151*/, 3424, xtBOOL, NV2A_LINE_SMOOTH_ENABLE, D3DRS_ANTIALIASEDLINEENABLE }, // Was D3DRS_EDGEANTIALIAS. Dxbx note : No Xbox ext. (according to Direct3D8) !
{ "D3DRS_MULTISAMPLEANTIALIAS" /*= 152*/, 3424, xtBOOL, NV2A_MULTISAMPLE_CONTROL, D3DRS_MULTISAMPLEANTIALIAS },
{ "D3DRS_MULTISAMPLEMASK" /*= 153*/, 3424, xtDWORD, NV2A_MULTISAMPLE_CONTROL, D3DRS_MULTISAMPLEMASK },
{ "D3DRS_MULTISAMPLETYPE" /*= 154*/, 3424, xtD3DMULTISAMPLE_TYPE, 0, D3DRS_UNSUPPORTED, "aliasses D3DMULTISAMPLE_TYPE, removed from 4039 onward", 4039 }, // Verified present in 3944, removed in 4039 TODO : Might be removed in 4034?
{ "D3DRS_MULTISAMPLETYPE" /*= 154*/, 3424, xtD3DMULTISAMPLE_TYPE, 0, D3DRS_UNSUPPORTED, "aliasses D3DMULTISAMPLE_TYPE, removed from 4039 onward", 4039 }, // Verified present in 3944, removed in 4039 TODO : Might be removed in 4034?
{ "D3DRS_MULTISAMPLEMODE" /*= 155*/, 4039, xtD3DMULTISAMPLEMODE, 0 }, // D3DMULTISAMPLEMODE for the backbuffer. Verified absent in 3944, present in 4039 TODO : Might be introduced in 4034?
{ "D3DRS_MULTISAMPLERENDERTARGETMODE" /*= 156*/, 4034, xtD3DMULTISAMPLEMODE, NV2A_RT_FORMAT }, // Verified absent in 3944, present in 4039. Presence in 4034 is based on test-case : The Simpsons Road Rage
{ "D3DRS_SHADOWFUNC" /*= 157*/, 3424, xtD3DCMPFUNC, NV2A_TX_RCOMP },
@ -1523,11 +1523,11 @@ const RenderStateInfo DxbxRenderStateInfo[] = {
{ "D3DRS_ROPZREAD" /*= 165*/, 3911, xtBOOL, 0 }, // Verified present in 3944
{ "D3DRS_DONOTCULLUNCOMPRESSED" /*= 166*/, 3911, xtBOOL, 0 } // Verified present in 3944
};
const RenderStateInfo& GetDxbxRenderStateInfo(int State)
{
return DxbxRenderStateInfo[State];
}
const RenderStateInfo& GetDxbxRenderStateInfo(int State)
{
return DxbxRenderStateInfo[State];
}
/*Direct3D8 states unused :
D3DRS_LINEPATTERN

View File

@ -26,11 +26,11 @@
#define XBCONVERT_H
#include "core\kernel\init\CxbxKrnl.h"
#include "core\hle\D3D8\XbD3D8Types.h"
#define VERTICES_PER_DOT 1
#define VERTICES_PER_LINE 2
#define VERTICES_PER_DOT 1
#define VERTICES_PER_LINE 2
#define VERTICES_PER_TRIANGLE 3
#define VERTICES_PER_QUAD 4
#define TRIANGLES_PER_QUAD 2
@ -95,7 +95,7 @@ else
// convert from xbox to pc texture transform state types
inline D3DTRANSFORMSTATETYPE EmuXB2PC_D3DTS(D3DTRANSFORMSTATETYPE State)
{
{
// Handle Xbox -> D3D State mapping
switch (State) {
case 0: return (D3DTRANSFORMSTATETYPE)D3DTS_VIEW;
@ -146,22 +146,22 @@ inline D3DBLENDOP EmuXB2PC_D3DBLENDOP(XTL::X_D3DBLENDOP Value)
// convert from xbox to pc blend types
inline D3DBLEND EmuXB2PC_D3DBLEND(XTL::X_D3DBLEND Value)
{
{
switch (Value) {
case 0x000: return D3DBLEND_ZERO;
case 0x001: return D3DBLEND_ONE;
case 0x300: return D3DBLEND_SRCCOLOR;
case 0x301: return D3DBLEND_INVSRCCOLOR;
case 0x302: return D3DBLEND_SRCALPHA;
case 0x303: return D3DBLEND_INVSRCALPHA;
case 0x304: return D3DBLEND_DESTALPHA;
case 0x305: return D3DBLEND_INVDESTALPHA;
case 0x306: return D3DBLEND_DESTCOLOR;
case 0x307: return D3DBLEND_INVDESTCOLOR;
case 0x308: return D3DBLEND_SRCALPHASAT;
case 0x8001:return D3DBLEND_BLENDFACTOR; // Maps Xbox D3DBLEND_CONSTANTCOLOR
case 0x8002:return D3DBLEND_INVBLENDFACTOR; // Maps Xbox D3DBLEND_INVCONSTANTCOLOR
case 0x8003: EmuLogEx(LOG_PREFIX_D3DCVT, LOG_LEVEL::WARNING, "Unsupported Xbox D3DBlend Extension: D3DBLEND_CONSTANTALPHA"); return D3DBLEND_ONE;
case 0x000: return D3DBLEND_ZERO;
case 0x001: return D3DBLEND_ONE;
case 0x300: return D3DBLEND_SRCCOLOR;
case 0x301: return D3DBLEND_INVSRCCOLOR;
case 0x302: return D3DBLEND_SRCALPHA;
case 0x303: return D3DBLEND_INVSRCALPHA;
case 0x304: return D3DBLEND_DESTALPHA;
case 0x305: return D3DBLEND_INVDESTALPHA;
case 0x306: return D3DBLEND_DESTCOLOR;
case 0x307: return D3DBLEND_INVDESTCOLOR;
case 0x308: return D3DBLEND_SRCALPHASAT;
case 0x8001:return D3DBLEND_BLENDFACTOR; // Maps Xbox D3DBLEND_CONSTANTCOLOR
case 0x8002:return D3DBLEND_INVBLENDFACTOR; // Maps Xbox D3DBLEND_INVCONSTANTCOLOR
case 0x8003: EmuLogEx(LOG_PREFIX_D3DCVT, LOG_LEVEL::WARNING, "Unsupported Xbox D3DBlend Extension: D3DBLEND_CONSTANTALPHA"); return D3DBLEND_ONE;
case 0x8004: EmuLogEx(LOG_PREFIX_D3DCVT, LOG_LEVEL::WARNING, "Unsupported Xbox D3DBlend Extension: D3DBLEND_INVCONSTANTALPHA"); return D3DBLEND_ONE;
}
@ -173,13 +173,13 @@ inline D3DBLEND EmuXB2PC_D3DBLEND(XTL::X_D3DBLEND Value)
inline D3DCMPFUNC EmuXB2PC_D3DCMPFUNC(XTL::X_D3DCMPFUNC Value)
{
switch (Value) {
case 0x200: return D3DCMP_NEVER;
case 0x201: return D3DCMP_LESS;
case 0x202: return D3DCMP_EQUAL;
case 0x203: return D3DCMP_LESSEQUAL;
case 0x204: return D3DCMP_GREATER;
case 0x205: return D3DCMP_NOTEQUAL;
case 0x206: return D3DCMP_GREATEREQUAL;
case 0x200: return D3DCMP_NEVER;
case 0x201: return D3DCMP_LESS;
case 0x202: return D3DCMP_EQUAL;
case 0x203: return D3DCMP_LESSEQUAL;
case 0x204: return D3DCMP_GREATER;
case 0x205: return D3DCMP_NOTEQUAL;
case 0x206: return D3DCMP_GREATEREQUAL;
case 0x207: return D3DCMP_ALWAYS;
}
@ -191,8 +191,8 @@ inline D3DCMPFUNC EmuXB2PC_D3DCMPFUNC(XTL::X_D3DCMPFUNC Value)
inline D3DFILLMODE EmuXB2PC_D3DFILLMODE(XTL::X_D3DFILLMODE Value)
{
switch (Value) {
case 0x1B00: return D3DFILL_POINT;
case 0x1B01: return D3DFILL_WIREFRAME;
case 0x1B00: return D3DFILL_POINT;
case 0x1B01: return D3DFILL_WIREFRAME;
case 0x1B02: return D3DFILL_SOLID;
}
@ -204,7 +204,7 @@ inline D3DFILLMODE EmuXB2PC_D3DFILLMODE(XTL::X_D3DFILLMODE Value)
inline D3DSHADEMODE EmuXB2PC_D3DSHADEMODE(XTL::X_D3DSHADEMODE Value)
{
switch (Value) {
case 0x1D00: return D3DSHADE_FLAT;
case 0x1D00: return D3DSHADE_FLAT;
case 0x1D01: return D3DSHADE_GOURAUD;
}
@ -214,7 +214,7 @@ inline D3DSHADEMODE EmuXB2PC_D3DSHADEMODE(XTL::X_D3DSHADEMODE Value)
// convert from xbox to pc stencilop modes
inline D3DSTENCILOP EmuXB2PC_D3DSTENCILOP(XTL::X_D3DSTENCILOP Value)
{
{
switch(Value)
{
case 0x1e00: return D3DSTENCILOP_KEEP;
@ -236,8 +236,8 @@ inline D3DSTENCILOP EmuXB2PC_D3DSTENCILOP(XTL::X_D3DSTENCILOP Value)
extern const UINT g_XboxPrimitiveTypeInfo[XTL::X_D3DPT_POLYGON + 1][2];
inline bool IsValidXboxVertexCount(XTL::X_D3DPRIMITIVETYPE XboxPrimitiveType, UINT VertexCount)
{
assert(XboxPrimitiveType < XTL::X_D3DPT_MAX);
{
assert(XboxPrimitiveType < XTL::X_D3DPT_MAX);
// Are there more vertices than required for setup?
if (VertexCount > g_XboxPrimitiveTypeInfo[XboxPrimitiveType][0])
@ -251,22 +251,22 @@ inline bool IsValidXboxVertexCount(XTL::X_D3DPRIMITIVETYPE XboxPrimitiveType, UI
// convert from vertex count to primitive count (Xbox)
inline unsigned ConvertXboxVertexCountToPrimitiveCount(XTL::X_D3DPRIMITIVETYPE XboxPrimitiveType, unsigned VertexCount)
{
assert(XboxPrimitiveType < XTL::X_D3DPT_MAX);
assert(XboxPrimitiveType < XTL::X_D3DPT_MAX);
return (VertexCount - g_XboxPrimitiveTypeInfo[XboxPrimitiveType][0]) / g_XboxPrimitiveTypeInfo[XboxPrimitiveType][1];
}
// conversion table for xbox->pc primitive types
extern const D3DPRIMITIVETYPE g_XboxPrimitiveTypeToHost[];
// convert xbox->pc primitive type
inline D3DPRIMITIVETYPE EmuXB2PC_D3DPrimitiveType(XTL::X_D3DPRIMITIVETYPE XboxPrimitiveType)
{
if (XboxPrimitiveType >= XTL::X_D3DPT_MAX) {
if (XboxPrimitiveType >= XTL::X_D3DPT_MAX) {
LOG_TEST_CASE("XboxPrimitiveType too large");
return D3DPT_FORCE_DWORD;
return D3DPT_FORCE_DWORD;
}
return g_XboxPrimitiveTypeToHost[XboxPrimitiveType];
}
@ -1810,14 +1810,14 @@ typedef struct _RenderStateInfo {
TXBType T = xt_Unknown; // The Xbox data type. Defaults to xt_Unknown.
XTL::NV2AMETHOD M; // The related push buffer method. Not always a 1-to-1 mapping. Needs push-buffer interpretation & conversion code.
D3DRENDERSTATETYPE PC = (D3DRENDERSTATETYPE)0; // Map XBox to PC render state
char *N; // XDK notes. Defaults to ''.
char *N; // XDK notes. Defaults to ''.
WORD R; // The XDK version since which a render state was removed
}
RenderStateInfo;
#define D3DRS_UNSUPPORTED ((D3DRENDERSTATETYPE)0)
extern const RenderStateInfo& GetDxbxRenderStateInfo(int State);
extern const RenderStateInfo& GetDxbxRenderStateInfo(int State);
#endif

View File

@ -27,17 +27,17 @@
#include "Logging.h"
#include "XbD3D8Types.h"
extern const char* D3DErrorString(HRESULT hResult); // Implemented in Direct3D9.cpp
#define DEBUG_D3DRESULT(hRet, message) \
do { \
LOG_CHECK_ENABLED(LOG_LEVEL::DEBUG) { \
if (FAILED(hRet)) \
if(g_bPrintfOn) \
printf("%s%s : %s D3D error (0x%.08X: %s)\n", _logThreadPrefix.c_str(), _logFuncPrefix.c_str(), message, hRet, D3DErrorString(hRet)); \
} \
} while (0)
extern const char* D3DErrorString(HRESULT hResult); // Implemented in Direct3D9.cpp
#define DEBUG_D3DRESULT(hRet, message) \
do { \
LOG_CHECK_ENABLED(LOG_LEVEL::DEBUG) { \
if (FAILED(hRet)) \
if(g_bPrintfOn) \
printf("%s%s : %s D3D error (0x%.08X: %s)\n", _logThreadPrefix.c_str(), _logFuncPrefix.c_str(), message, hRet, D3DErrorString(hRet)); \
} \
} while (0)
// Additional types, exclusively for logging (not really enums) :
enum D3DVS20CAPS : int;
@ -71,8 +71,8 @@ enum X_D3DCOMMON_TYPE : int;
enum X_D3DRESOURCE_COMMON : int;
enum X_D3DRESOURCE_FORMAT : int;
enum X_D3DRESOURCE_SIZE : int;
} // end of namespace XTL
} // end of namespace XTL
//
// Headers for rendering host D3D enum types :
@ -117,7 +117,7 @@ LOGRENDER_HEADER(D3DPSHADERCAPS2_0)
LOGRENDER_HEADER(D3DCAPS)
LOGRENDER_HEADER(D3DLOCKED_RECT)
LOGRENDER_HEADER(RECT)
namespace XTL {
//
@ -160,4 +160,4 @@ LOGRENDER_HEADER(X_D3DPixelContainer)
} // end of namespace XTL
#endif _EMU_D3D8_LOGGING_H
#endif _EMU_D3D8_LOGGING_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,40 +1,40 @@
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef XBPIXELSHADER_H
#define XBPIXELSHADER_H
#include "Cxbx.h"
#include "core\hle\D3D8\XbD3D8Types.h"
// dump pixel shader definition to file
void DumpPixelShaderDefToFile( XTL::X_D3DPIXELSHADERDEF* pPSDef, const char* pszCode );
// print relevant contents to the debug console
void PrintPixelShaderDefContents(XTL::X_D3DPIXELSHADERDEF* pDSDef );
// PatrickvL's Dxbx pixel shader translation
VOID DxbxUpdateActivePixelShader(); // NOPATCH
#endif // PIXELSHADER_H
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef XBPIXELSHADER_H
#define XBPIXELSHADER_H
#include "Cxbx.h"
#include "core\hle\D3D8\XbD3D8Types.h"
// dump pixel shader definition to file
void DumpPixelShaderDefToFile( XTL::X_D3DPIXELSHADERDEF* pPSDef, const char* pszCode );
// print relevant contents to the debug console
void PrintPixelShaderDefContents(XTL::X_D3DPIXELSHADERDEF* pDSDef );
// PatrickvL's Dxbx pixel shader translation
VOID DxbxUpdateActivePixelShader(); // NOPATCH
#endif // PIXELSHADER_H

View File

@ -31,9 +31,9 @@
#include "core\kernel\support\Emu.h"
#include "core\hle\D3D8\XbD3D8Types.h" // For X_D3DFORMAT
#include "core\hle\D3D8\ResourceTracker.h"
#include "core\hle\D3D8\ResourceTracker.h"
#include "core\hle\D3D8\Direct3D9\Direct3D9.h" // For g_Xbox_VertexShader_Handle
#include "core\hle\D3D8\XbPushBuffer.h"
#include "core\hle\D3D8\XbPushBuffer.h"
#include "core\hle\D3D8\XbConvert.h"
#include "devices/video/nv2a.h" // For g_NV2A, PGRAPHState
#include "devices/video/nv2a_int.h" // For NV** defines

View File

@ -24,8 +24,8 @@
// ******************************************************************
#ifndef XBPUSHBUFFER_H
#define XBPUSHBUFFER_H
#include "core/hle/D3D8/XbVertexBuffer.h" // for CxbxDrawContext
#include "core/hle/D3D8/XbVertexBuffer.h" // for CxbxDrawContext
extern int DxbxFVF_GetNumberOfTextureCoordinates(DWORD dwFVF, int aTextureIndex);
extern UINT DxbxFVFToVertexSizeInBytes(DWORD dwFVF, BOOL bIncludeTextures);
@ -45,4 +45,4 @@ extern void EmuExecutePushBufferRaw
uint32_t uSizeInBytes
);
#endif
#endif

View File

@ -32,10 +32,10 @@
#include "common\util\hasher.h"
#include "core\kernel\support\Emu.h"
#include "core\hle\D3D8\Direct3D9\Direct3D9.h" // For g_pD3DDevice
#include "core\hle\D3D8\Direct3D9\WalkIndexBuffer.h" // for WalkIndexBuffer
#include "core\hle\D3D8\ResourceTracker.h"
#include "core\hle\D3D8\Direct3D9\WalkIndexBuffer.h" // for WalkIndexBuffer
#include "core\hle\D3D8\ResourceTracker.h"
#include "core\hle\D3D8\XbPushBuffer.h" // for DxbxFVF_GetNumberOfTextureCoordinates
#include "core\hle\D3D8\XbVertexBuffer.h"
#include "core\hle\D3D8\XbVertexBuffer.h"
#include "core\hle\D3D8\XbConvert.h"
#include <ctime>
@ -60,13 +60,13 @@ extern DWORD g_dwPrimPerFrame = 0;
XTL::X_STREAMINPUT g_Xbox_SetStreamSource[X_VSH_MAX_STREAMS] = { 0 }; // Note : .Offset member is never set (so always 0)
extern XTL::X_D3DSurface* g_pXbox_RenderTarget;
extern XTL::X_D3DSurface* g_pXbox_BackBufferSurface;
extern XTL::X_D3DMULTISAMPLE_TYPE g_Xbox_MultiSampleType;
extern XTL::X_D3DSurface* g_pXbox_BackBufferSurface;
extern XTL::X_D3DMULTISAMPLE_TYPE g_Xbox_MultiSampleType;
void *GetDataFromXboxResource(XTL::X_D3DResource *pXboxResource);
bool GetHostRenderTargetDimensions(DWORD* pHostWidth, DWORD* pHostHeight, IDirect3DSurface* pHostRenderTarget = nullptr);
uint32_t GetPixelContainerWidth(XTL::X_D3DPixelContainer* pPixelContainer);
uint32_t GetPixelContainerHeight(XTL::X_D3DPixelContainer* pPixelContainer);
uint32_t GetPixelContainerHeight(XTL::X_D3DPixelContainer* pPixelContainer);
void ApplyXboxMultiSampleOffsetAndScale(float& x, float& y);
void CxbxPatchedStream::Activate(CxbxDrawContext *pDrawContext, UINT uiStream) const
@ -620,10 +620,10 @@ void CxbxVertexBufferConverter::ConvertStream
pHostVertexAsFloat[3] = pXboxVertexAsFloat[2];
break;
}
case XTL::X_D3DVSDT_NONE: { // 0x02:
// Test-case : WWE RAW2
case XTL::X_D3DVSDT_NONE: { // 0x02:
// Test-case : WWE RAW2
// Test-case : PetitCopter
LOG_TEST_CASE("X_D3DVSDT_NONE");
LOG_TEST_CASE("X_D3DVSDT_NONE");
// No host element data (but Xbox size can be above zero, when used for X_D3DVSD_MASK_SKIP*
break;
}
@ -689,8 +689,8 @@ void CxbxVertexBufferConverter::ConvertStream
// Transforming always breaks render to non-upscaled textures: Only surfaces are upscaled, intentionally so
if (bNeedRHWTransform) {
pVertexDataAsFloat[0] *= g_RenderScaleFactor;
pVertexDataAsFloat[1] *= g_RenderScaleFactor;
pVertexDataAsFloat[1] *= g_RenderScaleFactor;
ApplyXboxMultiSampleOffsetAndScale(pVertexDataAsFloat[0], pVertexDataAsFloat[1]);
}
@ -777,22 +777,22 @@ void CxbxVertexBufferConverter::Apply(CxbxDrawContext *pDrawContext)
m_pCxbxVertexDeclaration = &(GetCxbxVertexShader(g_Xbox_VertexShader_Handle)->Declaration);
}
// If we are drawing from an offset, we know that the vertex count must have
// If we are drawing from an offset, we know that the vertex count must have
// 'offset' vertices before the first drawn vertices
pDrawContext->VerticesInBuffer = pDrawContext->dwStartVertex + pDrawContext->dwVertexCount;
// When this is an indexed draw, take the index buffer into account
if (pDrawContext->pXboxIndexData) {
// Is the highest index in this buffer not set yet?
if (pDrawContext->HighIndex == 0) {
// TODO : Instead of calling WalkIndexBuffer here, set LowIndex and HighIndex
pDrawContext->VerticesInBuffer = pDrawContext->dwStartVertex + pDrawContext->dwVertexCount;
// When this is an indexed draw, take the index buffer into account
if (pDrawContext->pXboxIndexData) {
// Is the highest index in this buffer not set yet?
if (pDrawContext->HighIndex == 0) {
// TODO : Instead of calling WalkIndexBuffer here, set LowIndex and HighIndex
// in all callers that end up here (since they might be able to avoid the call)
LOG_TEST_CASE("HighIndex == 0"); // TODO : If this is never hit, replace entire block by assert(pDrawContext->HighIndex > 0);
WalkIndexBuffer(pDrawContext->LowIndex, pDrawContext->HighIndex, pDrawContext->pXboxIndexData, pDrawContext->dwVertexCount);
}
// Convert highest index (including the base offset) into a count
DWORD dwHighestVertexCount = pDrawContext->dwBaseVertexIndex + pDrawContext->HighIndex + 1;
// Use the biggest vertex count that can be reached
if (pDrawContext->VerticesInBuffer < dwHighestVertexCount)
LOG_TEST_CASE("HighIndex == 0"); // TODO : If this is never hit, replace entire block by assert(pDrawContext->HighIndex > 0);
WalkIndexBuffer(pDrawContext->LowIndex, pDrawContext->HighIndex, pDrawContext->pXboxIndexData, pDrawContext->dwVertexCount);
}
// Convert highest index (including the base offset) into a count
DWORD dwHighestVertexCount = pDrawContext->dwBaseVertexIndex + pDrawContext->HighIndex + 1;
// Use the biggest vertex count that can be reached
if (pDrawContext->VerticesInBuffer < dwHighestVertexCount)
pDrawContext->VerticesInBuffer = dwHighestVertexCount;
}

View File

@ -24,9 +24,9 @@
// ******************************************************************
#ifndef XBVERTEXBUFFER_H
#define XBVERTEXBUFFER_H
#include <unordered_map>
#include <list>
#include <unordered_map>
#include <list>
#include "Cxbx.h"
@ -37,8 +37,8 @@ typedef struct _CxbxDrawContext
IN XTL::X_D3DPRIMITIVETYPE XboxPrimitiveType;
IN DWORD dwVertexCount;
IN DWORD dwStartVertex; // Only D3DDevice_DrawVertices sets this (potentially higher than default 0)
IN PWORD pXboxIndexData; // Set by D3DDevice_DrawIndexedVertices, D3DDevice_DrawIndexedVerticesUP and HLE_draw_inline_elements
IN DWORD dwBaseVertexIndex; // Set to g_Xbox_BaseVertexIndex in D3DDevice_DrawIndexedVertices
IN PWORD pXboxIndexData; // Set by D3DDevice_DrawIndexedVertices, D3DDevice_DrawIndexedVerticesUP and HLE_draw_inline_elements
IN DWORD dwBaseVertexIndex; // Set to g_Xbox_BaseVertexIndex in D3DDevice_DrawIndexedVertices
IN INDEX16 LowIndex, HighIndex; // Set when pXboxIndexData is set
IN size_t VerticesInBuffer; // Set by CxbxVertexBufferConverter::Apply
// Data if Draw...UP call

File diff suppressed because it is too large Load Diff

View File

@ -73,7 +73,7 @@ typedef struct _CxbxVertexDeclaration
CxbxVertexShaderStreamInfo VertexStreams[X_VSH_MAX_STREAMS];
IDirect3DVertexDeclaration* pHostVertexDeclaration;
DWORD* pXboxDeclarationCopy;
DWORD XboxDeclarationCount; // Xbox's number of DWORD-sized X_D3DVSD* tokens
DWORD XboxDeclarationCount; // Xbox's number of DWORD-sized X_D3DVSD* tokens
UINT NumberOfVertexStreams; // The number of streams the vertex shader uses
bool vRegisterInDeclaration[X_VSH_MAX_ATTRIBUTES];
}
@ -232,17 +232,17 @@ extern boolean IsValidCurrentShader(void);
inline boolean VshHandleIsVertexShader(DWORD Handle) { return (Handle & X_D3DFVF_RESERVED0) ? TRUE : FALSE; }
inline boolean VshHandleIsFVF(DWORD Handle) { return !VshHandleIsVertexShader(Handle); }
inline XTL::X_D3DVertexShader *VshHandleToXboxVertexShader(DWORD Handle) { return (XTL::X_D3DVertexShader *)(Handle & ~X_D3DFVF_RESERVED0);}
extern CxbxVertexShader* GetCxbxVertexShader(DWORD XboxVertexShaderHandle);
extern CxbxVertexShader* GetCxbxVertexShader(DWORD XboxVertexShaderHandle);
extern void CxbxImpl_LoadVertexShaderProgram(CONST DWORD* pFunction, DWORD Address);
extern void CxbxImpl_LoadVertexShader(DWORD Handle, DWORD Address);
extern void CxbxImpl_SetVertexShader(DWORD Handle);
extern void CxbxImpl_SelectVertexShaderDirect(XTL::X_VERTEXATTRIBUTEFORMAT* pVAF, DWORD Address);
extern void CxbxImpl_SelectVertexShader(DWORD Handle, DWORD Address);
extern void CxbxImpl_SetVertexShaderInput(DWORD Handle, UINT StreamCount, XTL::X_STREAMINPUT* pStreamInputs);
extern void CxbxImpl_SetVertexShaderConstant(INT Register, PVOID pConstantData, DWORD ConstantCount);
extern HRESULT CxbxImpl_CreateVertexShader(CONST DWORD *pDeclaration, CONST DWORD *pFunction, DWORD *pHandle, DWORD Usage);
extern void CxbxImpl_DeleteVertexShader(DWORD Handle);
extern void CxbxImpl_LoadVertexShader(DWORD Handle, DWORD Address);
extern void CxbxImpl_SetVertexShader(DWORD Handle);
extern void CxbxImpl_SelectVertexShaderDirect(XTL::X_VERTEXATTRIBUTEFORMAT* pVAF, DWORD Address);
extern void CxbxImpl_SelectVertexShader(DWORD Handle, DWORD Address);
extern void CxbxImpl_SetVertexShaderInput(DWORD Handle, UINT StreamCount, XTL::X_STREAMINPUT* pStreamInputs);
extern void CxbxImpl_SetVertexShaderConstant(INT Register, PVOID pConstantData, DWORD ConstantCount);
extern HRESULT CxbxImpl_CreateVertexShader(CONST DWORD *pDeclaration, CONST DWORD *pFunction, DWORD *pHandle, DWORD Usage);
extern void CxbxImpl_DeleteVertexShader(DWORD Handle);
#endif

View File

@ -25,13 +25,13 @@
// ******************************************************************
#ifndef EMUDSOUND_H
#define EMUDSOUND_H
#include "core\kernel\init\CxbxKrnl.h"
#include "core\hle\DSOUND\XbDSoundTypes.h"
#include "core\hle\DSOUND\common\XbInternalStruct.hpp"
typedef struct IDirectSound3DListener8* LPDIRECTSOUND3DLISTENER8;
typedef struct IDirectSound3DBuffer8* LPDIRECTSOUND3DBUFFER8;
#include "core\kernel\init\CxbxKrnl.h"
#include "core\hle\DSOUND\XbDSoundTypes.h"
#include "core\hle\DSOUND\common\XbInternalStruct.hpp"
typedef struct IDirectSound3DListener8* LPDIRECTSOUND3DLISTENER8;
typedef struct IDirectSound3DBuffer8* LPDIRECTSOUND3DBUFFER8;
#ifdef __cplusplus
extern "C" {
@ -46,7 +46,7 @@ void CxbxInitAudio();
namespace XTL {
#undef FIELD_OFFSET // prevent macro redefinition warnings
#include <dsound.h> // TODO: FIXME after global namespace XTL issue is resolved.
#include <dsound.h> // TODO: FIXME after global namespace XTL issue is resolved.
// ******************************************************************
// * X_CDirectSound
@ -107,26 +107,26 @@ struct EmuDirectSoundBuffer
DSoundBuffer_Lock X_lock;
REFERENCE_TIME Xb_rtPauseEx;
REFERENCE_TIME Xb_rtStopEx;
LONG Xb_VolumeMixbin;
LONG Xb_VolumeMixbin;
X_DSENVOLOPEDESC Xb_EnvolopeDesc;
X_DSVOICEPROPS Xb_VoiceProperties;
DWORD Xb_Flags;
};
struct XbHybridDSBuffer : DSBUFFER_S::DSBUFFER_I {
EmuDirectSoundBuffer* emuDSBuffer;
};
struct SharedDSBuffer : DSBUFFER_S {
SharedDSBuffer(bool is3D) : DSBUFFER_S(is3D) {
emuDSBuffer = new EmuDirectSoundBuffer();
}
EmuDirectSoundBuffer* emuDSBuffer;
virtual ~SharedDSBuffer() {
delete emuDSBuffer;
}
};
X_DSVOICEPROPS Xb_VoiceProperties;
DWORD Xb_Flags;
};
struct XbHybridDSBuffer : DSBUFFER_S::DSBUFFER_I {
EmuDirectSoundBuffer* emuDSBuffer;
};
struct SharedDSBuffer : DSBUFFER_S {
SharedDSBuffer(bool is3D) : DSBUFFER_S(is3D) {
emuDSBuffer = new EmuDirectSoundBuffer();
}
EmuDirectSoundBuffer* emuDSBuffer;
virtual ~SharedDSBuffer() {
delete emuDSBuffer;
}
};
//Custom flags (4 bytes support up to 31 shifts,starting from 0)
#define DSE_FLAG_PCM (1 << 0)
@ -278,10 +278,10 @@ class X_CDirectSoundStream
LPVOID Xb_lpvContext;
REFERENCE_TIME Xb_rtFlushEx;
REFERENCE_TIME Xb_rtPauseEx;
LONG Xb_VolumeMixbin;
LONG Xb_VolumeMixbin;
X_DSENVOLOPEDESC Xb_EnvolopeDesc;
X_DSVOICEPROPS Xb_VoiceProperties;
DWORD Host_dwLastWritePos;
X_DSVOICEPROPS Xb_VoiceProperties;
DWORD Host_dwLastWritePos;
DWORD Xb_Flags;
DWORD Xb_Status;
};
@ -1682,55 +1682,55 @@ HRESULT WINAPI EMUPATCH(IDirectSoundStream_SetFrequency)
HRESULT WINAPI EMUPATCH(IDirectSoundStream_SetMixBins)
(
X_CDirectSoundStream* pThis,
DWORD dwMixBinMask);
DWORD dwMixBinMask);
// ******************************************************************
// * patch: CDirectSound3DCalculator_Calculate3D
// ******************************************************************
VOID WINAPI EMUPATCH(CDirectSound3DCalculator_Calculate3D)
(
DWORD a1,
DWORD a2);
DWORD a2);
// ******************************************************************
// * patch: CDirectSound3DCalculator_GetVoiceData
// ******************************************************************
VOID WINAPI EMUPATCH(CDirectSound3DCalculator_GetVoiceData)
(
DWORD a1,
DWORD a2,
DWORD a3,
DWORD a4,
DWORD a5);
DWORD a2,
DWORD a3,
DWORD a4,
DWORD a5);
// ******************************************************************
// * patch: IDirectSoundBuffer_Set3DVoiceData
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Set3DVoiceData)
(
XbHybridDSBuffer* pHybridThis,
DWORD a2);
DWORD a2);
// ******************************************************************
// * patch: IDirectSoundStream_Set3DVoiceData
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundStream_Set3DVoiceData)
(
X_CDirectSoundStream* pThis,
DWORD a2
);
DWORD a2
);
// ******************************************************************
// * patch: IDirectSoundStrea,_Use3DVoiceData
// ******************************************************************
HRESULT WINAPI EMUPATCH(IDirectSoundStream_Use3DVoiceData)
(
X_CDirectSoundStream* pThis,
DWORD a2
);
} // end of extern "C"
DWORD a2
);
} // end of namespace XTL
#endif
} // end of extern "C"
} // end of namespace XTL
#endif

View File

@ -1,224 +1,224 @@
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// *
// * (c) 2019 RadWolfie
// *
// * All rights reserved
// *
// ******************************************************************
#include "Logging.h"
#include "DirectSoundLogging.hpp"
#include <mmreg.h>
#include "..\XbDSoundTypes.h"
// For MiNGW
#ifndef DSBCAPS_TRUEPLAYPOSITION
#define DSBCAPS_TRUEPLAYPOSITION 0x00080000
#endif
FLAGS2STR_START(DS_BCAPS)
FLAG2STR(DSBCAPS_PRIMARYBUFFER)
FLAG2STR(DSBCAPS_STATIC)
FLAG2STR(DSBCAPS_LOCHARDWARE)
FLAG2STR(DSBCAPS_LOCSOFTWARE)
FLAG2STR(DSBCAPS_CTRL3D)
FLAG2STR(DSBCAPS_CTRLFREQUENCY)
FLAG2STR(DSBCAPS_CTRLPAN)
FLAG2STR(DSBCAPS_CTRLVOLUME)
FLAG2STR(DSBCAPS_CTRLPOSITIONNOTIFY)
FLAG2STR(DSBCAPS_CTRLFX)
FLAG2STR(DSBCAPS_STICKYFOCUS)
FLAG2STR(DSBCAPS_GLOBALFOCUS)
FLAG2STR(DSBCAPS_GETCURRENTPOSITION2)
FLAG2STR(DSBCAPS_MUTE3DATMAXDISTANCE)
FLAG2STR(DSBCAPS_LOCDEFER)
FLAG2STR(DSBCAPS_TRUEPLAYPOSITION)
FLAGS2STR_END_and_LOGRENDER(DS_BCAPS)
ENUM2STR_START(DS_RESULT)
ENUM2STR_CASE(DS_OK)
ENUM2STR_CASE(DS_NO_VIRTUALIZATION)
ENUM2STR_CASE(DSERR_ALLOCATED)
ENUM2STR_CASE(DSERR_CONTROLUNAVAIL)
ENUM2STR_CASE(DSERR_INVALIDPARAM)
ENUM2STR_CASE(DSERR_INVALIDCALL)
ENUM2STR_CASE(DSERR_GENERIC)
ENUM2STR_CASE(DSERR_PRIOLEVELNEEDED)
ENUM2STR_CASE(DSERR_OUTOFMEMORY)
ENUM2STR_CASE(DSERR_BADFORMAT)
ENUM2STR_CASE(DSERR_UNSUPPORTED)
ENUM2STR_CASE(DSERR_NODRIVER)
ENUM2STR_CASE(DSERR_ALREADYINITIALIZED)
ENUM2STR_CASE(DSERR_NOAGGREGATION)
ENUM2STR_CASE(DSERR_BUFFERLOST)
ENUM2STR_CASE(DSERR_OTHERAPPHASPRIO)
ENUM2STR_CASE(DSERR_UNINITIALIZED)
ENUM2STR_CASE(DSERR_NOINTERFACE)
ENUM2STR_CASE(DSERR_ACCESSDENIED)
ENUM2STR_CASE(DSERR_BUFFERTOOSMALL)
ENUM2STR_CASE(DSERR_DS8_REQUIRED)
ENUM2STR_CASE(DSERR_SENDLOOP)
ENUM2STR_CASE(DSERR_BADSENDBUFFERGUID)
ENUM2STR_CASE(DSERR_OBJECTNOTFOUND)
ENUM2STR_CASE(DSERR_FXUNAVAILABLE)
ENUM2STR_END_and_LOGRENDER(DS_RESULT)
ENUM2STR_START(WAVEFORMAT_TAG)
ENUM2STR_CASE(0)
ENUM2STR_CASE(WAVE_FORMAT_PCM)
ENUM2STR_CASE(WAVE_FORMAT_ADPCM)
ENUM2STR_CASE(WAVE_FORMAT_XBOX_ADPCM)
ENUM2STR_CASE(WAVE_FORMAT_EXTENSIBLE)
ENUM2STR_END_and_LOGRENDER(WAVEFORMAT_TAG)
#define WFC_MONO 1
#define WFC_STEREO 2
#define WFC_2POINT1 3
#define WFC_QUAD 4
#define WFC_5POINT0 5
#define WFC_5POINT1 6
ENUM2STR_START(WAVEFORMAT_CHANNEL)
ENUM2STR_CASE(WFC_MONO)
ENUM2STR_CASE(WFC_STEREO)
ENUM2STR_CASE(WFC_2POINT1)
ENUM2STR_CASE(WFC_QUAD)
ENUM2STR_CASE(WFC_5POINT0)
ENUM2STR_CASE(WFC_5POINT1)
ENUM2STR_END_and_LOGRENDER(WAVEFORMAT_CHANNEL)
LOGRENDER(WAVEFORMATEX)
{
return os
LOGRENDER_MEMBER_TYPE(WAVEFORMAT_TAG, wFormatTag)
LOGRENDER_MEMBER_TYPE(WAVEFORMAT_CHANNEL, nChannels)
LOGRENDER_MEMBER(nSamplesPerSec)
LOGRENDER_MEMBER(nAvgBytesPerSec)
LOGRENDER_MEMBER(nBlockAlign)
LOGRENDER_MEMBER(wBitsPerSample)
LOGRENDER_MEMBER(cbSize)
;
}
LOGRENDER(GUID)
{
return os
LOGRENDER_MEMBER(Data1)
LOGRENDER_MEMBER(Data2)
LOGRENDER_MEMBER(Data3)
LOGRENDER_MEMBER(Data4)
;
}
LOGRENDER(WAVEFORMATEXTENSIBLE)
{
if (value.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
return os
LOGRENDER_MEMBER_TYPE(WAVEFORMATEX, Format)
LOGRENDER_MEMBER(Samples.wValidBitsPerSample)
LOGRENDER_MEMBER(dwChannelMask)
LOGRENDER_MEMBER_TYPE(GUID, SubFormat)
;
}
else {
return os
LOGRENDER_MEMBER_TYPE(WAVEFORMATEX, Format)
;
}
}
LOGRENDER(DSBUFFERDESC)
{
return os
LOGRENDER_MEMBER(dwSize)
LOGRENDER_MEMBER_TYPE(DS_BCAPS, dwFlags)
LOGRENDER_MEMBER(dwBufferBytes)
LOGRENDER_MEMBER(dwReserved)
LOGRENDER_MEMBER_TYPE(LPWAVEFORMATEX, lpwfxFormat)
;
}
LOGRENDER(D3DVECTOR)
{
return os
LOGRENDER_MEMBER(x)
LOGRENDER_MEMBER(y)
LOGRENDER_MEMBER(z)
;
}
std::string DirectSoundErrorString(HRESULT hResult)
{
switch (hResult) {
case DS_OK:
return "";
case DS_NO_VIRTUALIZATION:
return "The call succeeded, but we had to substitute the 3D algorithm";
case DSERR_ALLOCATED:
return "The call failed because resources(such as a priority level) were already being used by another caller";
case DSERR_CONTROLUNAVAIL:
return "The control (vol, pan, etc.) requested by the caller is not available";
case DSERR_INVALIDPARAM:
return "An invalid parameter was passed to the returning function";
case DSERR_INVALIDCALL:
return "This call is not valid for the current state of this object";
case DSERR_GENERIC:
return "An undetermined error occurred inside the DirectSound subsystem";
case DSERR_PRIOLEVELNEEDED:
return "The caller does not have the priority level required for the function to succeed";
case DSERR_OUTOFMEMORY:
return "Not enough free memory is available to complete the operation";
case DSERR_BADFORMAT:
return "The specified WAVE format is not supported";
case DSERR_UNSUPPORTED:
return "The function called is not supported at this time";
case DSERR_NODRIVER:
return "No sound driver is available for use";
case DSERR_ALREADYINITIALIZED:
return "This object is already initialized";
case DSERR_NOAGGREGATION:
return "This object does not support aggregation";
case DSERR_BUFFERLOST:
return "The buffer memory has been lost, and must be restored";
case DSERR_OTHERAPPHASPRIO:
return "Another app has a higher priority level, preventing this call from succeeding";
case DSERR_UNINITIALIZED:
return "This object has not been initialized";
case DSERR_NOINTERFACE:
return "The requested COM interface is not available";
case DSERR_ACCESSDENIED:
return "Access is denied";
case DSERR_BUFFERTOOSMALL:
return "Tried to create a DSBCAPS_CTRLFX buffer shorter than DSBSIZE_FX_MIN milliseconds";
case DSERR_DS8_REQUIRED:
return "Attempt to use DirectSound 8 functionality on an older DirectSound object";
case DSERR_SENDLOOP:
return "A circular loop of send effects was detected";
case DSERR_BADSENDBUFFERGUID:
return "The GUID specified in an audiopath file does not match a valid MIXIN buffer";
case DSERR_OBJECTNOTFOUND:
return "The object requested was not found (numerically equal to DMUS_E_NOT_FOUND)";
case DSERR_FXUNAVAILABLE:
return "The effects requested could not be found on the system, or they were found"
"but in the wrong order, or in the wrong hardware/software locations.";
default:
return "Unknown error";
}
}
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// *
// * (c) 2019 RadWolfie
// *
// * All rights reserved
// *
// ******************************************************************
#include "Logging.h"
#include "DirectSoundLogging.hpp"
#include <mmreg.h>
#include "..\XbDSoundTypes.h"
// For MiNGW
#ifndef DSBCAPS_TRUEPLAYPOSITION
#define DSBCAPS_TRUEPLAYPOSITION 0x00080000
#endif
FLAGS2STR_START(DS_BCAPS)
FLAG2STR(DSBCAPS_PRIMARYBUFFER)
FLAG2STR(DSBCAPS_STATIC)
FLAG2STR(DSBCAPS_LOCHARDWARE)
FLAG2STR(DSBCAPS_LOCSOFTWARE)
FLAG2STR(DSBCAPS_CTRL3D)
FLAG2STR(DSBCAPS_CTRLFREQUENCY)
FLAG2STR(DSBCAPS_CTRLPAN)
FLAG2STR(DSBCAPS_CTRLVOLUME)
FLAG2STR(DSBCAPS_CTRLPOSITIONNOTIFY)
FLAG2STR(DSBCAPS_CTRLFX)
FLAG2STR(DSBCAPS_STICKYFOCUS)
FLAG2STR(DSBCAPS_GLOBALFOCUS)
FLAG2STR(DSBCAPS_GETCURRENTPOSITION2)
FLAG2STR(DSBCAPS_MUTE3DATMAXDISTANCE)
FLAG2STR(DSBCAPS_LOCDEFER)
FLAG2STR(DSBCAPS_TRUEPLAYPOSITION)
FLAGS2STR_END_and_LOGRENDER(DS_BCAPS)
ENUM2STR_START(DS_RESULT)
ENUM2STR_CASE(DS_OK)
ENUM2STR_CASE(DS_NO_VIRTUALIZATION)
ENUM2STR_CASE(DSERR_ALLOCATED)
ENUM2STR_CASE(DSERR_CONTROLUNAVAIL)
ENUM2STR_CASE(DSERR_INVALIDPARAM)
ENUM2STR_CASE(DSERR_INVALIDCALL)
ENUM2STR_CASE(DSERR_GENERIC)
ENUM2STR_CASE(DSERR_PRIOLEVELNEEDED)
ENUM2STR_CASE(DSERR_OUTOFMEMORY)
ENUM2STR_CASE(DSERR_BADFORMAT)
ENUM2STR_CASE(DSERR_UNSUPPORTED)
ENUM2STR_CASE(DSERR_NODRIVER)
ENUM2STR_CASE(DSERR_ALREADYINITIALIZED)
ENUM2STR_CASE(DSERR_NOAGGREGATION)
ENUM2STR_CASE(DSERR_BUFFERLOST)
ENUM2STR_CASE(DSERR_OTHERAPPHASPRIO)
ENUM2STR_CASE(DSERR_UNINITIALIZED)
ENUM2STR_CASE(DSERR_NOINTERFACE)
ENUM2STR_CASE(DSERR_ACCESSDENIED)
ENUM2STR_CASE(DSERR_BUFFERTOOSMALL)
ENUM2STR_CASE(DSERR_DS8_REQUIRED)
ENUM2STR_CASE(DSERR_SENDLOOP)
ENUM2STR_CASE(DSERR_BADSENDBUFFERGUID)
ENUM2STR_CASE(DSERR_OBJECTNOTFOUND)
ENUM2STR_CASE(DSERR_FXUNAVAILABLE)
ENUM2STR_END_and_LOGRENDER(DS_RESULT)
ENUM2STR_START(WAVEFORMAT_TAG)
ENUM2STR_CASE(0)
ENUM2STR_CASE(WAVE_FORMAT_PCM)
ENUM2STR_CASE(WAVE_FORMAT_ADPCM)
ENUM2STR_CASE(WAVE_FORMAT_XBOX_ADPCM)
ENUM2STR_CASE(WAVE_FORMAT_EXTENSIBLE)
ENUM2STR_END_and_LOGRENDER(WAVEFORMAT_TAG)
#define WFC_MONO 1
#define WFC_STEREO 2
#define WFC_2POINT1 3
#define WFC_QUAD 4
#define WFC_5POINT0 5
#define WFC_5POINT1 6
ENUM2STR_START(WAVEFORMAT_CHANNEL)
ENUM2STR_CASE(WFC_MONO)
ENUM2STR_CASE(WFC_STEREO)
ENUM2STR_CASE(WFC_2POINT1)
ENUM2STR_CASE(WFC_QUAD)
ENUM2STR_CASE(WFC_5POINT0)
ENUM2STR_CASE(WFC_5POINT1)
ENUM2STR_END_and_LOGRENDER(WAVEFORMAT_CHANNEL)
LOGRENDER(WAVEFORMATEX)
{
return os
LOGRENDER_MEMBER_TYPE(WAVEFORMAT_TAG, wFormatTag)
LOGRENDER_MEMBER_TYPE(WAVEFORMAT_CHANNEL, nChannels)
LOGRENDER_MEMBER(nSamplesPerSec)
LOGRENDER_MEMBER(nAvgBytesPerSec)
LOGRENDER_MEMBER(nBlockAlign)
LOGRENDER_MEMBER(wBitsPerSample)
LOGRENDER_MEMBER(cbSize)
;
}
LOGRENDER(GUID)
{
return os
LOGRENDER_MEMBER(Data1)
LOGRENDER_MEMBER(Data2)
LOGRENDER_MEMBER(Data3)
LOGRENDER_MEMBER(Data4)
;
}
LOGRENDER(WAVEFORMATEXTENSIBLE)
{
if (value.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
return os
LOGRENDER_MEMBER_TYPE(WAVEFORMATEX, Format)
LOGRENDER_MEMBER(Samples.wValidBitsPerSample)
LOGRENDER_MEMBER(dwChannelMask)
LOGRENDER_MEMBER_TYPE(GUID, SubFormat)
;
}
else {
return os
LOGRENDER_MEMBER_TYPE(WAVEFORMATEX, Format)
;
}
}
LOGRENDER(DSBUFFERDESC)
{
return os
LOGRENDER_MEMBER(dwSize)
LOGRENDER_MEMBER_TYPE(DS_BCAPS, dwFlags)
LOGRENDER_MEMBER(dwBufferBytes)
LOGRENDER_MEMBER(dwReserved)
LOGRENDER_MEMBER_TYPE(LPWAVEFORMATEX, lpwfxFormat)
;
}
LOGRENDER(D3DVECTOR)
{
return os
LOGRENDER_MEMBER(x)
LOGRENDER_MEMBER(y)
LOGRENDER_MEMBER(z)
;
}
std::string DirectSoundErrorString(HRESULT hResult)
{
switch (hResult) {
case DS_OK:
return "";
case DS_NO_VIRTUALIZATION:
return "The call succeeded, but we had to substitute the 3D algorithm";
case DSERR_ALLOCATED:
return "The call failed because resources(such as a priority level) were already being used by another caller";
case DSERR_CONTROLUNAVAIL:
return "The control (vol, pan, etc.) requested by the caller is not available";
case DSERR_INVALIDPARAM:
return "An invalid parameter was passed to the returning function";
case DSERR_INVALIDCALL:
return "This call is not valid for the current state of this object";
case DSERR_GENERIC:
return "An undetermined error occurred inside the DirectSound subsystem";
case DSERR_PRIOLEVELNEEDED:
return "The caller does not have the priority level required for the function to succeed";
case DSERR_OUTOFMEMORY:
return "Not enough free memory is available to complete the operation";
case DSERR_BADFORMAT:
return "The specified WAVE format is not supported";
case DSERR_UNSUPPORTED:
return "The function called is not supported at this time";
case DSERR_NODRIVER:
return "No sound driver is available for use";
case DSERR_ALREADYINITIALIZED:
return "This object is already initialized";
case DSERR_NOAGGREGATION:
return "This object does not support aggregation";
case DSERR_BUFFERLOST:
return "The buffer memory has been lost, and must be restored";
case DSERR_OTHERAPPHASPRIO:
return "Another app has a higher priority level, preventing this call from succeeding";
case DSERR_UNINITIALIZED:
return "This object has not been initialized";
case DSERR_NOINTERFACE:
return "The requested COM interface is not available";
case DSERR_ACCESSDENIED:
return "Access is denied";
case DSERR_BUFFERTOOSMALL:
return "Tried to create a DSBCAPS_CTRLFX buffer shorter than DSBSIZE_FX_MIN milliseconds";
case DSERR_DS8_REQUIRED:
return "Attempt to use DirectSound 8 functionality on an older DirectSound object";
case DSERR_SENDLOOP:
return "A circular loop of send effects was detected";
case DSERR_BADSENDBUFFERGUID:
return "The GUID specified in an audiopath file does not match a valid MIXIN buffer";
case DSERR_OBJECTNOTFOUND:
return "The object requested was not found (numerically equal to DMUS_E_NOT_FOUND)";
case DSERR_FXUNAVAILABLE:
return "The effects requested could not be found on the system, or they were found"
"but in the wrong order, or in the wrong hardware/software locations.";
default:
return "Unknown error";
}
}

View File

@ -1,49 +1,49 @@
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// *
// * (c) 2019 RadWolfie
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef DIRECTSOUNDLOGGING_H
#define DIRECTSOUNDLOGGING_H
#include <dsound.h>
#include <mmreg.h>
#include "Logging.h"
enum DS_BCAPS : int;
enum DS_RESULT : int;
enum WAVEFORMAT_CHANNEL : int;
enum WAVEFORMAT_TAG : int;
FLAGS2STR_HEADER(DS_BCAPS)
ENUM2STR_HEADER(DS_RESULT)
ENUM2STR_HEADER(WAVEFORMAT_CHANNEL)
ENUM2STR_HEADER(WAVEFORMAT_TAG)
LOGRENDER_HEADER(GUID)
LOGRENDER_HEADER(WAVEFORMATEX)
LOGRENDER_HEADER(WAVEFORMATEXTENSIBLE)
LOGRENDER_HEADER(DSBUFFERDESC)
LOGRENDER_HEADER(D3DVECTOR)
std::string DirectSoundErrorString(HRESULT hResult);
#endif
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// *
// * (c) 2019 RadWolfie
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef DIRECTSOUNDLOGGING_H
#define DIRECTSOUNDLOGGING_H
#include <dsound.h>
#include <mmreg.h>
#include "Logging.h"
enum DS_BCAPS : int;
enum DS_RESULT : int;
enum WAVEFORMAT_CHANNEL : int;
enum WAVEFORMAT_TAG : int;
FLAGS2STR_HEADER(DS_BCAPS)
ENUM2STR_HEADER(DS_RESULT)
ENUM2STR_HEADER(WAVEFORMAT_CHANNEL)
ENUM2STR_HEADER(WAVEFORMAT_TAG)
LOGRENDER_HEADER(GUID)
LOGRENDER_HEADER(WAVEFORMATEX)
LOGRENDER_HEADER(WAVEFORMATEXTENSIBLE)
LOGRENDER_HEADER(DSBUFFERDESC)
LOGRENDER_HEADER(D3DVECTOR)
std::string DirectSoundErrorString(HRESULT hResult);
#endif

View File

@ -1,389 +1,389 @@
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// *
// * (c) 2019 RadWolfie
// *
// * All rights reserved
// *
// ******************************************************************
#include <dsound.h> // Temporary placeholder until XbDSoundTypes.h is cross-platform + filled in the blanks
#include "Logging.h"
#include "XbDSoundLogging.hpp"
#include "common/Settings.hpp"
// For XTL::DSBUFFERDESC and XTL::DSSTREAMDESC temporary usage
extern LOGRENDER_HEADER(WAVEFORMATEX)
extern LOGRENDER_HEADER(D3DVECTOR)
namespace XTL {
// DSound class usage
ENUM2STR_START(DSMIXBIN_SPEAKER)
ENUM2STR_CASE(XDSMIXBIN_FRONT_LEFT)
ENUM2STR_CASE(XDSMIXBIN_FRONT_RIGHT)
ENUM2STR_CASE(XDSMIXBIN_FRONT_CENTER)
ENUM2STR_CASE(XDSMIXBIN_LOW_FREQUENCY)
ENUM2STR_CASE(XDSMIXBIN_BACK_LEFT)
ENUM2STR_CASE(XDSMIXBIN_BACK_RIGHT)
//ENUM2STR_CASE(XDSMIXBIN_SPEAKERS_MAX) // NOTE: Only used as a counter.
ENUM2STR_END_and_LOGRENDER(DSMIXBIN_SPEAKER)
FLAGS2STR_START(DSSPEAKER_FLAG)
FLAG2STR(X_DSSPEAKER_STEREO)
FLAG2STR(X_DSSPEAKER_MONO)
FLAG2STR(X_DSSPEAKER_SURROUND)
FLAG2STR(X_DSSPEAKER_ENABLE_AC3)
FLAG2STR(X_DSSPEAKER_ENABLE_DTS)
FLAGS2STR_END_and_LOGRENDER(DSSPEAKER_FLAG)
// DSound generic flag/enum
ENUM2STR_START(DSFILTER_MODE)
ENUM2STR_CASE(DSFILTER_MODE_BYPASS)
ENUM2STR_CASE(DSFILTER_MODE_DLS2)
ENUM2STR_CASE(DSFILTER_MODE_PARAMEQ)
ENUM2STR_CASE(DSFILTER_MODE_MULTI)
ENUM2STR_END_and_LOGRENDER(DSFILTER_MODE)
// DSound Buffer flag/enum
FLAGS2STR_START(DSBCAPS_FLAG)
FLAG2STR(XTL_DSBCAPS_CTRL3D)
FLAG2STR(XTL_DSBCAPS_CTRLFREQUENCY)
FLAG2STR(XTL_DSBCAPS_CTRLVOLUME)
FLAG2STR(XTL_DSBCAPS_CTRLPOSITIONNOTIFY)
FLAG2STR(XTL_DSBCAPS_MIXIN)
FLAG2STR(XTL_DSBCAPS_MUTE3DATMAXDISTANCE)
FLAG2STR(XTL_DSBCAPS_LOCDEFER)
FLAG2STR(XTL_DSBCAPS_FXIN)
FLAG2STR(XTL_DSBCAPS_FXIN2)
FLAGS2STR_END_and_LOGRENDER(DSBCAPS_FLAG)
FLAGS2STR_START(DSBPAUSE_FLAG)
FLAG2STR(X_DSBPAUSE_RESUME)
FLAG2STR(X_DSBPAUSE_PAUSE)
FLAG2STR(X_DSBPAUSE_SYNCHPLAYBACK)
FLAGS2STR_END_and_LOGRENDER(DSBPAUSE_FLAG)
FLAGS2STR_START(DSBPLAY_FLAG)
FLAG2STR(X_DSBPLAY_LOOPING)
FLAG2STR(X_DSBPLAY_FROMSTART)
FLAG2STR(X_DSBPLAY_SYNCHPLAYBACK)
FLAGS2STR_END_and_LOGRENDER(DSBPLAY_FLAG)
FLAGS2STR_START(DSBSTATUS_FLAG)
FLAG2STR(X_DSBSTATUS_PLAYING)
FLAG2STR(X_DSBSTATUS_PAUSED)
FLAG2STR(X_DSBSTATUS_LOOPING)
FLAGS2STR_END_and_LOGRENDER(DSBSTATUS_FLAG)
FLAGS2STR_START(DSBSTOPEX_FLAG)
FLAG2STR(X_DSBSTOPEX_IMMEDIATE)
FLAG2STR(X_DSBSTOPEX_ENVELOPE)
FLAG2STR(X_DSBSTOPEX_RELEASEWAVEFORM)
//FLAG2STR(X_DSBSTOPEX_ALL) // NOTE: Only a combine of envelope and releasewaveform flags together.
FLAGS2STR_END_and_LOGRENDER(DSBSTOPEX_FLAG)
// DSound Stream flag/enum
FLAGS2STR_START(DSSCAPS_FLAG)
FLAG2STR(XTL_DSSCAPS_CTRL3D)
FLAG2STR(XTL_DSSCAPS_CTRLFREQUENCY)
FLAG2STR(XTL_DSSCAPS_CTRLVOLUME)
FLAG2STR(XTL_DSSCAPS_MUTE3DATMAXDISTANCE)
FLAG2STR(XTL_DSSCAPS_LOCDEFER)
FLAG2STR(XTL_DSSCAPS_NOMERGE)
FLAG2STR(XTL_DSSCAPS_ACCURATENOTIFY)
FLAGS2STR_END_and_LOGRENDER(DSSCAPS_FLAG)
FLAGS2STR_START(DSSFLUSHEX_FLAG)
FLAG2STR(X_DSSFLUSHEX_IMMEDIATE)
FLAG2STR(X_DSSFLUSHEX_ASYNC)
FLAG2STR(X_DSSFLUSHEX_ENVELOPE)
FLAG2STR(X_DSSFLUSHEX_ENVELOPE2)
FLAGS2STR_END_and_LOGRENDER(DSSFLUSHEX_FLAG)
FLAGS2STR_START(DSSPAUSE_FLAG)
FLAG2STR(X_DSSPAUSE_RESUME)
FLAG2STR(X_DSSPAUSE_PAUSE)
FLAG2STR(X_DSSPAUSE_SYNCHPLAYBACK)
FLAG2STR(X_DSSPAUSE_PAUSENOACTIVATE)
FLAGS2STR_END_and_LOGRENDER(DSSPAUSE_FLAG)
FLAGS2STR_START(DSSSTATUS_FLAG)
FLAG2STR(X_DSSSTATUS_READY)
FLAG2STR(X_DSSSTATUS_PLAYING)
FLAG2STR(X_DSSSTATUS_PAUSED)
FLAG2STR(X_DSSSTATUS_STARVED)
FLAG2STR(X_DSSSTATUS_ENVELOPECOMPLETE)
FLAGS2STR_END_and_LOGRENDER(DSSSTATUS_FLAG)
// DSound XMedia flag/enum
ENUM2STR_START(XMP_STATUS)
ENUM2STR_CASE(XMP_STATUS_SUCCESS)
ENUM2STR_CASE(XMP_STATUS_PENDING)
ENUM2STR_CASE(XMP_STATUS_FLUSHED)
ENUM2STR_CASE(XMP_STATUS_FAILURE)
ENUM2STR_CASE((int)XMP_STATUS_RELEASE_CXBXR) // NOTE: Custom status for Cxbx-Reloaded.
ENUM2STR_END_and_LOGRENDER(XMP_STATUS)
FLAGS2STR_START(XMO_STREAMF)
FLAG2STR(XMO_STREAMF_FIXED_SAMPLE_SIZE)
FLAG2STR(XMO_STREAMF_FIXED_PACKET_ALIGNMENT)
FLAG2STR(XMO_STREAMF_INPUT_ASYNC)
FLAG2STR(XMO_STREAMF_OUTPUT_ASYNC)
FLAG2STR(XMO_STREAMF_IN_PLACE)
FLAG2STR(XMO_STREAMF_MASK)
FLAGS2STR_END_and_LOGRENDER(XMO_STREAMF)
// DSound class usage
LOGRENDER(X_DSCAPS)
{
return os
LOGRENDER_MEMBER(dwFree2DBuffers)
LOGRENDER_MEMBER(dwFree3DBuffers)
LOGRENDER_MEMBER(dwFreeBufferSGEs)
LOGRENDER_MEMBER(dwMemoryAllocated)
;
}
LOGRENDER(X_DSI3DL2LISTENER)
{
return os
LOGRENDER_MEMBER(lRoom)
LOGRENDER_MEMBER(lRoomHF)
LOGRENDER_MEMBER(flRoomRolloffFactor)
LOGRENDER_MEMBER(flDecayTime)
LOGRENDER_MEMBER(flDecayHFRatio)
LOGRENDER_MEMBER(lReflections)
LOGRENDER_MEMBER(flReflectionsDelay)
LOGRENDER_MEMBER(lReverb)
LOGRENDER_MEMBER(flReverbDelay)
LOGRENDER_MEMBER(flDiffusion)
LOGRENDER_MEMBER(flDensity)
LOGRENDER_MEMBER(flHFReference)
;
}
LOGRENDER(X_DSMIXBINS)
{
return os
LOGRENDER_MEMBER(dwCount)
LOGRENDER_MEMBER_ARRAY_TYPE(X_DSMIXBINVOLUMEPAIR, lpMixBinVolumePairs, dwCount)
;
}
LOGRENDER(X_DSMIXBINVOLUMEPAIR)
{
return os
LOGRENDER_MEMBER(dwMixBin)
LOGRENDER_MEMBER(lVolume)
;
}
LOGRENDER(X_DSOUTPUTLEVELS)
{
return os
LOGRENDER_MEMBER(dwAnalogLeftTotalPeak)
LOGRENDER_MEMBER(dwAnalogRightTotalPeak)
LOGRENDER_MEMBER(dwAnalogLeftTotalRMS)
LOGRENDER_MEMBER(dwAnalogRightTotalRMS)
LOGRENDER_MEMBER(dwDigitalFrontLeftPeak)
LOGRENDER_MEMBER(dwDigitalFrontCenterPeak)
LOGRENDER_MEMBER(dwDigitalFrontRightPeak)
LOGRENDER_MEMBER(dwDigitalBackLeftPeak)
LOGRENDER_MEMBER(dwDigitalBackRightPeak)
LOGRENDER_MEMBER(dwDigitalLowFrequencyPeak)
LOGRENDER_MEMBER(dwDigitalFrontLeftRMS)
LOGRENDER_MEMBER(dwDigitalFrontCenterRMS)
LOGRENDER_MEMBER(dwDigitalFrontRightRMS)
LOGRENDER_MEMBER(dwDigitalBackLeftRMS)
LOGRENDER_MEMBER(dwDigitalBackRightRMS)
LOGRENDER_MEMBER(dwDigitalLowFrequencyRMS)
;
}
// DSound generic class usage
LOGRENDER(X_DS3DBUFFER)
{
return os
LOGRENDER_MEMBER(dwSize)
LOGRENDER_MEMBER_TYPE(D3DVECTOR, vPosition)
LOGRENDER_MEMBER_TYPE(D3DVECTOR, vVelocity)
LOGRENDER_MEMBER(dwInsideConeAngle)
LOGRENDER_MEMBER(dwOutsideConeAngle)
LOGRENDER_MEMBER_TYPE(D3DVECTOR, vConeOrientation)
LOGRENDER_MEMBER(lConeOutsideVolume)
LOGRENDER_MEMBER(flMinDistance)
LOGRENDER_MEMBER(flMaxDistance)
LOGRENDER_MEMBER(dwMode)
LOGRENDER_MEMBER(flDistanceFactor)
LOGRENDER_MEMBER(flRolloffFactor)
LOGRENDER_MEMBER(flDopplerFactor)
;
}
LOGRENDER(X_DSENVOLOPEDESC)
{
return os
LOGRENDER_MEMBER(dwEnvelopGenerator)
LOGRENDER_MEMBER(dwMode)
LOGRENDER_MEMBER(dwDelay)
LOGRENDER_MEMBER(dwAttack)
LOGRENDER_MEMBER(dwHold)
LOGRENDER_MEMBER(dwDecay)
LOGRENDER_MEMBER(dwRelease)
LOGRENDER_MEMBER(dwSustain)
LOGRENDER_MEMBER(lPitchScale)
LOGRENDER_MEMBER(lFilterCutOff)
;
}
LOGRENDER(X_DSFILTERDESC)
{
return os
LOGRENDER_MEMBER_TYPE(DSFILTER_MODE, dwMode)
LOGRENDER_MEMBER(dwQCoefficient)
LOGRENDER_MEMBER(adwCoefficients)
;
}
LOGRENDER(X_DSI3DL2BUFFER)
{
return os
LOGRENDER_MEMBER(lDirect)
LOGRENDER_MEMBER(lDirectHF)
LOGRENDER_MEMBER(lRoom)
LOGRENDER_MEMBER(lRoomHF)
LOGRENDER_MEMBER(flRoomRolloffFactor)
LOGRENDER_MEMBER_TYPE(X_DSI3DL2OBSTRUCTION, Obstruction)
LOGRENDER_MEMBER_TYPE(X_DSI3DL2OCCLUSION, Occlusion)
;
}
LOGRENDER(X_DSI3DL2OBSTRUCTION)
{
return os
LOGRENDER_MEMBER(lHFLevel)
LOGRENDER_MEMBER(flLFRatio)
;
}
LOGRENDER(X_DSI3DL2OCCLUSION)
{
return os
LOGRENDER_MEMBER(lHFLevel)
LOGRENDER_MEMBER(flLFRatio)
;
}
LOGRENDER(DSLFODESC)
{
return os
LOGRENDER_MEMBER(dwLFO)
LOGRENDER_MEMBER(dwDelay)
LOGRENDER_MEMBER(dwDelta)
LOGRENDER_MEMBER(lPitchModulation)
LOGRENDER_MEMBER(lFilterCutOffRange)
LOGRENDER_MEMBER(lAmplitudeModulation)
;
}
LOGRENDER(XBOXADPCMWAVEFORMAT)
{
return os
LOGRENDER_MEMBER_TYPE(WAVEFORMATEX, wfx)
LOGRENDER_MEMBER(wSamplesPerBlock)
;
}
// DSound Buffer class usage
LOGRENDER(X_DSBUFFERDESC)
{
if (g_LibVersion_DSOUND < 4039) {
return os
LOGRENDER_MEMBER(dwSize)
LOGRENDER_MEMBER_TYPE(DSBCAPS_FLAG, dwFlags)
LOGRENDER_MEMBER(dwBufferBytes)
LOGRENDER_MEMBER_TYPE(LPWAVEFORMATEX, lpwfxFormat)
LOGRENDER_MEMBER_TYPE(DWORD, lpMixBinsOutput)
LOGRENDER_MEMBER(dwInputMixBin)
;
}
else {
return os
LOGRENDER_MEMBER(dwSize)
LOGRENDER_MEMBER_TYPE(DSBCAPS_FLAG, dwFlags)
LOGRENDER_MEMBER(dwBufferBytes)
LOGRENDER_MEMBER_TYPE(LPWAVEFORMATEX, lpwfxFormat)
LOGRENDER_MEMBER(lpMixBinsOutput)
LOGRENDER_MEMBER(dwInputMixBin)
;
}
}
// DSound Stream class usage
LOGRENDER(X_DSSTREAMDESC)
{
if (g_LibVersion_DSOUND < 4039) {
return os
LOGRENDER_MEMBER_TYPE(DSSCAPS_FLAG, dwFlags)
LOGRENDER_MEMBER(dwMaxAttachedPackets)
LOGRENDER_MEMBER_TYPE(LPWAVEFORMATEX, lpwfxFormat)
LOGRENDER_MEMBER_TYPE(void*, lpfnCallback)
LOGRENDER_MEMBER(lpvContext)
LOGRENDER_MEMBER_TYPE(DWORD, lpMixBinsOutput)
;
}
else {
return os
LOGRENDER_MEMBER_TYPE(DSSCAPS_FLAG, dwFlags)
LOGRENDER_MEMBER(dwMaxAttachedPackets)
LOGRENDER_MEMBER_TYPE(LPWAVEFORMATEX, lpwfxFormat)
LOGRENDER_MEMBER_TYPE(void*, lpfnCallback)
LOGRENDER_MEMBER(lpvContext)
LOGRENDER_MEMBER(lpMixBinsOutput)
;
}
}
// DSound XMedia class usage
LOGRENDER(XMEDIAINFO)
{
return os
LOGRENDER_MEMBER(dwFlags)
LOGRENDER_MEMBER(dwInputSize)
LOGRENDER_MEMBER(dwOutputSize)
LOGRENDER_MEMBER(dwMaxLookahead)
;
}
LOGRENDER(XMEDIAPACKET)
{
return os
LOGRENDER_MEMBER(pvBuffer)
LOGRENDER_MEMBER(dwMaxSize)
LOGRENDER_MEMBER(pdwCompletedSize)
LOGRENDER_MEMBER_TYPE(XMO_STREAMF*, pdwStatus)
// NOTE: hCompletionEvent and pContext are a union.
//LOGRENDER_MEMBER(hCompletionEvent)
//LOGRENDER_MEMBER(pContext)
LOGRENDER_MEMBER(prtTimestamp)
;
}
}
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// *
// * (c) 2019 RadWolfie
// *
// * All rights reserved
// *
// ******************************************************************
#include <dsound.h> // Temporary placeholder until XbDSoundTypes.h is cross-platform + filled in the blanks
#include "Logging.h"
#include "XbDSoundLogging.hpp"
#include "common/Settings.hpp"
// For XTL::DSBUFFERDESC and XTL::DSSTREAMDESC temporary usage
extern LOGRENDER_HEADER(WAVEFORMATEX)
extern LOGRENDER_HEADER(D3DVECTOR)
namespace XTL {
// DSound class usage
ENUM2STR_START(DSMIXBIN_SPEAKER)
ENUM2STR_CASE(XDSMIXBIN_FRONT_LEFT)
ENUM2STR_CASE(XDSMIXBIN_FRONT_RIGHT)
ENUM2STR_CASE(XDSMIXBIN_FRONT_CENTER)
ENUM2STR_CASE(XDSMIXBIN_LOW_FREQUENCY)
ENUM2STR_CASE(XDSMIXBIN_BACK_LEFT)
ENUM2STR_CASE(XDSMIXBIN_BACK_RIGHT)
//ENUM2STR_CASE(XDSMIXBIN_SPEAKERS_MAX) // NOTE: Only used as a counter.
ENUM2STR_END_and_LOGRENDER(DSMIXBIN_SPEAKER)
FLAGS2STR_START(DSSPEAKER_FLAG)
FLAG2STR(X_DSSPEAKER_STEREO)
FLAG2STR(X_DSSPEAKER_MONO)
FLAG2STR(X_DSSPEAKER_SURROUND)
FLAG2STR(X_DSSPEAKER_ENABLE_AC3)
FLAG2STR(X_DSSPEAKER_ENABLE_DTS)
FLAGS2STR_END_and_LOGRENDER(DSSPEAKER_FLAG)
// DSound generic flag/enum
ENUM2STR_START(DSFILTER_MODE)
ENUM2STR_CASE(DSFILTER_MODE_BYPASS)
ENUM2STR_CASE(DSFILTER_MODE_DLS2)
ENUM2STR_CASE(DSFILTER_MODE_PARAMEQ)
ENUM2STR_CASE(DSFILTER_MODE_MULTI)
ENUM2STR_END_and_LOGRENDER(DSFILTER_MODE)
// DSound Buffer flag/enum
FLAGS2STR_START(DSBCAPS_FLAG)
FLAG2STR(XTL_DSBCAPS_CTRL3D)
FLAG2STR(XTL_DSBCAPS_CTRLFREQUENCY)
FLAG2STR(XTL_DSBCAPS_CTRLVOLUME)
FLAG2STR(XTL_DSBCAPS_CTRLPOSITIONNOTIFY)
FLAG2STR(XTL_DSBCAPS_MIXIN)
FLAG2STR(XTL_DSBCAPS_MUTE3DATMAXDISTANCE)
FLAG2STR(XTL_DSBCAPS_LOCDEFER)
FLAG2STR(XTL_DSBCAPS_FXIN)
FLAG2STR(XTL_DSBCAPS_FXIN2)
FLAGS2STR_END_and_LOGRENDER(DSBCAPS_FLAG)
FLAGS2STR_START(DSBPAUSE_FLAG)
FLAG2STR(X_DSBPAUSE_RESUME)
FLAG2STR(X_DSBPAUSE_PAUSE)
FLAG2STR(X_DSBPAUSE_SYNCHPLAYBACK)
FLAGS2STR_END_and_LOGRENDER(DSBPAUSE_FLAG)
FLAGS2STR_START(DSBPLAY_FLAG)
FLAG2STR(X_DSBPLAY_LOOPING)
FLAG2STR(X_DSBPLAY_FROMSTART)
FLAG2STR(X_DSBPLAY_SYNCHPLAYBACK)
FLAGS2STR_END_and_LOGRENDER(DSBPLAY_FLAG)
FLAGS2STR_START(DSBSTATUS_FLAG)
FLAG2STR(X_DSBSTATUS_PLAYING)
FLAG2STR(X_DSBSTATUS_PAUSED)
FLAG2STR(X_DSBSTATUS_LOOPING)
FLAGS2STR_END_and_LOGRENDER(DSBSTATUS_FLAG)
FLAGS2STR_START(DSBSTOPEX_FLAG)
FLAG2STR(X_DSBSTOPEX_IMMEDIATE)
FLAG2STR(X_DSBSTOPEX_ENVELOPE)
FLAG2STR(X_DSBSTOPEX_RELEASEWAVEFORM)
//FLAG2STR(X_DSBSTOPEX_ALL) // NOTE: Only a combine of envelope and releasewaveform flags together.
FLAGS2STR_END_and_LOGRENDER(DSBSTOPEX_FLAG)
// DSound Stream flag/enum
FLAGS2STR_START(DSSCAPS_FLAG)
FLAG2STR(XTL_DSSCAPS_CTRL3D)
FLAG2STR(XTL_DSSCAPS_CTRLFREQUENCY)
FLAG2STR(XTL_DSSCAPS_CTRLVOLUME)
FLAG2STR(XTL_DSSCAPS_MUTE3DATMAXDISTANCE)
FLAG2STR(XTL_DSSCAPS_LOCDEFER)
FLAG2STR(XTL_DSSCAPS_NOMERGE)
FLAG2STR(XTL_DSSCAPS_ACCURATENOTIFY)
FLAGS2STR_END_and_LOGRENDER(DSSCAPS_FLAG)
FLAGS2STR_START(DSSFLUSHEX_FLAG)
FLAG2STR(X_DSSFLUSHEX_IMMEDIATE)
FLAG2STR(X_DSSFLUSHEX_ASYNC)
FLAG2STR(X_DSSFLUSHEX_ENVELOPE)
FLAG2STR(X_DSSFLUSHEX_ENVELOPE2)
FLAGS2STR_END_and_LOGRENDER(DSSFLUSHEX_FLAG)
FLAGS2STR_START(DSSPAUSE_FLAG)
FLAG2STR(X_DSSPAUSE_RESUME)
FLAG2STR(X_DSSPAUSE_PAUSE)
FLAG2STR(X_DSSPAUSE_SYNCHPLAYBACK)
FLAG2STR(X_DSSPAUSE_PAUSENOACTIVATE)
FLAGS2STR_END_and_LOGRENDER(DSSPAUSE_FLAG)
FLAGS2STR_START(DSSSTATUS_FLAG)
FLAG2STR(X_DSSSTATUS_READY)
FLAG2STR(X_DSSSTATUS_PLAYING)
FLAG2STR(X_DSSSTATUS_PAUSED)
FLAG2STR(X_DSSSTATUS_STARVED)
FLAG2STR(X_DSSSTATUS_ENVELOPECOMPLETE)
FLAGS2STR_END_and_LOGRENDER(DSSSTATUS_FLAG)
// DSound XMedia flag/enum
ENUM2STR_START(XMP_STATUS)
ENUM2STR_CASE(XMP_STATUS_SUCCESS)
ENUM2STR_CASE(XMP_STATUS_PENDING)
ENUM2STR_CASE(XMP_STATUS_FLUSHED)
ENUM2STR_CASE(XMP_STATUS_FAILURE)
ENUM2STR_CASE((int)XMP_STATUS_RELEASE_CXBXR) // NOTE: Custom status for Cxbx-Reloaded.
ENUM2STR_END_and_LOGRENDER(XMP_STATUS)
FLAGS2STR_START(XMO_STREAMF)
FLAG2STR(XMO_STREAMF_FIXED_SAMPLE_SIZE)
FLAG2STR(XMO_STREAMF_FIXED_PACKET_ALIGNMENT)
FLAG2STR(XMO_STREAMF_INPUT_ASYNC)
FLAG2STR(XMO_STREAMF_OUTPUT_ASYNC)
FLAG2STR(XMO_STREAMF_IN_PLACE)
FLAG2STR(XMO_STREAMF_MASK)
FLAGS2STR_END_and_LOGRENDER(XMO_STREAMF)
// DSound class usage
LOGRENDER(X_DSCAPS)
{
return os
LOGRENDER_MEMBER(dwFree2DBuffers)
LOGRENDER_MEMBER(dwFree3DBuffers)
LOGRENDER_MEMBER(dwFreeBufferSGEs)
LOGRENDER_MEMBER(dwMemoryAllocated)
;
}
LOGRENDER(X_DSI3DL2LISTENER)
{
return os
LOGRENDER_MEMBER(lRoom)
LOGRENDER_MEMBER(lRoomHF)
LOGRENDER_MEMBER(flRoomRolloffFactor)
LOGRENDER_MEMBER(flDecayTime)
LOGRENDER_MEMBER(flDecayHFRatio)
LOGRENDER_MEMBER(lReflections)
LOGRENDER_MEMBER(flReflectionsDelay)
LOGRENDER_MEMBER(lReverb)
LOGRENDER_MEMBER(flReverbDelay)
LOGRENDER_MEMBER(flDiffusion)
LOGRENDER_MEMBER(flDensity)
LOGRENDER_MEMBER(flHFReference)
;
}
LOGRENDER(X_DSMIXBINS)
{
return os
LOGRENDER_MEMBER(dwCount)
LOGRENDER_MEMBER_ARRAY_TYPE(X_DSMIXBINVOLUMEPAIR, lpMixBinVolumePairs, dwCount)
;
}
LOGRENDER(X_DSMIXBINVOLUMEPAIR)
{
return os
LOGRENDER_MEMBER(dwMixBin)
LOGRENDER_MEMBER(lVolume)
;
}
LOGRENDER(X_DSOUTPUTLEVELS)
{
return os
LOGRENDER_MEMBER(dwAnalogLeftTotalPeak)
LOGRENDER_MEMBER(dwAnalogRightTotalPeak)
LOGRENDER_MEMBER(dwAnalogLeftTotalRMS)
LOGRENDER_MEMBER(dwAnalogRightTotalRMS)
LOGRENDER_MEMBER(dwDigitalFrontLeftPeak)
LOGRENDER_MEMBER(dwDigitalFrontCenterPeak)
LOGRENDER_MEMBER(dwDigitalFrontRightPeak)
LOGRENDER_MEMBER(dwDigitalBackLeftPeak)
LOGRENDER_MEMBER(dwDigitalBackRightPeak)
LOGRENDER_MEMBER(dwDigitalLowFrequencyPeak)
LOGRENDER_MEMBER(dwDigitalFrontLeftRMS)
LOGRENDER_MEMBER(dwDigitalFrontCenterRMS)
LOGRENDER_MEMBER(dwDigitalFrontRightRMS)
LOGRENDER_MEMBER(dwDigitalBackLeftRMS)
LOGRENDER_MEMBER(dwDigitalBackRightRMS)
LOGRENDER_MEMBER(dwDigitalLowFrequencyRMS)
;
}
// DSound generic class usage
LOGRENDER(X_DS3DBUFFER)
{
return os
LOGRENDER_MEMBER(dwSize)
LOGRENDER_MEMBER_TYPE(D3DVECTOR, vPosition)
LOGRENDER_MEMBER_TYPE(D3DVECTOR, vVelocity)
LOGRENDER_MEMBER(dwInsideConeAngle)
LOGRENDER_MEMBER(dwOutsideConeAngle)
LOGRENDER_MEMBER_TYPE(D3DVECTOR, vConeOrientation)
LOGRENDER_MEMBER(lConeOutsideVolume)
LOGRENDER_MEMBER(flMinDistance)
LOGRENDER_MEMBER(flMaxDistance)
LOGRENDER_MEMBER(dwMode)
LOGRENDER_MEMBER(flDistanceFactor)
LOGRENDER_MEMBER(flRolloffFactor)
LOGRENDER_MEMBER(flDopplerFactor)
;
}
LOGRENDER(X_DSENVOLOPEDESC)
{
return os
LOGRENDER_MEMBER(dwEnvelopGenerator)
LOGRENDER_MEMBER(dwMode)
LOGRENDER_MEMBER(dwDelay)
LOGRENDER_MEMBER(dwAttack)
LOGRENDER_MEMBER(dwHold)
LOGRENDER_MEMBER(dwDecay)
LOGRENDER_MEMBER(dwRelease)
LOGRENDER_MEMBER(dwSustain)
LOGRENDER_MEMBER(lPitchScale)
LOGRENDER_MEMBER(lFilterCutOff)
;
}
LOGRENDER(X_DSFILTERDESC)
{
return os
LOGRENDER_MEMBER_TYPE(DSFILTER_MODE, dwMode)
LOGRENDER_MEMBER(dwQCoefficient)
LOGRENDER_MEMBER(adwCoefficients)
;
}
LOGRENDER(X_DSI3DL2BUFFER)
{
return os
LOGRENDER_MEMBER(lDirect)
LOGRENDER_MEMBER(lDirectHF)
LOGRENDER_MEMBER(lRoom)
LOGRENDER_MEMBER(lRoomHF)
LOGRENDER_MEMBER(flRoomRolloffFactor)
LOGRENDER_MEMBER_TYPE(X_DSI3DL2OBSTRUCTION, Obstruction)
LOGRENDER_MEMBER_TYPE(X_DSI3DL2OCCLUSION, Occlusion)
;
}
LOGRENDER(X_DSI3DL2OBSTRUCTION)
{
return os
LOGRENDER_MEMBER(lHFLevel)
LOGRENDER_MEMBER(flLFRatio)
;
}
LOGRENDER(X_DSI3DL2OCCLUSION)
{
return os
LOGRENDER_MEMBER(lHFLevel)
LOGRENDER_MEMBER(flLFRatio)
;
}
LOGRENDER(DSLFODESC)
{
return os
LOGRENDER_MEMBER(dwLFO)
LOGRENDER_MEMBER(dwDelay)
LOGRENDER_MEMBER(dwDelta)
LOGRENDER_MEMBER(lPitchModulation)
LOGRENDER_MEMBER(lFilterCutOffRange)
LOGRENDER_MEMBER(lAmplitudeModulation)
;
}
LOGRENDER(XBOXADPCMWAVEFORMAT)
{
return os
LOGRENDER_MEMBER_TYPE(WAVEFORMATEX, wfx)
LOGRENDER_MEMBER(wSamplesPerBlock)
;
}
// DSound Buffer class usage
LOGRENDER(X_DSBUFFERDESC)
{
if (g_LibVersion_DSOUND < 4039) {
return os
LOGRENDER_MEMBER(dwSize)
LOGRENDER_MEMBER_TYPE(DSBCAPS_FLAG, dwFlags)
LOGRENDER_MEMBER(dwBufferBytes)
LOGRENDER_MEMBER_TYPE(LPWAVEFORMATEX, lpwfxFormat)
LOGRENDER_MEMBER_TYPE(DWORD, lpMixBinsOutput)
LOGRENDER_MEMBER(dwInputMixBin)
;
}
else {
return os
LOGRENDER_MEMBER(dwSize)
LOGRENDER_MEMBER_TYPE(DSBCAPS_FLAG, dwFlags)
LOGRENDER_MEMBER(dwBufferBytes)
LOGRENDER_MEMBER_TYPE(LPWAVEFORMATEX, lpwfxFormat)
LOGRENDER_MEMBER(lpMixBinsOutput)
LOGRENDER_MEMBER(dwInputMixBin)
;
}
}
// DSound Stream class usage
LOGRENDER(X_DSSTREAMDESC)
{
if (g_LibVersion_DSOUND < 4039) {
return os
LOGRENDER_MEMBER_TYPE(DSSCAPS_FLAG, dwFlags)
LOGRENDER_MEMBER(dwMaxAttachedPackets)
LOGRENDER_MEMBER_TYPE(LPWAVEFORMATEX, lpwfxFormat)
LOGRENDER_MEMBER_TYPE(void*, lpfnCallback)
LOGRENDER_MEMBER(lpvContext)
LOGRENDER_MEMBER_TYPE(DWORD, lpMixBinsOutput)
;
}
else {
return os
LOGRENDER_MEMBER_TYPE(DSSCAPS_FLAG, dwFlags)
LOGRENDER_MEMBER(dwMaxAttachedPackets)
LOGRENDER_MEMBER_TYPE(LPWAVEFORMATEX, lpwfxFormat)
LOGRENDER_MEMBER_TYPE(void*, lpfnCallback)
LOGRENDER_MEMBER(lpvContext)
LOGRENDER_MEMBER(lpMixBinsOutput)
;
}
}
// DSound XMedia class usage
LOGRENDER(XMEDIAINFO)
{
return os
LOGRENDER_MEMBER(dwFlags)
LOGRENDER_MEMBER(dwInputSize)
LOGRENDER_MEMBER(dwOutputSize)
LOGRENDER_MEMBER(dwMaxLookahead)
;
}
LOGRENDER(XMEDIAPACKET)
{
return os
LOGRENDER_MEMBER(pvBuffer)
LOGRENDER_MEMBER(dwMaxSize)
LOGRENDER_MEMBER(pdwCompletedSize)
LOGRENDER_MEMBER_TYPE(XMO_STREAMF*, pdwStatus)
// NOTE: hCompletionEvent and pContext are a union.
//LOGRENDER_MEMBER(hCompletionEvent)
//LOGRENDER_MEMBER(pContext)
LOGRENDER_MEMBER(prtTimestamp)
;
}
}

View File

@ -1,94 +1,94 @@
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// *
// * (c) 2019 RadWolfie
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef XBDSOUNDLOGGING_H
#define XBDSOUNDLOGGING_H
#include "Logging.h"
#include "XbDSoundTypes.h"
namespace XTL {
// TODO: Everything, only small portions had been implemented.
// DSound flag/enum
enum DSMIXBIN_SPEAKER : int;
enum DSSPEAKER_FLAG : int;
// DSound generic flag/enum
enum DSFILTER_MODE : int;
// DSound Buffer flag/enum
enum DSBCAPS_FLAG : int;
enum DSBPAUSE_FLAG : int;
enum DSBPLAY_FLAG : int;
enum DSBSTATUS_FLAG : int;
enum DSBSTOPEX_FLAG : int;
// DSound Stream flag/enum
enum DSSCAPS_FLAG : int;
enum DSSFLUSHEX_FLAG : int;
enum DSSPAUSE_FLAG : int;
enum DSSSTATUS_FLAG : int;
// DSound XMedia flag/enum
enum XMP_STATUS : int;
enum XMO_STREAMF : int;
// DSound flag/enum
FLAGS2STR_HEADER(DSSPEAKER_FLAG)
// DSound generic flag/enum
ENUM2STR_HEADER(DSFILTER_MODE)
// DSound Buffer flag/enum
FLAGS2STR_HEADER(DSBCAPS_FLAG)
FLAGS2STR_HEADER(DSBPAUSE_FLAG)
FLAGS2STR_HEADER(DSBPLAY_FLAG)
FLAGS2STR_HEADER(DSBSTATUS_FLAG)
FLAGS2STR_HEADER(DSBSTOPEX_FLAG)
// DSound Stream flag/enum
FLAGS2STR_HEADER(DSSCAPS_FLAG)
FLAGS2STR_HEADER(DSSFLUSHEX_FLAG)
FLAGS2STR_HEADER(DSSPAUSE_FLAG)
FLAGS2STR_HEADER(DSSSTATUS_FLAG)
// DSound class usage
LOGRENDER_HEADER(X_DSCAPS)
LOGRENDER_HEADER(X_DSI3DL2LISTENER)
LOGRENDER_HEADER(X_DSMIXBINS)
LOGRENDER_HEADER(X_DSMIXBINVOLUMEPAIR)
LOGRENDER_HEADER(X_DSOUTPUTLEVELS)
// DSound generic class usage
LOGRENDER_HEADER(X_DS3DBUFFER)
LOGRENDER_HEADER(X_DSENVOLOPEDESC)
LOGRENDER_HEADER(X_DSFILTERDESC)
LOGRENDER_HEADER(X_DSI3DL2BUFFER)
LOGRENDER_HEADER(X_DSI3DL2OBSTRUCTION)
LOGRENDER_HEADER(X_DSI3DL2OCCLUSION)
LOGRENDER_HEADER(DSLFODESC)
LOGRENDER_HEADER(XBOXADPCMWAVEFORMAT)
// DSound Buffer class usage
LOGRENDER_HEADER(X_DSBUFFERDESC)
// DSound Stream class usage
LOGRENDER_HEADER(X_DSSTREAMDESC)
// DSound XMedia class usage
LOGRENDER_HEADER(XMEDIAINFO)
LOGRENDER_HEADER(XMEDIAPACKET)
}
#endif
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// *
// * (c) 2019 RadWolfie
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef XBDSOUNDLOGGING_H
#define XBDSOUNDLOGGING_H
#include "Logging.h"
#include "XbDSoundTypes.h"
namespace XTL {
// TODO: Everything, only small portions had been implemented.
// DSound flag/enum
enum DSMIXBIN_SPEAKER : int;
enum DSSPEAKER_FLAG : int;
// DSound generic flag/enum
enum DSFILTER_MODE : int;
// DSound Buffer flag/enum
enum DSBCAPS_FLAG : int;
enum DSBPAUSE_FLAG : int;
enum DSBPLAY_FLAG : int;
enum DSBSTATUS_FLAG : int;
enum DSBSTOPEX_FLAG : int;
// DSound Stream flag/enum
enum DSSCAPS_FLAG : int;
enum DSSFLUSHEX_FLAG : int;
enum DSSPAUSE_FLAG : int;
enum DSSSTATUS_FLAG : int;
// DSound XMedia flag/enum
enum XMP_STATUS : int;
enum XMO_STREAMF : int;
// DSound flag/enum
FLAGS2STR_HEADER(DSSPEAKER_FLAG)
// DSound generic flag/enum
ENUM2STR_HEADER(DSFILTER_MODE)
// DSound Buffer flag/enum
FLAGS2STR_HEADER(DSBCAPS_FLAG)
FLAGS2STR_HEADER(DSBPAUSE_FLAG)
FLAGS2STR_HEADER(DSBPLAY_FLAG)
FLAGS2STR_HEADER(DSBSTATUS_FLAG)
FLAGS2STR_HEADER(DSBSTOPEX_FLAG)
// DSound Stream flag/enum
FLAGS2STR_HEADER(DSSCAPS_FLAG)
FLAGS2STR_HEADER(DSSFLUSHEX_FLAG)
FLAGS2STR_HEADER(DSSPAUSE_FLAG)
FLAGS2STR_HEADER(DSSSTATUS_FLAG)
// DSound class usage
LOGRENDER_HEADER(X_DSCAPS)
LOGRENDER_HEADER(X_DSI3DL2LISTENER)
LOGRENDER_HEADER(X_DSMIXBINS)
LOGRENDER_HEADER(X_DSMIXBINVOLUMEPAIR)
LOGRENDER_HEADER(X_DSOUTPUTLEVELS)
// DSound generic class usage
LOGRENDER_HEADER(X_DS3DBUFFER)
LOGRENDER_HEADER(X_DSENVOLOPEDESC)
LOGRENDER_HEADER(X_DSFILTERDESC)
LOGRENDER_HEADER(X_DSI3DL2BUFFER)
LOGRENDER_HEADER(X_DSI3DL2OBSTRUCTION)
LOGRENDER_HEADER(X_DSI3DL2OCCLUSION)
LOGRENDER_HEADER(DSLFODESC)
LOGRENDER_HEADER(XBOXADPCMWAVEFORMAT)
// DSound Buffer class usage
LOGRENDER_HEADER(X_DSBUFFERDESC)
// DSound Stream class usage
LOGRENDER_HEADER(X_DSSTREAMDESC)
// DSound XMedia class usage
LOGRENDER_HEADER(XMEDIAINFO)
LOGRENDER_HEADER(XMEDIAPACKET)
}
#endif

View File

@ -1,375 +1,375 @@
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// * (c) 2017-2019 RadWolfie
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef XBDSOUNDTYPES_H
#define XBDSOUNDTYPES_H
namespace XTL {
#include <dsound.h> // TODO: FIXME after global namespace XTL issue is resolved.
// TODO: Port PC dsound.h to xbox edition here base on previous research.
// TODO: Also need to use fixed size to able support cross-platform without extra work.
// Such as uint32_t, uint16_t, etc.
#define WAVE_FORMAT_XBOX_ADPCM 0x0069
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// * (c) 2017-2019 RadWolfie
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef XBDSOUNDTYPES_H
#define XBDSOUNDTYPES_H
namespace XTL {
#include <dsound.h> // TODO: FIXME after global namespace XTL issue is resolved.
// TODO: Port PC dsound.h to xbox edition here base on previous research.
// TODO: Also need to use fixed size to able support cross-platform without extra work.
// Such as uint32_t, uint16_t, etc.
#define WAVE_FORMAT_XBOX_ADPCM 0x0069
// Xbox SGE Memory layout
#define XTL_DS_SGE_COUNT_MAX 2047
#define XTL_DS_SGE_PAGE_MAX (4 * ONE_KB)
#define XTL_DS_SGE_SIZE_MAX (XTL_DS_SGE_COUNT_MAX * XTL_DS_SGE_PAGE_MAX)
// XDSMIXBIN Flags
#define XDSMIXBIN_FRONT_LEFT 0
#define XDSMIXBIN_FRONT_RIGHT 1
#define XDSMIXBIN_FRONT_CENTER 2
#define XDSMIXBIN_LOW_FREQUENCY 3
#define XDSMIXBIN_BACK_LEFT 4
#define XDSMIXBIN_BACK_RIGHT 5
#define XDSMIXBIN_SPEAKERS_MAX 6 // Max count for speakers
// Other flags are used
// ******************************************************************
// * X_DSMIXBINVOLUMEPAIR
// ******************************************************************
typedef struct _XDSMIXBINVOLUMEPAIR {
DWORD dwMixBin;
LONG lVolume;
} X_DSMIXBINVOLUMEPAIR, *X_LPDSMIXBINVOLUMEPAIR;
// ******************************************************************
// * X_DSMIXBINS
// ******************************************************************
// Revision 2 (4039+)
typedef struct _XDSMIXBINS {
DWORD dwCount;
X_LPDSMIXBINVOLUMEPAIR lpMixBinVolumePairs;
} X_DSMIXBINS, *X_LPDSMIXBINS;
// EmuIDirectSoundBuffer_Play flags
#define X_DSBPLAY_LOOPING 0x00000001
#define X_DSBPLAY_FROMSTART 0x00000002
#define X_DSBPLAY_SYNCHPLAYBACK 0x00000004
// EmuIDirectSoundBuffer_Pause flags
#define X_DSBPAUSE_RESUME 0x00000000
#define X_DSBPAUSE_PAUSE 0x00000001
#define X_DSBPAUSE_SYNCHPLAYBACK 0x00000002
// EmuIDirectSoundStream_Pause flags
#define X_DSSPAUSE_RESUME 0x00000000
#define X_DSSPAUSE_PAUSE 0x00000001
#define X_DSSPAUSE_SYNCHPLAYBACK 0x00000002
#define X_DSSPAUSE_PAUSENOACTIVATE 0x00000003
// EmuIDirectSoundStream_FlushEx flags
#define X_DSSFLUSHEX_IMMEDIATE 0x00000000
#define X_DSSFLUSHEX_ASYNC 0x00000001
#define X_DSSFLUSHEX_ENVELOPE 0x00000002
#define X_DSSFLUSHEX_ENVELOPE2 0x00000004
// EmuIDirectSoundStream_GetStatus flags
#define X_DSSSTATUS_READY 0x00000001
#define X_DSSSTATUS_PLAYING 0x00010000
#define X_DSSSTATUS_PAUSED 0x00020000
#define X_DSSSTATUS_STARVED 0x00040000
#define X_DSSSTATUS_ENVELOPECOMPLETE 0x00080000
// EmuIDirectSoundBuffer_GetStatus flags
#define X_DSBSTATUS_PLAYING 0x00000001
#define X_DSBSTATUS_PAUSED 0x00000002
#define X_DSBSTATUS_LOOPING 0x00000004
// EmuIDirectSoundBuffer_StopEx flags
#define X_DSBSTOPEX_IMMEDIATE 0x00000000
#define X_DSBSTOPEX_ENVELOPE 0x00000001
#define X_DSBSTOPEX_RELEASEWAVEFORM 0x00000002
#define X_DSBSTOPEX_ALL (X_DSBSTOPEX_ENVELOPE | X_DSBSTOPEX_RELEASEWAVEFORM)
// Generic frequency range
#define XTL_DSXFREQUENCY_ORIGINAL 0x00000000
//#define XTL_DSGFREQUENCY_MIN 0x00000???
//#define XTL_DSGFREQUENCY_MAX 0x000?????
#define XTL_DSBCAPS_CTRL3D 0x00000010
#define XTL_DSBCAPS_CTRLFREQUENCY 0x00000020
#define XTL_DSBCAPS_CTRLVOLUME 0x00000080
#define XTL_DSBCAPS_CTRLPOSITIONNOTIFY 0x00000100
#define XTL_DSBCAPS_MIXIN 0x00002000
#define XTL_DSBCAPS_MUTE3DATMAXDISTANCE 0x00020000
#define XTL_DSBCAPS_LOCDEFER 0x00040000
#define XTL_DSBCAPS_FXIN 0x00080000
#define XTL_DSBCAPS_FXIN2 0x00100000
// ******************************************************************
// * X_DSBUFFERDESC
// ******************************************************************
struct X_DSBUFFERDESC
{
DWORD dwSize;
DWORD dwFlags;
DWORD dwBufferBytes;
LPWAVEFORMATEX lpwfxFormat;
X_LPDSMIXBINS lpMixBinsOutput;
DWORD dwInputMixBin;
};
// ******************************************************************
// * X_DSENVELOPEDESC
// ******************************************************************
struct X_DSENVOLOPEDESC
{
DWORD dwEnvelopGenerator;
DWORD dwMode;
DWORD dwDelay;
DWORD dwAttack;
DWORD dwHold;
DWORD dwDecay;
DWORD dwRelease;
DWORD dwSustain;
LONG lPitchScale;
LONG lFilterCutOff;
};
#define XTL_DSSCAPS_CTRL3D 0x00000010
#define XTL_DSSCAPS_CTRLFREQUENCY 0x00000020
#define XTL_DSSCAPS_CTRLVOLUME 0x00000080
#define XTL_DSSCAPS_MUTE3DATMAXDISTANCE 0x00020000
#define XTL_DSSCAPS_LOCDEFER 0x00040000
#define XTL_DSSCAPS_NOMERGE 0x20000000
#define XTL_DSSCAPS_ACCURATENOTIFY 0x40000000
typedef VOID(CALLBACK *LPFNXMOCALLBACK)(LPVOID pStreamContext, LPVOID pPacketContext, DWORD dwStatus);
// ******************************************************************
// * X_DSSTREAMDESC
// ******************************************************************
struct X_DSSTREAMDESC
{
DWORD dwFlags;
DWORD dwMaxAttachedPackets;
LPWAVEFORMATEX lpwfxFormat;
LPFNXMOCALLBACK lpfnCallback;
LPVOID lpvContext;
X_LPDSMIXBINS lpMixBinsOutput;
};
// ******************************************************************
// * REFERENCE_TIME
// ******************************************************************
typedef LONGLONG REFERENCE_TIME, *PREFERENCE_TIME, *LPREFERENCE_TIME;
// ******************************************************************
// * XMEDIAPACKET
// ******************************************************************
typedef struct _XMEDIAPACKET
{
LPVOID pvBuffer;
DWORD dwMaxSize;
PDWORD pdwCompletedSize;
PDWORD pdwStatus;
union {
HANDLE hCompletionEvent;
PVOID pContext;
};
PREFERENCE_TIME prtTimestamp; // Not supported in xbox
}
XMEDIAPACKET, *PXMEDIAPACKET, *LPXMEDIAPACKET;
#define XMP_STATUS_SUCCESS S_OK
#define XMP_STATUS_PENDING E_PENDING
#define XMP_STATUS_FLUSHED E_ABORT
#define XMP_STATUS_FAILURE E_FAIL
#define XMP_STATUS_RELEASE_CXBXR 0xFFFFFFFF
// ******************************************************************
// * XMEDIAINFO
// ******************************************************************
typedef struct _XMEDIAINFO
{
DWORD dwFlags;
DWORD dwInputSize;
DWORD dwOutputSize;
DWORD dwMaxLookahead;
}
XMEDIAINFO, *PXEIDIAINFO, *LPXMEDIAINFO;
// XMEDIAINFO Flags
#define XMO_STREAMF_FIXED_SAMPLE_SIZE 0x00000001 // The object supports only a fixed sample size
#define XMO_STREAMF_FIXED_PACKET_ALIGNMENT 0x00000002 // The object supports only a fixed packet alignment
#define XMO_STREAMF_INPUT_ASYNC 0x00000004 // The object supports receiving input data asynchronously
#define XMO_STREAMF_OUTPUT_ASYNC 0x00000008 // The object supports providing output data asynchronously
#define XMO_STREAMF_IN_PLACE 0x00000010 // The object supports in-place modification of data
#define XMO_STREAMF_MASK 0x0000001F
// ******************************************************************
// * X_DSFILTERDESC
// ******************************************************************
struct X_DSFILTERDESC
{
DWORD dwMode;
DWORD dwQCoefficient;
DWORD adwCoefficients[4];
};
// X_DSFILTERDESC modes
#define DSFILTER_MODE_BYPASS 0x00000000 // The filter is bypassed
#define DSFILTER_MODE_DLS2 0x00000001 // DLS2 mode
#define DSFILTER_MODE_PARAMEQ 0x00000002 // Parametric equalizer mode
#define DSFILTER_MODE_MULTI 0x00000003 // Multifunction mode
// ******************************************************************
// * DSLFODESC
// ******************************************************************
typedef struct _DSLFODESC
{
DWORD dwLFO;
DWORD dwDelay;
DWORD dwDelta;
LONG lPitchModulation;
LONG lFilterCutOffRange;
LONG lAmplitudeModulation;
}
DSLFODESC, *LPCDSLFODESC;
// ******************************************************************
// * XBOXADPCMWAVEFORMAT
// ******************************************************************
typedef struct xbox_adpcmwaveformat_tag
{
WAVEFORMATEX wfx; // WAVEFORMATEX data
WORD wSamplesPerBlock; // Number of samples per encoded block. It must be 64.
}
XBOXADPCMWAVEFORMAT, *PXBOXADPCMWAVEFORMAT, *LPXBOXADPCMWAVEFORMAT;
typedef const XBOXADPCMWAVEFORMAT *LPCXBOXADPCMWAVEFORMAT;
// ******************************************************************
// * X_DSOUTPUTLEVELS
// ******************************************************************
struct X_DSOUTPUTLEVELS
{
DWORD dwAnalogLeftTotalPeak; // analog peak
DWORD dwAnalogRightTotalPeak;
DWORD dwAnalogLeftTotalRMS; // analog RMS
DWORD dwAnalogRightTotalRMS;
DWORD dwDigitalFrontLeftPeak; // digital peak levels
DWORD dwDigitalFrontCenterPeak;
DWORD dwDigitalFrontRightPeak;
DWORD dwDigitalBackLeftPeak;
DWORD dwDigitalBackRightPeak;
DWORD dwDigitalLowFrequencyPeak;
DWORD dwDigitalFrontLeftRMS; // digital RMS levels
DWORD dwDigitalFrontCenterRMS;
DWORD dwDigitalFrontRightRMS;
DWORD dwDigitalBackLeftRMS;
DWORD dwDigitalBackRightRMS;
DWORD dwDigitalLowFrequencyRMS;
};
// ******************************************************************
// * X_DSCAPS
// ******************************************************************
struct X_DSCAPS
{
DWORD dwFree2DBuffers;
DWORD dwFree3DBuffers;
DWORD dwFreeBufferSGEs;
DWORD dwMemoryAllocated;
};
#define X_DSSPEAKER_STEREO 0x00000000
#define X_DSSPEAKER_MONO 0x00000001
#define X_DSSPEAKER_SURROUND 0x00000002
#define X_DSSPEAKER_ENABLE_AC3 0x00010000
#define X_DSSPEAKER_ENABLE_DTS 0x00020000
struct X_DS3DBUFFER {
DWORD dwSize;
D3DVECTOR vPosition;
D3DVECTOR vVelocity;
DWORD dwInsideConeAngle;
DWORD dwOutsideConeAngle;
D3DVECTOR vConeOrientation;
LONG lConeOutsideVolume;
FLOAT flMinDistance;
FLOAT flMaxDistance;
DWORD dwMode;
FLOAT flDistanceFactor;
FLOAT flRolloffFactor;
FLOAT flDopplerFactor;
};
struct X_DSI3DL2LISTENER {
LONG lRoom;
LONG lRoomHF;
FLOAT flRoomRolloffFactor;
FLOAT flDecayTime;
FLOAT flDecayHFRatio;
LONG lReflections;
FLOAT flReflectionsDelay;
LONG lReverb;
FLOAT flReverbDelay;
FLOAT flDiffusion;
FLOAT flDensity;
FLOAT flHFReference;
};
struct X_DSI3DL2OBSTRUCTION {
LONG lHFLevel;
FLOAT flLFRatio;
};
struct X_DSI3DL2OCCLUSION {
LONG lHFLevel;
FLOAT flLFRatio;
};
struct X_DSI3DL2BUFFER {
LONG lDirect;
LONG lDirectHF;
LONG lRoom;
LONG lRoomHF;
FLOAT flRoomRolloffFactor;
X_DSI3DL2OBSTRUCTION Obstruction;
X_DSI3DL2OCCLUSION Occlusion;
};
typedef struct IDirectSoundStream IDirectSoundStream;
typedef IDirectSoundStream *LPDIRECTSOUNDSTREAM;
struct X_DSVOICEPROPS {
DWORD dwMixBinCount;
X_DSMIXBINVOLUMEPAIR MixBinVolumePairs[8];
LONG lPitch;
LONG l3DDistanceVolume;
LONG l3DConeVolume;
LONG l3DDopplerPitch;
LONG lI3DL2DirectVolume;
LONG lI3DL2RoomVolume;
};
} // end of namespace XTL
#endif
#define XTL_DS_SGE_SIZE_MAX (XTL_DS_SGE_COUNT_MAX * XTL_DS_SGE_PAGE_MAX)
// XDSMIXBIN Flags
#define XDSMIXBIN_FRONT_LEFT 0
#define XDSMIXBIN_FRONT_RIGHT 1
#define XDSMIXBIN_FRONT_CENTER 2
#define XDSMIXBIN_LOW_FREQUENCY 3
#define XDSMIXBIN_BACK_LEFT 4
#define XDSMIXBIN_BACK_RIGHT 5
#define XDSMIXBIN_SPEAKERS_MAX 6 // Max count for speakers
// Other flags are used
// ******************************************************************
// * X_DSMIXBINVOLUMEPAIR
// ******************************************************************
typedef struct _XDSMIXBINVOLUMEPAIR {
DWORD dwMixBin;
LONG lVolume;
} X_DSMIXBINVOLUMEPAIR, *X_LPDSMIXBINVOLUMEPAIR;
// ******************************************************************
// * X_DSMIXBINS
// ******************************************************************
// Revision 2 (4039+)
typedef struct _XDSMIXBINS {
DWORD dwCount;
X_LPDSMIXBINVOLUMEPAIR lpMixBinVolumePairs;
} X_DSMIXBINS, *X_LPDSMIXBINS;
// EmuIDirectSoundBuffer_Play flags
#define X_DSBPLAY_LOOPING 0x00000001
#define X_DSBPLAY_FROMSTART 0x00000002
#define X_DSBPLAY_SYNCHPLAYBACK 0x00000004
// EmuIDirectSoundBuffer_Pause flags
#define X_DSBPAUSE_RESUME 0x00000000
#define X_DSBPAUSE_PAUSE 0x00000001
#define X_DSBPAUSE_SYNCHPLAYBACK 0x00000002
// EmuIDirectSoundStream_Pause flags
#define X_DSSPAUSE_RESUME 0x00000000
#define X_DSSPAUSE_PAUSE 0x00000001
#define X_DSSPAUSE_SYNCHPLAYBACK 0x00000002
#define X_DSSPAUSE_PAUSENOACTIVATE 0x00000003
// EmuIDirectSoundStream_FlushEx flags
#define X_DSSFLUSHEX_IMMEDIATE 0x00000000
#define X_DSSFLUSHEX_ASYNC 0x00000001
#define X_DSSFLUSHEX_ENVELOPE 0x00000002
#define X_DSSFLUSHEX_ENVELOPE2 0x00000004
// EmuIDirectSoundStream_GetStatus flags
#define X_DSSSTATUS_READY 0x00000001
#define X_DSSSTATUS_PLAYING 0x00010000
#define X_DSSSTATUS_PAUSED 0x00020000
#define X_DSSSTATUS_STARVED 0x00040000
#define X_DSSSTATUS_ENVELOPECOMPLETE 0x00080000
// EmuIDirectSoundBuffer_GetStatus flags
#define X_DSBSTATUS_PLAYING 0x00000001
#define X_DSBSTATUS_PAUSED 0x00000002
#define X_DSBSTATUS_LOOPING 0x00000004
// EmuIDirectSoundBuffer_StopEx flags
#define X_DSBSTOPEX_IMMEDIATE 0x00000000
#define X_DSBSTOPEX_ENVELOPE 0x00000001
#define X_DSBSTOPEX_RELEASEWAVEFORM 0x00000002
#define X_DSBSTOPEX_ALL (X_DSBSTOPEX_ENVELOPE | X_DSBSTOPEX_RELEASEWAVEFORM)
// Generic frequency range
#define XTL_DSXFREQUENCY_ORIGINAL 0x00000000
//#define XTL_DSGFREQUENCY_MIN 0x00000???
//#define XTL_DSGFREQUENCY_MAX 0x000?????
#define XTL_DSBCAPS_CTRL3D 0x00000010
#define XTL_DSBCAPS_CTRLFREQUENCY 0x00000020
#define XTL_DSBCAPS_CTRLVOLUME 0x00000080
#define XTL_DSBCAPS_CTRLPOSITIONNOTIFY 0x00000100
#define XTL_DSBCAPS_MIXIN 0x00002000
#define XTL_DSBCAPS_MUTE3DATMAXDISTANCE 0x00020000
#define XTL_DSBCAPS_LOCDEFER 0x00040000
#define XTL_DSBCAPS_FXIN 0x00080000
#define XTL_DSBCAPS_FXIN2 0x00100000
// ******************************************************************
// * X_DSBUFFERDESC
// ******************************************************************
struct X_DSBUFFERDESC
{
DWORD dwSize;
DWORD dwFlags;
DWORD dwBufferBytes;
LPWAVEFORMATEX lpwfxFormat;
X_LPDSMIXBINS lpMixBinsOutput;
DWORD dwInputMixBin;
};
// ******************************************************************
// * X_DSENVELOPEDESC
// ******************************************************************
struct X_DSENVOLOPEDESC
{
DWORD dwEnvelopGenerator;
DWORD dwMode;
DWORD dwDelay;
DWORD dwAttack;
DWORD dwHold;
DWORD dwDecay;
DWORD dwRelease;
DWORD dwSustain;
LONG lPitchScale;
LONG lFilterCutOff;
};
#define XTL_DSSCAPS_CTRL3D 0x00000010
#define XTL_DSSCAPS_CTRLFREQUENCY 0x00000020
#define XTL_DSSCAPS_CTRLVOLUME 0x00000080
#define XTL_DSSCAPS_MUTE3DATMAXDISTANCE 0x00020000
#define XTL_DSSCAPS_LOCDEFER 0x00040000
#define XTL_DSSCAPS_NOMERGE 0x20000000
#define XTL_DSSCAPS_ACCURATENOTIFY 0x40000000
typedef VOID(CALLBACK *LPFNXMOCALLBACK)(LPVOID pStreamContext, LPVOID pPacketContext, DWORD dwStatus);
// ******************************************************************
// * X_DSSTREAMDESC
// ******************************************************************
struct X_DSSTREAMDESC
{
DWORD dwFlags;
DWORD dwMaxAttachedPackets;
LPWAVEFORMATEX lpwfxFormat;
LPFNXMOCALLBACK lpfnCallback;
LPVOID lpvContext;
X_LPDSMIXBINS lpMixBinsOutput;
};
// ******************************************************************
// * REFERENCE_TIME
// ******************************************************************
typedef LONGLONG REFERENCE_TIME, *PREFERENCE_TIME, *LPREFERENCE_TIME;
// ******************************************************************
// * XMEDIAPACKET
// ******************************************************************
typedef struct _XMEDIAPACKET
{
LPVOID pvBuffer;
DWORD dwMaxSize;
PDWORD pdwCompletedSize;
PDWORD pdwStatus;
union {
HANDLE hCompletionEvent;
PVOID pContext;
};
PREFERENCE_TIME prtTimestamp; // Not supported in xbox
}
XMEDIAPACKET, *PXMEDIAPACKET, *LPXMEDIAPACKET;
#define XMP_STATUS_SUCCESS S_OK
#define XMP_STATUS_PENDING E_PENDING
#define XMP_STATUS_FLUSHED E_ABORT
#define XMP_STATUS_FAILURE E_FAIL
#define XMP_STATUS_RELEASE_CXBXR 0xFFFFFFFF
// ******************************************************************
// * XMEDIAINFO
// ******************************************************************
typedef struct _XMEDIAINFO
{
DWORD dwFlags;
DWORD dwInputSize;
DWORD dwOutputSize;
DWORD dwMaxLookahead;
}
XMEDIAINFO, *PXEIDIAINFO, *LPXMEDIAINFO;
// XMEDIAINFO Flags
#define XMO_STREAMF_FIXED_SAMPLE_SIZE 0x00000001 // The object supports only a fixed sample size
#define XMO_STREAMF_FIXED_PACKET_ALIGNMENT 0x00000002 // The object supports only a fixed packet alignment
#define XMO_STREAMF_INPUT_ASYNC 0x00000004 // The object supports receiving input data asynchronously
#define XMO_STREAMF_OUTPUT_ASYNC 0x00000008 // The object supports providing output data asynchronously
#define XMO_STREAMF_IN_PLACE 0x00000010 // The object supports in-place modification of data
#define XMO_STREAMF_MASK 0x0000001F
// ******************************************************************
// * X_DSFILTERDESC
// ******************************************************************
struct X_DSFILTERDESC
{
DWORD dwMode;
DWORD dwQCoefficient;
DWORD adwCoefficients[4];
};
// X_DSFILTERDESC modes
#define DSFILTER_MODE_BYPASS 0x00000000 // The filter is bypassed
#define DSFILTER_MODE_DLS2 0x00000001 // DLS2 mode
#define DSFILTER_MODE_PARAMEQ 0x00000002 // Parametric equalizer mode
#define DSFILTER_MODE_MULTI 0x00000003 // Multifunction mode
// ******************************************************************
// * DSLFODESC
// ******************************************************************
typedef struct _DSLFODESC
{
DWORD dwLFO;
DWORD dwDelay;
DWORD dwDelta;
LONG lPitchModulation;
LONG lFilterCutOffRange;
LONG lAmplitudeModulation;
}
DSLFODESC, *LPCDSLFODESC;
// ******************************************************************
// * XBOXADPCMWAVEFORMAT
// ******************************************************************
typedef struct xbox_adpcmwaveformat_tag
{
WAVEFORMATEX wfx; // WAVEFORMATEX data
WORD wSamplesPerBlock; // Number of samples per encoded block. It must be 64.
}
XBOXADPCMWAVEFORMAT, *PXBOXADPCMWAVEFORMAT, *LPXBOXADPCMWAVEFORMAT;
typedef const XBOXADPCMWAVEFORMAT *LPCXBOXADPCMWAVEFORMAT;
// ******************************************************************
// * X_DSOUTPUTLEVELS
// ******************************************************************
struct X_DSOUTPUTLEVELS
{
DWORD dwAnalogLeftTotalPeak; // analog peak
DWORD dwAnalogRightTotalPeak;
DWORD dwAnalogLeftTotalRMS; // analog RMS
DWORD dwAnalogRightTotalRMS;
DWORD dwDigitalFrontLeftPeak; // digital peak levels
DWORD dwDigitalFrontCenterPeak;
DWORD dwDigitalFrontRightPeak;
DWORD dwDigitalBackLeftPeak;
DWORD dwDigitalBackRightPeak;
DWORD dwDigitalLowFrequencyPeak;
DWORD dwDigitalFrontLeftRMS; // digital RMS levels
DWORD dwDigitalFrontCenterRMS;
DWORD dwDigitalFrontRightRMS;
DWORD dwDigitalBackLeftRMS;
DWORD dwDigitalBackRightRMS;
DWORD dwDigitalLowFrequencyRMS;
};
// ******************************************************************
// * X_DSCAPS
// ******************************************************************
struct X_DSCAPS
{
DWORD dwFree2DBuffers;
DWORD dwFree3DBuffers;
DWORD dwFreeBufferSGEs;
DWORD dwMemoryAllocated;
};
#define X_DSSPEAKER_STEREO 0x00000000
#define X_DSSPEAKER_MONO 0x00000001
#define X_DSSPEAKER_SURROUND 0x00000002
#define X_DSSPEAKER_ENABLE_AC3 0x00010000
#define X_DSSPEAKER_ENABLE_DTS 0x00020000
struct X_DS3DBUFFER {
DWORD dwSize;
D3DVECTOR vPosition;
D3DVECTOR vVelocity;
DWORD dwInsideConeAngle;
DWORD dwOutsideConeAngle;
D3DVECTOR vConeOrientation;
LONG lConeOutsideVolume;
FLOAT flMinDistance;
FLOAT flMaxDistance;
DWORD dwMode;
FLOAT flDistanceFactor;
FLOAT flRolloffFactor;
FLOAT flDopplerFactor;
};
struct X_DSI3DL2LISTENER {
LONG lRoom;
LONG lRoomHF;
FLOAT flRoomRolloffFactor;
FLOAT flDecayTime;
FLOAT flDecayHFRatio;
LONG lReflections;
FLOAT flReflectionsDelay;
LONG lReverb;
FLOAT flReverbDelay;
FLOAT flDiffusion;
FLOAT flDensity;
FLOAT flHFReference;
};
struct X_DSI3DL2OBSTRUCTION {
LONG lHFLevel;
FLOAT flLFRatio;
};
struct X_DSI3DL2OCCLUSION {
LONG lHFLevel;
FLOAT flLFRatio;
};
struct X_DSI3DL2BUFFER {
LONG lDirect;
LONG lDirectHF;
LONG lRoom;
LONG lRoomHF;
FLOAT flRoomRolloffFactor;
X_DSI3DL2OBSTRUCTION Obstruction;
X_DSI3DL2OCCLUSION Occlusion;
};
typedef struct IDirectSoundStream IDirectSoundStream;
typedef IDirectSoundStream *LPDIRECTSOUNDSTREAM;
struct X_DSVOICEPROPS {
DWORD dwMixBinCount;
X_DSMIXBINVOLUMEPAIR MixBinVolumePairs[8];
LONG lPitch;
LONG l3DDistanceVolume;
LONG l3DConeVolume;
LONG l3DDopplerPitch;
LONG lI3DL2DirectVolume;
LONG lI3DL2RoomVolume;
};
} // end of namespace XTL
#endif

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@
#define EMUXACTENG_H
#include "common\xbe\Xbe.h"
#include "core\hle\XAPI\Xapi.h" // For EMUPATCH
#include "core\hle\XAPI\Xapi.h" // For EMUPATCH
#undef FIELD_OFFSET // prevent macro redefinition warnings
#include <windows.h>

View File

@ -27,11 +27,11 @@
#define LOG_PREFIX CXBXR_MODULE::XAPI
#undef FIELD_OFFSET // prevent macro redefinition warnings
#undef FIELD_OFFSET // prevent macro redefinition warnings
#include <xboxkrnl\xboxkrnl.h>
#include "common\input\SdlJoystick.h"
#include <xboxkrnl\xboxkrnl.h>
#include "common\input\SdlJoystick.h"
#include "common\input\InputManager.h"
#include <Shlwapi.h>
#include "core\kernel\init\CxbxKrnl.h"
@ -43,7 +43,7 @@
#include "core\hle\Intercept.hpp"
#include "vsbc\CxbxVSBC.h"
#include "Windef.h"
#include <vector>
#include <vector>
#include "core\hle\XAPI\Xapi.h"
#include "core\hle\XAPI\XapiCxbxr.h"
@ -61,128 +61,128 @@ PFARPROC1 fnCxbxVSBCOpen;
//typedef DWORD(*fnCxbxVSBCOpen)(HWND);
//typedef DWORD(*fnCxbxVSBCSetState)(UCHAR *);
//typedef DWORD(*fnCxbxVSBCGetState)(UCHAR *);
XTL::PXPP_DEVICE_TYPE g_DeviceType_Gamepad = nullptr;
// Flag is unset after initialize devices is done by simulate LLE USB thread.
XTL::PXPP_DEVICE_TYPE g_DeviceType_Gamepad = nullptr;
// Flag is unset after initialize devices is done by simulate LLE USB thread.
std::atomic<bool> g_bIsDevicesInitializing = true;
std::atomic<bool> g_bIsDevicesEmulating = false;
//global bridge for xbox controller to host, 4 elements for 4 ports.
CXBX_CONTROLLER_HOST_BRIDGE g_XboxControllerHostBridge[4] = {
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, nullptr, false, false, false, { 0, 0, 0, 0, 0 } },
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, nullptr, false, false, false, { 0, 0, 0, 0, 0 } },
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, nullptr, false, false, false, { 0, 0, 0, 0, 0 } },
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, nullptr, false, false, false, { 0, 0, 0, 0, 0 } },
CXBX_CONTROLLER_HOST_BRIDGE g_XboxControllerHostBridge[4] = {
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, nullptr, false, false, false, { 0, 0, 0, 0, 0 } },
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, nullptr, false, false, false, { 0, 0, 0, 0, 0 } },
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, nullptr, false, false, false, { 0, 0, 0, 0, 0 } },
{ NULL, PORT_INVALID, XBOX_INPUT_DEVICE::DEVICE_INVALID, nullptr, false, false, false, { 0, 0, 0, 0, 0 } },
};
bool operator==(XTL::PXPP_DEVICE_TYPE XppType, XBOX_INPUT_DEVICE XidType)
{
switch (XidType)
{
case XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE:
case XBOX_INPUT_DEVICE::MS_CONTROLLER_S: {
if (XppType == g_DeviceType_Gamepad) {
return true;
}
}
break;
case XBOX_INPUT_DEVICE::LIGHT_GUN:
case XBOX_INPUT_DEVICE::STEERING_WHEEL:
case XBOX_INPUT_DEVICE::MEMORY_UNIT:
case XBOX_INPUT_DEVICE::IR_DONGLE:
case XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER:
default:
break;
}
return false;
}
bool operator!=(XTL::PXPP_DEVICE_TYPE XppType, XBOX_INPUT_DEVICE XidType)
{
return !(XppType == XidType);
}
bool ConstructHleInputDevice(int Type, int Port)
{
g_bIsDevicesEmulating = true;
bool ret = true;
switch (Type)
{
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE): {
g_XboxControllerHostBridge[Port].XboxPort = Port;
g_XboxControllerHostBridge[Port].XboxType = XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE;
g_XboxControllerHostBridge[Port].InState = new XpadInput();
g_XboxControllerHostBridge[Port].bPendingRemoval = false;
g_XboxControllerHostBridge[Port].bSignaled = false;
g_XboxControllerHostBridge[Port].bIoInProgress = false;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucType = XINPUT_DEVTYPE_GAMEPAD;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucSubType = XINPUT_DEVSUBTYPE_GC_GAMEPAD;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucInputStateSize = sizeof(XpadInput);
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucFeedbackSize = sizeof(XpadOutput);
g_XboxControllerHostBridge[Port].XboxDeviceInfo.dwPacketNumber = 0;
}
break;
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
g_XboxControllerHostBridge[Port].XboxPort = Port;
g_XboxControllerHostBridge[Port].XboxType = XBOX_INPUT_DEVICE::MS_CONTROLLER_S;
g_XboxControllerHostBridge[Port].InState = new XpadInput();
g_XboxControllerHostBridge[Port].bPendingRemoval = false;
g_XboxControllerHostBridge[Port].bSignaled = false;
g_XboxControllerHostBridge[Port].bIoInProgress = false;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucType = XINPUT_DEVTYPE_GAMEPAD;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucSubType = XINPUT_DEVSUBTYPE_GC_GAMEPAD_ALT;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucInputStateSize = sizeof(XpadInput);
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucFeedbackSize = sizeof(XpadOutput);
g_XboxControllerHostBridge[Port].XboxDeviceInfo.dwPacketNumber = 0;
}
break;
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER): {
// TODO
}
break;
case to_underlying(XBOX_INPUT_DEVICE::LIGHT_GUN):
case to_underlying(XBOX_INPUT_DEVICE::STEERING_WHEEL):
case to_underlying(XBOX_INPUT_DEVICE::MEMORY_UNIT):
case to_underlying(XBOX_INPUT_DEVICE::IR_DONGLE): {
EmuLog(LOG_LEVEL::INFO, "%s: device %s is not yet supported", __func__, GetInputDeviceName(Type).c_str());
ret = false;
}
break;
default:
EmuLog(LOG_LEVEL::WARNING, "Attempted to attach an unknown device type (type was %d)", Type);
ret = false;
break;
}
g_bIsDevicesEmulating = false;
return ret;
}
void DestructHleInputDevice(int Port)
{
g_bIsDevicesEmulating = true;
g_XboxControllerHostBridge[Port].XboxType = XBOX_INPUT_DEVICE::DEVICE_INVALID;
g_XboxControllerHostBridge[Port].XboxPort = PORT_INVALID;
while (g_XboxControllerHostBridge[Port].bIoInProgress) {}
delete g_XboxControllerHostBridge[Port].InState;
g_XboxControllerHostBridge[Port].bPendingRemoval = false;
g_XboxControllerHostBridge[Port].bSignaled = false;
g_XboxControllerHostBridge[Port].bIoInProgress = false;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucType = 0;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucSubType = 0;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucInputStateSize = 0;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucFeedbackSize = 0;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.dwPacketNumber = 0;
g_bIsDevicesEmulating = false;
}
bool operator==(XTL::PXPP_DEVICE_TYPE XppType, XBOX_INPUT_DEVICE XidType)
{
switch (XidType)
{
case XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE:
case XBOX_INPUT_DEVICE::MS_CONTROLLER_S: {
if (XppType == g_DeviceType_Gamepad) {
return true;
}
}
break;
case XBOX_INPUT_DEVICE::LIGHT_GUN:
case XBOX_INPUT_DEVICE::STEERING_WHEEL:
case XBOX_INPUT_DEVICE::MEMORY_UNIT:
case XBOX_INPUT_DEVICE::IR_DONGLE:
case XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER:
default:
break;
}
return false;
}
bool operator!=(XTL::PXPP_DEVICE_TYPE XppType, XBOX_INPUT_DEVICE XidType)
{
return !(XppType == XidType);
}
bool ConstructHleInputDevice(int Type, int Port)
{
g_bIsDevicesEmulating = true;
bool ret = true;
switch (Type)
{
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE): {
g_XboxControllerHostBridge[Port].XboxPort = Port;
g_XboxControllerHostBridge[Port].XboxType = XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE;
g_XboxControllerHostBridge[Port].InState = new XpadInput();
g_XboxControllerHostBridge[Port].bPendingRemoval = false;
g_XboxControllerHostBridge[Port].bSignaled = false;
g_XboxControllerHostBridge[Port].bIoInProgress = false;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucType = XINPUT_DEVTYPE_GAMEPAD;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucSubType = XINPUT_DEVSUBTYPE_GC_GAMEPAD;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucInputStateSize = sizeof(XpadInput);
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucFeedbackSize = sizeof(XpadOutput);
g_XboxControllerHostBridge[Port].XboxDeviceInfo.dwPacketNumber = 0;
}
break;
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
g_XboxControllerHostBridge[Port].XboxPort = Port;
g_XboxControllerHostBridge[Port].XboxType = XBOX_INPUT_DEVICE::MS_CONTROLLER_S;
g_XboxControllerHostBridge[Port].InState = new XpadInput();
g_XboxControllerHostBridge[Port].bPendingRemoval = false;
g_XboxControllerHostBridge[Port].bSignaled = false;
g_XboxControllerHostBridge[Port].bIoInProgress = false;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucType = XINPUT_DEVTYPE_GAMEPAD;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucSubType = XINPUT_DEVSUBTYPE_GC_GAMEPAD_ALT;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucInputStateSize = sizeof(XpadInput);
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucFeedbackSize = sizeof(XpadOutput);
g_XboxControllerHostBridge[Port].XboxDeviceInfo.dwPacketNumber = 0;
}
break;
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER): {
// TODO
}
break;
case to_underlying(XBOX_INPUT_DEVICE::LIGHT_GUN):
case to_underlying(XBOX_INPUT_DEVICE::STEERING_WHEEL):
case to_underlying(XBOX_INPUT_DEVICE::MEMORY_UNIT):
case to_underlying(XBOX_INPUT_DEVICE::IR_DONGLE): {
EmuLog(LOG_LEVEL::INFO, "%s: device %s is not yet supported", __func__, GetInputDeviceName(Type).c_str());
ret = false;
}
break;
default:
EmuLog(LOG_LEVEL::WARNING, "Attempted to attach an unknown device type (type was %d)", Type);
ret = false;
break;
}
g_bIsDevicesEmulating = false;
return ret;
}
void DestructHleInputDevice(int Port)
{
g_bIsDevicesEmulating = true;
g_XboxControllerHostBridge[Port].XboxType = XBOX_INPUT_DEVICE::DEVICE_INVALID;
g_XboxControllerHostBridge[Port].XboxPort = PORT_INVALID;
while (g_XboxControllerHostBridge[Port].bIoInProgress) {}
delete g_XboxControllerHostBridge[Port].InState;
g_XboxControllerHostBridge[Port].bPendingRemoval = false;
g_XboxControllerHostBridge[Port].bSignaled = false;
g_XboxControllerHostBridge[Port].bIoInProgress = false;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucType = 0;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucSubType = 0;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucInputStateSize = 0;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucFeedbackSize = 0;
g_XboxControllerHostBridge[Port].XboxDeviceInfo.dwPacketNumber = 0;
g_bIsDevicesEmulating = false;
}
void SetupXboxDeviceTypes()
{
@ -281,36 +281,36 @@ VOID WINAPI XTL::EMUPATCH(XInitDevices)
}).detach();
}
// This is called to emulate async for both XGetDevices and XGetDeviceChanges
void UpdateConnectedDeviceState(XTL::PXPP_DEVICE_TYPE DeviceType) {
// Do not process the queries until initialize delay and device emulating are complete.
if (g_bIsDevicesInitializing || g_bIsDevicesEmulating){
return;
}
// This is called to emulate async for both XGetDevices and XGetDeviceChanges
void UpdateConnectedDeviceState(XTL::PXPP_DEVICE_TYPE DeviceType) {
// Do not process the queries until initialize delay and device emulating are complete.
if (g_bIsDevicesInitializing || g_bIsDevicesEmulating){
return;
}
int Port, PortMask;
for (Port = PORT_1, PortMask = 1; Port <= PORT_4; Port++, PortMask <<= 1) {
if (DeviceType == g_XboxControllerHostBridge[Port].XboxType) {
if (DeviceType == g_XboxControllerHostBridge[Port].XboxType) {
if (!g_XboxControllerHostBridge[Port].bPendingRemoval) {
DeviceType->CurrentConnected |= PortMask;
}
else {
if (!g_XboxControllerHostBridge[Port].bSignaled) {
g_XboxControllerHostBridge[Port].bSignaled = true;
SDL_Event DeviceRemoveEvent;
SDL_memset(&DeviceRemoveEvent, 0, sizeof(SDL_Event));
DeviceRemoveEvent.type = Sdl::DeviceRemoveAck_t;
DeviceRemoveEvent.user.data1 = new int(Port);
SDL_PushEvent(&DeviceRemoveEvent);
}
DeviceType->CurrentConnected &= ~PortMask;
}
}
else {
if (!g_XboxControllerHostBridge[Port].bSignaled) {
g_XboxControllerHostBridge[Port].bSignaled = true;
SDL_Event DeviceRemoveEvent;
SDL_memset(&DeviceRemoveEvent, 0, sizeof(SDL_Event));
DeviceRemoveEvent.type = Sdl::DeviceRemoveAck_t;
DeviceRemoveEvent.user.data1 = new int(Port);
SDL_PushEvent(&DeviceRemoveEvent);
}
DeviceType->CurrentConnected &= ~PortMask;
}
}
else {
DeviceType->CurrentConnected &= ~PortMask;
}
}
}
DeviceType->ChangeConnected = DeviceType->PreviousConnected ^ DeviceType->CurrentConnected;
}
@ -326,14 +326,14 @@ DWORD WINAPI XTL::EMUPATCH(XGetDevices)
PXPP_DEVICE_TYPE DeviceType
)
{
LOG_FUNC_ONE_ARG(DeviceType);
LOG_FUNC_ONE_ARG(DeviceType);
UpdateConnectedDeviceState(DeviceType);
UCHAR oldIrql = xboxkrnl::KeRaiseIrqlToDpcLevel();
DWORD ret = DeviceType->CurrentConnected;
DWORD ret = DeviceType->CurrentConnected;
DeviceType->ChangeConnected = 0;
DeviceType->PreviousConnected = DeviceType->CurrentConnected;
@ -362,8 +362,8 @@ BOOL WINAPI XTL::EMUPATCH(XGetDeviceChanges)
LOG_FUNC_ARG(pdwRemovals)
LOG_FUNC_END;
UpdateConnectedDeviceState(DeviceType);
UpdateConnectedDeviceState(DeviceType);
BOOL ret = FALSE;
@ -375,17 +375,17 @@ BOOL WINAPI XTL::EMUPATCH(XGetDeviceChanges)
else
{
UCHAR oldIrql = xboxkrnl::KeRaiseIrqlToDpcLevel();
// Insertions and removals
*pdwInsertions = (DeviceType->CurrentConnected & ~DeviceType->PreviousConnected);
*pdwRemovals = (DeviceType->PreviousConnected & ~DeviceType->CurrentConnected);
*pdwRemovals = (DeviceType->PreviousConnected & ~DeviceType->CurrentConnected);
// Detect devices that were removed and then immediately inserted again
ULONG RemoveInsert = DeviceType->ChangeConnected &
DeviceType->CurrentConnected &
DeviceType->PreviousConnected;
*pdwRemovals |= RemoveInsert;
*pdwInsertions |= RemoveInsert;
*pdwInsertions |= RemoveInsert;
DeviceType->ChangeConnected = 0;
DeviceType->PreviousConnected = DeviceType->CurrentConnected;
@ -416,7 +416,7 @@ HANDLE WINAPI XTL::EMUPATCH(XInputOpen)
LOG_FUNC_END;
if (dwPort >= PORT_1 && dwPort <= PORT_4) {
if (DeviceType == g_XboxControllerHostBridge[dwPort].XboxType) {
if (DeviceType == g_XboxControllerHostBridge[dwPort].XboxType) {
#if 0 // TODO
if(g_XboxControllerHostBridge[dwPort].dwHostType==X_XONTROLLER_HOST_BRIDGE_HOSTTYPE_VIRTUAL_SBC){
//if DLL not loaded yet, load it.
@ -441,8 +441,8 @@ HANDLE WINAPI XTL::EMUPATCH(XInputOpen)
}
//DWORD dwVXBCOpenResult = CxbxVSBC::MyCxbxVSBC::VSBCOpen(X_XONTROLLER_HOST_BRIDGE_HOSTTYPE_VIRTUAL_SBC);
}
#endif
}
#endif
g_XboxControllerHostBridge[dwPort].hXboxDevice = &g_XboxControllerHostBridge[dwPort];
RETURN(g_XboxControllerHostBridge[dwPort].hXboxDevice);
}
@ -462,10 +462,10 @@ VOID WINAPI XTL::EMUPATCH(XInputClose)
{
LOG_FUNC_ONE_ARG(hDevice);
PCXBX_CONTROLLER_HOST_BRIDGE Device = (PCXBX_CONTROLLER_HOST_BRIDGE)hDevice;
int Port = Device->XboxPort;
PCXBX_CONTROLLER_HOST_BRIDGE Device = (PCXBX_CONTROLLER_HOST_BRIDGE)hDevice;
int Port = Device->XboxPort;
if (g_XboxControllerHostBridge[Port].hXboxDevice == hDevice) {
Device->hXboxDevice = NULL;
Device->hXboxDevice = NULL;
}
}
@ -477,9 +477,9 @@ DWORD WINAPI XTL::EMUPATCH(XInputPoll)
IN HANDLE hDevice
)
{
LOG_FUNC_ONE_ARG(hDevice);
// Nothing to do
LOG_FUNC_ONE_ARG(hDevice);
// Nothing to do
RETURN(ERROR_SUCCESS);
}
@ -498,8 +498,8 @@ DWORD WINAPI XTL::EMUPATCH(XInputGetCapabilities)
LOG_FUNC_ARG_OUT(pCapabilities)
LOG_FUNC_END;
DWORD ret = ERROR_DEVICE_NOT_CONNECTED;
PCXBX_CONTROLLER_HOST_BRIDGE Device = (PCXBX_CONTROLLER_HOST_BRIDGE)hDevice;
DWORD ret = ERROR_DEVICE_NOT_CONNECTED;
PCXBX_CONTROLLER_HOST_BRIDGE Device = (PCXBX_CONTROLLER_HOST_BRIDGE)hDevice;
int Port = Device->XboxPort;
if (g_XboxControllerHostBridge[Port].hXboxDevice == hDevice && !g_XboxControllerHostBridge[Port].bPendingRemoval) {
pCapabilities->SubType = g_XboxControllerHostBridge[Port].XboxDeviceInfo.ucSubType;
@ -752,18 +752,18 @@ DWORD WINAPI XTL::EMUPATCH(XInputGetState)
LOG_FUNC_ARG_OUT(pState)
LOG_FUNC_END;
DWORD ret = ERROR_DEVICE_NOT_CONNECTED;
PCXBX_CONTROLLER_HOST_BRIDGE Device = (PCXBX_CONTROLLER_HOST_BRIDGE)hDevice;
DWORD ret = ERROR_DEVICE_NOT_CONNECTED;
PCXBX_CONTROLLER_HOST_BRIDGE Device = (PCXBX_CONTROLLER_HOST_BRIDGE)hDevice;
int Port = Device->XboxPort;
if (g_XboxControllerHostBridge[Port].hXboxDevice == hDevice) {
if (!g_XboxControllerHostBridge[Port].bPendingRemoval) {
g_XboxControllerHostBridge[Port].bIoInProgress = true;
if (g_InputDeviceManager.UpdateXboxPortInput(Port, g_XboxControllerHostBridge[Port].InState, DIRECTION_IN, to_underlying(g_XboxControllerHostBridge[Port].XboxType))) {
pState->dwPacketNumber = g_XboxControllerHostBridge[Port].XboxDeviceInfo.dwPacketNumber++;
}
memcpy((void*)&pState->Gamepad, g_XboxControllerHostBridge[Port].InState, sizeof(pState->Gamepad));
g_XboxControllerHostBridge[Port].bIoInProgress = false;
ret = ERROR_SUCCESS;
if (g_XboxControllerHostBridge[Port].hXboxDevice == hDevice) {
if (!g_XboxControllerHostBridge[Port].bPendingRemoval) {
g_XboxControllerHostBridge[Port].bIoInProgress = true;
if (g_InputDeviceManager.UpdateXboxPortInput(Port, g_XboxControllerHostBridge[Port].InState, DIRECTION_IN, to_underlying(g_XboxControllerHostBridge[Port].XboxType))) {
pState->dwPacketNumber = g_XboxControllerHostBridge[Port].XboxDeviceInfo.dwPacketNumber++;
}
memcpy((void*)&pState->Gamepad, g_XboxControllerHostBridge[Port].InState, sizeof(pState->Gamepad));
g_XboxControllerHostBridge[Port].bIoInProgress = false;
ret = ERROR_SUCCESS;
}
}
@ -785,18 +785,18 @@ DWORD WINAPI XTL::EMUPATCH(XInputSetState)
LOG_FUNC_ARG(hDevice)
LOG_FUNC_ARG(pFeedback)
LOG_FUNC_END;
PCXBX_CONTROLLER_HOST_BRIDGE Device = (PCXBX_CONTROLLER_HOST_BRIDGE)hDevice;
PCXBX_CONTROLLER_HOST_BRIDGE Device = (PCXBX_CONTROLLER_HOST_BRIDGE)hDevice;
int Port = Device->XboxPort;
if (g_XboxControllerHostBridge[Port].hXboxDevice == hDevice && !g_XboxControllerHostBridge[Port].bPendingRemoval) {
pFeedback->Header.dwStatus = ERROR_IO_PENDING;
g_InputDeviceManager.UpdateXboxPortInput(Port, (void*)&pFeedback->Rumble, DIRECTION_OUT, to_underlying(g_XboxControllerHostBridge[Port].XboxType));
pFeedback->Header.dwStatus = ERROR_SUCCESS;
if (pFeedback->Header.hEvent != NULL &&
ObReferenceObjectByHandle(pFeedback->Header.hEvent, &xboxkrnl::ExEventObjectType, (PVOID*)&pFeedback->Header.IoCompletedEvent) == ERROR_SUCCESS) {
KeSetEvent((xboxkrnl::PKEVENT)pFeedback->Header.IoCompletedEvent, NULL, FALSE);
g_InputDeviceManager.UpdateXboxPortInput(Port, (void*)&pFeedback->Rumble, DIRECTION_OUT, to_underlying(g_XboxControllerHostBridge[Port].XboxType));
pFeedback->Header.dwStatus = ERROR_SUCCESS;
if (pFeedback->Header.hEvent != NULL &&
ObReferenceObjectByHandle(pFeedback->Header.hEvent, &xboxkrnl::ExEventObjectType, (PVOID*)&pFeedback->Header.IoCompletedEvent) == ERROR_SUCCESS) {
KeSetEvent((xboxkrnl::PKEVENT)pFeedback->Header.IoCompletedEvent, NULL, FALSE);
}
}
}
else {
pFeedback->Header.dwStatus = ERROR_DEVICE_NOT_CONNECTED;
}

View File

@ -24,8 +24,8 @@
// ******************************************************************
#ifndef XAPI_H
#define XAPI_H
namespace XTL {
namespace XTL {
// ******************************************************************
// * calling conventions
@ -842,7 +842,7 @@ DWORD WINAPI EMUPATCH(XCalculateSignatureEnd)
);
//*/
// +s
} // end of namespace XTL
} // end of namespace XTL
#endif

View File

@ -33,7 +33,7 @@
#include "core\kernel\support\Emu.h"
#include "common\Logging.h"
#include "core\kernel\init\CxbxKrnl.h" // For CxbxKrnlCleanup()
#include "core\hle\XAPI\Xapi.h" // For EMUPATCH
#include "core\hle\XAPI\Xapi.h" // For EMUPATCH
#include "core\hle\D3D8\XbD3D8Logging.h" // for log rendering of X_D3DFORMAT, etc.
#include "core\hle\XGRAPHIC\XGraphic.h"

View File

@ -24,9 +24,9 @@
// ******************************************************************
#ifndef XGRAPHIC_H
#define XGRAPHIC_H
#include "core\hle\D3D8\XbD3D8Types.h"
namespace XTL {
typedef struct _XGPOINT3D
@ -114,7 +114,7 @@ HRESULT WINAPI EMUPATCH(XFONT_OpenBitmapFontFromMemory)
unsigned uFontDataSize,
void **ppFont
);
} // end of namespace XTL
} // end of namespace XTL
#endif

View File

@ -23,9 +23,9 @@
// *
// ******************************************************************
#if 0 // XOnline.h isn't used, but below is still useful documentation.
#include "core\kernel\support\Emu.h"
#include "core\hle\XAPI\Xapi.h" // For EMUPATCH
#include "core\kernel\support\Emu.h"
#include "core\hle\XAPI\Xapi.h" // For EMUPATCH
namespace XTL {

View File

@ -26,7 +26,7 @@
// ******************************************************************
#define LOG_PREFIX CXBXR_MODULE::KRNL
#include <xboxkrnl/xboxkrnl.h>
#include <cstdio>
@ -173,8 +173,8 @@ void CallSoftwareInterrupt(const xboxkrnl::KIRQL SoftwareIrql)
HalSystemInterrupts[SoftwareIrql - 4].Trigger(EmuInterruptList[SoftwareIrql - 4]);
}
break;
}
}
HalInterruptRequestRegister ^= (1 << SoftwareIrql);
}

View File

@ -1,416 +1,416 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// * (c) 2016 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
#define LOG_PREFIX CXBXR_MODULE::AV
#include <xboxkrnl/xboxkrnl.h> // For AvGetSavedDataAddress, etc.
#include "Logging.h" // For LOG_FUNC()
#include "EmuKrnlLogging.h"
// prevent name collisions
namespace NtDll
{
#include "core\kernel\support\EmuNtDll.h"
};
#include "core\kernel\support\Emu.h" // For EmuLog(LOG_LEVEL::WARNING, )
#include "core\hle\D3D8\Direct3D9\Direct3D9.h"
#include "devices\x86\EmuX86.h"
#include "EmuKrnlAvModes.h"
#include "devices\Xbox.h" // For g_NV2A
#include "devices\video\nv2a_int.h"
#include "devices\video\nv2a.h" // For NV2ABlockInfo, EmuNV2A_Block()
#ifndef VOID
#define VOID void
#endif
// HW Register helper functions
xboxkrnl::UCHAR REG_RD08(VOID* Ptr, xboxkrnl::ULONG Addr)
{
return EmuX86_Read((xbaddr)Ptr + Addr, sizeof(uint8_t));
}
VOID REG_WR08(VOID* Ptr, xboxkrnl::ULONG Addr, xboxkrnl::UCHAR Val)
{
EmuX86_Write((xbaddr)Ptr + Addr, Val, sizeof(uint8_t));
}
xboxkrnl::ULONG REG_RD32(VOID* Ptr, xboxkrnl::ULONG Addr)
{
return EmuX86_Read((xbaddr)Ptr + Addr, sizeof(uint32_t));
}
VOID REG_WR32(VOID* Ptr, xboxkrnl::ULONG Addr, xboxkrnl::ULONG Val)
{
EmuX86_Write((xbaddr)Ptr + Addr, Val, sizeof(uint32_t));
}
VOID CRTC_WR(VOID* Ptr, xboxkrnl::UCHAR i, xboxkrnl::UCHAR d)
{
static const NV2ABlockInfo* block = EmuNV2A_Block(NV_PRMCIO_CRX__COLOR);
g_NV2A->BlockWrite(block, NV_PRMCIO_CRX__COLOR, i, sizeof(uint8_t));
g_NV2A->BlockWrite(block, NV_PRMCIO_CR__COLOR, d, sizeof(uint8_t));
}
VOID SRX_WR(VOID *Ptr, xboxkrnl::UCHAR i, xboxkrnl::UCHAR d)
{
static const NV2ABlockInfo* block = EmuNV2A_Block(NV_PRMVIO_SRX);
g_NV2A->BlockWrite(block, NV_PRMVIO_SRX, i, sizeof(uint8_t));
g_NV2A->BlockWrite(block, NV_PRMVIO_SR, d, sizeof(uint8_t));
}
VOID GRX_WR(VOID *Ptr, xboxkrnl::UCHAR i, xboxkrnl::UCHAR d)
{
static const NV2ABlockInfo* block = EmuNV2A_Block(NV_PRMVIO_GRX);
g_NV2A->BlockWrite(block, NV_PRMVIO_GRX, i, sizeof(uint8_t));
g_NV2A->BlockWrite(block, NV_PRMVIO_GX, d, sizeof(uint8_t));
}
VOID ARX_WR(VOID *Ptr, xboxkrnl::UCHAR i, xboxkrnl::UCHAR d)
{
static const NV2ABlockInfo* block = EmuNV2A_Block(NV_PRMCIO_ARX);
g_NV2A->BlockWrite(block, NV_PRMCIO_ARX, i, sizeof(uint8_t));
g_NV2A->BlockWrite(block, NV_PRMCIO_ARX, d, sizeof(uint8_t));
}
// Global Variable(s)
PVOID g_pPersistedData = NULL;
ULONG AvpCurrentMode = 0;
ULONG AvSMCVideoModeToAVPack(ULONG VideoMode)
{
switch (VideoMode)
{
case 0x0: return AV_PACK_SCART;
case 0x1: return AV_PACK_HDTV;
case 0x2: return AV_PACK_VGA;
case 0x3: return AV_PACK_RFU;
case 0x4: return AV_PACK_SVIDEO;
case 0x6: return AV_PACK_STANDARD;
}
return AV_PACK_NONE;
}
ULONG AvQueryAvCapabilities()
{
ULONG avpack = AvSMCVideoModeToAVPack(xboxkrnl::HalBootSMCVideoMode);
ULONG type;
ULONG resultSize;
// First, read the factory AV settings
ULONG avRegion;
NTSTATUS result = xboxkrnl::ExQueryNonVolatileSetting(
xboxkrnl::XC_FACTORY_AV_REGION,
&type,
&avRegion,
sizeof(ULONG),
&resultSize);
// If this failed, default to AV_STANDARD_NTSC_M | AV_FLAGS_60Hz
if (result != STATUS_SUCCESS || resultSize != sizeof(ULONG)) {
avRegion = AV_STANDARD_NTSC_M | AV_FLAGS_60Hz;
}
// Read the user-configurable (via the dashboard) settings
ULONG userSettings;
result = xboxkrnl::ExQueryNonVolatileSetting(
xboxkrnl::XC_VIDEO,
&type,
&userSettings,
sizeof(ULONG),
&resultSize);
// If this failed, default to no user-options set
if (result != STATUS_SUCCESS || resultSize != sizeof(ULONG)) {
userSettings = 0;
}
return avpack | (avRegion & (AV_STANDARD_MASK | AV_REFRESH_MASK)) | (userSettings & ~(AV_STANDARD_MASK | AV_PACK_MASK));
}
xboxkrnl::PVOID xboxkrnl::AvSavedDataAddress = xbnullptr;
// ******************************************************************
// * 0x0001 - AvGetSavedDataAddress()
// ******************************************************************
XBSYSAPI EXPORTNUM(1) xboxkrnl::PVOID NTAPI xboxkrnl::AvGetSavedDataAddress(void)
{
LOG_FUNC();
RETURN(AvSavedDataAddress);
}
// ******************************************************************
// * 0x0002 - AvSendTVEncoderOption()
// ******************************************************************
XBSYSAPI EXPORTNUM(2) VOID NTAPI xboxkrnl::AvSendTVEncoderOption
(
IN PVOID RegisterBase,
IN ULONG Option,
IN ULONG Param,
OUT ULONG *Result
)
{
LOG_FUNC_BEGIN;
LOG_FUNC_ARG(RegisterBase)
LOG_FUNC_ARG(Option)
LOG_FUNC_ARG(Param)
LOG_FUNC_ARG_OUT(Result)
LOG_FUNC_END;
//if (RegisterBase == NULL)
// RegisterBase = (void *)NV20_REG_BASE_KERNEL;
switch (Option) {
case AV_OPTION_MACROVISION_MODE:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_ENABLE_CC:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_DISABLE_CC:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_SEND_CC_DATA:
LOG_UNIMPLEMENTED();
break;
case AV_QUERY_CC_STATUS:
LOG_UNIMPLEMENTED();
break;
case AV_QUERY_AV_CAPABILITIES:
*Result = AvQueryAvCapabilities();
break;
case AV_OPTION_BLANK_SCREEN:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_MACROVISION_COMMIT:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_FLICKER_FILTER:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_ZERO_MODE:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_QUERY_MODE:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_ENABLE_LUMA_FILTER:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_GUESS_FIELD:
LOG_UNIMPLEMENTED();
break;
case AV_QUERY_ENCODER_TYPE:
LOG_UNIMPLEMENTED();
break;
case AV_QUERY_MODE_TABLE_VERSION:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_CGMS:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_WIDESCREEN:
LOG_UNIMPLEMENTED();
break;
default:
// do nothing
break;
}
}
// ******************************************************************
// * 0x0003 - AvSetDisplayMode()
// ******************************************************************
XBSYSAPI EXPORTNUM(3) xboxkrnl::ULONG NTAPI xboxkrnl::AvSetDisplayMode
(
IN PVOID RegisterBase,
IN ULONG Step,
IN ULONG Mode,
IN ULONG Format,
IN ULONG Pitch,
IN ULONG FrameBuffer
)
{
LOG_FUNC_BEGIN;
LOG_FUNC_ARG(RegisterBase)
LOG_FUNC_ARG(Step)
LOG_FUNC_ARG(Mode)
LOG_FUNC_ARG(Format)
LOG_FUNC_ARG(Pitch)
LOG_FUNC_ARG(FrameBuffer)
LOG_FUNC_END;
if (Mode == AV_MODE_OFF) {
Mode = AV_MODE_640x480_TO_NTSC_M_YC | AV_MODE_FLAGS_DACA_DISABLE | AV_MODE_FLAGS_DACB_DISABLE
| AV_MODE_FLAGS_DACC_DISABLE | AV_MODE_FLAGS_DACD_DISABLE;
}
ULONG OutputMode = Mode & AV_MODE_OUT_MASK;
ULONG iRegister = (Mode & 0x00FF0000) >> 16;
ULONG iCRTC = (Mode & 0x0000FF00) >> 8;
ULONG iTV = (Mode & 0x0000007F);
UCHAR DACs = (UCHAR)((Mode & 0x0F000000) >> 24);
ULONG GeneralControl = 0;
UCHAR CR28Depth = 0;
switch (Format)
{
case XTL::X_D3DFMT_LIN_A1R5G5B5:
case XTL::X_D3DFMT_LIN_X1R5G5B5:
GeneralControl = NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS | NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON; /*=0x00100030*/
CR28Depth = 2;
break;
case XTL::X_D3DFMT_LIN_R5G6B5:
GeneralControl = NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS | NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL | NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON; /*=0x00101030*/
CR28Depth = 2;
break;
case XTL::X_D3DFMT_LIN_A8R8G8B8:
case XTL::X_D3DFMT_LIN_X8R8G8B8:
GeneralControl = NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS | NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON; /*=0x00100030*/
CR28Depth = 3;
break;
}
Pitch /= 8;
if (AvpCurrentMode == Mode) {
REG_WR32(RegisterBase, NV_PRAMDAC_GENERAL_CONTROL, GeneralControl);
CRTC_WR(RegisterBase, NV_CIO_SR_LOCK_INDEX /*=0x1c*/, NV_CIO_SR_UNLOCK_RW_VALUE); /* crtc lock */
CRTC_WR(RegisterBase, NV_CIO_CR_OFFSET_INDEX /*=0x13*/, (UCHAR)(Pitch & 0xFF)); /* sets screen pitch */
CRTC_WR(RegisterBase, NV_CIO_CRE_RPC0_INDEX /*=0x19*/, (UCHAR)((Pitch & 0x700) >> 3)); /* repaint control 0 */
CRTC_WR(RegisterBase, NV_CIO_CRE_PIXEL_INDEX /*=0x28*/, 0x80 | CR28Depth);
REG_WR32(RegisterBase, NV_PCRTC_START, FrameBuffer);
AvSendTVEncoderOption(RegisterBase, AV_OPTION_FLICKER_FILTER, 5, NULL);
AvSendTVEncoderOption(RegisterBase, AV_OPTION_ENABLE_LUMA_FILTER, FALSE, NULL);
RETURN(STATUS_SUCCESS);
}
CRTC_WR(RegisterBase, NV_CIO_CRE_PIXEL_INDEX /*=0x28*/, 0x80 | CR28Depth);
// TODO: Lots of setup/TV encoder configuration
// Ignored for now since we don't emulate that stuff yet...
LOG_INCOMPLETE();
REG_WR32(RegisterBase, NV_PRAMDAC_GENERAL_CONTROL, GeneralControl);
const ULONG* pLong = AvpRegisters[iRegister];
const ULONG* pLongMax = pLong + sizeof(AvpRegisters[0]) / sizeof(ULONG);
for (long i = 0; pLong < pLongMax; pLong++, i++) {
REG_WR32(RegisterBase, AvpRegisters[0][i], *pLong);
}
if (Mode & AV_MODE_FLAGS_SCART) {
REG_WR32(RegisterBase, 0x00680630, 0); // NV_RAMDAC + 0x0630
REG_WR32(RegisterBase, 0x006808C4, 0); // NV_RAMDAC + 0x08C4
REG_WR32(RegisterBase, 0x0068084C, 0); // NV_RAMDAC + 0x084C
}
const UCHAR* pByte = AvpSRXRegisters;
const UCHAR* pByteMax = pByte + sizeof(AvpSRXRegisters);
for (long i = 0; pByte < pByteMax; pByte++, i++) {
SRX_WR(RegisterBase, (UCHAR)i, *pByte);
}
pByte = AvpGRXRegisters;
pByteMax = pByte + sizeof(AvpGRXRegisters);
for (long i = 0; pByte < pByteMax; pByte++, i++) {
GRX_WR(RegisterBase, (UCHAR)i, *pByte);
}
REG_RD08(RegisterBase, NV_PRMCIO_INP0__COLOR);
pByte = AvpARXRegisters;
pByteMax = pByte + sizeof(AvpARXRegisters);
for (long i = 0; pByte < pByteMax; pByte++, i++) {
ARX_WR(RegisterBase, (UCHAR)i, *pByte);
}
REG_WR08(RegisterBase, NV_PRMCIO_ARX, 0x20);
CRTC_WR(RegisterBase, NV_CIO_CR_VRE_INDEX /*=0x11*/, 0x00);
pByte = AvpCRTCRegisters[iCRTC];
pByteMax = pByte + sizeof(AvpCRTCRegisters[0]);
for (long i = 0; pByte < pByteMax; pByte++, i++) {
UCHAR Register = AvpCRTCRegisters[0][i];
UCHAR Data = *pByte;
switch (Register) {
case NV_CIO_CR_OFFSET_INDEX /*=0x13*/:
Data = (UCHAR)(Pitch & 0xFF);
break;
case NV_CIO_CRE_RPC0_INDEX /*=0x19*/:
Data |= (UCHAR)((Pitch & 0x700) >> 3);
break;
case NV_CIO_CRE_LSR_INDEX /*=0x25*/:
Data |= (UCHAR)((Pitch & 0x800) >> 6);
break;
}
CRTC_WR(RegisterBase, Register, Data);
}
// TODO: More TV Encoder stuff...
REG_WR32(RegisterBase, NV_PCRTC_START, FrameBuffer);
AvpCurrentMode = Mode;
RETURN(STATUS_SUCCESS);
}
// ******************************************************************
// * 0x0004 - AvSetSavedDataAddress()
// ******************************************************************
XBSYSAPI EXPORTNUM(4) VOID NTAPI xboxkrnl::AvSetSavedDataAddress
(
IN PVOID Address
)
{
LOG_FUNC_ONE_ARG(Address);
AvSavedDataAddress = Address;
}
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// * (c) 2016 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
#define LOG_PREFIX CXBXR_MODULE::AV
#include <xboxkrnl/xboxkrnl.h> // For AvGetSavedDataAddress, etc.
#include "Logging.h" // For LOG_FUNC()
#include "EmuKrnlLogging.h"
// prevent name collisions
namespace NtDll
{
#include "core\kernel\support\EmuNtDll.h"
};
#include "core\kernel\support\Emu.h" // For EmuLog(LOG_LEVEL::WARNING, )
#include "core\hle\D3D8\Direct3D9\Direct3D9.h"
#include "devices\x86\EmuX86.h"
#include "EmuKrnlAvModes.h"
#include "devices\Xbox.h" // For g_NV2A
#include "devices\video\nv2a_int.h"
#include "devices\video\nv2a.h" // For NV2ABlockInfo, EmuNV2A_Block()
#ifndef VOID
#define VOID void
#endif
// HW Register helper functions
xboxkrnl::UCHAR REG_RD08(VOID* Ptr, xboxkrnl::ULONG Addr)
{
return EmuX86_Read((xbaddr)Ptr + Addr, sizeof(uint8_t));
}
VOID REG_WR08(VOID* Ptr, xboxkrnl::ULONG Addr, xboxkrnl::UCHAR Val)
{
EmuX86_Write((xbaddr)Ptr + Addr, Val, sizeof(uint8_t));
}
xboxkrnl::ULONG REG_RD32(VOID* Ptr, xboxkrnl::ULONG Addr)
{
return EmuX86_Read((xbaddr)Ptr + Addr, sizeof(uint32_t));
}
VOID REG_WR32(VOID* Ptr, xboxkrnl::ULONG Addr, xboxkrnl::ULONG Val)
{
EmuX86_Write((xbaddr)Ptr + Addr, Val, sizeof(uint32_t));
}
VOID CRTC_WR(VOID* Ptr, xboxkrnl::UCHAR i, xboxkrnl::UCHAR d)
{
static const NV2ABlockInfo* block = EmuNV2A_Block(NV_PRMCIO_CRX__COLOR);
g_NV2A->BlockWrite(block, NV_PRMCIO_CRX__COLOR, i, sizeof(uint8_t));
g_NV2A->BlockWrite(block, NV_PRMCIO_CR__COLOR, d, sizeof(uint8_t));
}
VOID SRX_WR(VOID *Ptr, xboxkrnl::UCHAR i, xboxkrnl::UCHAR d)
{
static const NV2ABlockInfo* block = EmuNV2A_Block(NV_PRMVIO_SRX);
g_NV2A->BlockWrite(block, NV_PRMVIO_SRX, i, sizeof(uint8_t));
g_NV2A->BlockWrite(block, NV_PRMVIO_SR, d, sizeof(uint8_t));
}
VOID GRX_WR(VOID *Ptr, xboxkrnl::UCHAR i, xboxkrnl::UCHAR d)
{
static const NV2ABlockInfo* block = EmuNV2A_Block(NV_PRMVIO_GRX);
g_NV2A->BlockWrite(block, NV_PRMVIO_GRX, i, sizeof(uint8_t));
g_NV2A->BlockWrite(block, NV_PRMVIO_GX, d, sizeof(uint8_t));
}
VOID ARX_WR(VOID *Ptr, xboxkrnl::UCHAR i, xboxkrnl::UCHAR d)
{
static const NV2ABlockInfo* block = EmuNV2A_Block(NV_PRMCIO_ARX);
g_NV2A->BlockWrite(block, NV_PRMCIO_ARX, i, sizeof(uint8_t));
g_NV2A->BlockWrite(block, NV_PRMCIO_ARX, d, sizeof(uint8_t));
}
// Global Variable(s)
PVOID g_pPersistedData = NULL;
ULONG AvpCurrentMode = 0;
ULONG AvSMCVideoModeToAVPack(ULONG VideoMode)
{
switch (VideoMode)
{
case 0x0: return AV_PACK_SCART;
case 0x1: return AV_PACK_HDTV;
case 0x2: return AV_PACK_VGA;
case 0x3: return AV_PACK_RFU;
case 0x4: return AV_PACK_SVIDEO;
case 0x6: return AV_PACK_STANDARD;
}
return AV_PACK_NONE;
}
ULONG AvQueryAvCapabilities()
{
ULONG avpack = AvSMCVideoModeToAVPack(xboxkrnl::HalBootSMCVideoMode);
ULONG type;
ULONG resultSize;
// First, read the factory AV settings
ULONG avRegion;
NTSTATUS result = xboxkrnl::ExQueryNonVolatileSetting(
xboxkrnl::XC_FACTORY_AV_REGION,
&type,
&avRegion,
sizeof(ULONG),
&resultSize);
// If this failed, default to AV_STANDARD_NTSC_M | AV_FLAGS_60Hz
if (result != STATUS_SUCCESS || resultSize != sizeof(ULONG)) {
avRegion = AV_STANDARD_NTSC_M | AV_FLAGS_60Hz;
}
// Read the user-configurable (via the dashboard) settings
ULONG userSettings;
result = xboxkrnl::ExQueryNonVolatileSetting(
xboxkrnl::XC_VIDEO,
&type,
&userSettings,
sizeof(ULONG),
&resultSize);
// If this failed, default to no user-options set
if (result != STATUS_SUCCESS || resultSize != sizeof(ULONG)) {
userSettings = 0;
}
return avpack | (avRegion & (AV_STANDARD_MASK | AV_REFRESH_MASK)) | (userSettings & ~(AV_STANDARD_MASK | AV_PACK_MASK));
}
xboxkrnl::PVOID xboxkrnl::AvSavedDataAddress = xbnullptr;
// ******************************************************************
// * 0x0001 - AvGetSavedDataAddress()
// ******************************************************************
XBSYSAPI EXPORTNUM(1) xboxkrnl::PVOID NTAPI xboxkrnl::AvGetSavedDataAddress(void)
{
LOG_FUNC();
RETURN(AvSavedDataAddress);
}
// ******************************************************************
// * 0x0002 - AvSendTVEncoderOption()
// ******************************************************************
XBSYSAPI EXPORTNUM(2) VOID NTAPI xboxkrnl::AvSendTVEncoderOption
(
IN PVOID RegisterBase,
IN ULONG Option,
IN ULONG Param,
OUT ULONG *Result
)
{
LOG_FUNC_BEGIN;
LOG_FUNC_ARG(RegisterBase)
LOG_FUNC_ARG(Option)
LOG_FUNC_ARG(Param)
LOG_FUNC_ARG_OUT(Result)
LOG_FUNC_END;
//if (RegisterBase == NULL)
// RegisterBase = (void *)NV20_REG_BASE_KERNEL;
switch (Option) {
case AV_OPTION_MACROVISION_MODE:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_ENABLE_CC:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_DISABLE_CC:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_SEND_CC_DATA:
LOG_UNIMPLEMENTED();
break;
case AV_QUERY_CC_STATUS:
LOG_UNIMPLEMENTED();
break;
case AV_QUERY_AV_CAPABILITIES:
*Result = AvQueryAvCapabilities();
break;
case AV_OPTION_BLANK_SCREEN:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_MACROVISION_COMMIT:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_FLICKER_FILTER:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_ZERO_MODE:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_QUERY_MODE:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_ENABLE_LUMA_FILTER:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_GUESS_FIELD:
LOG_UNIMPLEMENTED();
break;
case AV_QUERY_ENCODER_TYPE:
LOG_UNIMPLEMENTED();
break;
case AV_QUERY_MODE_TABLE_VERSION:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_CGMS:
LOG_UNIMPLEMENTED();
break;
case AV_OPTION_WIDESCREEN:
LOG_UNIMPLEMENTED();
break;
default:
// do nothing
break;
}
}
// ******************************************************************
// * 0x0003 - AvSetDisplayMode()
// ******************************************************************
XBSYSAPI EXPORTNUM(3) xboxkrnl::ULONG NTAPI xboxkrnl::AvSetDisplayMode
(
IN PVOID RegisterBase,
IN ULONG Step,
IN ULONG Mode,
IN ULONG Format,
IN ULONG Pitch,
IN ULONG FrameBuffer
)
{
LOG_FUNC_BEGIN;
LOG_FUNC_ARG(RegisterBase)
LOG_FUNC_ARG(Step)
LOG_FUNC_ARG(Mode)
LOG_FUNC_ARG(Format)
LOG_FUNC_ARG(Pitch)
LOG_FUNC_ARG(FrameBuffer)
LOG_FUNC_END;
if (Mode == AV_MODE_OFF) {
Mode = AV_MODE_640x480_TO_NTSC_M_YC | AV_MODE_FLAGS_DACA_DISABLE | AV_MODE_FLAGS_DACB_DISABLE
| AV_MODE_FLAGS_DACC_DISABLE | AV_MODE_FLAGS_DACD_DISABLE;
}
ULONG OutputMode = Mode & AV_MODE_OUT_MASK;
ULONG iRegister = (Mode & 0x00FF0000) >> 16;
ULONG iCRTC = (Mode & 0x0000FF00) >> 8;
ULONG iTV = (Mode & 0x0000007F);
UCHAR DACs = (UCHAR)((Mode & 0x0F000000) >> 24);
ULONG GeneralControl = 0;
UCHAR CR28Depth = 0;
switch (Format)
{
case XTL::X_D3DFMT_LIN_A1R5G5B5:
case XTL::X_D3DFMT_LIN_X1R5G5B5:
GeneralControl = NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS | NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON; /*=0x00100030*/
CR28Depth = 2;
break;
case XTL::X_D3DFMT_LIN_R5G6B5:
GeneralControl = NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS | NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL | NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON; /*=0x00101030*/
CR28Depth = 2;
break;
case XTL::X_D3DFMT_LIN_A8R8G8B8:
case XTL::X_D3DFMT_LIN_X8R8G8B8:
GeneralControl = NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS | NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON; /*=0x00100030*/
CR28Depth = 3;
break;
}
Pitch /= 8;
if (AvpCurrentMode == Mode) {
REG_WR32(RegisterBase, NV_PRAMDAC_GENERAL_CONTROL, GeneralControl);
CRTC_WR(RegisterBase, NV_CIO_SR_LOCK_INDEX /*=0x1c*/, NV_CIO_SR_UNLOCK_RW_VALUE); /* crtc lock */
CRTC_WR(RegisterBase, NV_CIO_CR_OFFSET_INDEX /*=0x13*/, (UCHAR)(Pitch & 0xFF)); /* sets screen pitch */
CRTC_WR(RegisterBase, NV_CIO_CRE_RPC0_INDEX /*=0x19*/, (UCHAR)((Pitch & 0x700) >> 3)); /* repaint control 0 */
CRTC_WR(RegisterBase, NV_CIO_CRE_PIXEL_INDEX /*=0x28*/, 0x80 | CR28Depth);
REG_WR32(RegisterBase, NV_PCRTC_START, FrameBuffer);
AvSendTVEncoderOption(RegisterBase, AV_OPTION_FLICKER_FILTER, 5, NULL);
AvSendTVEncoderOption(RegisterBase, AV_OPTION_ENABLE_LUMA_FILTER, FALSE, NULL);
RETURN(STATUS_SUCCESS);
}
CRTC_WR(RegisterBase, NV_CIO_CRE_PIXEL_INDEX /*=0x28*/, 0x80 | CR28Depth);
// TODO: Lots of setup/TV encoder configuration
// Ignored for now since we don't emulate that stuff yet...
LOG_INCOMPLETE();
REG_WR32(RegisterBase, NV_PRAMDAC_GENERAL_CONTROL, GeneralControl);
const ULONG* pLong = AvpRegisters[iRegister];
const ULONG* pLongMax = pLong + sizeof(AvpRegisters[0]) / sizeof(ULONG);
for (long i = 0; pLong < pLongMax; pLong++, i++) {
REG_WR32(RegisterBase, AvpRegisters[0][i], *pLong);
}
if (Mode & AV_MODE_FLAGS_SCART) {
REG_WR32(RegisterBase, 0x00680630, 0); // NV_RAMDAC + 0x0630
REG_WR32(RegisterBase, 0x006808C4, 0); // NV_RAMDAC + 0x08C4
REG_WR32(RegisterBase, 0x0068084C, 0); // NV_RAMDAC + 0x084C
}
const UCHAR* pByte = AvpSRXRegisters;
const UCHAR* pByteMax = pByte + sizeof(AvpSRXRegisters);
for (long i = 0; pByte < pByteMax; pByte++, i++) {
SRX_WR(RegisterBase, (UCHAR)i, *pByte);
}
pByte = AvpGRXRegisters;
pByteMax = pByte + sizeof(AvpGRXRegisters);
for (long i = 0; pByte < pByteMax; pByte++, i++) {
GRX_WR(RegisterBase, (UCHAR)i, *pByte);
}
REG_RD08(RegisterBase, NV_PRMCIO_INP0__COLOR);
pByte = AvpARXRegisters;
pByteMax = pByte + sizeof(AvpARXRegisters);
for (long i = 0; pByte < pByteMax; pByte++, i++) {
ARX_WR(RegisterBase, (UCHAR)i, *pByte);
}
REG_WR08(RegisterBase, NV_PRMCIO_ARX, 0x20);
CRTC_WR(RegisterBase, NV_CIO_CR_VRE_INDEX /*=0x11*/, 0x00);
pByte = AvpCRTCRegisters[iCRTC];
pByteMax = pByte + sizeof(AvpCRTCRegisters[0]);
for (long i = 0; pByte < pByteMax; pByte++, i++) {
UCHAR Register = AvpCRTCRegisters[0][i];
UCHAR Data = *pByte;
switch (Register) {
case NV_CIO_CR_OFFSET_INDEX /*=0x13*/:
Data = (UCHAR)(Pitch & 0xFF);
break;
case NV_CIO_CRE_RPC0_INDEX /*=0x19*/:
Data |= (UCHAR)((Pitch & 0x700) >> 3);
break;
case NV_CIO_CRE_LSR_INDEX /*=0x25*/:
Data |= (UCHAR)((Pitch & 0x800) >> 6);
break;
}
CRTC_WR(RegisterBase, Register, Data);
}
// TODO: More TV Encoder stuff...
REG_WR32(RegisterBase, NV_PCRTC_START, FrameBuffer);
AvpCurrentMode = Mode;
RETURN(STATUS_SUCCESS);
}
// ******************************************************************
// * 0x0004 - AvSetSavedDataAddress()
// ******************************************************************
XBSYSAPI EXPORTNUM(4) VOID NTAPI xboxkrnl::AvSetSavedDataAddress
(
IN PVOID Address
)
{
LOG_FUNC_ONE_ARG(Address);
AvSavedDataAddress = Address;
}

View File

@ -1,420 +1,420 @@
#pragma once
// Mode enum values where:
//
// 0xC0000000 - output mode mask:
//
// 0x00000000 - 480 line SDTV
// 0x40000000 - 525 line SDTV
// 0x80000000 - HDTV
// 0xC0000000 - VGA
//
// 0x10000000 - enable WSS (_16x9)
// 0x20000000 - use SCART output (_RGB)
//
// 0x01000000 - disable DAC A
// 0x02000000 - disable DAC B
// 0x04000000 - disable DAC C
// 0x08000000 - disable DAC D
//
// 0x00FF0000 - register table index
// 0x0000FF00 - CRTC table index
// 0x000000FF - TV table index, based on output mode mask above
#define AV_MODE_TABLE_VERSION 0
#define AV_MODE_OFF 0x00000000
#define AV_MODE_640x480_TO_NTSC_M_YC 0x04010101
#define AV_MODE_640x480_TO_NTSC_M_YC_16x9 0x14010101
#define AV_MODE_720x480_TO_NTSC_M_YC 0x04020202
#define AV_MODE_720x480_TO_NTSC_M_YC_16x9 0x14020202
#define AV_MODE_640x480_TO_NTSC_M_RGB 0x20010101
#define AV_MODE_640x480_TO_NTSC_M_RGB_16x9 0x30010101
#define AV_MODE_720x480_TO_NTSC_M_RGB 0x20020202
#define AV_MODE_720x480_TO_NTSC_M_RGB_16x9 0x30020202
#define AV_MODE_640x480_TO_NTSC_J_YC 0x04010103
#define AV_MODE_640x480_TO_NTSC_J_YC_16x9 0x14010103
#define AV_MODE_720x480_TO_NTSC_J_YC 0x04020204
#define AV_MODE_720x480_TO_NTSC_J_YC_16x9 0x14020204
#define AV_MODE_640x480_TO_NTSC_J_RGB 0x20010103
#define AV_MODE_640x480_TO_NTSC_J_RGB_16x9 0x30010103
#define AV_MODE_720x480_TO_NTSC_J_RGB 0x20020204
#define AV_MODE_720x480_TO_NTSC_J_RGB_16x9 0x30020204
#define AV_MODE_640x480_TO_PAL_M_YC 0x04010105
#define AV_MODE_640x480_TO_PAL_M_YC_16x9 0x14010105
#define AV_MODE_720x480_TO_PAL_M_YC 0x04020206
#define AV_MODE_720x480_TO_PAL_M_YC_16x9 0x14020206
#define AV_MODE_640x480_TO_PAL_M_RGB 0x20010105
#define AV_MODE_640x480_TO_PAL_M_RGB_16x9 0x30010105
#define AV_MODE_720x480_TO_PAL_M_RGB 0x20020206
#define AV_MODE_720x480_TO_PAL_M_RGB_16x9 0x30020206
#define AV_MODE_640x480_TO_PAL_I_YC 0x44030307
#define AV_MODE_640x480_TO_PAL_I_YC_16x9 0x54030307
#define AV_MODE_720x480_TO_PAL_I_YC 0x44040408
#define AV_MODE_720x480_TO_PAL_I_YC_16x9 0x54040408
#define AV_MODE_640x576_TO_PAL_I_YC 0x44050509
#define AV_MODE_640x576_TO_PAL_I_YC_16x9 0x54050509
#define AV_MODE_720x576_TO_PAL_I_YC 0x4406060A
#define AV_MODE_720x576_TO_PAL_I_YC_16x9 0x5406060A
#define AV_MODE_640x480_TO_PAL_I_RGB 0x60030307
#define AV_MODE_640x480_TO_PAL_I_RGB_16x9 0x70030307
#define AV_MODE_720x480_TO_PAL_I_RGB 0x60040408
#define AV_MODE_720x480_TO_PAL_I_RGB_16x9 0x70040408
#define AV_MODE_640x576_TO_PAL_I_RGB 0x60050509
#define AV_MODE_640x576_TO_PAL_I_RGB_16x9 0x70050509
#define AV_MODE_720x576_TO_PAL_I_RGB 0x6006060A
#define AV_MODE_720x576_TO_PAL_I_RGB_16x9 0x7006060A
#define AV_MODE_640x480_TO_PAL_60_YC 0x0401010B
#define AV_MODE_640x480_TO_PAL_60_YC_16x9 0x1401010B
#define AV_MODE_720x480_TO_PAL_60_YC 0x0402020C
#define AV_MODE_720x480_TO_PAL_60_YC_16x9 0x1402020C
#define AV_MODE_640x480_TO_PAL_60_RGB 0x2001010B
#define AV_MODE_640x480_TO_PAL_60_RGB_16x9 0x3001010B
#define AV_MODE_720x480_TO_PAL_60_RGB 0x2002020C
#define AV_MODE_720x480_TO_PAL_60_RGB_16x9 0x3002020C
#define AV_MODE_640x480_TO_NTSC_YPrPb 0x0801010D
#define AV_MODE_640x480_TO_NTSC_YPrPb_16x9 0x1801010D
#define AV_MODE_720x480_TO_NTSC_YPrPb 0x0802020E
#define AV_MODE_720x480_TO_NTSC_YPrPb_16x9 0x1802020E
#define AV_MODE_640x480_FPAR_TO_NTSC_M_YC 0x040F0D0F
#define AV_MODE_640x480_FPAR_TO_NTSC_M_YC_16x9 0x140F0D0F
#define AV_MODE_640x480_FPAR_TO_NTSC_M_RGB 0x200F0D0F
#define AV_MODE_640x480_FPAR_TO_NTSC_M_RGB_16x9 0x300F0D0F
#define AV_MODE_640x480_FPAR_TO_NTSC_J_YC 0x040F0D10
#define AV_MODE_640x480_FPAR_TO_NTSC_J_YC_16x9 0x140F0D10
#define AV_MODE_640x480_FPAR_TO_NTSC_J_RGB 0x200F0D10
#define AV_MODE_640x480_FPAR_TO_NTSC_J_RGB_16x9 0x300F0D10
#define AV_MODE_640x480_FPAR_TO_PAL_60_YC 0x040F0D11
#define AV_MODE_640x480_FPAR_TO_PAL_60_YC_16x9 0x140F0D11
#define AV_MODE_640x480_FPAR_TO_PAL_60_RGB 0x200F0D11
#define AV_MODE_640x480_FPAR_TO_PAL_60_RGB_16x9 0x300F0D11
#define AV_MODE_640x480_FPAR_TO_NTSC_YPrPb 0x080F0D12
#define AV_MODE_640x480_FPAR_TO_NTSC_YPrPb_16x9 0x180F0D12
#define AV_MODE_640x480_FPAR_TO_PAL_I_YC 0x44100E13
#define AV_MODE_640x480_FPAR_TO_PAL_I_YC_16x9 0x54100E13
#define AV_MODE_640x480_FPAR_TO_PAL_I_RGB 0x60100E13
#define AV_MODE_640x480_FPAR_TO_PAL_I_RGB_16x9 0x70100E13
#define AV_MODE_640x480_TO_PAL_I_YPrPb 0x48030314
#define AV_MODE_640x480_TO_PAL_I_YPrPb_16x9 0x58030314
#define AV_MODE_720x480_TO_PAL_I_YPrPb 0x48040415
#define AV_MODE_720x480_TO_PAL_I_YPrPb_16x9 0x58040415
#define AV_MODE_640x576_TO_PAL_I_YPrPb 0x48050516
#define AV_MODE_640x576_TO_PAL_I_YPrPb_16x9 0x58050516
#define AV_MODE_720x576_TO_PAL_I_YPrPb 0x48060617
#define AV_MODE_720x576_TO_PAL_I_YPrPb_16x9 0x58060617
#define AV_MODE_640x480_FPAR_TO_PAL_I_YPrPb 0x48100E18
#define AV_MODE_640x480_FPAR_TO_PAL_I_YPrPb_16x9 0x58100E18
#define AV_MODE_640x480_TO_PAL_60_YPrPb 0x08010119
#define AV_MODE_640x480_TO_PAL_60_YPrPb_16x9 0x18010119
#define AV_MODE_720x480_TO_PAL_60_YPrPb 0x0802021A
#define AV_MODE_720x480_TO_PAL_60_YPrPb_16x9 0x1802021A
#define AV_MODE_640x480_FPAR_TO_PAL_60_YPrPb 0x080F0D1B
#define AV_MODE_640x480_FPAR_TO_PAL_60_YPrPb_16x9 0x180F0D1B
#define AV_MODE_640x576_FPAR_TO_PAL_I_YC 0x4412101C
#define AV_MODE_640x576_FPAR_TO_PAL_I_YC_16x9 0x5412101C
#define AV_MODE_640x576_FPAR_TO_PAL_I_RGB 0x6012101C
#define AV_MODE_640x576_FPAR_TO_PAL_I_RGB_16x9 0x7012101C
#define AV_MODE_640x576_FPAR_TO_PAL_I_YPrPb 0x4812101D
#define AV_MODE_640x576_FPAR_TO_PAL_I_YPrPb_16x9 0x5812101D
#define AV_MODE_640x480_TO_VGA 0x88070701
#define AV_MODE_720x480_TO_VGA 0x88080801
#define AV_MODE_1280x720_TO_VGA 0x880B0A02
#define AV_MODE_1920x1080_TO_VGA 0x880E0C03
#define AV_MODE_640x480_TO_480P 0x88070701
#define AV_MODE_720x480_TO_480P 0x88080801
#define AV_MODE_1280x720P_TO_720P 0x880B0A02
#define AV_MODE_1920x1080I_TO_1080I 0x880E0C03
#define AV_MODE_640x480_FPAR_TO_480P 0x88110F01
#define AV_MODE_FLAGS_DACA_DISABLE 0x01000000
#define AV_MODE_FLAGS_DACB_DISABLE 0x02000000
#define AV_MODE_FLAGS_DACC_DISABLE 0x04000000
#define AV_MODE_FLAGS_DACD_DISABLE 0x08000000
#define AV_MODE_FLAGS_WSS 0x10000000 // _16x9
#define AV_MODE_FLAGS_SCART 0x20000000 // _RGB
#define AV_MODE_FLAGS_NTSCJ 0x00000080
#define AV_MODE_OUT_MASK 0xC0000000
#define AV_MODE_OUT_480SDTV 0x00000000
#define AV_MODE_OUT_525SDTV 0x40000000
#define AV_MODE_OUT_HDTV 0x80000000
#define AV_MODE_OUT_VGA 0xC0000000
// Register Tables
const ULONG AvpRegisters[][26] =
{
{ /* offset */ 0x00680898, 0x0068089C, 0x006808C0, 0x006808C4, 0x0068084C, 0x00680630, 0x00680800, 0x00680804, 0x00680808, 0x0068080C, 0x00680810, 0x00680814, 0x00680818, 0x00680820, 0x00680824, 0x00680828, 0x0068082C, 0x00680830, 0x00680834, 0x00680838, 0x00680848, 0x00680680, 0x00680684, 0x00680688, 0x0068068C, 0x00680690 }, /* offset */
{ /* 1 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001F2, 0x000001F4, 0x00000000, 0x000001DF, 0x0000027F, 0x000003A7, 0x00000257, 0x000002F3, 0x00000333, 0x00000000, 0x0000027F, 0x10100111, 0x000C6ED0, 0x0000020D, 0x0000009B, 0x0000026C, 0x00000000 }, /* 1 */
{ /* 2 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001F2, 0x000001F4, 0x00000000, 0x000001DF, 0x000002CF, 0x000003A7, 0x000002A7, 0x0000031B, 0x0000035B, 0x00000000, 0x000002CF, 0x10100111, 0x000DF05C, 0x0000020D, 0x000000AE, 0x000002B8, 0x00000000 }, /* 2 */
{ /* 3 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001F4, 0x000001F6, 0x00000000, 0x000001DF, 0x0000027F, 0x0000035F, 0x00000257, 0x000002CF, 0x0000030F, 0x00000000, 0x0000027F, 0x10100111, 0x000F387C, 0x00000271, 0x000000BE, 0x000002F8, 0x00000000 }, /* 3 */
{ /* 4 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001F4, 0x000001F6, 0x00000000, 0x000001DF, 0x000002CF, 0x0000035F, 0x000002AF, 0x0000030B, 0x0000034B, 0x00000000, 0x000002CF, 0x10100111, 0x0010D2A4, 0x00000271, 0x000000D2, 0x00000348, 0x00000000 }, /* 4 */
{ /* 5 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x0000023F, 0x00000270, 0x0000023F, 0x00000256, 0x00000258, 0x00000000, 0x0000023F, 0x0000027F, 0x0000035F, 0x00000257, 0x000002CF, 0x0000030F, 0x00000000, 0x0000027F, 0x10100111, 0x000F07A8, 0x00000271, 0x0000009D, 0x00000276, 0x00000000 }, /* 5 */
{ /* 6 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x0000023F, 0x00000270, 0x0000023F, 0x00000256, 0x00000258, 0x00000000, 0x0000023F, 0x000002CF, 0x0000035F, 0x000002AF, 0x0000030B, 0x0000034B, 0x00000000, 0x000002CF, 0x10100111, 0x0010E62C, 0x00000271, 0x000000B1, 0x000002C4, 0x00000000 }, /* 6 */
{ /* 7 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001E8, 0x000001EE, 0x00000000, 0x000001DF, 0x000002CF, 0x00000359, 0x0000029F, 0x000002E1, 0x00000320, 0x00000000, 0x000002CF, 0x10100011, 0x0000035A, 0x00000001, 0x000000AB, 0x000002AE, 0x00000001 }, /* 7 */
{ /* 8 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001E8, 0x000001EE, 0x00000000, 0x000001DF, 0x000002CF, 0x00000359, 0x0000029F, 0x000002E1, 0x00000320, 0x00000000, 0x000002CF, 0x10100111, 0x0000035A, 0x00000001, 0x000000AB, 0x000002AE, 0x00000001 }, /* 8 */
{ /* 9 */ 0x0AA94000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000003, 0x000002CF, 0x000002ED, 0x000002CF, 0x000002D4, 0x000002D9, 0x00000000, 0x000002CF, 0x000004FF, 0x00000671, 0x000004FF, 0x00000545, 0x00000595, 0x000000A0, 0x0000045F, 0x10100011, 0x00000672, 0x00000001, 0x0000014A, 0x00000528, 0x00000001 }, /* 9 */
{ /* A */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000003, 0x000002CF, 0x000002ED, 0x000002CF, 0x000002D4, 0x000002D9, 0x00000000, 0x000002CF, 0x000004FF, 0x00000671, 0x000004CF, 0x00000545, 0x00000595, 0x00000000, 0x000004FF, 0x10100011, 0x00000672, 0x00000001, 0x0000014A, 0x00000528, 0x00000001 }, /* A */
{ /* B */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000003, 0x000002CF, 0x000002ED, 0x000002CF, 0x000002D4, 0x000002D9, 0x00000000, 0x000002CF, 0x000004FF, 0x00000671, 0x000004FF, 0x00000545, 0x00000595, 0x00000000, 0x000004FF, 0x10100111, 0x00000672, 0x00000001, 0x0000014A, 0x00000528, 0x00000001 }, /* B */
{ /* C */ 0x071AE000, 0x07183800, 0x00000000, 0x40801080, 0x00801080, 0x00000003, 0x00000437, 0x00000464, 0x0000043C, 0x0000043C, 0x00000446, 0x00000000, 0x00000437, 0x0000077F, 0x00000897, 0x000007AA, 0x000007AB, 0x00000803, 0x000000F0, 0x0000068F, 0x10133011, 0x00000898, 0x00000001, 0x000001B8, 0x000006E0, 0x00000001 }, /* C */
{ /* D */ 0x10000000, 0x07183800, 0x00000000, 0x40801080, 0x00801080, 0x00000003, 0x00000437, 0x00000464, 0x0000043C, 0x0000043C, 0x00000446, 0x00000000, 0x00000437, 0x0000077F, 0x00000897, 0x00000759, 0x000007AB, 0x00000803, 0x00000000, 0x0000077F, 0x10133011, 0x00000898, 0x00000001, 0x000001B8, 0x000006E0, 0x00000001 }, /* D */
{ /* E */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000003, 0x00000437, 0x00000464, 0x0000043B, 0x0000043B, 0x00000445, 0x00000000, 0x00000437, 0x0000077F, 0x00000897, 0x000007AB, 0x000007AC, 0x00000804, 0x00000000, 0x0000077F, 0x10133111, 0x00000898, 0x00000001, 0x000001B8, 0x000006E0, 0x00000001 }, /* E */
{ /* F */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001F2, 0x000001F4, 0x00000000, 0x000001DF, 0x0000027F, 0x000003A7, 0x000002A7, 0x000002F3, 0x00000333, 0x00000000, 0x0000027F, 0x10100111, 0x000DF05C, 0x0000020D, 0x000000AE, 0x000002B8, 0x00000000 }, /* F */
{ /* 10 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001F4, 0x000001F6, 0x00000000, 0x000001DF, 0x0000027F, 0x0000035F, 0x000002A7, 0x000002CF, 0x0000030F, 0x00000000, 0x0000027F, 0x10100111, 0x000DF05C, 0x0000020D, 0x000000AE, 0x000002B8, 0x00000000 }, /* 10 */
{ /* 11 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001E8, 0x000001EE, 0x00000000, 0x000001DF, 0x000002CF, 0x00000359, 0x000002CF, 0x000002DF, 0x0000031E, 0x00000020, 0x000002AD, 0x10100011, 0x0000035A, 0x00000001, 0x000000AB, 0x000002AE, 0x00000001 }, /* 11 */
{ /* 12 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x0000023F, 0x00000270, 0x0000023F, 0x00000256, 0x00000258, 0x00000000, 0x0000023F, 0x0000027F, 0x0000035F, 0x00000257, 0x000002CF, 0x0000030F, 0x00000000, 0x0000027F, 0x10100111, 0x000F07A8, 0x00000271, 0x0000009D, 0x00000276, 0x00000000 }, /* 12 */
};
const UCHAR AvpSRXRegisters[] =
{
0x03, 0x21, 0x0F, 0x00, 0x06,
};
const UCHAR AvpGRXRegisters[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF,
};
const UCHAR AvpARXRegisters[] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x01, 0x4A, 0x0F, 0x00, 0x00,
};
const UCHAR AvpCRTCRegisters[][34] =
{
{ /* offset */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x20, 0x25, 0x2D, 0x33, 0x39, 0x41 }, /* offset */
{ /* 1 */ 0x70, 0x4F, 0x4F, 0x94, 0x5D, 0xBF, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0x04, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 1 */
{ /* 2 */ 0x70, 0x59, 0x59, 0x94, 0x62, 0xA4, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0x04, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 2 */
{ /* 3 */ 0x67, 0x4F, 0x4F, 0x8B, 0x59, 0xBB, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x06, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 3 */
{ /* 4 */ 0x67, 0x59, 0x59, 0x8B, 0x5E, 0xBF, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x06, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 4 */
{ /* 5 */ 0x67, 0x4F, 0x4F, 0x8B, 0x59, 0xBB, 0x6F, 0xF0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x08, 0x3F, 0x00, 0x00, 0x3F, 0x70, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 5 */
{ /* 6 */ 0x67, 0x59, 0x59, 0x8B, 0x5E, 0xBF, 0x6F, 0xF0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x08, 0x3F, 0x00, 0x00, 0x3F, 0x70, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 6 */
{ /* 7 */ 0x59, 0x4F, 0x4F, 0x9D, 0x51, 0x39, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x0E, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 7 */
{ /* 8 */ 0x63, 0x59, 0x59, 0x87, 0x5B, 0xA3, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x0E, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 8 */
{ /* 9 */ 0x78, 0x4F, 0x4F, 0x9C, 0x57, 0xA1, 0xFC, 0x1F, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x09, 0xDF, 0x00, 0x00, 0xDF, 0xFD, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 9 */
{ /* A */ 0xC8, 0x9F, 0x9F, 0x8C, 0xA7, 0x31, 0xEC, 0xF0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x09, 0xCF, 0x00, 0x00, 0xCF, 0xED, 0xE3, 0xFF, 0x00, 0x38, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* A */
{ /* B */ 0x67, 0x4F, 0x4F, 0x8B, 0x54, 0xBF, 0x03, 0x11, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0x06, 0xEF, 0x00, 0x00, 0xEF, 0x04, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0x36, 0x00 }, /* B */
{ /* C */ 0x04, 0xEF, 0xEF, 0x88, 0xF4, 0x3F, 0x2F, 0xF0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x02, 0x1B, 0x00, 0x00, 0x1B, 0x30, 0xE3, 0xFF, 0x00, 0x38, 0x05, 0x80, 0x00, 0x01, 0x11, 0x10, 0x00 }, /* C */
{ /* D */ 0x70, 0x4F, 0x4F, 0x94, 0x5D, 0xBF, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0x04, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* D */
{ /* E */ 0x67, 0x4F, 0x4F, 0x8B, 0x59, 0xBF, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x06, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x00, 0x00, 0x11, 0xFF, 0x00 }, /* E */
{ /* F */ 0x61, 0x57, 0x57, 0x85, 0x59, 0xBF, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x0E, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* F */
{ /* 10 */ 0x67, 0x4F, 0x4F, 0x94, 0x59, 0xBF, 0x6F, 0xF0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x08, 0x3F, 0x00, 0x00, 0x3F, 0x70, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 10 */
};
typedef struct
{
ULONG AvInfo;
USHORT Width;
USHORT Height;
ULONG DisplayMode;
} XB_DisplayMode;
const XB_DisplayMode g_DisplayModes[] =
{
{ AV_PACK_VGA | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 1280, 720, AV_MODE_1280x720_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 1920, 1080, AV_MODE_1920x1080_TO_VGA },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | 0 | 0 | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | 0 | 0 | AV_FLAGS_HDTV_480p, 720, 480, AV_MODE_720x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480p, 720, 480, AV_MODE_720x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | 0 | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_FPAR_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_FPAR_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_720p, 1280, 720, AV_MODE_1280x720P_TO_720P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | AV_FLAGS_HDTV_480i, 720, 480, AV_MODE_720x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 720, 480, AV_MODE_720x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | AV_FLAGS_HDTV_480i, 720, 240, AV_MODE_720x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 720, 240, AV_MODE_720x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_1080i, 1920, 1080, AV_MODE_1920x1080I_TO_1080I },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_1080i, 1920, 540, AV_MODE_1920x1080I_TO_1080I },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_M_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_M_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_M_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_M_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_M_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_M_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_M_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_M_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_M_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_M_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_M_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_M_RGB_16x9 },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_M_YC },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_M_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_M_YC },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_M_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_M_YC },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_M_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_M_YC },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_M_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_M_YC },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_M_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_M_YC },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_M_YC_16x9 },
{ AV_PACK_VGA | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 1280, 720, AV_MODE_1280x720_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 1920, 1080, AV_MODE_1920x1080_TO_VGA },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | 0 | 0 | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | 0 | 0 | AV_FLAGS_HDTV_480p, 720, 480, AV_MODE_720x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480p, 720, 480, AV_MODE_720x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | 0 | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_FPAR_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_FPAR_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_720p, 1280, 720, AV_MODE_1280x720P_TO_720P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | AV_FLAGS_HDTV_480i, 720, 480, AV_MODE_720x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 720, 480, AV_MODE_720x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | AV_FLAGS_HDTV_480i, 720, 240, AV_MODE_720x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 720, 240, AV_MODE_720x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_1080i, 1920, 1080, AV_MODE_1920x1080I_TO_1080I },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_1080i, 1920, 540, AV_MODE_1920x1080I_TO_1080I },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_J_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_J_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_J_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_J_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_J_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_J_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_J_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_J_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_J_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_J_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_J_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_J_RGB_16x9 },
// All other AV packs are the same.
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_J_YC },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_J_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_J_YC },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_J_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_J_YC },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_J_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_J_YC },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_J_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_J_YC },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_J_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_J_YC },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_J_YC_16x9 },
{ AV_PACK_VGA | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 1280, 720, AV_MODE_1280x720_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 1920, 1080, AV_MODE_1920x1080_TO_VGA },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 576, AV_MODE_640x576_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 576, AV_MODE_640x576_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 576, AV_MODE_720x576_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 576, AV_MODE_720x576_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 288, AV_MODE_640x576_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 288, AV_MODE_640x576_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 288, AV_MODE_720x576_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 288, AV_MODE_720x576_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 576, AV_MODE_640x576_FPAR_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 576, AV_MODE_640x576_FPAR_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 288, AV_MODE_640x576_FPAR_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 288, AV_MODE_640x576_FPAR_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_60_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_60_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_60_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_60_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 240, AV_MODE_640x480_TO_PAL_60_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 240, AV_MODE_640x480_TO_PAL_60_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 240, AV_MODE_720x480_TO_PAL_60_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 240, AV_MODE_720x480_TO_PAL_60_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_60_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_60_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_PAL_60_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_PAL_60_YPrPb_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 576, AV_MODE_640x576_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 576, AV_MODE_640x576_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 576, AV_MODE_720x576_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 576, AV_MODE_720x576_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 288, AV_MODE_640x576_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 288, AV_MODE_640x576_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 288, AV_MODE_720x576_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 288, AV_MODE_720x576_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 576, AV_MODE_640x576_FPAR_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 576, AV_MODE_640x576_FPAR_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 288, AV_MODE_640x576_FPAR_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 288, AV_MODE_640x576_FPAR_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_60_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_60_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_60_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_60_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 240, AV_MODE_640x480_TO_PAL_60_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 240, AV_MODE_640x480_TO_PAL_60_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 240, AV_MODE_720x480_TO_PAL_60_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 240, AV_MODE_720x480_TO_PAL_60_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_60_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_60_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_PAL_60_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_PAL_60_RGB_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 576, AV_MODE_640x576_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 576, AV_MODE_640x576_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 576, AV_MODE_720x576_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 576, AV_MODE_720x576_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 288, AV_MODE_640x576_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 288, AV_MODE_640x576_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 288, AV_MODE_720x576_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 288, AV_MODE_720x576_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 576, AV_MODE_640x576_FPAR_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 576, AV_MODE_640x576_FPAR_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 288, AV_MODE_640x576_FPAR_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 288, AV_MODE_640x576_FPAR_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_60_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_60_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_60_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_60_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 240, AV_MODE_640x480_TO_PAL_60_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 240, AV_MODE_640x480_TO_PAL_60_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 240, AV_MODE_720x480_TO_PAL_60_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 240, AV_MODE_720x480_TO_PAL_60_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_60_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_60_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_PAL_60_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_PAL_60_YC_16x9 },
{ 0xFFFFFFFF, 0, 0, 0 },
};
#pragma once
// Mode enum values where:
//
// 0xC0000000 - output mode mask:
//
// 0x00000000 - 480 line SDTV
// 0x40000000 - 525 line SDTV
// 0x80000000 - HDTV
// 0xC0000000 - VGA
//
// 0x10000000 - enable WSS (_16x9)
// 0x20000000 - use SCART output (_RGB)
//
// 0x01000000 - disable DAC A
// 0x02000000 - disable DAC B
// 0x04000000 - disable DAC C
// 0x08000000 - disable DAC D
//
// 0x00FF0000 - register table index
// 0x0000FF00 - CRTC table index
// 0x000000FF - TV table index, based on output mode mask above
#define AV_MODE_TABLE_VERSION 0
#define AV_MODE_OFF 0x00000000
#define AV_MODE_640x480_TO_NTSC_M_YC 0x04010101
#define AV_MODE_640x480_TO_NTSC_M_YC_16x9 0x14010101
#define AV_MODE_720x480_TO_NTSC_M_YC 0x04020202
#define AV_MODE_720x480_TO_NTSC_M_YC_16x9 0x14020202
#define AV_MODE_640x480_TO_NTSC_M_RGB 0x20010101
#define AV_MODE_640x480_TO_NTSC_M_RGB_16x9 0x30010101
#define AV_MODE_720x480_TO_NTSC_M_RGB 0x20020202
#define AV_MODE_720x480_TO_NTSC_M_RGB_16x9 0x30020202
#define AV_MODE_640x480_TO_NTSC_J_YC 0x04010103
#define AV_MODE_640x480_TO_NTSC_J_YC_16x9 0x14010103
#define AV_MODE_720x480_TO_NTSC_J_YC 0x04020204
#define AV_MODE_720x480_TO_NTSC_J_YC_16x9 0x14020204
#define AV_MODE_640x480_TO_NTSC_J_RGB 0x20010103
#define AV_MODE_640x480_TO_NTSC_J_RGB_16x9 0x30010103
#define AV_MODE_720x480_TO_NTSC_J_RGB 0x20020204
#define AV_MODE_720x480_TO_NTSC_J_RGB_16x9 0x30020204
#define AV_MODE_640x480_TO_PAL_M_YC 0x04010105
#define AV_MODE_640x480_TO_PAL_M_YC_16x9 0x14010105
#define AV_MODE_720x480_TO_PAL_M_YC 0x04020206
#define AV_MODE_720x480_TO_PAL_M_YC_16x9 0x14020206
#define AV_MODE_640x480_TO_PAL_M_RGB 0x20010105
#define AV_MODE_640x480_TO_PAL_M_RGB_16x9 0x30010105
#define AV_MODE_720x480_TO_PAL_M_RGB 0x20020206
#define AV_MODE_720x480_TO_PAL_M_RGB_16x9 0x30020206
#define AV_MODE_640x480_TO_PAL_I_YC 0x44030307
#define AV_MODE_640x480_TO_PAL_I_YC_16x9 0x54030307
#define AV_MODE_720x480_TO_PAL_I_YC 0x44040408
#define AV_MODE_720x480_TO_PAL_I_YC_16x9 0x54040408
#define AV_MODE_640x576_TO_PAL_I_YC 0x44050509
#define AV_MODE_640x576_TO_PAL_I_YC_16x9 0x54050509
#define AV_MODE_720x576_TO_PAL_I_YC 0x4406060A
#define AV_MODE_720x576_TO_PAL_I_YC_16x9 0x5406060A
#define AV_MODE_640x480_TO_PAL_I_RGB 0x60030307
#define AV_MODE_640x480_TO_PAL_I_RGB_16x9 0x70030307
#define AV_MODE_720x480_TO_PAL_I_RGB 0x60040408
#define AV_MODE_720x480_TO_PAL_I_RGB_16x9 0x70040408
#define AV_MODE_640x576_TO_PAL_I_RGB 0x60050509
#define AV_MODE_640x576_TO_PAL_I_RGB_16x9 0x70050509
#define AV_MODE_720x576_TO_PAL_I_RGB 0x6006060A
#define AV_MODE_720x576_TO_PAL_I_RGB_16x9 0x7006060A
#define AV_MODE_640x480_TO_PAL_60_YC 0x0401010B
#define AV_MODE_640x480_TO_PAL_60_YC_16x9 0x1401010B
#define AV_MODE_720x480_TO_PAL_60_YC 0x0402020C
#define AV_MODE_720x480_TO_PAL_60_YC_16x9 0x1402020C
#define AV_MODE_640x480_TO_PAL_60_RGB 0x2001010B
#define AV_MODE_640x480_TO_PAL_60_RGB_16x9 0x3001010B
#define AV_MODE_720x480_TO_PAL_60_RGB 0x2002020C
#define AV_MODE_720x480_TO_PAL_60_RGB_16x9 0x3002020C
#define AV_MODE_640x480_TO_NTSC_YPrPb 0x0801010D
#define AV_MODE_640x480_TO_NTSC_YPrPb_16x9 0x1801010D
#define AV_MODE_720x480_TO_NTSC_YPrPb 0x0802020E
#define AV_MODE_720x480_TO_NTSC_YPrPb_16x9 0x1802020E
#define AV_MODE_640x480_FPAR_TO_NTSC_M_YC 0x040F0D0F
#define AV_MODE_640x480_FPAR_TO_NTSC_M_YC_16x9 0x140F0D0F
#define AV_MODE_640x480_FPAR_TO_NTSC_M_RGB 0x200F0D0F
#define AV_MODE_640x480_FPAR_TO_NTSC_M_RGB_16x9 0x300F0D0F
#define AV_MODE_640x480_FPAR_TO_NTSC_J_YC 0x040F0D10
#define AV_MODE_640x480_FPAR_TO_NTSC_J_YC_16x9 0x140F0D10
#define AV_MODE_640x480_FPAR_TO_NTSC_J_RGB 0x200F0D10
#define AV_MODE_640x480_FPAR_TO_NTSC_J_RGB_16x9 0x300F0D10
#define AV_MODE_640x480_FPAR_TO_PAL_60_YC 0x040F0D11
#define AV_MODE_640x480_FPAR_TO_PAL_60_YC_16x9 0x140F0D11
#define AV_MODE_640x480_FPAR_TO_PAL_60_RGB 0x200F0D11
#define AV_MODE_640x480_FPAR_TO_PAL_60_RGB_16x9 0x300F0D11
#define AV_MODE_640x480_FPAR_TO_NTSC_YPrPb 0x080F0D12
#define AV_MODE_640x480_FPAR_TO_NTSC_YPrPb_16x9 0x180F0D12
#define AV_MODE_640x480_FPAR_TO_PAL_I_YC 0x44100E13
#define AV_MODE_640x480_FPAR_TO_PAL_I_YC_16x9 0x54100E13
#define AV_MODE_640x480_FPAR_TO_PAL_I_RGB 0x60100E13
#define AV_MODE_640x480_FPAR_TO_PAL_I_RGB_16x9 0x70100E13
#define AV_MODE_640x480_TO_PAL_I_YPrPb 0x48030314
#define AV_MODE_640x480_TO_PAL_I_YPrPb_16x9 0x58030314
#define AV_MODE_720x480_TO_PAL_I_YPrPb 0x48040415
#define AV_MODE_720x480_TO_PAL_I_YPrPb_16x9 0x58040415
#define AV_MODE_640x576_TO_PAL_I_YPrPb 0x48050516
#define AV_MODE_640x576_TO_PAL_I_YPrPb_16x9 0x58050516
#define AV_MODE_720x576_TO_PAL_I_YPrPb 0x48060617
#define AV_MODE_720x576_TO_PAL_I_YPrPb_16x9 0x58060617
#define AV_MODE_640x480_FPAR_TO_PAL_I_YPrPb 0x48100E18
#define AV_MODE_640x480_FPAR_TO_PAL_I_YPrPb_16x9 0x58100E18
#define AV_MODE_640x480_TO_PAL_60_YPrPb 0x08010119
#define AV_MODE_640x480_TO_PAL_60_YPrPb_16x9 0x18010119
#define AV_MODE_720x480_TO_PAL_60_YPrPb 0x0802021A
#define AV_MODE_720x480_TO_PAL_60_YPrPb_16x9 0x1802021A
#define AV_MODE_640x480_FPAR_TO_PAL_60_YPrPb 0x080F0D1B
#define AV_MODE_640x480_FPAR_TO_PAL_60_YPrPb_16x9 0x180F0D1B
#define AV_MODE_640x576_FPAR_TO_PAL_I_YC 0x4412101C
#define AV_MODE_640x576_FPAR_TO_PAL_I_YC_16x9 0x5412101C
#define AV_MODE_640x576_FPAR_TO_PAL_I_RGB 0x6012101C
#define AV_MODE_640x576_FPAR_TO_PAL_I_RGB_16x9 0x7012101C
#define AV_MODE_640x576_FPAR_TO_PAL_I_YPrPb 0x4812101D
#define AV_MODE_640x576_FPAR_TO_PAL_I_YPrPb_16x9 0x5812101D
#define AV_MODE_640x480_TO_VGA 0x88070701
#define AV_MODE_720x480_TO_VGA 0x88080801
#define AV_MODE_1280x720_TO_VGA 0x880B0A02
#define AV_MODE_1920x1080_TO_VGA 0x880E0C03
#define AV_MODE_640x480_TO_480P 0x88070701
#define AV_MODE_720x480_TO_480P 0x88080801
#define AV_MODE_1280x720P_TO_720P 0x880B0A02
#define AV_MODE_1920x1080I_TO_1080I 0x880E0C03
#define AV_MODE_640x480_FPAR_TO_480P 0x88110F01
#define AV_MODE_FLAGS_DACA_DISABLE 0x01000000
#define AV_MODE_FLAGS_DACB_DISABLE 0x02000000
#define AV_MODE_FLAGS_DACC_DISABLE 0x04000000
#define AV_MODE_FLAGS_DACD_DISABLE 0x08000000
#define AV_MODE_FLAGS_WSS 0x10000000 // _16x9
#define AV_MODE_FLAGS_SCART 0x20000000 // _RGB
#define AV_MODE_FLAGS_NTSCJ 0x00000080
#define AV_MODE_OUT_MASK 0xC0000000
#define AV_MODE_OUT_480SDTV 0x00000000
#define AV_MODE_OUT_525SDTV 0x40000000
#define AV_MODE_OUT_HDTV 0x80000000
#define AV_MODE_OUT_VGA 0xC0000000
// Register Tables
const ULONG AvpRegisters[][26] =
{
{ /* offset */ 0x00680898, 0x0068089C, 0x006808C0, 0x006808C4, 0x0068084C, 0x00680630, 0x00680800, 0x00680804, 0x00680808, 0x0068080C, 0x00680810, 0x00680814, 0x00680818, 0x00680820, 0x00680824, 0x00680828, 0x0068082C, 0x00680830, 0x00680834, 0x00680838, 0x00680848, 0x00680680, 0x00680684, 0x00680688, 0x0068068C, 0x00680690 }, /* offset */
{ /* 1 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001F2, 0x000001F4, 0x00000000, 0x000001DF, 0x0000027F, 0x000003A7, 0x00000257, 0x000002F3, 0x00000333, 0x00000000, 0x0000027F, 0x10100111, 0x000C6ED0, 0x0000020D, 0x0000009B, 0x0000026C, 0x00000000 }, /* 1 */
{ /* 2 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001F2, 0x000001F4, 0x00000000, 0x000001DF, 0x000002CF, 0x000003A7, 0x000002A7, 0x0000031B, 0x0000035B, 0x00000000, 0x000002CF, 0x10100111, 0x000DF05C, 0x0000020D, 0x000000AE, 0x000002B8, 0x00000000 }, /* 2 */
{ /* 3 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001F4, 0x000001F6, 0x00000000, 0x000001DF, 0x0000027F, 0x0000035F, 0x00000257, 0x000002CF, 0x0000030F, 0x00000000, 0x0000027F, 0x10100111, 0x000F387C, 0x00000271, 0x000000BE, 0x000002F8, 0x00000000 }, /* 3 */
{ /* 4 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001F4, 0x000001F6, 0x00000000, 0x000001DF, 0x000002CF, 0x0000035F, 0x000002AF, 0x0000030B, 0x0000034B, 0x00000000, 0x000002CF, 0x10100111, 0x0010D2A4, 0x00000271, 0x000000D2, 0x00000348, 0x00000000 }, /* 4 */
{ /* 5 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x0000023F, 0x00000270, 0x0000023F, 0x00000256, 0x00000258, 0x00000000, 0x0000023F, 0x0000027F, 0x0000035F, 0x00000257, 0x000002CF, 0x0000030F, 0x00000000, 0x0000027F, 0x10100111, 0x000F07A8, 0x00000271, 0x0000009D, 0x00000276, 0x00000000 }, /* 5 */
{ /* 6 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x0000023F, 0x00000270, 0x0000023F, 0x00000256, 0x00000258, 0x00000000, 0x0000023F, 0x000002CF, 0x0000035F, 0x000002AF, 0x0000030B, 0x0000034B, 0x00000000, 0x000002CF, 0x10100111, 0x0010E62C, 0x00000271, 0x000000B1, 0x000002C4, 0x00000000 }, /* 6 */
{ /* 7 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001E8, 0x000001EE, 0x00000000, 0x000001DF, 0x000002CF, 0x00000359, 0x0000029F, 0x000002E1, 0x00000320, 0x00000000, 0x000002CF, 0x10100011, 0x0000035A, 0x00000001, 0x000000AB, 0x000002AE, 0x00000001 }, /* 7 */
{ /* 8 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001E8, 0x000001EE, 0x00000000, 0x000001DF, 0x000002CF, 0x00000359, 0x0000029F, 0x000002E1, 0x00000320, 0x00000000, 0x000002CF, 0x10100111, 0x0000035A, 0x00000001, 0x000000AB, 0x000002AE, 0x00000001 }, /* 8 */
{ /* 9 */ 0x0AA94000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000003, 0x000002CF, 0x000002ED, 0x000002CF, 0x000002D4, 0x000002D9, 0x00000000, 0x000002CF, 0x000004FF, 0x00000671, 0x000004FF, 0x00000545, 0x00000595, 0x000000A0, 0x0000045F, 0x10100011, 0x00000672, 0x00000001, 0x0000014A, 0x00000528, 0x00000001 }, /* 9 */
{ /* A */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000003, 0x000002CF, 0x000002ED, 0x000002CF, 0x000002D4, 0x000002D9, 0x00000000, 0x000002CF, 0x000004FF, 0x00000671, 0x000004CF, 0x00000545, 0x00000595, 0x00000000, 0x000004FF, 0x10100011, 0x00000672, 0x00000001, 0x0000014A, 0x00000528, 0x00000001 }, /* A */
{ /* B */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000003, 0x000002CF, 0x000002ED, 0x000002CF, 0x000002D4, 0x000002D9, 0x00000000, 0x000002CF, 0x000004FF, 0x00000671, 0x000004FF, 0x00000545, 0x00000595, 0x00000000, 0x000004FF, 0x10100111, 0x00000672, 0x00000001, 0x0000014A, 0x00000528, 0x00000001 }, /* B */
{ /* C */ 0x071AE000, 0x07183800, 0x00000000, 0x40801080, 0x00801080, 0x00000003, 0x00000437, 0x00000464, 0x0000043C, 0x0000043C, 0x00000446, 0x00000000, 0x00000437, 0x0000077F, 0x00000897, 0x000007AA, 0x000007AB, 0x00000803, 0x000000F0, 0x0000068F, 0x10133011, 0x00000898, 0x00000001, 0x000001B8, 0x000006E0, 0x00000001 }, /* C */
{ /* D */ 0x10000000, 0x07183800, 0x00000000, 0x40801080, 0x00801080, 0x00000003, 0x00000437, 0x00000464, 0x0000043C, 0x0000043C, 0x00000446, 0x00000000, 0x00000437, 0x0000077F, 0x00000897, 0x00000759, 0x000007AB, 0x00000803, 0x00000000, 0x0000077F, 0x10133011, 0x00000898, 0x00000001, 0x000001B8, 0x000006E0, 0x00000001 }, /* D */
{ /* E */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000003, 0x00000437, 0x00000464, 0x0000043B, 0x0000043B, 0x00000445, 0x00000000, 0x00000437, 0x0000077F, 0x00000897, 0x000007AB, 0x000007AC, 0x00000804, 0x00000000, 0x0000077F, 0x10133111, 0x00000898, 0x00000001, 0x000001B8, 0x000006E0, 0x00000001 }, /* E */
{ /* F */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001F2, 0x000001F4, 0x00000000, 0x000001DF, 0x0000027F, 0x000003A7, 0x000002A7, 0x000002F3, 0x00000333, 0x00000000, 0x0000027F, 0x10100111, 0x000DF05C, 0x0000020D, 0x000000AE, 0x000002B8, 0x00000000 }, /* F */
{ /* 10 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001F4, 0x000001F6, 0x00000000, 0x000001DF, 0x0000027F, 0x0000035F, 0x000002A7, 0x000002CF, 0x0000030F, 0x00000000, 0x0000027F, 0x10100111, 0x000DF05C, 0x0000020D, 0x000000AE, 0x000002B8, 0x00000000 }, /* 10 */
{ /* 11 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x000001DF, 0x0000020C, 0x000001DF, 0x000001E8, 0x000001EE, 0x00000000, 0x000001DF, 0x000002CF, 0x00000359, 0x000002CF, 0x000002DF, 0x0000031E, 0x00000020, 0x000002AD, 0x10100011, 0x0000035A, 0x00000001, 0x000000AB, 0x000002AE, 0x00000001 }, /* 11 */
{ /* 12 */ 0x10000000, 0x10000000, 0x00000000, 0x40801080, 0x00801080, 0x00000002, 0x0000023F, 0x00000270, 0x0000023F, 0x00000256, 0x00000258, 0x00000000, 0x0000023F, 0x0000027F, 0x0000035F, 0x00000257, 0x000002CF, 0x0000030F, 0x00000000, 0x0000027F, 0x10100111, 0x000F07A8, 0x00000271, 0x0000009D, 0x00000276, 0x00000000 }, /* 12 */
};
const UCHAR AvpSRXRegisters[] =
{
0x03, 0x21, 0x0F, 0x00, 0x06,
};
const UCHAR AvpGRXRegisters[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF,
};
const UCHAR AvpARXRegisters[] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x01, 0x4A, 0x0F, 0x00, 0x00,
};
const UCHAR AvpCRTCRegisters[][34] =
{
{ /* offset */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x20, 0x25, 0x2D, 0x33, 0x39, 0x41 }, /* offset */
{ /* 1 */ 0x70, 0x4F, 0x4F, 0x94, 0x5D, 0xBF, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0x04, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 1 */
{ /* 2 */ 0x70, 0x59, 0x59, 0x94, 0x62, 0xA4, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0x04, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 2 */
{ /* 3 */ 0x67, 0x4F, 0x4F, 0x8B, 0x59, 0xBB, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x06, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 3 */
{ /* 4 */ 0x67, 0x59, 0x59, 0x8B, 0x5E, 0xBF, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x06, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 4 */
{ /* 5 */ 0x67, 0x4F, 0x4F, 0x8B, 0x59, 0xBB, 0x6F, 0xF0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x08, 0x3F, 0x00, 0x00, 0x3F, 0x70, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 5 */
{ /* 6 */ 0x67, 0x59, 0x59, 0x8B, 0x5E, 0xBF, 0x6F, 0xF0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x08, 0x3F, 0x00, 0x00, 0x3F, 0x70, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 6 */
{ /* 7 */ 0x59, 0x4F, 0x4F, 0x9D, 0x51, 0x39, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x0E, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 7 */
{ /* 8 */ 0x63, 0x59, 0x59, 0x87, 0x5B, 0xA3, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x0E, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 8 */
{ /* 9 */ 0x78, 0x4F, 0x4F, 0x9C, 0x57, 0xA1, 0xFC, 0x1F, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x09, 0xDF, 0x00, 0x00, 0xDF, 0xFD, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 9 */
{ /* A */ 0xC8, 0x9F, 0x9F, 0x8C, 0xA7, 0x31, 0xEC, 0xF0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x09, 0xCF, 0x00, 0x00, 0xCF, 0xED, 0xE3, 0xFF, 0x00, 0x38, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* A */
{ /* B */ 0x67, 0x4F, 0x4F, 0x8B, 0x54, 0xBF, 0x03, 0x11, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0x06, 0xEF, 0x00, 0x00, 0xEF, 0x04, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0x36, 0x00 }, /* B */
{ /* C */ 0x04, 0xEF, 0xEF, 0x88, 0xF4, 0x3F, 0x2F, 0xF0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x02, 0x1B, 0x00, 0x00, 0x1B, 0x30, 0xE3, 0xFF, 0x00, 0x38, 0x05, 0x80, 0x00, 0x01, 0x11, 0x10, 0x00 }, /* C */
{ /* D */ 0x70, 0x4F, 0x4F, 0x94, 0x5D, 0xBF, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0x04, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* D */
{ /* E */ 0x67, 0x4F, 0x4F, 0x8B, 0x59, 0xBF, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x06, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x00, 0x00, 0x11, 0xFF, 0x00 }, /* E */
{ /* F */ 0x61, 0x57, 0x57, 0x85, 0x59, 0xBF, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x0E, 0xDF, 0x00, 0x00, 0xDF, 0x0C, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* F */
{ /* 10 */ 0x67, 0x4F, 0x4F, 0x94, 0x59, 0xBF, 0x6F, 0xF0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x08, 0x3F, 0x00, 0x00, 0x3F, 0x70, 0xE3, 0xFF, 0x00, 0x3A, 0x05, 0x80, 0x10, 0x00, 0x11, 0xFF, 0x00 }, /* 10 */
};
typedef struct
{
ULONG AvInfo;
USHORT Width;
USHORT Height;
ULONG DisplayMode;
} XB_DisplayMode;
const XB_DisplayMode g_DisplayModes[] =
{
{ AV_PACK_VGA | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 1280, 720, AV_MODE_1280x720_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 1920, 1080, AV_MODE_1920x1080_TO_VGA },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | 0 | 0 | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | 0 | 0 | AV_FLAGS_HDTV_480p, 720, 480, AV_MODE_720x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480p, 720, 480, AV_MODE_720x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | 0 | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_FPAR_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_FPAR_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_720p, 1280, 720, AV_MODE_1280x720P_TO_720P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | AV_FLAGS_HDTV_480i, 720, 480, AV_MODE_720x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 720, 480, AV_MODE_720x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | AV_FLAGS_HDTV_480i, 720, 240, AV_MODE_720x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 720, 240, AV_MODE_720x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_1080i, 1920, 1080, AV_MODE_1920x1080I_TO_1080I },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_1080i, 1920, 540, AV_MODE_1920x1080I_TO_1080I },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_M_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_M_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_M_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_M_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_M_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_M_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_M_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_M_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_M_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_M_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_M_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_M_RGB_16x9 },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_M_YC },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_M_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_M_YC },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_M_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_M_YC },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_M_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_M_YC },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_M_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_M_YC },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_M_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_M_YC },
{ 0 | AV_STANDARD_NTSC_M | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_M_YC_16x9 },
{ AV_PACK_VGA | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 1280, 720, AV_MODE_1280x720_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 1920, 1080, AV_MODE_1920x1080_TO_VGA },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | 0 | 0 | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | 0 | 0 | AV_FLAGS_HDTV_480p, 720, 480, AV_MODE_720x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480p, 720, 480, AV_MODE_720x480_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | 0 | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_FPAR_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480p, 640, 480, AV_MODE_640x480_FPAR_TO_480P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | 0 | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_720p, 1280, 720, AV_MODE_1280x720P_TO_720P },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | AV_FLAGS_HDTV_480i, 720, 480, AV_MODE_720x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 720, 480, AV_MODE_720x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | AV_FLAGS_HDTV_480i, 720, 240, AV_MODE_720x480_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_480i, 720, 240, AV_MODE_720x480_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | AV_FLAGS_HDTV_480i, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_1080i, 1920, 1080, AV_MODE_1920x1080I_TO_1080I },
{ AV_PACK_HDTV | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | AV_FLAGS_HDTV_1080i, 1920, 540, AV_MODE_1920x1080I_TO_1080I },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_J_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_J_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_J_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_J_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_J_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_J_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_J_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_J_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_J_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_J_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_J_RGB },
{ AV_PACK_SCART | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_J_RGB_16x9 },
// All other AV packs are the same.
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_J_YC },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_NTSC_J_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_J_YC },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_NTSC_J_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_J_YC },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 240, AV_MODE_640x480_TO_NTSC_J_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_J_YC },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 240, AV_MODE_720x480_TO_NTSC_J_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_J_YC },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_NTSC_J_YC_16x9 },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_J_YC },
{ 0 | AV_STANDARD_NTSC_J | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_NTSC_J_YC_16x9 },
{ AV_PACK_VGA | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 1280, 720, AV_MODE_1280x720_TO_VGA },
{ AV_PACK_VGA | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | 0 | 0 | 0 | 0, 1920, 1080, AV_MODE_1920x1080_TO_VGA },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 576, AV_MODE_640x576_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 576, AV_MODE_640x576_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 576, AV_MODE_720x576_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 576, AV_MODE_720x576_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 288, AV_MODE_640x576_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 288, AV_MODE_640x576_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 288, AV_MODE_720x576_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 288, AV_MODE_720x576_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 576, AV_MODE_640x576_FPAR_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 576, AV_MODE_640x576_FPAR_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 288, AV_MODE_640x576_FPAR_TO_PAL_I_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 288, AV_MODE_640x576_FPAR_TO_PAL_I_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_60_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_60_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_60_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_60_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 240, AV_MODE_640x480_TO_PAL_60_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 240, AV_MODE_640x480_TO_PAL_60_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 240, AV_MODE_720x480_TO_PAL_60_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 240, AV_MODE_720x480_TO_PAL_60_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_60_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_60_YPrPb_16x9 },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_PAL_60_YPrPb },
{ AV_PACK_HDTV | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_PAL_60_YPrPb_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 576, AV_MODE_640x576_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 576, AV_MODE_640x576_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 576, AV_MODE_720x576_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 576, AV_MODE_720x576_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 288, AV_MODE_640x576_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 288, AV_MODE_640x576_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 288, AV_MODE_720x576_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 288, AV_MODE_720x576_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 576, AV_MODE_640x576_FPAR_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 576, AV_MODE_640x576_FPAR_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 288, AV_MODE_640x576_FPAR_TO_PAL_I_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 288, AV_MODE_640x576_FPAR_TO_PAL_I_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_60_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_60_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_60_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_60_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 240, AV_MODE_640x480_TO_PAL_60_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 240, AV_MODE_640x480_TO_PAL_60_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 240, AV_MODE_720x480_TO_PAL_60_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 240, AV_MODE_720x480_TO_PAL_60_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_60_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_60_RGB_16x9 },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_PAL_60_RGB },
{ AV_PACK_SCART | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_PAL_60_RGB_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 576, AV_MODE_640x576_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 576, AV_MODE_640x576_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 576, AV_MODE_720x576_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 576, AV_MODE_720x576_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 288, AV_MODE_640x576_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 288, AV_MODE_640x576_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 288, AV_MODE_720x576_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 288, AV_MODE_720x576_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 576, AV_MODE_640x576_FPAR_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 576, AV_MODE_640x576_FPAR_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 288, AV_MODE_640x576_FPAR_TO_PAL_I_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_50Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 288, AV_MODE_640x576_FPAR_TO_PAL_I_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_60_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 480, AV_MODE_640x480_TO_PAL_60_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_60_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 480, AV_MODE_720x480_TO_PAL_60_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 640, 240, AV_MODE_640x480_TO_PAL_60_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 640, 240, AV_MODE_640x480_TO_PAL_60_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | 0 | 0, 720, 240, AV_MODE_720x480_TO_PAL_60_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | 0 | 0, 720, 240, AV_MODE_720x480_TO_PAL_60_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | 0 | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_60_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_INTERLACED | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 480, AV_MODE_640x480_FPAR_TO_PAL_60_YC_16x9 },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | 0 | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_PAL_60_YC },
{ 0 | AV_STANDARD_PAL_I | AV_FLAGS_60Hz | AV_FLAGS_FIELD | AV_FLAGS_WIDESCREEN | AV_FLAGS_10x11PAR | 0, 640, 240, AV_MODE_640x480_FPAR_TO_PAL_60_YC_16x9 },
{ 0xFFFFFFFF, 0, 0, 0 },
};
const uint32_t g_DisplayModeCount = sizeof(g_DisplayModes) / sizeof(XB_DisplayMode);

View File

@ -29,7 +29,7 @@
#define LOG_PREFIX CXBXR_MODULE::KD
#include <xboxkrnl/xboxkrnl.h> // For KdDebuggerEnabled, etc.
#include <xboxkrnl/xboxkrnl.h> // For KdDebuggerEnabled, etc.
#include "Logging.h"
// ******************************************************************

View File

@ -24,42 +24,42 @@
// *
// * All rights reserved
// *
// ******************************************************************
// Acknowledgment (timer functions): ReactOS (GPLv2)
// https://github.com/reactos/reactos
// KeSetSystemTime
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ke/clock.c
* PURPOSE: System Clock Support
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
// KeInitializeTimerEx, KeSetTimer, KeSetTimerEx, KeCancelTimer
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ke/timerobj.c
* PURPOSE: Handle Kernel Timers (Kernel-part of Executive Timers)
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
// COPYING file:
/*
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
ReactOS may be used, runtime linked, and distributed with non-free software
(meaning that such software has no obligations to open-source, or render
free, their non-free code) such as commercial device drivers and commercial
applications. This exception does not alter any other responsibilities of
the licensee under the GPL (meaning that such software must still obey
the GPL for the free ("open-sourced") code that has been integrated into
the said software).
*/
// ******************************************************************
// Acknowledgment (timer functions): ReactOS (GPLv2)
// https://github.com/reactos/reactos
// KeSetSystemTime
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ke/clock.c
* PURPOSE: System Clock Support
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
// KeInitializeTimerEx, KeSetTimer, KeSetTimerEx, KeCancelTimer
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ke/timerobj.c
* PURPOSE: Handle Kernel Timers (Kernel-part of Executive Timers)
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
// COPYING file:
/*
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
ReactOS may be used, runtime linked, and distributed with non-free software
(meaning that such software has no obligations to open-source, or render
free, their non-free code) such as commercial device drivers and commercial
applications. This exception does not alter any other responsibilities of
the licensee under the GPL (meaning that such software must still obey
the GPL for the free ("open-sourced") code that has been integrated into
the said software).
*/
#define LOG_PREFIX CXBXR_MODULE::KE
@ -78,9 +78,9 @@ namespace NtDll
#include "core\kernel\init\CxbxKrnl.h" // For CxbxKrnlCleanup
#include "core\kernel\support\Emu.h" // For EmuLog(LOG_LEVEL::WARNING, )
#include "EmuKrnl.h" // For InitializeListHead(), etc.
#include "EmuKrnlKi.h" // For KiRemoveTreeTimer(), KiInsertTreeTimer()
#include "EmuKrnlKi.h" // For KiRemoveTreeTimer(), KiInsertTreeTimer()
#include "EmuKrnlKe.h"
#include "core\kernel\support\EmuFile.h" // For IsEmuHandle(), NtStatusToString()
#include "core\kernel\support\EmuFile.h" // For IsEmuHandle(), NtStatusToString()
#include "Timer.h"
#include <chrono>
@ -155,100 +155,100 @@ xboxkrnl::KPCR* WINAPI KeGetPcr()
xboxkrnl::KPRCB *KeGetCurrentPrcb()
{
return &(KeGetPcr()->PrcbData);
}
}
// ******************************************************************
// * KeSetSystemTime()
// ******************************************************************
xboxkrnl::VOID NTAPI xboxkrnl::KeSetSystemTime
(
IN xboxkrnl::PLARGE_INTEGER NewTime,
OUT xboxkrnl::PLARGE_INTEGER OldTime
)
{
KIRQL OldIrql, OldIrql2;
LARGE_INTEGER DeltaTime, HostTime;
PLIST_ENTRY ListHead, NextEntry;
PKTIMER Timer;
LIST_ENTRY TempList, TempList2;
ULONG Hand, i;
/* Sanity checks */
assert((NewTime->u.HighPart & 0xF0000000) == 0);
assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
/* Lock the dispatcher, and raise IRQL */
KiTimerLock();
KiLockDispatcherDatabase(&OldIrql);
OldIrql2 = KfRaiseIrql(HIGH_LEVEL);
/* Query the system time now */
KeQuerySystemTime(OldTime);
/* Surely, we won't set the system time here, but we CAN remember a delta to the host system time */
HostTime.QuadPart = OldTime->QuadPart - HostSystemTimeDelta.load();
HostSystemTimeDelta = NewTime->QuadPart - HostTime.QuadPart;
/* Calculate the difference between the new and the old time */
DeltaTime.QuadPart = NewTime->QuadPart - OldTime->QuadPart;
/* Lower IRQL back */
KfLowerIrql(OldIrql2);
/* Setup a temporary list of absolute timers */
InitializeListHead(&TempList);
/* Loop current timers */
for (i = 0; i < TIMER_TABLE_SIZE; i++)
{
/* Loop the entries in this table and lock the timers */
ListHead = &KiTimerTableListHead[i].Entry;
NextEntry = ListHead->Flink;
while (NextEntry != ListHead)
{
/* Get the timer */
Timer = CONTAINING_RECORD(NextEntry, KTIMER, TimerListEntry);
NextEntry = NextEntry->Flink;
/* Is it absolute? */
if (Timer->Header.Absolute)
{
/* Remove it from the timer list */
KiRemoveEntryTimer(Timer, i);
/* Insert it into our temporary list */
InsertTailList(&TempList, &Timer->TimerListEntry);
}
}
}
/* Setup a temporary list of expired timers */
InitializeListHead(&TempList2);
/* Loop absolute timers */
while (TempList.Flink != &TempList)
{
/* Get the timer */
Timer = CONTAINING_RECORD(TempList.Flink, KTIMER, TimerListEntry);
RemoveEntryList(&Timer->TimerListEntry);
/* Update the due time and handle */
Timer->DueTime.QuadPart -= DeltaTime.QuadPart;
Hand = KiComputeTimerTableIndex(Timer->DueTime.QuadPart);
/* Lock the timer and re-insert it */
if (KiInsertTimerTable(Timer, Hand))
{
/* Remove it from the timer list */
KiRemoveEntryTimer(Timer, Hand);
/* Insert it into our temporary list */
InsertTailList(&TempList2, &Timer->TimerListEntry);
}
}
/* Process expired timers. This releases the dispatcher and timer locks */
KiTimerListExpire(&TempList2, OldIrql);
// ******************************************************************
xboxkrnl::VOID NTAPI xboxkrnl::KeSetSystemTime
(
IN xboxkrnl::PLARGE_INTEGER NewTime,
OUT xboxkrnl::PLARGE_INTEGER OldTime
)
{
KIRQL OldIrql, OldIrql2;
LARGE_INTEGER DeltaTime, HostTime;
PLIST_ENTRY ListHead, NextEntry;
PKTIMER Timer;
LIST_ENTRY TempList, TempList2;
ULONG Hand, i;
/* Sanity checks */
assert((NewTime->u.HighPart & 0xF0000000) == 0);
assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
/* Lock the dispatcher, and raise IRQL */
KiTimerLock();
KiLockDispatcherDatabase(&OldIrql);
OldIrql2 = KfRaiseIrql(HIGH_LEVEL);
/* Query the system time now */
KeQuerySystemTime(OldTime);
/* Surely, we won't set the system time here, but we CAN remember a delta to the host system time */
HostTime.QuadPart = OldTime->QuadPart - HostSystemTimeDelta.load();
HostSystemTimeDelta = NewTime->QuadPart - HostTime.QuadPart;
/* Calculate the difference between the new and the old time */
DeltaTime.QuadPart = NewTime->QuadPart - OldTime->QuadPart;
/* Lower IRQL back */
KfLowerIrql(OldIrql2);
/* Setup a temporary list of absolute timers */
InitializeListHead(&TempList);
/* Loop current timers */
for (i = 0; i < TIMER_TABLE_SIZE; i++)
{
/* Loop the entries in this table and lock the timers */
ListHead = &KiTimerTableListHead[i].Entry;
NextEntry = ListHead->Flink;
while (NextEntry != ListHead)
{
/* Get the timer */
Timer = CONTAINING_RECORD(NextEntry, KTIMER, TimerListEntry);
NextEntry = NextEntry->Flink;
/* Is it absolute? */
if (Timer->Header.Absolute)
{
/* Remove it from the timer list */
KiRemoveEntryTimer(Timer, i);
/* Insert it into our temporary list */
InsertTailList(&TempList, &Timer->TimerListEntry);
}
}
}
/* Setup a temporary list of expired timers */
InitializeListHead(&TempList2);
/* Loop absolute timers */
while (TempList.Flink != &TempList)
{
/* Get the timer */
Timer = CONTAINING_RECORD(TempList.Flink, KTIMER, TimerListEntry);
RemoveEntryList(&Timer->TimerListEntry);
/* Update the due time and handle */
Timer->DueTime.QuadPart -= DeltaTime.QuadPart;
Hand = KiComputeTimerTableIndex(Timer->DueTime.QuadPart);
/* Lock the timer and re-insert it */
if (KiInsertTimerTable(Timer, Hand))
{
/* Remove it from the timer list */
KiRemoveEntryTimer(Timer, Hand);
/* Insert it into our temporary list */
InsertTailList(&TempList2, &Timer->TimerListEntry);
}
}
/* Process expired timers. This releases the dispatcher and timer locks */
KiTimerListExpire(&TempList2, OldIrql);
}
// ******************************************************************
@ -259,10 +259,10 @@ xboxkrnl::VOID NTAPI xboxkrnl::KeInitializeTimer
IN PKTIMER Timer
)
{
LOG_FORWARD("KeInitializeTimerEx");
KeInitializeTimerEx(Timer, NotificationTimer);
}
LOG_FORWARD("KeInitializeTimerEx");
KeInitializeTimerEx(Timer, NotificationTimer);
}
// Forward KeLowerIrql() to KfLowerIrql()
#define KeLowerIrql(NewIrql) \
@ -324,17 +324,17 @@ void InitDpcThread()
g_DpcData.DpcEvent = CreateEvent(/*lpEventAttributes=*/nullptr, /*bManualReset=*/FALSE, /*bInitialState=*/FALSE, /*lpName=*/nullptr);
}
#define XBOX_TSC_FREQUENCY 733333333 // Xbox Time Stamp Counter Frequency = 733333333 (CPU Clock)
#define XBOX_TSC_FREQUENCY 733333333 // Xbox Time Stamp Counter Frequency = 733333333 (CPU Clock)
#define XBOX_ACPI_FREQUENCY 3375000 // Xbox ACPI frequency (3.375 mhz)
ULONGLONG NativeToXbox_FactorForRdtsc;
ULONGLONG NativeToXbox_FactorForRdtsc;
ULONGLONG NativeToXbox_FactorForAcpi;
ULONGLONG CxbxGetPerformanceCounter(bool acpi) {
LARGE_INTEGER tsc;
ULARGE_INTEGER scaledTsc;
QueryPerformanceCounter(&tsc);
ULARGE_INTEGER scaledTsc;
QueryPerformanceCounter(&tsc);
scaledTsc.QuadPart = 1000000000;
scaledTsc.QuadPart *= (ULONGLONG)tsc.QuadPart;
@ -355,11 +355,11 @@ void CxbxInitPerformanceCounters()
t = 1000000000;
t *= HostClockFrequency;
t /= XBOX_TSC_FREQUENCY;
NativeToXbox_FactorForRdtsc = t;
NativeToXbox_FactorForRdtsc = t;
t = 1000000000;
t *= HostClockFrequency;
t /= XBOX_ACPI_FREQUENCY;
t /= XBOX_ACPI_FREQUENCY;
NativeToXbox_FactorForAcpi = t;
// Let's initialize the Dpc handling thread too,
@ -496,27 +496,27 @@ XBSYSAPI EXPORTNUM(96) xboxkrnl::BOOLEAN NTAPI xboxkrnl::KeCancelTimer
IN PKTIMER Timer
)
{
LOG_FUNC_ONE_ARG(Timer);
KIRQL OldIrql;
BOOLEAN Inserted;
assert(Timer);
/* Lock the Database and Raise IRQL */
KiTimerLock();
KiLockDispatcherDatabase(&OldIrql);
/* Check if it's inserted, and remove it if it is */
Inserted = Timer->Header.Inserted;
if (Inserted) {
KxRemoveTreeTimer(Timer);
}
/* Release Dispatcher Lock */
KiUnlockDispatcherDatabase(OldIrql);
KiTimerUnlock();
LOG_FUNC_ONE_ARG(Timer);
KIRQL OldIrql;
BOOLEAN Inserted;
assert(Timer);
/* Lock the Database and Raise IRQL */
KiTimerLock();
KiLockDispatcherDatabase(&OldIrql);
/* Check if it's inserted, and remove it if it is */
Inserted = Timer->Header.Inserted;
if (Inserted) {
KxRemoveTreeTimer(Timer);
}
/* Release Dispatcher Lock */
KiUnlockDispatcherDatabase(OldIrql);
KiTimerUnlock();
/* Return the old state */
RETURN(Inserted);
}
@ -737,14 +737,14 @@ XBSYSAPI EXPORTNUM(108) xboxkrnl::VOID NTAPI xboxkrnl::KeInitializeEvent
LOG_FUNC_ARG(Type)
LOG_FUNC_ARG(SignalState)
LOG_FUNC_END;
// HACK: Since we forward to NtDll::NtCreateEvent, this *might* be a Windows handle instead of our own
// In this case, it is already initialized so no need tod o anything
// Test Case: Xbox Live Dashboard, Network Test (or any other Xbox Live connection)
DWORD flags = 0;
if (GetHandleInformation((HANDLE)Event, &flags)) {
return;
}
// HACK: Since we forward to NtDll::NtCreateEvent, this *might* be a Windows handle instead of our own
// In this case, it is already initialized so no need tod o anything
// Test Case: Xbox Live Dashboard, Network Test (or any other Xbox Live connection)
DWORD flags = 0;
if (GetHandleInformation((HANDLE)Event, &flags)) {
return;
}
// Setup the Xbox event struct
Event->Header.Type = Type;
@ -894,8 +894,8 @@ XBSYSAPI EXPORTNUM(113) xboxkrnl::VOID NTAPI xboxkrnl::KeInitializeTimerEx
LOG_FUNC_BEGIN
LOG_FUNC_ARG(Timer)
LOG_FUNC_ARG(Type)
LOG_FUNC_END;
LOG_FUNC_END;
assert(Timer);
// Initialize header :
@ -1137,16 +1137,16 @@ XBSYSAPI EXPORTNUM(123) xboxkrnl::LONG NTAPI xboxkrnl::KePulseEvent
LOG_FUNC_END;
KIRQL OldIrql;
KiLockDispatcherDatabase(&OldIrql);
// HACK: Since we forward to NtDll::NtCreateEvent, this *might* be a Windows handle instead of our own
// In this case, we must call the NtDll function
// Test Case: Xbox Live Dashboard, Network Test (or any other Xbox Live connection)
DWORD flags = 0;
if (GetHandleInformation((HANDLE)Event, &flags)) {
KiUnlockDispatcherDatabase(OldIrql);
return NtDll::NtPulseEvent((HANDLE)Event, nullptr);
}
KiLockDispatcherDatabase(&OldIrql);
// HACK: Since we forward to NtDll::NtCreateEvent, this *might* be a Windows handle instead of our own
// In this case, we must call the NtDll function
// Test Case: Xbox Live Dashboard, Network Test (or any other Xbox Live connection)
DWORD flags = 0;
if (GetHandleInformation((HANDLE)Event, &flags)) {
KiUnlockDispatcherDatabase(OldIrql);
return NtDll::NtPulseEvent((HANDLE)Event, nullptr);
}
LONG OldState = Event->Header.SignalState;
if ((OldState == 0) && (IsListEmpty(&Event->Header.WaitListHead) == FALSE)) {
@ -1214,8 +1214,8 @@ XBSYSAPI EXPORTNUM(125) xboxkrnl::ULONGLONG NTAPI xboxkrnl::KeQueryInterruptTime
}
// ******************************************************************
// * 0x007E - KeQueryPerformanceCounter()
// NOTE: The KeQueryPerformance* functions run at the ACPI clock
// * 0x007E - KeQueryPerformanceCounter()
// NOTE: The KeQueryPerformance* functions run at the ACPI clock
// The XAPI QueryPerformance* functions run at the TSC clock
// ******************************************************************
XBSYSAPI EXPORTNUM(126) xboxkrnl::ULONGLONG NTAPI xboxkrnl::KeQueryPerformanceCounter(void)
@ -1245,8 +1245,8 @@ XBSYSAPI EXPORTNUM(128) xboxkrnl::VOID NTAPI xboxkrnl::KeQuerySystemTime
)
{
LOG_FUNC_ONE_ARG(CurrentTime);
LARGE_INTEGER SystemTime;
LARGE_INTEGER SystemTime;
while (true)
{
@ -1317,30 +1317,30 @@ XBSYSAPI EXPORTNUM(132) xboxkrnl::LONG NTAPI xboxkrnl::KeReleaseSemaphore
LOG_FUNC_ARG(Wait)
LOG_FUNC_END;
UCHAR orig_irql = KeRaiseIrqlToDpcLevel();
LONG initial_state = Semaphore->Header.SignalState;
LONG adjusted_signalstate = Semaphore->Header.SignalState + Adjustment;
BOOL limit_reached = adjusted_signalstate > Semaphore->Limit;
BOOL signalstate_overflow = adjusted_signalstate < initial_state;
if (limit_reached || signalstate_overflow) {
KiUnlockDispatcherDatabase(orig_irql);
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
}
Semaphore->Header.SignalState = adjusted_signalstate;
//TODO: Implement KiWaitTest
#if 0
if ((initial_state == 0) && (IsListEmpty(&Semaphore->Header.WaitListHead) == FALSE)) {
UCHAR orig_irql = KeRaiseIrqlToDpcLevel();
LONG initial_state = Semaphore->Header.SignalState;
LONG adjusted_signalstate = Semaphore->Header.SignalState + Adjustment;
BOOL limit_reached = adjusted_signalstate > Semaphore->Limit;
BOOL signalstate_overflow = adjusted_signalstate < initial_state;
if (limit_reached || signalstate_overflow) {
KiUnlockDispatcherDatabase(orig_irql);
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
}
Semaphore->Header.SignalState = adjusted_signalstate;
//TODO: Implement KiWaitTest
#if 0
if ((initial_state == 0) && (IsListEmpty(&Semaphore->Header.WaitListHead) == FALSE)) {
KiWaitTest(&Semaphore->Header, Increment);
}
#endif
}
#endif
if (Wait) {
PKTHREAD current_thread = KeGetCurrentThread();
current_thread->WaitNext = TRUE;
PKTHREAD current_thread = KeGetCurrentThread();
current_thread->WaitNext = TRUE;
current_thread->WaitIrql = orig_irql;
}
}
else {
KiUnlockDispatcherDatabase(orig_irql);
}
@ -1503,15 +1503,15 @@ XBSYSAPI EXPORTNUM(138) xboxkrnl::LONG NTAPI xboxkrnl::KeResetEvent
LOG_FUNC_ONE_ARG(Event);
KIRQL OldIrql;
KiLockDispatcherDatabase(&OldIrql);
// HACK: Since we forward to NtDll::NtCreateEvent, this *might* be a Windows handle instead of our own
// In this case, we must call the NtDll function
// Test Case: Xbox Live Dashboard, Network Test (or any other Xbox Live connection)
DWORD flags = 0;
if (GetHandleInformation((HANDLE)Event, &flags)) {
KiUnlockDispatcherDatabase(OldIrql);
return NtDll::NtResetEvent((HANDLE)Event, nullptr);
KiLockDispatcherDatabase(&OldIrql);
// HACK: Since we forward to NtDll::NtCreateEvent, this *might* be a Windows handle instead of our own
// In this case, we must call the NtDll function
// Test Case: Xbox Live Dashboard, Network Test (or any other Xbox Live connection)
DWORD flags = 0;
if (GetHandleInformation((HANDLE)Event, &flags)) {
KiUnlockDispatcherDatabase(OldIrql);
return NtDll::NtResetEvent((HANDLE)Event, nullptr);
}
LONG OldState = Event->Header.SignalState;
@ -1648,15 +1648,15 @@ XBSYSAPI EXPORTNUM(145) xboxkrnl::LONG NTAPI xboxkrnl::KeSetEvent
LOG_FUNC_END;
KIRQL OldIrql;
KiLockDispatcherDatabase(&OldIrql);
// HACK: Since we forward to NtDll::NtCreateEvent, this *might* be a Windows handle instead of our own
// In this case, we must call the NtDll function
// Test Case: Xbox Live Dashboard, Network Test (or any other Xbox Live connection)
DWORD flags = 0;
if (GetHandleInformation((HANDLE)Event, &flags)) {
KiUnlockDispatcherDatabase(OldIrql);
return NtDll::NtSetEvent((HANDLE)Event, nullptr);
KiLockDispatcherDatabase(&OldIrql);
// HACK: Since we forward to NtDll::NtCreateEvent, this *might* be a Windows handle instead of our own
// In this case, we must call the NtDll function
// Test Case: Xbox Live Dashboard, Network Test (or any other Xbox Live connection)
DWORD flags = 0;
if (GetHandleInformation((HANDLE)Event, &flags)) {
KiUnlockDispatcherDatabase(OldIrql);
return NtDll::NtSetEvent((HANDLE)Event, nullptr);
}
LONG OldState = Event->Header.SignalState;
@ -1703,15 +1703,15 @@ XBSYSAPI EXPORTNUM(146) xboxkrnl::VOID NTAPI xboxkrnl::KeSetEventBoostPriority
LOG_FUNC_ARG(Thread)
LOG_FUNC_END;
KIRQL OldIrql;
KiLockDispatcherDatabase(&OldIrql);
// HACK: Since we forward to NtDll::NtCreateEvent, this *might* be a Windows handle instead of our own
// In this case, we must do nothing. Anything else *will* cause crashes
// Test Case: Xbox Live Dashboard, Network Test (or any other Xbox Live connection)
DWORD flags = 0;
if (GetHandleInformation((HANDLE)Event, &flags)) {
KiUnlockDispatcherDatabase(OldIrql);
return;
KiLockDispatcherDatabase(&OldIrql);
// HACK: Since we forward to NtDll::NtCreateEvent, this *might* be a Windows handle instead of our own
// In this case, we must do nothing. Anything else *will* cause crashes
// Test Case: Xbox Live Dashboard, Network Test (or any other Xbox Live connection)
DWORD flags = 0;
if (GetHandleInformation((HANDLE)Event, &flags)) {
KiUnlockDispatcherDatabase(OldIrql);
return;
}
if (IsListEmpty(&Event->Header.WaitListHead) != FALSE) {
@ -1803,15 +1803,15 @@ XBSYSAPI EXPORTNUM(150) xboxkrnl::BOOLEAN NTAPI xboxkrnl::KeSetTimerEx
LOG_FUNC_ARG(Dpc)
LOG_FUNC_END;
BOOLEAN Inserted;
BOOLEAN RequestInterrupt = FALSE;
KIRQL OldIrql;
BOOLEAN Inserted;
BOOLEAN RequestInterrupt = FALSE;
KIRQL OldIrql;
ULONG Hand;
assert(Timer);
assert(Timer->Header.Type == TimerNotificationObject || Timer->Header.Type == TimerSynchronizationObject);
KiTimerLock();
assert(Timer->Header.Type == TimerNotificationObject || Timer->Header.Type == TimerSynchronizationObject);
KiTimerLock();
KiLockDispatcherDatabase(&OldIrql);
// Same as KeCancelTimer(Timer) :
@ -1820,29 +1820,29 @@ XBSYSAPI EXPORTNUM(150) xboxkrnl::BOOLEAN NTAPI xboxkrnl::KeSetTimerEx
// Do some unlinking if already inserted in the linked list
KxRemoveTreeTimer(Timer);
}
/* Set Default Timer Data */
Timer->Dpc = Dpc;
Timer->Period = Period;
if (!KiComputeDueTime(Timer, DueTime, &Hand))
{
/* Signal the timer */
RequestInterrupt = KiSignalTimer(Timer);
/* Check if we need to do an interrupt */
if (RequestInterrupt) {
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
}
}
else
{
/* Insert the timer */
Timer->Header.SignalState = FALSE;
KxInsertTimer(Timer, Hand);
}
/* Exit the dispatcher */
KiUnlockDispatcherDatabase(OldIrql);
/* Set Default Timer Data */
Timer->Dpc = Dpc;
Timer->Period = Period;
if (!KiComputeDueTime(Timer, DueTime, &Hand))
{
/* Signal the timer */
RequestInterrupt = KiSignalTimer(Timer);
/* Check if we need to do an interrupt */
if (RequestInterrupt) {
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
}
}
else
{
/* Insert the timer */
Timer->Header.SignalState = FALSE;
KxInsertTimer(Timer, Hand);
}
/* Exit the dispatcher */
KiUnlockDispatcherDatabase(OldIrql);
KiTimerUnlock();
RETURN(Inserted);
@ -1998,7 +1998,7 @@ XBSYSAPI EXPORTNUM(158) xboxkrnl::NTSTATUS NTAPI xboxkrnl::KeWaitForMultipleObje
BOOLEAN WaitSatisfied;
NTSTATUS WaitStatus;
PKMUTANT ObjectMutant;
// Hack variable (remove this when the thread scheduler is here)
// Hack variable (remove this when the thread scheduler is here)
bool timeout_set = false;
do {
// Check if we need to let an APC run. This should immediately trigger APC interrupt via a call to UnlockDispatcherDatabase
@ -2074,8 +2074,8 @@ XBSYSAPI EXPORTNUM(158) xboxkrnl::NTSTATUS NTAPI xboxkrnl::KeWaitForMultipleObje
goto NoWait;
}
// Setup a timer for the thread but only once (for now)
if (!timeout_set) {
// Setup a timer for the thread but only once (for now)
if (!timeout_set) {
KiTimerLock();
PKTIMER Timer = &Thread->Timer;
PKWAIT_BLOCK WaitTimer = &Thread->TimerWaitBlock;
@ -2084,25 +2084,25 @@ XBSYSAPI EXPORTNUM(158) xboxkrnl::NTSTATUS NTAPI xboxkrnl::KeWaitForMultipleObje
Timer->Header.WaitListHead.Blink = &WaitTimer->WaitListEntry;
WaitTimer->NextWaitBlock = WaitBlock;
if (KiInsertTreeTimer(Timer, *Timeout) == FALSE) {
WaitStatus = (NTSTATUS)STATUS_TIMEOUT;
WaitStatus = (NTSTATUS)STATUS_TIMEOUT;
KiTimerUnlock();
goto NoWait;
}
// Boring, ensure that we only set the thread timer once. Otherwise, this will cause to insert the same
// thread timer over and over in the timer list, which will prevent KiTimerExpiration from removing these
// duplicated timers and thus it will attempt to endlessly remove the same unremoved timers, causing a deadlock.
// This can be removed once KiSwapThread and the kernel/user APCs are implemented
// Boring, ensure that we only set the thread timer once. Otherwise, this will cause to insert the same
// thread timer over and over in the timer list, which will prevent KiTimerExpiration from removing these
// duplicated timers and thus it will attempt to endlessly remove the same unremoved timers, causing a deadlock.
// This can be removed once KiSwapThread and the kernel/user APCs are implemented
timeout_set = true;
DueTime.QuadPart = Timer->DueTime.QuadPart;
DueTime.QuadPart = Timer->DueTime.QuadPart;
KiTimerUnlock();
}
// KiTimerExpiration has removed the timer but the objects were not signaled, so we have a timeout
// (remove this when the thread scheduler is here)
if (Thread->Timer.Header.Inserted == FALSE) {
// KiTimerExpiration has removed the timer but the objects were not signaled, so we have a timeout
// (remove this when the thread scheduler is here)
if (Thread->Timer.Header.Inserted == FALSE) {
WaitStatus = (NTSTATUS)(STATUS_TIMEOUT);
goto NoWait;
goto NoWait;
}
}
else {
@ -2167,8 +2167,8 @@ XBSYSAPI EXPORTNUM(158) xboxkrnl::NTSTATUS NTAPI xboxkrnl::KeWaitForMultipleObje
}
} while (TRUE);
// NOTE: we don't need to remove the wait blocks for the object and/or the timer because InsertTailList is disabled at
// the moment, which means they are never attached to the object wait list. TimerWaitBlock can also stay attached to the timer wait
// NOTE: we don't need to remove the wait blocks for the object and/or the timer because InsertTailList is disabled at
// the moment, which means they are never attached to the object wait list. TimerWaitBlock can also stay attached to the timer wait
// list since KiTimerExpiration disregards it for now.
// The waiting thead has been alerted, or an APC needs to be delivered
@ -2185,11 +2185,11 @@ NoWait:
// Unlock the database and return the status
//TODO: KiAdjustQuantumThread(Thread);
// Don't forget to remove the thread timer if the objects were signaled before the timer expired
// (remove this when the thread scheduler is here)
// Don't forget to remove the thread timer if the objects were signaled before the timer expired
// (remove this when the thread scheduler is here)
if (timeout_set && Thread->Timer.Header.Inserted == TRUE) {
KiTimerLock();
KxRemoveTreeTimer(&Thread->Timer);
KiTimerLock();
KxRemoveTreeTimer(&Thread->Timer);
KiTimerUnlock();
}
@ -2238,7 +2238,7 @@ XBSYSAPI EXPORTNUM(159) xboxkrnl::NTSTATUS NTAPI xboxkrnl::KeWaitForSingleObject
KWAIT_BLOCK StackWaitBlock;
PKWAIT_BLOCK WaitBlock = &StackWaitBlock;
NTSTATUS WaitStatus;
// Hack variable (remove this when the thread scheduler is here)
// Hack variable (remove this when the thread scheduler is here)
bool timeout_set = false;
do {
// Check if we need to let an APC run. This should immediately trigger APC interrupt via a call to UnlockDispatcherDatabase
@ -2311,11 +2311,11 @@ XBSYSAPI EXPORTNUM(159) xboxkrnl::NTSTATUS NTAPI xboxkrnl::KeWaitForSingleObject
KiTimerUnlock();
}
// KiTimerExpiration has removed the timer but the object was not signaled, so we have a timeout
// (remove this when the thread scheduler is here)
if (Thread->Timer.Header.Inserted == FALSE) {
// KiTimerExpiration has removed the timer but the object was not signaled, so we have a timeout
// (remove this when the thread scheduler is here)
if (Thread->Timer.Header.Inserted == FALSE) {
WaitStatus = (NTSTATUS)(STATUS_TIMEOUT);
goto NoWait;
goto NoWait;
}
}
else {
@ -2372,8 +2372,8 @@ XBSYSAPI EXPORTNUM(159) xboxkrnl::NTSTATUS NTAPI xboxkrnl::KeWaitForSingleObject
}
} while (TRUE);
// NOTE: we don't need to remove the wait blocks for the object and/or the timer because InsertTailList is disabled at
// the moment, which means they are never attached to the object wait list. TimerWaitBlock can also stay attached to the timer wait
// NOTE: we don't need to remove the wait blocks for the object and/or the timer because InsertTailList is disabled at
// the moment, which means they are never attached to the object wait list. TimerWaitBlock can also stay attached to the timer wait
// list since KiTimerExpiration disregards it for now.
// The waiting thead has been alerted, or an APC needs to be delivered
@ -2390,11 +2390,11 @@ NoWait:
// Unlock the database and return the status
//TODO: KiAdjustQuantumThread(Thread);
// Don't forget to remove the thread timer if the object was signaled before the timer expired
// (remove this when the thread scheduler is here)
// Don't forget to remove the thread timer if the object was signaled before the timer expired
// (remove this when the thread scheduler is here)
if (timeout_set && Thread->Timer.Header.Inserted == TRUE) {
KiTimerLock();
KxRemoveTreeTimer(&Thread->Timer);
KiTimerLock();
KxRemoveTreeTimer(&Thread->Timer);
KiTimerUnlock();
}

View File

@ -21,20 +21,20 @@
// *
// * All rights reserved
// *
// ******************************************************************
#pragma once
namespace xboxkrnl
{
VOID NTAPI KeSetSystemTime
(
IN PLARGE_INTEGER NewTime,
OUT PLARGE_INTEGER OldTime
);
VOID NTAPI KeInitializeTimer
(
IN PKTIMER Timer
);
}
// ******************************************************************
#pragma once
namespace xboxkrnl
{
VOID NTAPI KeSetSystemTime
(
IN PLARGE_INTEGER NewTime,
OUT PLARGE_INTEGER OldTime
);
VOID NTAPI KeInitializeTimer
(
IN PKTIMER Timer
);
}

File diff suppressed because it is too large Load Diff

View File

@ -17,138 +17,138 @@
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2018 Patrick van Logchem <pvanlogchem@gmail.com>
// * (c) 2018 Patrick van Logchem <pvanlogchem@gmail.com>
// * (c) 2019 ergo720
// *
// * All rights reserved
// *
// ******************************************************************
// ******************************************************************
#pragma once
#include <mutex>
// Workaround to avoid collisions with the VOID provided by Windows and the one of xboxkrnl
#ifdef VOID
#undef VOID
#endif
// ReactOS uses a size of 512, but disassembling the kernel reveals it to be 32 instead
#define TIMER_TABLE_SIZE 32
namespace xboxkrnl
{
typedef struct _KTIMER_TABLE_ENTRY
{
LIST_ENTRY Entry;
ULARGE_INTEGER Time;
} KTIMER_TABLE_ENTRY, *PKTIMER_TABLE_ENTRY;
// Actually, this lock isn't required, but because raising the irql to dpc level doesn't really prevent thread switching at the
// moment, we need it for now to prevent concurrent access to the timer table
typedef struct _KI_TIMER_LOCK
{
std::recursive_mutex Mtx;
int Acquired;
} KI_TIMER_LOCK;
VOID KiInitSystem();
VOID KiTimerLock();
VOID KiTimerUnlock();
VOID KiClockIsr
(
IN unsigned int ScalingFactor
);
VOID NTAPI KiCheckTimerTable
(
IN ULARGE_INTEGER CurrentTime
);
VOID KxInsertTimer
(
IN PKTIMER Timer,
IN ULONG Hand
);
VOID FASTCALL KiCompleteTimer
(
IN PKTIMER Timer,
IN ULONG Hand
);
VOID KiRemoveEntryTimer
(
IN PKTIMER Timer,
IN ULONG Hand
#pragma once
#include <mutex>
// Workaround to avoid collisions with the VOID provided by Windows and the one of xboxkrnl
#ifdef VOID
#undef VOID
#endif
// ReactOS uses a size of 512, but disassembling the kernel reveals it to be 32 instead
#define TIMER_TABLE_SIZE 32
namespace xboxkrnl
{
typedef struct _KTIMER_TABLE_ENTRY
{
LIST_ENTRY Entry;
ULARGE_INTEGER Time;
} KTIMER_TABLE_ENTRY, *PKTIMER_TABLE_ENTRY;
// Actually, this lock isn't required, but because raising the irql to dpc level doesn't really prevent thread switching at the
// moment, we need it for now to prevent concurrent access to the timer table
typedef struct _KI_TIMER_LOCK
{
std::recursive_mutex Mtx;
int Acquired;
} KI_TIMER_LOCK;
VOID KiInitSystem();
VOID KiTimerLock();
VOID KiTimerUnlock();
VOID KiClockIsr
(
IN unsigned int ScalingFactor
);
VOID KxRemoveTreeTimer
(
IN PKTIMER Timer
);
BOOLEAN FASTCALL KiInsertTimerTable
(
IN PKTIMER Timer,
IN ULONG Hand
);
BOOLEAN FASTCALL KiInsertTreeTimer
VOID NTAPI KiCheckTimerTable
(
IN ULARGE_INTEGER CurrentTime
);
VOID KxInsertTimer
(
IN PKTIMER Timer,
IN ULONG Hand
);
VOID FASTCALL KiCompleteTimer
(
IN PKTIMER Timer,
IN ULONG Hand
);
VOID KiRemoveEntryTimer
(
IN PKTIMER Timer,
IN ULONG Hand
);
VOID KxRemoveTreeTimer
(
IN PKTIMER Timer
);
BOOLEAN FASTCALL KiInsertTimerTable
(
IN PKTIMER Timer,
IN ULONG Hand
);
BOOLEAN FASTCALL KiInsertTreeTimer
(
IN PKTIMER Timer,
IN LARGE_INTEGER Interval
);
ULONG KiComputeTimerTableIndex
(
IN ULONGLONG Interval
);
BOOLEAN KiComputeDueTime
(
IN PKTIMER Timer,
IN LARGE_INTEGER DueTime,
OUT PULONG Hand
);
BOOLEAN FASTCALL KiSignalTimer
(
IN PKTIMER Timer
);
VOID NTAPI KiTimerExpiration
(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
VOID FASTCALL KiTimerListExpire
(
IN PLIST_ENTRY ExpiredListHead,
IN KIRQL OldIrql
);
VOID FASTCALL KiWaitSatisfyAll
);
ULONG KiComputeTimerTableIndex
(
IN ULONGLONG Interval
);
BOOLEAN KiComputeDueTime
(
IN PKTIMER Timer,
IN LARGE_INTEGER DueTime,
OUT PULONG Hand
);
BOOLEAN FASTCALL KiSignalTimer
(
IN PKTIMER Timer
);
VOID NTAPI KiTimerExpiration
(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
VOID FASTCALL KiTimerListExpire
(
IN PLIST_ENTRY ExpiredListHead,
IN KIRQL OldIrql
);
VOID FASTCALL KiWaitSatisfyAll
(
IN PKWAIT_BLOCK WaitBlock
);
};
extern const xboxkrnl::ULONG CLOCK_TIME_INCREMENT;
extern xboxkrnl::LIST_ENTRY KiWaitInListHead;
extern xboxkrnl::KTIMER_TABLE_ENTRY KiTimerTableListHead[TIMER_TABLE_SIZE];
extern xboxkrnl::KI_TIMER_LOCK KiTimerMtx;
);
};
extern const xboxkrnl::ULONG CLOCK_TIME_INCREMENT;
extern xboxkrnl::LIST_ENTRY KiWaitInListHead;
extern xboxkrnl::KTIMER_TABLE_ENTRY KiTimerTableListHead[TIMER_TABLE_SIZE];
extern xboxkrnl::KI_TIMER_LOCK KiTimerMtx;
#define KiLockDispatcherDatabase(OldIrql) \
*(OldIrql) = KeRaiseIrqlToDpcLevel()
*(OldIrql) = KeRaiseIrqlToDpcLevel()
#define KiLockDispatcherDatabaseAtDpcLevel() \
KeRaiseIrqlToDpcLevel()
@ -156,14 +156,14 @@ extern xboxkrnl::KI_TIMER_LOCK KiTimerMtx;
*(OldIrql) = KeRaiseIrqlToSynchLevel()
#define KiUnlockApcQueue(Thread, OldIrql) \
KfLowerIrql((OldIrql))
KfLowerIrql((OldIrql))
#define KiInsertWaitList(_WaitMode, _Thread) { \
PLIST_ENTRY _ListHead; \
_ListHead = &KiWaitInListHead; \
InsertTailList(_ListHead, &(_Thread)->WaitListEntry); \
}
}
#define KiWaitSatisfyMutant(_Object_, _Thread_) { \
(_Object_)->Header.SignalState -= 1; \
if ((_Object_)->Header.SignalState == 0) { \
@ -208,4 +208,4 @@ extern xboxkrnl::KI_TIMER_LOCK KiTimerMtx;
&(_Object_)->MutantListEntry); \
} \
} \
}
}

View File

@ -123,7 +123,7 @@ FLAGS2STR_START(CREATE_OPTION)
FLAG2STR(FILE_SEQUENTIAL_ONLY)
FLAG2STR(FILE_NO_INTERMEDIATE_BUFFERING)
FLAG2STR(FILE_SYNCHRONOUS_IO_ALERT)
FLAG2STR(FILE_SYNCHRONOUS_IO_NONALERT)
FLAG2STR(FILE_SYNCHRONOUS_IO_NONALERT)
FLAG2STR(FILE_NON_DIRECTORY_FILE)
FLAG2STR(FILE_CREATE_TREE_CONNECTION)
FLAG2STR(FILE_COMPLETE_IF_OPLOCKED)
@ -427,4 +427,4 @@ LOGRENDER(UNICODE_STRING)
LOGRENDER_MEMBER_SANITIZED(Buffer, wchar_t *, value.Length);
}
}; // end of namespace xboxkrnl;
}; // end of namespace xboxkrnl;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,7 @@
#include <xboxkrnl/xboxkrnl.h> // For PsCreateSystemThreadEx, etc.
#include <process.h> // For __beginthreadex(), etc.
#include <process.h> // For __beginthreadex(), etc.
#include <float.h> // For _controlfp constants
#include "Logging.h" // For LOG_FUNC()
@ -130,7 +130,7 @@ static unsigned int WINAPI PCSTProxy
SetEvent(hStartedEvent);
if (StartSuspended == TRUE) {
SuspendThread(GetCurrentThread());
SuspendThread(GetCurrentThread());
}
auto routine = (xboxkrnl::PKSYSTEM_ROUTINE)SystemRoutine;
@ -140,7 +140,7 @@ static unsigned int WINAPI PCSTProxy
// (To avoid repetitions, uncheck "Break when this exception type is thrown").
routine(xboxkrnl::PKSTART_ROUTINE(StartRoutine), StartContext);
// This will also handle thread notification :
// This will also handle thread notification :
LOG_TEST_CASE("Thread returned from SystemRoutine");
xboxkrnl::PsTerminateSystemThread(STATUS_SUCCESS);
@ -235,9 +235,9 @@ XBSYSAPI EXPORTNUM(255) xboxkrnl::NTSTATUS NTAPI xboxkrnl::PsCreateSystemThreadE
// use default kernel stack size if lesser specified
if (KernelStackSize < KERNEL_STACK_SIZE)
KernelStackSize = KERNEL_STACK_SIZE;
// Double the stack size, this is to account for the overhead HLE patching adds to the stack
KernelStackSize = KERNEL_STACK_SIZE;
// Double the stack size, this is to account for the overhead HLE patching adds to the stack
KernelStackSize *= 2;
// round up to the next page boundary if un-aligned
@ -260,17 +260,17 @@ XBSYSAPI EXPORTNUM(255) xboxkrnl::NTSTATUS NTAPI xboxkrnl::PsCreateSystemThreadE
iPCSTProxyParam->StartContext = StartContext;
iPCSTProxyParam->SystemRoutine = (PVOID)SystemRoutine; // NULL, XapiThreadStartup or unknown?
iPCSTProxyParam->StartSuspended = CreateSuspended;
iPCSTProxyParam->hStartedEvent = hStartedEvent;
/*
iPCSTProxyParam->hStartedEvent = hStartedEvent;
/*
// call thread notification routine(s)
if (g_iThreadNotificationCount != 0)
{
for (int i = 0; i < 16; i++)
{
// TODO: This is *very* wrong, ps notification routines are NOT the same as XApi notification routines
// TODO: XAPI notification routines are already handeld by XapiThreadStartup and don't need to be called by us
// TODO: This type of notification routine is PCREATE_THREAD_NOTIFY_ROUTINE, which takes an ETHREAD pointer as well as Thread ID as input
{
// TODO: This is *very* wrong, ps notification routines are NOT the same as XApi notification routines
// TODO: XAPI notification routines are already handeld by XapiThreadStartup and don't need to be called by us
// TODO: This type of notification routine is PCREATE_THREAD_NOTIFY_ROUTINE, which takes an ETHREAD pointer as well as Thread ID as input
// TODO: This is impossible to support currently, as we do not create or register Xbox ETHREAD objects, so we're better to skip it entirely!
XTL::XTHREAD_NOTIFY_PROC pfnNotificationRoutine = (XTL::XTHREAD_NOTIFY_PROC)g_pfnThreadNotification[i];
@ -282,8 +282,8 @@ XBSYSAPI EXPORTNUM(255) xboxkrnl::NTSTATUS NTAPI xboxkrnl::PsCreateSystemThreadE
pfnNotificationRoutine(TRUE);
}
}*/
}*/
*ThreadHandle = (HANDLE)_beginthreadex(NULL, KernelStackSize, PCSTProxy, iPCSTProxyParam, NULL, (unsigned int*)&dwThreadId);
// Note : DO NOT use iPCSTProxyParam anymore, since ownership is transferred to the proxy (which frees it too)
@ -325,9 +325,9 @@ XBSYSAPI EXPORTNUM(255) xboxkrnl::NTSTATUS NTAPI xboxkrnl::PsCreateSystemThreadE
if (ThreadId != NULL)
*ThreadId = (xboxkrnl::HANDLE)dwThreadId;
}
SwitchToThread();
}
SwitchToThread();
Sleep(10);
RETURN(STATUS_SUCCESS);
@ -403,7 +403,7 @@ XBSYSAPI EXPORTNUM(258) xboxkrnl::VOID NTAPI xboxkrnl::PsTerminateSystemThread
)
{
LOG_FUNC_ONE_ARG(ExitStatus);
/*
// call thread notification routine(s)
if (g_iThreadNotificationCount != 0)

View File

@ -49,20 +49,20 @@ namespace NtDll
// Prevent errors compiling
#undef RtlFillMemory
#undef RtlMoveMemory
#undef RtlZeroMemory
#undef EXCEPTION_NONCONTINUABLE
#undef EXCEPTION_UNWINDING
#undef EXCEPTION_EXIT_UNWIND
#undef EXCEPTION_STACK_INVALID
#undef EXCEPTION_NESTED_CALL
#undef EXCEPTION_TARGET_UNWIND
#undef EXCEPTION_COLLIDED_UNWIND
#undef RtlZeroMemory
#undef EXCEPTION_NONCONTINUABLE
#undef EXCEPTION_UNWINDING
#undef EXCEPTION_EXIT_UNWIND
#undef EXCEPTION_STACK_INVALID
#undef EXCEPTION_NESTED_CALL
#undef EXCEPTION_TARGET_UNWIND
#undef EXCEPTION_COLLIDED_UNWIND
#undef EXCEPTION_UNWIND
#endif // _WIN32
#endif // _WIN32
// Exception record flags
// Source: ReactOS
// Source: ReactOS
// NOTE: don't put these in xboxkrnl.h, they will conflict with the macros provided by Windows
#define EXCEPTION_NONCONTINUABLE 0x01
#define EXCEPTION_UNWINDING 0x02
@ -229,16 +229,16 @@ XBSYSAPI EXPORTNUM(264) xboxkrnl::VOID NTAPI xboxkrnl::RtlAssert
LOG_FUNC_ARG(FileName)
LOG_FUNC_ARG(LineNumber)
LOG_FUNC_ARG(Message)
LOG_FUNC_END;
std::stringstream ss;
ss << "RtlAssert() raised by emulated program\n" << FileName << ":" << LineNumber << ":" << FailedAssertion ;
if (Message) {
ss << " " << Message;
}
ss << ")";
LOG_FUNC_END;
std::stringstream ss;
ss << "RtlAssert() raised by emulated program\n" << FileName << ":" << LineNumber << ":" << FailedAssertion ;
if (Message) {
ss << " " << Message;
}
ss << ")";
PopupWarning(nullptr, ss.str().c_str());
}

View File

@ -29,7 +29,7 @@
#define LOG_PREFIX CXBXR_MODULE::XBOX
#include <xboxkrnl/xboxkrnl.h> // For XboxEEPROMKey, etc.
#include <xboxkrnl/xboxkrnl.h> // For XboxEEPROMKey, etc.
#include "Logging.h"
// Certificate Key

View File

@ -20,8 +20,8 @@
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// * (c) 2016 Patrick van Logchem <pvanlogchem@gmail.com>
// * (c) 2019 Jannik Vogel
// * (c) 2016 Patrick van Logchem <pvanlogchem@gmail.com>
// * (c) 2019 Jannik Vogel
// * (c) 2018-2019 ergo720
// *
// * All rights reserved
@ -35,7 +35,7 @@
#include "Logging.h" // For LOG_FUNC()
#include "EmuKrnlLogging.h"
#include "common\crypto\EmuSha.h" // For A_SHAInit, etc.
#include "common\crypto\LibRc4.h" // For RC4 Functions
#include "common\crypto\LibRc4.h" // For RC4 Functions
#include "common\crypto\EmuDes.h" // For DES Functions
#include "common\crypto\EmuRSA.h" // For RSA Functions
@ -44,7 +44,7 @@ namespace NtDll
{
#include "core\kernel\support\EmuNtDll.h"
};
// The following are the default implementations of the crypto functions
@ -209,8 +209,8 @@ xboxkrnl::ULONG NTAPI JumpedModExp
xboxkrnl::LPDWORD pD,
xboxkrnl::ULONG dwN
)
{
unsigned int len = dwN * 4;
{
unsigned int len = dwN * 4;
if (xbox_exp_mod((unsigned char*)pA, (const unsigned char*)pB, (const unsigned char*)pC, (const unsigned char*)pD, len, len, len, len)) {
return 1;
}
@ -233,12 +233,12 @@ xboxkrnl::VOID NTAPI JumpedKeyTable
xboxkrnl::PUCHAR pbKeyTable,
xboxkrnl::PUCHAR pbKey
)
{
{
if (dwCipher) {
mbedtls_des3_set3key_enc((mbedtls_des3_context*)pbKeyTable, pbKey);
}
}
else {
mbedtls_des_setkey_enc((mbedtls_des_context*)pbKeyTable, pbKey);
mbedtls_des_setkey_enc((mbedtls_des_context*)pbKeyTable, pbKey);
}
}
@ -250,10 +250,10 @@ xboxkrnl::VOID NTAPI JumpedBlockCrypt
xboxkrnl::PUCHAR pbKeyTable,
xboxkrnl::ULONG dwOp
)
{
if (dwCipher) {
mbedtls_des3_crypt_ecb((mbedtls_des3_context*)pbKeyTable, pbInput, pbOutput, dwOp);
}
{
if (dwCipher) {
mbedtls_des3_crypt_ecb((mbedtls_des3_context*)pbKeyTable, pbInput, pbOutput, dwOp);
}
else {
mbedtls_des_crypt_ecb((mbedtls_des_context*)pbKeyTable, pbInput, pbOutput, dwOp);
}
@ -269,16 +269,16 @@ xboxkrnl::VOID NTAPI JumpedBlockCryptCBC
xboxkrnl::ULONG dwOp,
xboxkrnl::PUCHAR pbFeedback
)
{
int ret;
{
int ret;
if (dwCipher) {
ret = mbedtls_des3_crypt_cbc((mbedtls_des3_context*)pbKeyTable, dwOp, dwInputLength, pbFeedback, pbInput, pbOutput);
}
if (dwCipher) {
ret = mbedtls_des3_crypt_cbc((mbedtls_des3_context*)pbKeyTable, dwOp, dwInputLength, pbFeedback, pbInput, pbOutput);
}
else {
ret = mbedtls_des_crypt_cbc((mbedtls_des_context*)pbKeyTable, dwOp, dwInputLength, pbFeedback, pbInput, pbOutput);
}
}
if (ret == MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH) {
EmuLog(LOG_LEVEL::DEBUG, "%s: dwInputLength was not a multiple of 8 (it was %lu)", __func__, dwInputLength);
}

View File

@ -79,11 +79,11 @@ XBSYSAPI EXPORTNUM(327) xboxkrnl::NTSTATUS NTAPI xboxkrnl::XeLoadSection
VAddr BaseAddress = (VAddr)Section->VirtualAddress;
size_t SectionSize = (VAddr)Section->VirtualSize;
ret = g_VMManager.XbAllocateVirtualMemory(&BaseAddress, 0, &SectionSize, XBOX_MEM_COMMIT, XBOX_PAGE_EXECUTE_READWRITE);
ret = g_VMManager.XbAllocateVirtualMemory(&BaseAddress, 0, &SectionSize, XBOX_MEM_COMMIT, XBOX_PAGE_EXECUTE_READWRITE);
if (ret != STATUS_SUCCESS) {
RETURN(ret);
}
// Clear the memory the section requires
memset(Section->VirtualAddress, 0, Section->VirtualSize);
// Copy the section data
@ -162,9 +162,9 @@ XBSYSAPI EXPORTNUM(328) xboxkrnl::NTSTATUS NTAPI xboxkrnl::XeUnloadSection
// ******************************************************************
// * 0x0163 - XePublicKeyData
// ******************************************************************
// Define XePublicKeyData: This will be overwritten by the correct key for the given Xbe at runtime
XBSYSAPI EXPORTNUM(355) xboxkrnl::UCHAR xboxkrnl::XePublicKeyData[284] = { 0 };
// ******************************************************************
// Define XePublicKeyData: This will be overwritten by the correct key for the given Xbe at runtime
XBSYSAPI EXPORTNUM(355) xboxkrnl::UCHAR xboxkrnl::XePublicKeyData[284] = { 0 };
// We are allowed to use the real RSA public key since it cannot be used to sign data, only verify it -> it's not secret/private
xboxkrnl::UCHAR xboxkrnl::XePublicKeyDataRetail[284] = {
@ -191,58 +191,58 @@ xboxkrnl::UCHAR xboxkrnl::XePublicKeyDataRetail[284] = {
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00
};
// Chihiro Game Public Key
xboxkrnl::UCHAR xboxkrnl::XePublicKeyDataChihiroGame[284] = {
0x52, 0x53, 0x41, 0x31, 0x08, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x9B, 0x83, 0xD4, 0xD5,
0xDE, 0x16, 0x25, 0x8E, 0xE5, 0x15, 0xF2, 0x18, 0x9D, 0x19, 0x1C, 0xF8,
0xFE, 0x91, 0xA5, 0x83, 0xAE, 0xA5, 0xA8, 0x95, 0x3F, 0x01, 0xB2, 0xC9,
0x34, 0xFB, 0xC7, 0x51, 0x2D, 0xAC, 0xFF, 0x38, 0xE6, 0xB6, 0x7B, 0x08,
0x4A, 0xDF, 0x98, 0xA3, 0xFD, 0x31, 0x81, 0xBF, 0xAA, 0xD1, 0x62, 0x58,
0xC0, 0x6C, 0x8F, 0x8E, 0xCD, 0x96, 0xCE, 0x6D, 0x03, 0x44, 0x59, 0x93,
0xCE, 0xEA, 0x8D, 0xF4, 0xD4, 0x6F, 0x6F, 0x34, 0x5D, 0x50, 0xF1, 0xAE,
0x99, 0x7F, 0x1D, 0x92, 0x15, 0xF3, 0x6B, 0xDB, 0xF9, 0x95, 0x8B, 0x3F,
0x54, 0xAD, 0x37, 0xB5, 0x4F, 0x0A, 0x58, 0x7B, 0x48, 0xA2, 0x9F, 0x9E,
0xA3, 0x16, 0xC8, 0xBD, 0x37, 0xDA, 0x9A, 0x37, 0xE6, 0x3F, 0x10, 0x1B,
0xA8, 0x4F, 0xA3, 0x14, 0xFA, 0xBE, 0x12, 0xFB, 0xD7, 0x19, 0x4C, 0xED,
0xAD, 0xA2, 0x95, 0x8F, 0x39, 0x8C, 0xC4, 0x69, 0x0F, 0x7D, 0xB8, 0x84,
0x0A, 0x99, 0x5C, 0x53, 0x2F, 0xDE, 0xF2, 0x1B, 0xC5, 0x1D, 0x4C, 0x43,
0x3C, 0x97, 0xA7, 0xBA, 0x8F, 0xC3, 0x22, 0x67, 0x39, 0xC2, 0x62, 0x74,
0x3A, 0x0C, 0xB5, 0x57, 0x01, 0x3A, 0x67, 0xC6, 0xDE, 0x0C, 0x0B, 0xF6,
0x08, 0x01, 0x64, 0xDB, 0xBD, 0x81, 0xE4, 0xDC, 0x09, 0x2E, 0xD0, 0xF1,
0xD0, 0xD6, 0x1E, 0xBA, 0x38, 0x36, 0xF4, 0x4A, 0xDD, 0xCA, 0x39, 0xEB,
0x76, 0xCF, 0x95, 0xDC, 0x48, 0x4C, 0xF2, 0x43, 0x8C, 0xD9, 0x44, 0x26,
0x7A, 0x9E, 0xEB, 0x99, 0xA3, 0xD8, 0xFB, 0x30, 0xA8, 0x14, 0x42, 0x82,
0x8D, 0xB4, 0x31, 0xB3, 0x1A, 0xD5, 0x2B, 0xF6, 0x32, 0xBC, 0x62, 0xC0,
0xFE, 0x81, 0x20, 0x49, 0xE7, 0xF7, 0x58, 0x2F, 0x2D, 0xA6, 0x1B, 0x41,
0x62, 0xC7, 0xE0, 0x32, 0x02, 0x5D, 0x82, 0xEC, 0xA3, 0xE4, 0x6C, 0x9B,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// Chihiro bootloader public key (Segaboot)
xboxkrnl::UCHAR xboxkrnl::XePublicKeyDataChihiroBoot[284] = {
0x52, 0x53, 0x41, 0x31, 0x08, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x6B, 0x7B, 0x38, 0x78,
0xE3, 0x16, 0x04, 0x88, 0x1D, 0xAF, 0x63, 0x4E, 0x23, 0xDB, 0x10, 0x14,
0xB4, 0x52, 0x87, 0xEB, 0xE3, 0x37, 0xC2, 0x35, 0x6E, 0x38, 0x08, 0xDC,
0x07, 0xC5, 0x92, 0x17, 0xC0, 0xBF, 0xDB, 0xF5, 0x9E, 0x72, 0xDB, 0x2F,
0x98, 0x93, 0x6E, 0x98, 0x5E, 0xD9, 0x69, 0x80, 0x17, 0xFC, 0x0C, 0x72,
0x2E, 0xE6, 0x75, 0x85, 0x48, 0xEA, 0xBD, 0xDA, 0x6E, 0x82, 0xD9, 0xFB,
0x10, 0xAA, 0x11, 0xEE, 0xB5, 0xC1, 0xF2, 0x53, 0xD6, 0xF0, 0xD3, 0x4B,
0xC2, 0x11, 0x4F, 0x8A, 0x18, 0xFB, 0xB7, 0x36, 0xFC, 0xDD, 0xD0, 0xBF,
0x5C, 0x32, 0x44, 0x40, 0xEB, 0x92, 0x70, 0xA4, 0xEF, 0x3A, 0xAB, 0x78,
0x66, 0x1A, 0x03, 0x0A, 0x9E, 0xC5, 0x3A, 0xB7, 0x8F, 0xE5, 0xB1, 0x5E,
0x44, 0x15, 0xBA, 0x42, 0xD9, 0x10, 0x2A, 0x60, 0x93, 0x47, 0x4C, 0x5B,
0xE1, 0x24, 0x04, 0x1E, 0x5C, 0x95, 0xB2, 0x17, 0x34, 0xD2, 0x37, 0x5F,
0x85, 0x83, 0x62, 0x8D, 0x6E, 0x90, 0x69, 0x06, 0xB9, 0xFB, 0x7A, 0x24,
0x8A, 0xE6, 0xCC, 0x77, 0x1E, 0x0A, 0x8C, 0x2B, 0x3B, 0xA2, 0x33, 0x79,
0x24, 0x8C, 0xD3, 0x88, 0x01, 0x3A, 0x38, 0x7F, 0xF0, 0xAB, 0x9E, 0x2F,
0x74, 0xCE, 0x50, 0xD1, 0xC2, 0x00, 0x57, 0xD3, 0xA7, 0x09, 0x45, 0x36,
0xFA, 0xC1, 0xC7, 0x1B, 0x65, 0xAD, 0x98, 0x9C, 0x63, 0xED, 0xBA, 0x99,
0x9B, 0x07, 0x3E, 0x57, 0xBD, 0xB5, 0x52, 0x44, 0x72, 0x09, 0x43, 0xE0,
0x5C, 0x35, 0xCC, 0xE4, 0xE0, 0x85, 0x6A, 0x61, 0xAA, 0xF5, 0x0D, 0x1E,
0xE7, 0x8F, 0xB0, 0xB9, 0xE3, 0xC3, 0x83, 0x10, 0x6C, 0x2F, 0x5D, 0xD4,
0xAB, 0x2D, 0xAB, 0x4D, 0xCE, 0xC9, 0x7F, 0x52, 0x39, 0x13, 0xED, 0x44,
0x06, 0x23, 0x2F, 0x62, 0xFF, 0xA1, 0x2B, 0xEE, 0x07, 0x98, 0x7D, 0xBC,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// Chihiro Game Public Key
xboxkrnl::UCHAR xboxkrnl::XePublicKeyDataChihiroGame[284] = {
0x52, 0x53, 0x41, 0x31, 0x08, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x9B, 0x83, 0xD4, 0xD5,
0xDE, 0x16, 0x25, 0x8E, 0xE5, 0x15, 0xF2, 0x18, 0x9D, 0x19, 0x1C, 0xF8,
0xFE, 0x91, 0xA5, 0x83, 0xAE, 0xA5, 0xA8, 0x95, 0x3F, 0x01, 0xB2, 0xC9,
0x34, 0xFB, 0xC7, 0x51, 0x2D, 0xAC, 0xFF, 0x38, 0xE6, 0xB6, 0x7B, 0x08,
0x4A, 0xDF, 0x98, 0xA3, 0xFD, 0x31, 0x81, 0xBF, 0xAA, 0xD1, 0x62, 0x58,
0xC0, 0x6C, 0x8F, 0x8E, 0xCD, 0x96, 0xCE, 0x6D, 0x03, 0x44, 0x59, 0x93,
0xCE, 0xEA, 0x8D, 0xF4, 0xD4, 0x6F, 0x6F, 0x34, 0x5D, 0x50, 0xF1, 0xAE,
0x99, 0x7F, 0x1D, 0x92, 0x15, 0xF3, 0x6B, 0xDB, 0xF9, 0x95, 0x8B, 0x3F,
0x54, 0xAD, 0x37, 0xB5, 0x4F, 0x0A, 0x58, 0x7B, 0x48, 0xA2, 0x9F, 0x9E,
0xA3, 0x16, 0xC8, 0xBD, 0x37, 0xDA, 0x9A, 0x37, 0xE6, 0x3F, 0x10, 0x1B,
0xA8, 0x4F, 0xA3, 0x14, 0xFA, 0xBE, 0x12, 0xFB, 0xD7, 0x19, 0x4C, 0xED,
0xAD, 0xA2, 0x95, 0x8F, 0x39, 0x8C, 0xC4, 0x69, 0x0F, 0x7D, 0xB8, 0x84,
0x0A, 0x99, 0x5C, 0x53, 0x2F, 0xDE, 0xF2, 0x1B, 0xC5, 0x1D, 0x4C, 0x43,
0x3C, 0x97, 0xA7, 0xBA, 0x8F, 0xC3, 0x22, 0x67, 0x39, 0xC2, 0x62, 0x74,
0x3A, 0x0C, 0xB5, 0x57, 0x01, 0x3A, 0x67, 0xC6, 0xDE, 0x0C, 0x0B, 0xF6,
0x08, 0x01, 0x64, 0xDB, 0xBD, 0x81, 0xE4, 0xDC, 0x09, 0x2E, 0xD0, 0xF1,
0xD0, 0xD6, 0x1E, 0xBA, 0x38, 0x36, 0xF4, 0x4A, 0xDD, 0xCA, 0x39, 0xEB,
0x76, 0xCF, 0x95, 0xDC, 0x48, 0x4C, 0xF2, 0x43, 0x8C, 0xD9, 0x44, 0x26,
0x7A, 0x9E, 0xEB, 0x99, 0xA3, 0xD8, 0xFB, 0x30, 0xA8, 0x14, 0x42, 0x82,
0x8D, 0xB4, 0x31, 0xB3, 0x1A, 0xD5, 0x2B, 0xF6, 0x32, 0xBC, 0x62, 0xC0,
0xFE, 0x81, 0x20, 0x49, 0xE7, 0xF7, 0x58, 0x2F, 0x2D, 0xA6, 0x1B, 0x41,
0x62, 0xC7, 0xE0, 0x32, 0x02, 0x5D, 0x82, 0xEC, 0xA3, 0xE4, 0x6C, 0x9B,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// Chihiro bootloader public key (Segaboot)
xboxkrnl::UCHAR xboxkrnl::XePublicKeyDataChihiroBoot[284] = {
0x52, 0x53, 0x41, 0x31, 0x08, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x6B, 0x7B, 0x38, 0x78,
0xE3, 0x16, 0x04, 0x88, 0x1D, 0xAF, 0x63, 0x4E, 0x23, 0xDB, 0x10, 0x14,
0xB4, 0x52, 0x87, 0xEB, 0xE3, 0x37, 0xC2, 0x35, 0x6E, 0x38, 0x08, 0xDC,
0x07, 0xC5, 0x92, 0x17, 0xC0, 0xBF, 0xDB, 0xF5, 0x9E, 0x72, 0xDB, 0x2F,
0x98, 0x93, 0x6E, 0x98, 0x5E, 0xD9, 0x69, 0x80, 0x17, 0xFC, 0x0C, 0x72,
0x2E, 0xE6, 0x75, 0x85, 0x48, 0xEA, 0xBD, 0xDA, 0x6E, 0x82, 0xD9, 0xFB,
0x10, 0xAA, 0x11, 0xEE, 0xB5, 0xC1, 0xF2, 0x53, 0xD6, 0xF0, 0xD3, 0x4B,
0xC2, 0x11, 0x4F, 0x8A, 0x18, 0xFB, 0xB7, 0x36, 0xFC, 0xDD, 0xD0, 0xBF,
0x5C, 0x32, 0x44, 0x40, 0xEB, 0x92, 0x70, 0xA4, 0xEF, 0x3A, 0xAB, 0x78,
0x66, 0x1A, 0x03, 0x0A, 0x9E, 0xC5, 0x3A, 0xB7, 0x8F, 0xE5, 0xB1, 0x5E,
0x44, 0x15, 0xBA, 0x42, 0xD9, 0x10, 0x2A, 0x60, 0x93, 0x47, 0x4C, 0x5B,
0xE1, 0x24, 0x04, 0x1E, 0x5C, 0x95, 0xB2, 0x17, 0x34, 0xD2, 0x37, 0x5F,
0x85, 0x83, 0x62, 0x8D, 0x6E, 0x90, 0x69, 0x06, 0xB9, 0xFB, 0x7A, 0x24,
0x8A, 0xE6, 0xCC, 0x77, 0x1E, 0x0A, 0x8C, 0x2B, 0x3B, 0xA2, 0x33, 0x79,
0x24, 0x8C, 0xD3, 0x88, 0x01, 0x3A, 0x38, 0x7F, 0xF0, 0xAB, 0x9E, 0x2F,
0x74, 0xCE, 0x50, 0xD1, 0xC2, 0x00, 0x57, 0xD3, 0xA7, 0x09, 0x45, 0x36,
0xFA, 0xC1, 0xC7, 0x1B, 0x65, 0xAD, 0x98, 0x9C, 0x63, 0xED, 0xBA, 0x99,
0x9B, 0x07, 0x3E, 0x57, 0xBD, 0xB5, 0x52, 0x44, 0x72, 0x09, 0x43, 0xE0,
0x5C, 0x35, 0xCC, 0xE4, 0xE0, 0x85, 0x6A, 0x61, 0xAA, 0xF5, 0x0D, 0x1E,
0xE7, 0x8F, 0xB0, 0xB9, 0xE3, 0xC3, 0x83, 0x10, 0x6C, 0x2F, 0x5D, 0xD4,
0xAB, 0x2D, 0xAB, 0x4D, 0xCE, 0xC9, 0x7F, 0x52, 0x39, 0x13, 0xED, 0x44,
0x06, 0x23, 0x2F, 0x62, 0xFF, 0xA1, 0x2B, 0xEE, 0x07, 0x98, 0x7D, 0xBC,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@
#include "Cxbx.h"
#include "common\AddressRanges.h"
#include "common/ReserveAddressRanges.h"
#include "common\xbe\Xbe.h"
#include "common\xbe\Xbe.h"
#include "Logging.h"
#undef FIELD_OFFSET // prevent macro redefinition warnings
@ -81,11 +81,11 @@ extern "C" {
// (called "$$XTIMAG") at 0x031C5260+0x00002800, which would
// fit in 51 MB. If we ever encounter an even larger XBE, this
// value will have to be increased likewise (maybe up to 64 MB
// for XBOX_MEMORY_SIZE or even 128 MB for CHIHIRO_MEMORY_SIZE).
#ifdef CXBXR_EMU
#define XBE_MAX_VA (128 * ONE_MB)
#else
#define XBE_MAX_VA (64 * ONE_MB)
// for XBOX_MEMORY_SIZE or even 128 MB for CHIHIRO_MEMORY_SIZE).
#ifdef CXBXR_EMU
#define XBE_MAX_VA (128 * ONE_MB)
#else
#define XBE_MAX_VA (64 * ONE_MB)
#endif
/*! base address of Cxbx host executable, see Cxbx project options, Linker, Advanced, Base Address */
@ -142,12 +142,12 @@ bool CxbxKrnlVerifyVersion(const char *szVersion);
extern bool g_bIsDebugKernel;
bool CreateSettings();
bool CreateSettings();
bool HandleFirstLaunch();
bool HandleFirstLaunch();
/*! Cxbx Kernel Entry Point */
void CxbxKrnlEmulate(unsigned int system, blocks_reserved_t blocks_reserved);
void CxbxKrnlEmulate(unsigned int system, blocks_reserved_t blocks_reserved);
/*! initialize emulation */
__declspec(noreturn) void CxbxKrnlInit(void *pTLSData, Xbe::TLS *pTLS, Xbe::LibraryVersion *LibraryVersion, DebugMode DbgMode, const char *szDebugFilename, Xbe::Header *XbeHeader, uint32_t XbeHeaderSize, void (*Entry)(), int BootFlags);
@ -187,7 +187,7 @@ void CxbxKrnlNoFunc();
void CxbxInitPerformanceCounters(); // Implemented in EmuKrnlKe.cpp
void CxbxInitFilePaths();
// For emulation usage only
bool CxbxLockFilePath();
void CxbxUnlockFilePath();

View File

@ -81,7 +81,7 @@ typedef union _MMPTE
/* PFN entry used by the memory manager */
typedef union _XBOX_PFN
typedef union _XBOX_PFN
{
ULONG Default;
struct {
@ -115,14 +115,14 @@ typedef enum _PageType
ContiguousType, // Used by MmAllocateContiguousMemoryEx and others
DebuggerType, // xbdm-related
COUNTtype // The size of the array containing the page usage per type
}PageType;
/* enum describing the memory layouts the memory manager can use */
typedef enum _MmLayout
}PageType;
/* enum describing the memory layouts the memory manager can use */
typedef enum _MmLayout
{
MmChihiro = 1,
MmDebug,
MmChihiro = 1,
MmDebug,
MmRetail,
}MmLayout;
@ -213,10 +213,10 @@ class PhysicalMemory
// number of allocated bytes for the nv2a instance memory
size_t m_NV2AInstanceMemoryBytes = NV2A_INSTANCE_PAGE_COUNT << PAGE_SHIFT;
// boolean that indicates that the extra 64 MiB on a devkit can be used for heap/Nt allocations
bool m_bAllowNonDebuggerOnTop64MiB = true;
// the memory layout that the VMManager is emulating
bool m_MmLayoutChihiro = false;
bool m_MmLayoutDebug = false;
bool m_bAllowNonDebuggerOnTop64MiB = true;
// the memory layout that the VMManager is emulating
bool m_MmLayoutChihiro = false;
bool m_MmLayoutDebug = false;
bool m_MmLayoutRetail = false;

View File

@ -27,9 +27,9 @@
// Acknowledgment:
// Some of the functions with the suffix VMA are from the vm_manager.cpp file of the citra emulator
// Copyright 2015 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Copyright 2015 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file of Citra at https://github.com/citra-emu/citra/blob/master/license.txt.
@ -42,10 +42,10 @@
#include "core\kernel\exports\EmuKrnl.h" // For InitializeListHead(), etc.
#include "common/util/cliConfig.hpp" // For GetSessionID
#include <assert.h>
// Temporary usage for need ReserveAddressRanges func with cxbx.exe's emulation.
#ifndef CXBXR_EMU
#include "common/ReserveAddressRanges.h"
#endif
// Temporary usage for need ReserveAddressRanges func with cxbx.exe's emulation.
#ifndef CXBXR_EMU
#include "common/ReserveAddressRanges.h"
#endif
constexpr char str_persistent_memory_s[] = "PersistentMemory-s";
@ -79,13 +79,13 @@ void VMManager::Initialize(unsigned int SystemType, int BootFlags, blocks_reserv
if ((BootFlags & BOOT_QUICK_REBOOT) == 0) {
g_EmuShared->SetMmLayout(&SystemType);
}
else {
else {
g_EmuShared->GetMmLayout(&SystemType);
}
}
m_MmLayoutChihiro = (SystemType == SYSTEM_CHIHIRO);
m_MmLayoutDebug = (SystemType == SYSTEM_DEVKIT);
m_MmLayoutRetail = (SystemType == SYSTEM_XBOX);
m_MmLayoutRetail = (SystemType == SYSTEM_XBOX);
// Set up the critical section to synchronize accesses
InitializeCriticalSectionAndSpinCount(&m_CriticalSection, 0x400);
@ -99,31 +99,31 @@ void VMManager::Initialize(unsigned int SystemType, int BootFlags, blocks_reserv
ConstructMemoryRegion(SYSTEM_MEMORY_BASE, SYSTEM_MEMORY_SIZE, SystemRegion);
ConstructMemoryRegion(DEVKIT_MEMORY_BASE, DEVKIT_MEMORY_SIZE, DevkitRegion);
// Commit all the memory reserved by the loader for the PTs
// We are looping here because memory-reservation happens in 64 KiB increments
for (int i = 0; i < 64; i++) {
LPVOID ret = VirtualAlloc((LPVOID)(PAGE_TABLES_BASE + i * m_AllocationGranularity), m_AllocationGranularity, MEM_COMMIT, PAGE_READWRITE);
if (ret != (LPVOID)(PAGE_TABLES_BASE + i * KiB(64))) {
CxbxKrnlCleanup("VirtualAlloc failed to commit the memory for the page tables. The error was 0x%08X", GetLastError());
}
}
// Commit all the memory reserved by the loader for the PTs
// We are looping here because memory-reservation happens in 64 KiB increments
for (int i = 0; i < 64; i++) {
LPVOID ret = VirtualAlloc((LPVOID)(PAGE_TABLES_BASE + i * m_AllocationGranularity), m_AllocationGranularity, MEM_COMMIT, PAGE_READWRITE);
if (ret != (LPVOID)(PAGE_TABLES_BASE + i * KiB(64))) {
CxbxKrnlCleanup("VirtualAlloc failed to commit the memory for the page tables. The error was 0x%08X", GetLastError());
}
}
// Construct VMAs base on reserved bit indexes for devkit and system region blocks.
// See "blocks_reserved_t" notes.
if (SystemType == SYSTEM_DEVKIT) {
for (unsigned int i = BLOCK_REGION_DEVKIT_INDEX_BEGIN; i < BLOCK_REGION_DEVKIT_INDEX_END; i++) {
if ((blocks_reserved[i / 32] & (1 << (i % 32))) == 0) {
// The loader was unable to reserve this block, so discard it from the memory region
ConstructVMA(DEVKIT_MEMORY_BASE + i * KiB(64), KiB(64), DevkitRegion, ReservedVma, false);
}
}
}
for (unsigned int i = BLOCK_REGION_SYSTEM_INDEX_BEGIN; i < BLOCK_REGION_SYSTEM_INDEX_END; i++) {
if ((blocks_reserved[i / 32] & (1 << (i % 32))) == 0) {
// The loader was unable to reserve this block, so discard it from the memory region
ConstructVMA(SYSTEM_MEMORY_BASE + i * KiB(64), KiB(64), SystemRegion, ReservedVma, false);
}
}
if (SystemType == SYSTEM_DEVKIT) {
for (unsigned int i = BLOCK_REGION_DEVKIT_INDEX_BEGIN; i < BLOCK_REGION_DEVKIT_INDEX_END; i++) {
if ((blocks_reserved[i / 32] & (1 << (i % 32))) == 0) {
// The loader was unable to reserve this block, so discard it from the memory region
ConstructVMA(DEVKIT_MEMORY_BASE + i * KiB(64), KiB(64), DevkitRegion, ReservedVma, false);
}
}
}
for (unsigned int i = BLOCK_REGION_SYSTEM_INDEX_BEGIN; i < BLOCK_REGION_SYSTEM_INDEX_END; i++) {
if ((blocks_reserved[i / 32] & (1 << (i % 32))) == 0) {
// The loader was unable to reserve this block, so discard it from the memory region
ConstructVMA(SYSTEM_MEMORY_BASE + i * KiB(64), KiB(64), SystemRegion, ReservedVma, false);
}
}
// Set up general memory variables according to the xbe type
if (m_MmLayoutChihiro)
@ -248,7 +248,7 @@ void VMManager::InitializeSystemAllocations()
}
addr = (VAddr)CONVERT_PFN_TO_CONTIGUOUS_PHYSICAL(pfn);
AllocateContiguousMemoryInternal(pfn_end - pfn + 1, pfn, pfn_end, 1, XBOX_PAGE_READWRITE);
AllocateContiguousMemoryInternal(pfn_end - pfn + 1, pfn, pfn_end, 1, XBOX_PAGE_READWRITE);
PersistMemory(addr, (pfn_end - pfn + 1) << PAGE_SHIFT, true);
if (m_MmLayoutDebug) { m_PhysicalPagesAvailable += 16; m_DebuggerPagesAvailable -= 16; }
@ -266,9 +266,9 @@ void VMManager::InitializeSystemAllocations()
PointerPte = GetPteAddress(addr);
EndingPte = GetPteAddress(CONVERT_PFN_TO_CONTIGUOUS_PHYSICAL(pfn_end));
AllocateContiguousMemoryInternal(pfn_end - pfn + 1, pfn, pfn_end, 1, XBOX_PAGE_READWRITE);
AllocateContiguousMemoryInternal(pfn_end - pfn + 1, pfn, pfn_end, 1, XBOX_PAGE_READWRITE);
while (PointerPte <= EndingPte) {
DISABLE_CACHING(*PointerPte);
DISABLE_CACHING(*PointerPte);
PointerPte++;
}
@ -282,95 +282,95 @@ void VMManager::InitializeSystemAllocations()
PointerPte = GetPteAddress(addr);
EndingPte = GetPteAddress(CONVERT_PFN_TO_CONTIGUOUS_PHYSICAL(pfn_end));
AllocateContiguousMemoryInternal(pfn_end - pfn + 1, pfn, pfn_end, 1, XBOX_PAGE_READWRITE);
AllocateContiguousMemoryInternal(pfn_end - pfn + 1, pfn, pfn_end, 1, XBOX_PAGE_READWRITE);
while (PointerPte <= EndingPte) {
DISABLE_CACHING(*PointerPte);
DISABLE_CACHING(*PointerPte);
PointerPte++;
}
}
}
void VMManager::GetPersistentMemory()
{
if (m_PersistentMemoryHandle != nullptr) {
CxbxKrnlCleanup("Persistent memory is already opened!");
return;
}
void VMManager::GetPersistentMemory()
{
if (m_PersistentMemoryHandle != nullptr) {
CxbxKrnlCleanup("Persistent memory is already opened!");
return;
}
std::string persisted_mem_sid = str_persistent_memory_s + std::to_string(cli_config::GetSessionID());
m_PersistentMemoryHandle = OpenFileMapping(FILE_MAP_READ, FALSE, persisted_mem_sid.c_str());
if (m_PersistentMemoryHandle == nullptr) {
CxbxKrnlCleanup("Couldn't open persistent memory! OpenFileMapping failed with error 0x%08X", GetLastError());
return;
}
m_PersistentMemoryHandle = OpenFileMapping(FILE_MAP_READ, FALSE, persisted_mem_sid.c_str());
if (m_PersistentMemoryHandle == nullptr) {
CxbxKrnlCleanup("Couldn't open persistent memory! OpenFileMapping failed with error 0x%08X", GetLastError());
return;
}
}
void VMManager::RestorePersistentMemory()
{
if (m_PersistentMemoryHandle == nullptr) {
CxbxKrnlCleanup("Persistent memory is not open!");
return;
}
void VMManager::RestorePersistentMemory()
{
if (m_PersistentMemoryHandle == nullptr) {
CxbxKrnlCleanup("Persistent memory is not open!");
return;
}
PersistedMemory* persisted_mem = (PersistedMemory*)MapViewOfFile(m_PersistentMemoryHandle, FILE_MAP_READ, 0, 0, 0);
if (persisted_mem == nullptr) {
CxbxKrnlCleanup("Couldn't restore persistent memory! MapViewOfFile failed with error 0x%08X", GetLastError());
return;
}
PersistedMemory* persisted_mem = (PersistedMemory*)MapViewOfFile(m_PersistentMemoryHandle, FILE_MAP_READ, 0, 0, 0);
if (persisted_mem == nullptr) {
CxbxKrnlCleanup("Couldn't restore persistent memory! MapViewOfFile failed with error 0x%08X", GetLastError());
return;
}
if (persisted_mem->LaunchFrameAddresses[0] != 0 && IS_PHYSICAL_ADDRESS(persisted_mem->LaunchFrameAddresses[0])) {
xboxkrnl::LaunchDataPage = (xboxkrnl::PLAUNCH_DATA_PAGE)persisted_mem->LaunchFrameAddresses[0];
EmuLog(LOG_LEVEL::INFO, "Restored LaunchDataPage\n");
}
if (persisted_mem->LaunchFrameAddresses[0] != 0 && IS_PHYSICAL_ADDRESS(persisted_mem->LaunchFrameAddresses[0])) {
xboxkrnl::LaunchDataPage = (xboxkrnl::PLAUNCH_DATA_PAGE)persisted_mem->LaunchFrameAddresses[0];
EmuLog(LOG_LEVEL::INFO, "Restored LaunchDataPage\n");
}
if (persisted_mem->LaunchFrameAddresses[1] != 0 && IS_PHYSICAL_ADDRESS(persisted_mem->LaunchFrameAddresses[1])) {
xboxkrnl::AvSavedDataAddress = (xboxkrnl::PVOID)persisted_mem->LaunchFrameAddresses[1];
EmuLog(LOG_LEVEL::INFO, "Restored Framebuffer\n");
}
if (persisted_mem->LaunchFrameAddresses[1] != 0 && IS_PHYSICAL_ADDRESS(persisted_mem->LaunchFrameAddresses[1])) {
xboxkrnl::AvSavedDataAddress = (xboxkrnl::PVOID)persisted_mem->LaunchFrameAddresses[1];
EmuLog(LOG_LEVEL::INFO, "Restored Framebuffer\n");
}
MMPTE pte;
PFN pfn;
for (unsigned int i = 0; i < persisted_mem->NumOfPtes; i++) {
pte.Default = persisted_mem->Data[persisted_mem->NumOfPtes + i];
assert(pte.Hardware.Valid != 0 && pte.Hardware.Persist != 0);
memcpy(GetPteAddress(persisted_mem->Data[i]), &pte.Default, sizeof(MMPTE));
RemoveFree(1, &pfn, 0, pte.Hardware.PFN, pte.Hardware.PFN);
if (m_MmLayoutChihiro) {
memcpy(CHIHIRO_PFN_ELEMENT(pte.Hardware.PFN),
&((PXBOX_PFN)&persisted_mem->Data[(persisted_mem->NumOfPtes * 2) + (persisted_mem->NumOfPtes - 32) * KiB(1)])[pte.Hardware.PFN],
sizeof(XBOX_PFN));
if ((uint32_t*)persisted_mem->Data[i] < (uint32_t*)CHIHIRO_PFN_ADDRESS) {
memcpy((void*)(persisted_mem->Data[i]), &persisted_mem->Data[persisted_mem->NumOfPtes * 2 + i * KiB(1)], PAGE_SIZE);
}
}
else {
memcpy(XBOX_PFN_ELEMENT(pte.Hardware.PFN),
&((PXBOX_PFN)&persisted_mem->Data[(persisted_mem->NumOfPtes * 2) + (persisted_mem->NumOfPtes - 16) * KiB(1)])[pte.Hardware.PFN],
sizeof(XBOX_PFN));
if ((uint32_t*)persisted_mem->Data[i] < (uint32_t*)XBOX_PFN_ADDRESS) {
memcpy((void*)(persisted_mem->Data[i]), &persisted_mem->Data[persisted_mem->NumOfPtes * 2 + i * KiB(1)], PAGE_SIZE);
}
}
}
MMPTE pte;
PFN pfn;
for (unsigned int i = 0; i < persisted_mem->NumOfPtes; i++) {
pte.Default = persisted_mem->Data[persisted_mem->NumOfPtes + i];
assert(pte.Hardware.Valid != 0 && pte.Hardware.Persist != 0);
memcpy(GetPteAddress(persisted_mem->Data[i]), &pte.Default, sizeof(MMPTE));
RemoveFree(1, &pfn, 0, pte.Hardware.PFN, pte.Hardware.PFN);
if (m_MmLayoutChihiro) {
memcpy(CHIHIRO_PFN_ELEMENT(pte.Hardware.PFN),
&((PXBOX_PFN)&persisted_mem->Data[(persisted_mem->NumOfPtes * 2) + (persisted_mem->NumOfPtes - 32) * KiB(1)])[pte.Hardware.PFN],
sizeof(XBOX_PFN));
if ((uint32_t*)persisted_mem->Data[i] < (uint32_t*)CHIHIRO_PFN_ADDRESS) {
memcpy((void*)(persisted_mem->Data[i]), &persisted_mem->Data[persisted_mem->NumOfPtes * 2 + i * KiB(1)], PAGE_SIZE);
}
}
else {
memcpy(XBOX_PFN_ELEMENT(pte.Hardware.PFN),
&((PXBOX_PFN)&persisted_mem->Data[(persisted_mem->NumOfPtes * 2) + (persisted_mem->NumOfPtes - 16) * KiB(1)])[pte.Hardware.PFN],
sizeof(XBOX_PFN));
if ((uint32_t*)persisted_mem->Data[i] < (uint32_t*)XBOX_PFN_ADDRESS) {
memcpy((void*)(persisted_mem->Data[i]), &persisted_mem->Data[persisted_mem->NumOfPtes * 2 + i * KiB(1)], PAGE_SIZE);
}
}
}
PFN_COUNT pages_num = 1;
for (unsigned int i = 0; i < persisted_mem->NumOfPtes; i++) {
PFN_COUNT pages_num = 1;
for (unsigned int i = 0; i < persisted_mem->NumOfPtes; i++) {
pte.Default = persisted_mem->Data[persisted_mem->NumOfPtes + i];
if (pte.Hardware.GuardOrEnd == 0) {
pages_num++;
continue;
}
size_t size = pages_num << PAGE_SHIFT;
VAddr addr = persisted_mem->Data[i] - (size - PAGE_SIZE);
AllocatePT(size, addr);
ConstructVMA(addr, size, ContiguousRegion, AllocatedVma, false);
GetPfnOfPT(GetPteAddress(addr))->PTPageFrame.PtesUsed += pages_num;
size_t size = pages_num << PAGE_SHIFT;
VAddr addr = persisted_mem->Data[i] - (size - PAGE_SIZE);
AllocatePT(size, addr);
ConstructVMA(addr, size, ContiguousRegion, AllocatedVma, false);
GetPfnOfPT(GetPteAddress(addr))->PTPageFrame.PtesUsed += pages_num;
pages_num = 1;
}
if (m_MmLayoutDebug) { m_PhysicalPagesAvailable += 16; m_DebuggerPagesAvailable -= 16; }
if (m_MmLayoutDebug) { m_PhysicalPagesAvailable += 16; m_DebuggerPagesAvailable -= 16; }
PFN pfn_end;
PFN pfn_end;
if (m_MmLayoutRetail || m_MmLayoutDebug) {
pfn = XBOX_INSTANCE_PHYSICAL_PAGE;
pfn_end = XBOX_INSTANCE_PHYSICAL_PAGE + NV2A_INSTANCE_PAGE_COUNT - 1;
@ -383,9 +383,9 @@ void VMManager::RestorePersistentMemory()
PMMPTE PointerPte = GetPteAddress(addr);
PMMPTE EndingPte = GetPteAddress(CONVERT_PFN_TO_CONTIGUOUS_PHYSICAL(pfn_end));
AllocateContiguousMemoryInternal(pfn_end - pfn + 1, pfn, pfn_end, 1, XBOX_PAGE_READWRITE);
AllocateContiguousMemoryInternal(pfn_end - pfn + 1, pfn, pfn_end, 1, XBOX_PAGE_READWRITE);
while (PointerPte <= EndingPte) {
DISABLE_CACHING(*PointerPte);
DISABLE_CACHING(*PointerPte);
PointerPte++;
}
@ -399,86 +399,86 @@ void VMManager::RestorePersistentMemory()
PointerPte = GetPteAddress(addr);
EndingPte = GetPteAddress(CONVERT_PFN_TO_CONTIGUOUS_PHYSICAL(pfn_end));
AllocateContiguousMemoryInternal(pfn_end - pfn + 1, pfn, pfn_end, 1, XBOX_PAGE_READWRITE);
AllocateContiguousMemoryInternal(pfn_end - pfn + 1, pfn, pfn_end, 1, XBOX_PAGE_READWRITE);
while (PointerPte <= EndingPte) {
DISABLE_CACHING(*PointerPte);
DISABLE_CACHING(*PointerPte);
PointerPte++;
}
}
UnmapViewOfFile(persisted_mem);
CloseHandle(m_PersistentMemoryHandle);
UnmapViewOfFile(persisted_mem);
CloseHandle(m_PersistentMemoryHandle);
m_PersistentMemoryHandle = nullptr;
}
void VMManager::SavePersistentMemory()
void VMManager::SavePersistentMemory()
{
PersistedMemory* persisted_mem;
size_t num_persisted_ptes;
std::vector<PMMPTE> cached_persisted_ptes;
LPVOID addr;
PMMPTE PointerPte;
PMMPTE EndingPte;
int i;
PersistedMemory* persisted_mem;
size_t num_persisted_ptes;
std::vector<PMMPTE> cached_persisted_ptes;
LPVOID addr;
PMMPTE PointerPte;
PMMPTE EndingPte;
int i;
Lock();
num_persisted_ptes = 0;
PointerPte = GetPteAddress(CONTIGUOUS_MEMORY_BASE);
if (m_MmLayoutRetail) {
EndingPte = GetPteAddress(CONTIGUOUS_MEMORY_BASE + XBOX_CONTIGUOUS_MEMORY_SIZE - 1);
Lock();
num_persisted_ptes = 0;
PointerPte = GetPteAddress(CONTIGUOUS_MEMORY_BASE);
if (m_MmLayoutRetail) {
EndingPte = GetPteAddress(CONTIGUOUS_MEMORY_BASE + XBOX_CONTIGUOUS_MEMORY_SIZE - 1);
}
else {
EndingPte = GetPteAddress(CONTIGUOUS_MEMORY_BASE + CHIHIRO_CONTIGUOUS_MEMORY_SIZE - 1);
}
while (PointerPte <= EndingPte)
else {
EndingPte = GetPteAddress(CONTIGUOUS_MEMORY_BASE + CHIHIRO_CONTIGUOUS_MEMORY_SIZE - 1);
}
while (PointerPte <= EndingPte)
{
if (PointerPte->Hardware.Valid != 0 && PointerPte->Hardware.Persist != 0) {
cached_persisted_ptes.push_back(PointerPte);
num_persisted_ptes++;
if (PointerPte->Hardware.Valid != 0 && PointerPte->Hardware.Persist != 0) {
cached_persisted_ptes.push_back(PointerPte);
num_persisted_ptes++;
}
PointerPte++;
}
PointerPte++;
}
std::string persistent_mem_sid = str_persistent_memory_s + std::to_string(cli_config::GetSessionID());
m_PersistentMemoryHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, num_persisted_ptes * PAGE_SIZE + num_persisted_ptes * 4 * 2 + sizeof(PersistedMemory), persistent_mem_sid.c_str());
if (m_PersistentMemoryHandle == NULL) {
CxbxKrnlCleanup("Couldn't persist memory! CreateFileMapping failed with error 0x%08X", GetLastError());
return;
}
addr = MapViewOfFile(m_PersistentMemoryHandle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if (addr == nullptr) {
CxbxKrnlCleanup("Couldn't persist memory! MapViewOfFile failed with error 0x%08X", GetLastError());
return;
}
persisted_mem = (PersistedMemory*)addr;
persisted_mem->NumOfPtes = num_persisted_ptes;
if (xboxkrnl::LaunchDataPage != xbnullptr) {
persisted_mem->LaunchFrameAddresses[0] = (VAddr)xboxkrnl::LaunchDataPage;
EmuLog(LOG_LEVEL::INFO, "Persisted LaunchDataPage\n");
m_PersistentMemoryHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, num_persisted_ptes * PAGE_SIZE + num_persisted_ptes * 4 * 2 + sizeof(PersistedMemory), persistent_mem_sid.c_str());
if (m_PersistentMemoryHandle == NULL) {
CxbxKrnlCleanup("Couldn't persist memory! CreateFileMapping failed with error 0x%08X", GetLastError());
return;
}
addr = MapViewOfFile(m_PersistentMemoryHandle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if (addr == nullptr) {
CxbxKrnlCleanup("Couldn't persist memory! MapViewOfFile failed with error 0x%08X", GetLastError());
return;
}
if (xboxkrnl::AvSavedDataAddress != xbnullptr) {
persisted_mem->LaunchFrameAddresses[1] = (VAddr)xboxkrnl::AvSavedDataAddress;
EmuLog(LOG_LEVEL::INFO, "Persisted Framebuffer\n");
}
persisted_mem = (PersistedMemory*)addr;
persisted_mem->NumOfPtes = num_persisted_ptes;
i = 0;
for (const auto &pte : cached_persisted_ptes) {
persisted_mem->Data[i] = GetVAddrMappedByPte(pte);
persisted_mem->Data[num_persisted_ptes + i] = pte->Default;
memcpy(&persisted_mem->Data[num_persisted_ptes * 2 + i * KiB(1)], (void *)(persisted_mem->Data[i]), PAGE_SIZE);
i++;
if (xboxkrnl::LaunchDataPage != xbnullptr) {
persisted_mem->LaunchFrameAddresses[0] = (VAddr)xboxkrnl::LaunchDataPage;
EmuLog(LOG_LEVEL::INFO, "Persisted LaunchDataPage\n");
}
assert(i == num_persisted_ptes);
if (xboxkrnl::AvSavedDataAddress != xbnullptr) {
persisted_mem->LaunchFrameAddresses[1] = (VAddr)xboxkrnl::AvSavedDataAddress;
EmuLog(LOG_LEVEL::INFO, "Persisted Framebuffer\n");
}
Unlock();
i = 0;
for (const auto &pte : cached_persisted_ptes) {
persisted_mem->Data[i] = GetVAddrMappedByPte(pte);
persisted_mem->Data[num_persisted_ptes + i] = pte->Default;
memcpy(&persisted_mem->Data[num_persisted_ptes * 2 + i * KiB(1)], (void *)(persisted_mem->Data[i]), PAGE_SIZE);
i++;
}
assert(i == num_persisted_ptes);
Unlock();
}
VAddr VMManager::DbgTestPte(VAddr addr, PMMPTE Pte, bool bWriteCheck)
@ -641,14 +641,14 @@ void VMManager::PersistMemory(VAddr addr, size_t Size, bool bPersist)
while (PointerPte <= EndingPte)
{
PointerPte->Hardware.Persist = 1;
PointerPte++;
PointerPte++;
}
}
else {
while (PointerPte <= EndingPte)
{
PointerPte->Hardware.Persist = 0;
PointerPte++;
PointerPte++;
}
}
@ -677,7 +677,7 @@ VAddr VMManager::Allocate(size_t Size)
ConvertXboxToPtePermissions(XBOX_PAGE_EXECUTE_READWRITE, &TempPte);
addr = MapMemoryBlock(UserRegion, PteNumber, MEM_RESERVE | MEM_COMMIT, false);
if (!addr) { goto Fail; }
if (!addr) { goto Fail; }
// Check if we have to construct the PT's for this allocation
if (!AllocatePT(PteNumber << PAGE_SHIFT, addr))
@ -744,10 +744,10 @@ VAddr VMManager::AllocateSystemMemory(PageType BusyType, DWORD Perms, size_t Siz
// NOTE: AllocateSystemMemory won't allocate a physical page for the guard page (if requested) and just adds an extra
// unallocated virtual page in front of the mapped allocation. For this reason we will decommmit later the extra guard page allocated
if (!Size || !ConvertXboxToSystemPtePermissions(Perms, &TempPte)) { RETURN(NULL); }
LowestAcceptablePfn = 0;
HighestAcceptablePfn = m_MmLayoutDebug ? XBOX_HIGHEST_PHYSICAL_PAGE : m_HighestPage;
if (!Size || !ConvertXboxToSystemPtePermissions(Perms, &TempPte)) { RETURN(NULL); }
LowestAcceptablePfn = 0;
HighestAcceptablePfn = m_MmLayoutDebug ? XBOX_HIGHEST_PHYSICAL_PAGE : m_HighestPage;
MemoryType = SystemRegion;
Lock();
@ -770,7 +770,7 @@ VAddr VMManager::AllocateSystemMemory(PageType BusyType, DWORD Perms, size_t Siz
addr = MapMemoryBlock(MemoryType, PteNumber, MEM_COMMIT, true);
if (!addr) { goto Fail; }
if (!addr) { goto Fail; }
// check if we have to construct the PT's for this allocation
if (!AllocatePT(PteNumber << PAGE_SHIFT, addr))
@ -843,19 +843,19 @@ VAddr VMManager::AllocateContiguousMemory(size_t Size, PAddr LowestAddress, PAdd
Lock();
if (!IsMappable(PteNumber, true, false)) {
Unlock();
RETURN(NULL);
}
Addr = AllocateContiguousMemoryInternal(PteNumber, LowestPfn, HighestPfn, PfnAlignment, Perms);
if (!IsMappable(PteNumber, true, false)) {
Unlock();
RETURN(NULL);
}
Addr = AllocateContiguousMemoryInternal(PteNumber, LowestPfn, HighestPfn, PfnAlignment, Perms);
Unlock();
RETURN(Addr);
}
VAddr VMManager::AllocateContiguousMemoryInternal(PFN_COUNT NumberOfPages, PFN LowestPfn, PFN HighestPfn, PFN PfnAlignment, DWORD Perms)
VAddr VMManager::AllocateContiguousMemoryInternal(PFN_COUNT NumberOfPages, PFN LowestPfn, PFN HighestPfn, PFN PfnAlignment, DWORD Perms)
{
MMPTE TempPte;
PMMPTE PointerPte;
@ -984,7 +984,7 @@ void VMManager::Deallocate(VAddr addr)
}
PointerPte = GetPteAddress(addr);
EndingPte = PointerPte + (it->second.size >> PAGE_SHIFT) - 1;
EndingPte = PointerPte + (it->second.size >> PAGE_SHIFT) - 1;
StartingPte = PointerPte;
PteNumber = EndingPte - StartingPte + 1;
@ -1093,7 +1093,7 @@ PFN_COUNT VMManager::DeallocateSystemMemory(PageType BusyType, VAddr addr, size_
bGuardPageAdded = true;
}
EndingPte = PointerPte + (Size >> PAGE_SHIFT) - 1;
EndingPte = PointerPte + (Size >> PAGE_SHIFT) - 1;
StartingPte = PointerPte;
PteNumber = EndingPte - PointerPte + 1;
@ -1561,8 +1561,8 @@ xboxkrnl::NTSTATUS VMManager::XbAllocateVirtualMemory(VAddr* addr, ULONG ZeroBit
goto Exit;
}
// Attempt to commit the requested range with VirtualAlloc *before* setting up and reserving the PT
// This allows an early-out in a failure scenario (Test Case: Star Wars Battlefront DVD Demo: LA-018 v1.02)
// Attempt to commit the requested range with VirtualAlloc *before* setting up and reserving the PT
// This allows an early-out in a failure scenario (Test Case: Star Wars Battlefront DVD Demo: LA-018 v1.02)
// We don't commit the requested range if it's within our placeholder, since that was already allocated earlier
if (AlignedCapturedBase >= XBE_MAX_VA)
{
@ -1570,10 +1570,10 @@ xboxkrnl::NTSTATUS VMManager::XbAllocateVirtualMemory(VAddr* addr, ULONG ZeroBit
(ConvertXboxToWinPermissions(PatchXboxPermissions(Protect))) & ~(PAGE_WRITECOMBINE | PAGE_NOCACHE)))
{
EmuLog(LOG_LEVEL::DEBUG, "%s: VirtualAlloc failed to commit the memory! The error was 0x%08X", __func__, GetLastError());
status = STATUS_NO_MEMORY;
status = STATUS_NO_MEMORY;
goto Exit;
}
}
}
// Check if we have to construct the PT's for this allocation
@ -2076,13 +2076,13 @@ VAddr VMManager::MapMemoryBlock(MemoryRegionType Type, PFN_COUNT PteNumber, DWOR
addr = ROUND_UP(addr, m_AllocationGranularity);
}
if (Permissions == 0xFFFFFFFF) {
if (addr + Size - 1 < it->first + it->second.size) {
return addr;
}
++it;
continue;
}
if (Permissions == 0xFFFFFFFF) {
if (addr + Size - 1 < it->first + it->second.size) {
return addr;
}
++it;
continue;
}
// Note that, even in free regions, somebody outside the manager could have allocated the memory so we just
// keep on trying until we succeed or fail entirely.
@ -2091,23 +2091,23 @@ VAddr VMManager::MapMemoryBlock(MemoryRegionType Type, PFN_COUNT PteNumber, DWOR
if (HighestAddress && (it->first + it->second.size > HighestAddress + 1)) { vma_end = HighestAddress + 1; }
else { vma_end = it->first + it->second.size; }
if (b64Blocks) {
if (addr + Size - 1 < vma_end) {
// The memory was reserved by the loader, commit it in 64kb blocks
VAddr start_addr = addr;
size_t start_size = 0;
while (addr < vma_end) {
addr = MapHostMemory(addr, m_AllocationGranularity, vma_end, Permissions);
assert(addr);
start_size += m_AllocationGranularity;
if (b64Blocks) {
if (addr + Size - 1 < vma_end) {
// The memory was reserved by the loader, commit it in 64kb blocks
VAddr start_addr = addr;
size_t start_size = 0;
while (addr < vma_end) {
addr = MapHostMemory(addr, m_AllocationGranularity, vma_end, Permissions);
assert(addr);
start_size += m_AllocationGranularity;
if (start_size >= Size) {
return start_addr;
}
addr += m_AllocationGranularity;
}
assert(0);
}
assert(0);
}
}
}
else {
addr = MapHostMemory(addr, Size, vma_end, Permissions);
if (addr) { return addr; }
@ -2144,31 +2144,31 @@ VAddr VMManager::MapMemoryBlock(MemoryRegionType Type, PFN_COUNT PteNumber, DWOR
size_t vma_end = it->first + it->second.size;
if (Permissions == 0xFFFFFFFF) {
if (addr + Size - 1 < vma_end) {
return addr;
}
--it;
continue;
if (Permissions == 0xFFFFFFFF) {
if (addr + Size - 1 < vma_end) {
return addr;
}
--it;
continue;
}
if (b64Blocks) {
if (addr + Size - 1 < vma_end) {
// The memory was reserved by the loader, commit it in 64kb blocks
VAddr start_addr = addr;
size_t start_size = 0;
while (addr < vma_end) {
addr = MapHostMemory(addr, m_AllocationGranularity, vma_end, Permissions);
assert(addr);
start_size += m_AllocationGranularity;
if (b64Blocks) {
if (addr + Size - 1 < vma_end) {
// The memory was reserved by the loader, commit it in 64kb blocks
VAddr start_addr = addr;
size_t start_size = 0;
while (addr < vma_end) {
addr = MapHostMemory(addr, m_AllocationGranularity, vma_end, Permissions);
assert(addr);
start_size += m_AllocationGranularity;
if (start_size >= Size) {
return start_addr;
}
addr += m_AllocationGranularity;
}
assert(0);
}
assert(0);
}
}
}
else {
addr = MapHostMemory(addr, Size, vma_end, Permissions);
if (addr) { return addr; }
@ -2239,7 +2239,7 @@ PAddr VMManager::TranslateVAddrToPAddr(const VAddr addr)
PAddr PAddr;
PMMPTE PointerPte;
// ergo720: horrendous hack, this identity maps all allocations done by the VMManager to keep the LLE USB working.
// ergo720: horrendous hack, this identity maps all allocations done by the VMManager to keep the LLE USB working.
// The problem is that if the user buffer pointed to by the TD is allocated by the VMManager with VirtualAlloc, then
// the physical allocation will not reside in the contiguous memory and if we tried to access the physical address of it,
// we would access a random page with undefined contents.
@ -2252,7 +2252,7 @@ PAddr VMManager::TranslateVAddrToPAddr(const VAddr addr)
RETURN(NULL);
}
Lock();
Lock();
PointerPte = GetPdeAddress(addr);
if (PointerPte->Hardware.Valid == 0) { // invalid pde -> addr is invalid
@ -2499,7 +2499,7 @@ void VMManager::ConstructVMA(VAddr Start, size_t Size, MemoryRegionType Type, VM
m_MemoryRegionArray[Type].LastFree = m_MemoryRegionArray[Type].RegionMap.end();
return;
}
}
void VMManager::DestructVMA(VAddr addr, MemoryRegionType Type, size_t Size)
{
@ -2510,9 +2510,9 @@ void VMManager::DestructVMA(VAddr addr, MemoryRegionType Type, size_t Size)
if ((addr >= XBE_MAX_VA) && (Type != ContiguousRegion))
{
if (Type == SystemRegion || Type == DevkitRegion)
{
// This memory was reserved by the loader, do not release it, only decommit
if (Type == SystemRegion || Type == DevkitRegion)
{
// This memory was reserved by the loader, do not release it, only decommit
ret = VirtualFree((void*)addr, Size, MEM_DECOMMIT);
}

View File

@ -53,39 +53,39 @@ bool g_UseAllCores = false;
bool g_SkipRdtscPatching = false;
int g_RenderScaleFactor = 1;
// Delta added to host SystemTime, used in KiClockIsr and KeSetSystemTime
// This shouldn't need to be atomic, but because raising the IRQL to high lv in KeSetSystemTime doesn't really stop KiClockIsr from running,
// Delta added to host SystemTime, used in KiClockIsr and KeSetSystemTime
// This shouldn't need to be atomic, but because raising the IRQL to high lv in KeSetSystemTime doesn't really stop KiClockIsr from running,
// we need it for now to prevent reading a corrupted value while KeSetSystemTime is in the middle of updating it
std::atomic_int64_t HostSystemTimeDelta(0);
// Static Function(s)
static int ExitException(LPEXCEPTION_POINTERS e);
std::string FormatTitleId(uint32_t title_id)
{
std::stringstream ss;
// If the Title ID prefix is a printable character, parse it
// This shows the correct game serial number for retail titles!
// EG: MS-001 for 1st tile published by MS, EA-002 for 2nd title by EA, etc
// Some special Xbes (Dashboard, XDK Samples) use non-alphanumeric serials
// We fall back to Hex for those
// ergo720: we cannot use isalnum() here because it will treat chars in the range -1 - 255 as valid ascii chars which can
// lead to unicode characters being printed in the title (e.g.: dashboard uses 0xFE and 0xFF)
uint8_t pTitleId1 = (title_id >> 24) & 0xFF;
uint8_t pTitleId2 = (title_id >> 16) & 0xFF;
if ((pTitleId1 < 65 || pTitleId1 > 90) || (pTitleId2 < 65 || pTitleId2 > 90)) {
// Prefix was non-printable, so we need to print a hex reprentation of the entire title_id
ss << std::setfill('0') << std::setw(8) << std::hex << std::uppercase << title_id;
return ss.str();
}
ss << pTitleId1 << pTitleId2;
ss << "-";
ss << std::setfill('0') << std::setw(3) << std::dec << (title_id & 0x0000FFFF);
return ss.str();
static int ExitException(LPEXCEPTION_POINTERS e);
std::string FormatTitleId(uint32_t title_id)
{
std::stringstream ss;
// If the Title ID prefix is a printable character, parse it
// This shows the correct game serial number for retail titles!
// EG: MS-001 for 1st tile published by MS, EA-002 for 2nd title by EA, etc
// Some special Xbes (Dashboard, XDK Samples) use non-alphanumeric serials
// We fall back to Hex for those
// ergo720: we cannot use isalnum() here because it will treat chars in the range -1 - 255 as valid ascii chars which can
// lead to unicode characters being printed in the title (e.g.: dashboard uses 0xFE and 0xFF)
uint8_t pTitleId1 = (title_id >> 24) & 0xFF;
uint8_t pTitleId2 = (title_id >> 16) & 0xFF;
if ((pTitleId1 < 65 || pTitleId1 > 90) || (pTitleId2 < 65 || pTitleId2 > 90)) {
// Prefix was non-printable, so we need to print a hex reprentation of the entire title_id
ss << std::setfill('0') << std::setw(8) << std::hex << std::uppercase << title_id;
return ss.str();
}
ss << pTitleId1 << pTitleId2;
ss << "-";
ss << std::setfill('0') << std::setw(3) << std::dec << (title_id & 0x0000FFFF);
return ss.str();
}
std::string EIPToString(xbaddr EIP)
@ -149,16 +149,16 @@ void EmuExceptionExitProcess()
}
bool EmuExceptionBreakpointAsk(LPEXCEPTION_POINTERS e)
{
{
EmuExceptionPrintDebugInformation(e, /*IsBreakpointException=*/true);
// We can skip Xbox as long as they are logged so we know about them
// There's no need to prevent emulation, we can just pretend we have a debugger attached and continue
// This is because some games (such as Crash Bandicoot) spam exceptions;
// We can skip Xbox as long as they are logged so we know about them
// There's no need to prevent emulation, we can just pretend we have a debugger attached and continue
// This is because some games (such as Crash Bandicoot) spam exceptions;
e->ContextRecord->Eip += EmuX86_OpcodeSize((uint8_t*)e->ContextRecord->Eip); // Skip 1 size bytes
return true;
#if 1
return true;
#if 1
#else
char buffer[256];
sprintf(buffer,
@ -184,9 +184,9 @@ bool EmuExceptionBreakpointAsk(LPEXCEPTION_POINTERS e)
return true;
}
return false;
return false;
#endif
}
}
void EmuExceptionNonBreakpointUnhandledShow(LPEXCEPTION_POINTERS e)
{
@ -212,18 +212,18 @@ bool IsXboxCodeAddress(xbaddr addr)
// TODO : Replace the following with a (fast) check weither
// the given address lies in xbox allocated virtual memory,
// for example by g_VMManager.CheckConflictingVMA(addr, 0).
return (addr >= XBE_IMAGE_BASE) && (addr <= XBE_MAX_VA);
// Note : Not IS_USER_ADDRESS(), that would include host DLL code
}
#include "distorm.h"
bool EmuX86_DecodeOpcode(const uint8_t* Eip, _DInst& info);
void EmuX86_DistormLogInstruction(const uint8_t* Eip, _DInst& info, LOG_LEVEL log_level);
void genericException(EXCEPTION_POINTERS *e) {
_DInst info;
if (EmuX86_DecodeOpcode((uint8_t*)e->ContextRecord->Eip, info)) {
EmuX86_DistormLogInstruction((uint8_t*)e->ContextRecord->Eip, info, LOG_LEVEL::FATAL);
}
return (addr >= XBE_IMAGE_BASE) && (addr <= XBE_MAX_VA);
// Note : Not IS_USER_ADDRESS(), that would include host DLL code
}
#include "distorm.h"
bool EmuX86_DecodeOpcode(const uint8_t* Eip, _DInst& info);
void EmuX86_DistormLogInstruction(const uint8_t* Eip, _DInst& info, LOG_LEVEL log_level);
void genericException(EXCEPTION_POINTERS *e) {
_DInst info;
if (EmuX86_DecodeOpcode((uint8_t*)e->ContextRecord->Eip, info)) {
EmuX86_DistormLogInstruction((uint8_t*)e->ContextRecord->Eip, info, LOG_LEVEL::FATAL);
}
// Try to report this exception to the debugger, which may allow handling of this exception
if (CxbxDebugger::CanReport()) {
bool DebuggerHandled = false;
@ -231,7 +231,7 @@ void genericException(EXCEPTION_POINTERS *e) {
if (!DebuggerHandled) {
// Kill the process immediately without the Cxbx notifier
EmuExceptionExitProcess();
}
}
// Bypass exception
}
@ -240,20 +240,20 @@ void genericException(EXCEPTION_POINTERS *e) {
EmuExceptionNonBreakpointUnhandledShow(e);
}
}
bool IsRdtscInstruction(xbaddr addr); // Implemented in CxbxKrnl.cpp
void EmuX86_Opcode_RDTSC(EXCEPTION_POINTERS *e); // Implemented in EmuX86.cpp
bool lleTryHandleException(EXCEPTION_POINTERS *e)
{
// Initalize local thread variable
bOverrideEmuException = false;
// Only handle exceptions which originate from Xbox code
if (!IsXboxCodeAddress(e->ContextRecord->Eip)) {
return false;
}
// Make sure access-violations reach EmuX86_DecodeException() as soon as possible
bool IsRdtscInstruction(xbaddr addr); // Implemented in CxbxKrnl.cpp
void EmuX86_Opcode_RDTSC(EXCEPTION_POINTERS *e); // Implemented in EmuX86.cpp
bool lleTryHandleException(EXCEPTION_POINTERS *e)
{
// Initalize local thread variable
bOverrideEmuException = false;
// Only handle exceptions which originate from Xbox code
if (!IsXboxCodeAddress(e->ContextRecord->Eip)) {
return false;
}
// Make sure access-violations reach EmuX86_DecodeException() as soon as possible
if (e->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION) {
switch (e->ExceptionRecord->ExceptionCode) {
case STATUS_PRIVILEGED_INSTRUCTION:
@ -267,82 +267,82 @@ bool lleTryHandleException(EXCEPTION_POINTERS *e)
break;
case STATUS_BREAKPOINT:
// Pass breakpoint down to EmuException since VEH doesn't have call stack viewable.
return false;
default:
return false;
default:
// Skip past CxbxDebugger-specific exceptions thrown when an unsupported was attached (ie Visual Studio)
if (CxbxDebugger::IsDebuggerException(e->ExceptionRecord->ExceptionCode)) {
return true;
return true;
}
}
}
// Pass the exception to our X86 implementation, to try and execute the failing instruction
if (EmuX86_DecodeException(e)) {
// We're allowed to continue :
return true;
}
// We do not need EmuException to handle it again.
}
// We do not need EmuException to handle it again.
bOverrideEmuException = true;
// Unhandled exception :
return false;
}
// Only for LLE emulation coding (to help performance a little bit better)
// Only for LLE emulation coding (to help performance a little bit better)
long WINAPI lleException(EXCEPTION_POINTERS *e)
{
g_bEmuException = true;
long result = lleTryHandleException(e) ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH;
g_bEmuException = false;
g_bEmuException = true;
long result = lleTryHandleException(e) ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH;
g_bEmuException = false;
return result;
}
// Only for Cxbx emulation coding (to catch all of last resort exception may occur.)
bool EmuTryHandleException(EXCEPTION_POINTERS *e)
{
// Check if lle exception is already called first before emu exception.
}
// Only for Cxbx emulation coding (to catch all of last resort exception may occur.)
bool EmuTryHandleException(EXCEPTION_POINTERS *e)
{
// Check if lle exception is already called first before emu exception.
if (bOverrideEmuException) {
genericException(e);
return false;
}
if (e->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION) {
bool isInt2Dh = *(uint16_t*)(e->ContextRecord->Eip - 2) == 0x2DCD;
}
if (e->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION) {
bool isInt2Dh = *(uint16_t*)(e->ContextRecord->Eip - 2) == 0x2DCD;
switch (e->ExceptionRecord->ExceptionCode) {
case STATUS_BREAKPOINT:
// First, check if the breakpoint was prefixed with int 0x2dh, if so, it's NOT a breakpoint, but a Debugger Command!
// Note: Because of a Windows quirk, this does NOT work when a debugger is attached, we'll get an UNCATCHABLE breakpoint instead
// But at least this gives us a working implementaton of Xbox DbgPrint when we don't attach a debugger
if (isInt2Dh ){
e->ContextRecord->Eip += 1;
// Now perform the command (stored in EAX)
switch (e->ContextRecord->Eax) {
case 1: // DEBUG_PRINT
// In this case, ECX should point to an ANSI String
printf("DEBUG_PRINT: %s\n", ((xboxkrnl::PANSI_STRING)e->ContextRecord->Ecx)->Buffer);
break;
default:
printf("Unhandled Debug Command: int 2Dh, EAX = %d", e->ContextRecord->Eip);
}
return true;
}
case STATUS_BREAKPOINT:
// First, check if the breakpoint was prefixed with int 0x2dh, if so, it's NOT a breakpoint, but a Debugger Command!
// Note: Because of a Windows quirk, this does NOT work when a debugger is attached, we'll get an UNCATCHABLE breakpoint instead
// But at least this gives us a working implementaton of Xbox DbgPrint when we don't attach a debugger
if (isInt2Dh ){
e->ContextRecord->Eip += 1;
// Now perform the command (stored in EAX)
switch (e->ContextRecord->Eax) {
case 1: // DEBUG_PRINT
// In this case, ECX should point to an ANSI String
printf("DEBUG_PRINT: %s\n", ((xboxkrnl::PANSI_STRING)e->ContextRecord->Ecx)->Buffer);
break;
default:
printf("Unhandled Debug Command: int 2Dh, EAX = %d", e->ContextRecord->Eip);
}
return true;
}
// Otherwise, let the user choose between continue or break
return EmuExceptionBreakpointAsk(e);
default:
printf("Unhandled Debug Command: int 2Dh, EAX = %d", e->ContextRecord->Eip);
return EmuExceptionBreakpointAsk(e);
default:
printf("Unhandled Debug Command: int 2Dh, EAX = %d", e->ContextRecord->Eip);
// Skip past CxbxDebugger-specific exceptions thrown when an unsupported was attached (ie Visual Studio)
if (CxbxDebugger::IsDebuggerException(e->ExceptionRecord->ExceptionCode)) {
return true;
return true;
}
}
}
}
genericException(e);
// Unhandled exception :

View File

@ -25,13 +25,13 @@
#ifndef EMU_H
#define EMU_H
#include "common\xbe\Xbe.h"
#include "common\xbe\Xbe.h"
#include "Logging.h"
#undef FIELD_OFFSET // prevent macro redefinition warnings
#include <windows.h>
#include <multimon.h>
#include <multimon.h>
std::string FormatTitleId(uint32_t title_id);
// exception handler
@ -67,8 +67,8 @@ extern void * funcExclude[2048];
// partition emulation directory handles
extern HANDLE g_hCurDir;
extern CHAR *g_strCurDrive;
extern HWND g_hEmuWindow;
extern HWND g_hEmuWindow;
#define GET_FRONT_WINDOW_HANDLE ((CxbxKrnl_hEmuParent != nullptr) ? CxbxKrnl_hEmuParent : g_hEmuWindow)
// thread notification routine
@ -91,10 +91,10 @@ typedef struct DUMMY_KERNEL
IMAGE_SECTION_HEADER SectionHeader;
} *PDUMMY_KERNEL;
typedef WORD INDEX16;
typedef WORD INDEX16;
extern bool g_DisablePixelShaders;
extern bool g_UseAllCores;
extern bool g_SkipRdtscPatching;
extern bool g_SkipRdtscPatching;
extern int g_RenderScaleFactor;
#endif

View File

@ -29,8 +29,8 @@
#include <xboxkrnl/xboxkrnl.h>
#include "core\kernel\exports\EmuKrnl.h" // For InitializeListHead(), etc.
#include "core\kernel\exports\EmuKrnlKe.h"
#include "core\kernel\exports\EmuKrnl.h" // For InitializeListHead(), etc.
#include "core\kernel\exports\EmuKrnlKe.h"
#include "core\kernel\support\EmuFS.h" // For fs_instruction_t
#include "core\kernel\init\CxbxKrnl.h"
#include "core\kernel\memory-manager\VMManager.h"
@ -38,7 +38,7 @@
#undef FIELD_OFFSET // prevent macro redefinition warnings
#include <windows.h>
#include <cstdio>
#include <cstdio>
#include <vector>
// NT_TIB (Thread Information Block) offsets - see https://www.microsoft.com/msj/archive/S2CE.aspx
@ -122,23 +122,23 @@ uint32_t fs_lock = 0;
__declspec(naked) void LockFS()
{
__asm {
// Backup Registers
pushfd
pushad
jmp entry
// Spin until we can aquire the lock
spinlock :
call SwitchToThread // Give other threads a chance to run if we couldn't get the lock
entry:
mov eax, 1
xchg eax, fs_lock
test eax, eax
jnz spinlock
// Restore registers and return
popad
popfd
// Backup Registers
pushfd
pushad
jmp entry
// Spin until we can aquire the lock
spinlock :
call SwitchToThread // Give other threads a chance to run if we couldn't get the lock
entry:
mov eax, 1
xchg eax, fs_lock
test eax, eax
jnz spinlock
// Restore registers and return
popad
popfd
ret
}
}
@ -386,14 +386,14 @@ __declspec(naked) void EmuFS_MovFs00Esp()
{
// Note : eax must be preserved here, hence the push/pop
__asm
{
{
pushfd
call EmuFS_RefreshKPCR
push eax
mov eax, fs : [TIB_ArbitraryDataSlot]
mov [eax], esp
push eax
mov eax, fs : [TIB_ArbitraryDataSlot]
mov [eax], esp
add [eax], 12 // account for esp changes from pushed registers and return address
pop eax
pop eax
popfd
ret
}
@ -534,7 +534,7 @@ void EmuGenerateFS(Xbe::TLS *pTLS, void *pTLSData)
}
/* + HACK: extra safety padding 0x100 */
pNewTLS = (void*)g_VMManager.AllocateZeroed(dwCopySize + dwZeroSize + 0x100 + 0xC);
pNewTLS = (void*)g_VMManager.AllocateZeroed(dwCopySize + dwZeroSize + 0x100 + 0xC);
/* Skip the first 12 bytes so that TLSData will be 16 byte aligned (addr returned by AllocateZeroed is 4K aligned) */
pNewTLS = (uint8_t*)pNewTLS + 12;
@ -601,11 +601,11 @@ void EmuGenerateFS(Xbe::TLS *pTLS, void *pTLSData)
// Fixup the TIB self pointer :
NewPcr->NtTib.Self = XbTib;
// Set the stack base - TODO : Verify this, doesn't look right?
NewPcr->NtTib.StackBase = pNewTLS;
// Write the Xbox stack base to the Host, allows ConvertThreadToFiber to work correctly
// Test case: DOA3
__writefsdword(TIB_StackBase, (DWORD)NewPcr->NtTib.StackBase);
NewPcr->NtTib.StackBase = pNewTLS;
// Write the Xbox stack base to the Host, allows ConvertThreadToFiber to work correctly
// Test case: DOA3
__writefsdword(TIB_StackBase, (DWORD)NewPcr->NtTib.StackBase);
__writefsdword(TIB_StackLimit, (DWORD)NewPcr->NtTib.StackLimit);
}
@ -631,19 +631,19 @@ void EmuGenerateFS(Xbe::TLS *pTLS, void *pTLSData)
EThread->Tcb.TlsData = pNewTLS;
EThread->UniqueThread = GetCurrentThreadId();
// Set PrcbData.CurrentThread
Prcb->CurrentThread = (xboxkrnl::KTHREAD*)EThread;
// Initialize the thread header and its wait list
Prcb->CurrentThread->Header.Type = xboxkrnl::ThreadObject;
Prcb->CurrentThread->Header.Size = sizeof(xboxkrnl::KTHREAD) / sizeof(xboxkrnl::LONG);
InitializeListHead(&Prcb->CurrentThread->Header.WaitListHead);
// Also initialize the timer associated with the thread
xboxkrnl::KeInitializeTimer(&Prcb->CurrentThread->Timer);
xboxkrnl::PKWAIT_BLOCK WaitBlock = &Prcb->CurrentThread->TimerWaitBlock;
WaitBlock->Object = &Prcb->CurrentThread->Timer;
WaitBlock->WaitKey = (xboxkrnl::CSHORT)STATUS_TIMEOUT;
WaitBlock->WaitType = xboxkrnl::WaitAny;
WaitBlock->Thread = Prcb->CurrentThread;
WaitBlock->WaitListEntry.Flink = &Prcb->CurrentThread->Timer.Header.WaitListHead;
Prcb->CurrentThread = (xboxkrnl::KTHREAD*)EThread;
// Initialize the thread header and its wait list
Prcb->CurrentThread->Header.Type = xboxkrnl::ThreadObject;
Prcb->CurrentThread->Header.Size = sizeof(xboxkrnl::KTHREAD) / sizeof(xboxkrnl::LONG);
InitializeListHead(&Prcb->CurrentThread->Header.WaitListHead);
// Also initialize the timer associated with the thread
xboxkrnl::KeInitializeTimer(&Prcb->CurrentThread->Timer);
xboxkrnl::PKWAIT_BLOCK WaitBlock = &Prcb->CurrentThread->TimerWaitBlock;
WaitBlock->Object = &Prcb->CurrentThread->Timer;
WaitBlock->WaitKey = (xboxkrnl::CSHORT)STATUS_TIMEOUT;
WaitBlock->WaitType = xboxkrnl::WaitAny;
WaitBlock->Thread = Prcb->CurrentThread;
WaitBlock->WaitListEntry.Flink = &Prcb->CurrentThread->Timer.Header.WaitListHead;
WaitBlock->WaitListEntry.Blink = &Prcb->CurrentThread->Timer.Header.WaitListHead;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,307 +1,307 @@
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef EMUFILE_H
#define EMUFILE_H
#include <xboxkrnl/xboxkrnl.h>
#include <vector>
#include <cstdio>
#include <string>
#include <memory>
// ******************************************************************
// * prevent name collisions
// ******************************************************************
namespace NtDll
{
#include "EmuNtDll.h"
};
#include "Emu.h"
// TODO : Move to a better suited file
//std::ostream& operator<<(std::ostream& os, const NtDll::NTSTATUS& value);
extern const std::string MediaBoardRomFile;
extern const std::string DrivePrefix;
extern const std::string DriveSerial;
extern const std::string DriveCdRom0;
extern const std::string DriveMbfs;
extern const std::string DriveMbcom;
extern const std::string DriveMbrom;
extern const std::string DriveA;
extern const std::string DriveC;
extern const std::string DriveD;
extern const std::string DriveE;
extern const std::string DriveF;
extern const std::string DriveS;
extern const std::string DriveT;
extern const std::string DriveU;
extern const std::string DriveV;
extern const std::string DriveW;
extern const std::string DriveX;
extern const std::string DriveY;
extern const std::string DriveZ;
extern const std::string DevicePrefix;
extern const std::string DeviceCdrom0;
extern const std::string DeviceHarddisk0;
extern const std::string DeviceHarddisk0PartitionPrefix;
extern const std::string DeviceHarddisk0Partition0;
extern const std::string DeviceHarddisk0Partition1;
extern const std::string DeviceHarddisk0Partition2;
extern const std::string DeviceHarddisk0Partition3;
extern const std::string DeviceHarddisk0Partition4;
extern const std::string DeviceHarddisk0Partition5;
extern const std::string DeviceHarddisk0Partition6;
extern const std::string DeviceHarddisk0Partition7;
extern const std::string DeviceHarddisk0Partition8;
extern const std::string DeviceHarddisk0Partition9;
extern const std::string DeviceHarddisk0Partition10;
extern const std::string DeviceHarddisk0Partition11;
extern const std::string DeviceHarddisk0Partition12;
extern const std::string DeviceHarddisk0Partition13;
extern const std::string DeviceHarddisk0Partition14;
extern const std::string DeviceHarddisk0Partition15;
extern const std::string DeviceHarddisk0Partition16;
extern const std::string DeviceHarddisk0Partition17;
extern const std::string DeviceHarddisk0Partition18;
extern const std::string DeviceHarddisk0Partition19;
extern const std::string DeviceHarddisk0Partition20;
extern const char CxbxDefaultXbeDriveLetter;
extern int CxbxDefaultXbeDriveIndex;
extern std::string CxbxBasePath;
extern HANDLE CxbxBasePathHandle;
const size_t XboxFileInfoStructSizes[xboxkrnl::FileMaximumInformation] = {
0, // (index 0)
sizeof(xboxkrnl::FILE_DIRECTORY_INFORMATION), // FileDirectoryInformation
sizeof(xboxkrnl::FILE_DIRECTORY_INFORMATION), // FileFullDirectoryInformation
sizeof(xboxkrnl::FILE_DIRECTORY_INFORMATION), // FileBothDirectoryInformation
sizeof(xboxkrnl::FILE_BASIC_INFORMATION), // FileBasicInformation
sizeof(xboxkrnl::FILE_STANDARD_INFORMATION), // FileStandardInformation
sizeof(xboxkrnl::FILE_INTERNAL_INFORMATION), // FileInternalInformation
sizeof(xboxkrnl::FILE_EA_INFORMATION), // FileEaInformation
sizeof(xboxkrnl::FILE_ACCESS_INFORMATION), // FileAccessInformation
sizeof(xboxkrnl::FILE_NAME_INFORMATION), // FileNameInformation
sizeof(xboxkrnl::FILE_RENAME_INFORMATION), // FileRenameInformation
sizeof(xboxkrnl::FILE_LINK_INFORMATION), // FileLinkInformation
sizeof(xboxkrnl::FILE_DIRECTORY_INFORMATION), // FileNamesInformation
sizeof(xboxkrnl::FILE_DISPOSITION_INFORMATION), // FileDispositionInformation
sizeof(xboxkrnl::FILE_POSITION_INFORMATION), // FilePositionInformation
sizeof(xboxkrnl::FILE_FULL_EA_INFORMATION), // FileFullEaInformation
sizeof(xboxkrnl::FILE_MODE_INFORMATION), // FileModeInformation
sizeof(xboxkrnl::FILE_ALIGNMENT_INFORMATION), // FileAlignmentInformation
sizeof(xboxkrnl::FILE_ALL_INFORMATION), // FileAllInformation
sizeof(xboxkrnl::FILE_ALLOCATION_INFORMATION), // FileAllocationInformation
sizeof(xboxkrnl::FILE_END_OF_FILE_INFORMATION), // FileEndOfFileInformation
sizeof(xboxkrnl::FILE_NAME_INFORMATION), // FileAlternateNameInformation
sizeof(xboxkrnl::FILE_STREAM_INFORMATION), // FileStreamInformation
sizeof(xboxkrnl::FILE_PIPE_INFORMATION), // FilePipeInformation
sizeof(xboxkrnl::FILE_PIPE_LOCAL_INFORMATION), // FilePipeLocalInformation
sizeof(xboxkrnl::FILE_PIPE_REMOTE_INFORMATION), // FilePipeRemoteInformation
sizeof(xboxkrnl::FILE_MAILSLOT_QUERY_INFORMATION), // FileMailslotQueryInformation
sizeof(xboxkrnl::FILE_MAILSLOT_SET_INFORMATION), // FileMailslotSetInformation
sizeof(xboxkrnl::FILE_COMPRESSION_INFORMATION), // FileCompressionInformation
0, // FileCopyOnWriteInformation
sizeof(xboxkrnl::FILE_COMPLETION_INFORMATION), // FileCompletionInformation
sizeof(xboxkrnl::FILE_MOVE_CLUSTER_INFORMATION), // FileMoveClusterInformation
0, // FileQuotaInformation
sizeof(xboxkrnl::FILE_REPARSE_POINT_INFORMATION), // FileReparsePointInformation
sizeof(xboxkrnl::FILE_NETWORK_OPEN_INFORMATION), // FileNetworkOpenInformation
sizeof(xboxkrnl::FILE_DIRECTORY_INFORMATION), // FileObjectIdInformation
sizeof(xboxkrnl::FILE_TRACKING_INFORMATION), // FileTrackingInformation
0, // FileOleDirectoryInformation
0, // FileContentIndexInformation
0, // FileInheritContentIndexInformation
0 // FileOleInformation
};
class EmuNtObject;
struct NativeObjectAttributes {
wchar_t wszObjectName[160];
NtDll::UNICODE_STRING NtUnicodeString;
NtDll::OBJECT_ATTRIBUTES NtObjAttr;
// This is what should be passed on to Windows
// after CxbxObjectAttributesToNT() has been called :
NtDll::POBJECT_ATTRIBUTES NtObjAttrPtr;
};
NTSTATUS CxbxObjectAttributesToNT(xboxkrnl::POBJECT_ATTRIBUTES ObjectAttributes, NativeObjectAttributes& nativeObjectAttributes, std::string aFileAPIName = "", bool partitionHeader = false);
NTSTATUS CxbxConvertFilePath(std::string RelativeXboxPath, OUT std::wstring &RelativeHostPath, IN OUT NtDll::HANDLE *RootDirectory, std::string aFileAPIName = "", bool partitionHeader = false);
// ******************************************************************
// * Wrapper of a handle object
// ******************************************************************
class EmuHandle
{
public:
EmuHandle(EmuNtObject* ntObject);
NTSTATUS NtClose();
NTSTATUS NtDuplicateObject(PHANDLE TargetHandle, DWORD Options);
EmuNtObject* NtObject;
};
// ******************************************************************
// * An NT fake object
// ******************************************************************
class EmuNtObject
{
public:
EmuNtObject();
HANDLE NewHandle();
NTSTATUS NtClose();
EmuNtObject* NtDuplicateObject(DWORD Options);
protected:
virtual ~EmuNtObject() {};
private:
ULONG RefCount;
};
// ******************************************************************
// * Emulated symbolic link handle
// ******************************************************************
class EmuNtSymbolicLinkObject : public EmuNtObject {
public:
char DriveLetter;
std::string SymbolicLinkName;
bool IsHostBasedPath;
std::string XboxSymbolicLinkPath;
std::string HostSymbolicLinkPath;
HANDLE RootDirectoryHandle;
NTSTATUS Init(std::string aSymbolicLinkName, std::string aFullPath);
~EmuNtSymbolicLinkObject();
};
struct XboxDevice {
std::string XboxDevicePath;
std::string HostDevicePath;
HANDLE HostRootHandle;
};
// ******************************************************************
// * is Handle a 'special' emulated handle?
// ******************************************************************
bool IsEmuHandle(HANDLE Handle);
EmuHandle* HandleToEmuHandle(HANDLE Handle);
HANDLE EmuHandleToHandle(EmuHandle* emuHandle);
CHAR* NtStatusToString(IN NTSTATUS Status);
int CxbxRegisterDeviceHostPath(std::string XboxFullPath, std::string HostDevicePath, bool IsFile = false);
int CxbxDeviceIndexByDevicePath(const char *XboxDevicePath);
XboxDevice *CxbxDeviceByDevicePath(const std::string XboxDevicePath);
char SymbolicLinkToDriveLetter(std::string aSymbolicLinkName);
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByDriveLetter(const char DriveLetter);
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByName(std::string SymbolicLinkName);
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByDevice(std::string DeviceName);
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByRootHandle(HANDLE Handle);
void CleanupSymbolicLinks();
HANDLE CxbxGetDeviceNativeRootHandle(std::string XboxFullPath);
NTSTATUS CxbxCreateSymbolicLink(std::string SymbolicLinkName, std::string FullPath);
std::wstring string_to_wstring(std::string const & src);
std::wstring PUNICODE_STRING_to_wstring(NtDll::PUNICODE_STRING const & src);
std::string PSTRING_to_string(xboxkrnl::PSTRING const & src);
void copy_string_to_PSTRING_to(std::string const & src, const xboxkrnl::PSTRING & dest);
static int NtFileDirectoryInformationSize = sizeof(NtDll::FILE_DIRECTORY_INFORMATION) - 1;
static int NtPathBufferSize = MAX_PATH * sizeof(wchar_t);
// Deletes structs created by the converters
void _CxbxPVOIDDeleter(PVOID *ptr);
// Creates a PVOID variable named var which takes the given value
// and is automatically deleted when it goes out of scope
#define SMART_PVOID(var, value, orig) \
PVOID var = value; \
std::shared_ptr<PVOID> __var_shared_ptr; \
if (nullptr == var) \
{ \
__var_shared_ptr = nullptr; \
var = orig; \
} \
else \
__var_shared_ptr = std::shared_ptr<PVOID>(&var, _CxbxPVOIDDeleter);
// Converts an Xbox FileInformation struct to the NT equivalent.
// Used by NtSetInformationFile.
#define XboxToNTFileInformation(var, i, c, l) SMART_PVOID(var, _XboxToNTFileInformation(i, c, l), i)
PVOID _XboxToNTFileInformation
(
IN PVOID xboxFileInformation,
IN ULONG FileInformationClass,
OUT ULONG *Length
);
// Converts an NT FileInformation struct to the Xbox equivalent.
// Used by NtQueryInformationFile and NtQueryDirectoryFile
NTSTATUS NTToXboxFileInformation
(
IN PVOID nativeFileInformation,
OUT PVOID xboxFileInformation,
IN ULONG FileInformationClass,
IN ULONG Length
);
// Xbox Partition Information
typedef struct
{
UCHAR Name[16];
ULONG Flags;
ULONG LBAStart;
ULONG LBASize;
ULONG Reserved;
} XboxPartitionTableEntry;
typedef struct
{
UCHAR Magic[16];
char Res0[32];
XboxPartitionTableEntry TableEntries[14];
} XboxPartitionTable;
typedef struct _FATX_SUPERBLOCK
{
char Tag[4];
unsigned int VolumeID;
unsigned int ClusterSize;
USHORT FatCopies;
int Resvd;
char Unused[4078];
} FATX_SUPERBLOCK;
XboxPartitionTable CxbxGetPartitionTable();
FATX_SUPERBLOCK CxbxGetFatXSuperBlock(int partitionNumber);
int CxbxGetPartitionNumberFromHandle(HANDLE hFile);
std::string CxbxGetPartitionDataPathFromHandle(HANDLE hFile);
void CxbxFormatPartitionByHandle(HANDLE hFile);
#endif
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef EMUFILE_H
#define EMUFILE_H
#include <xboxkrnl/xboxkrnl.h>
#include <vector>
#include <cstdio>
#include <string>
#include <memory>
// ******************************************************************
// * prevent name collisions
// ******************************************************************
namespace NtDll
{
#include "EmuNtDll.h"
};
#include "Emu.h"
// TODO : Move to a better suited file
//std::ostream& operator<<(std::ostream& os, const NtDll::NTSTATUS& value);
extern const std::string MediaBoardRomFile;
extern const std::string DrivePrefix;
extern const std::string DriveSerial;
extern const std::string DriveCdRom0;
extern const std::string DriveMbfs;
extern const std::string DriveMbcom;
extern const std::string DriveMbrom;
extern const std::string DriveA;
extern const std::string DriveC;
extern const std::string DriveD;
extern const std::string DriveE;
extern const std::string DriveF;
extern const std::string DriveS;
extern const std::string DriveT;
extern const std::string DriveU;
extern const std::string DriveV;
extern const std::string DriveW;
extern const std::string DriveX;
extern const std::string DriveY;
extern const std::string DriveZ;
extern const std::string DevicePrefix;
extern const std::string DeviceCdrom0;
extern const std::string DeviceHarddisk0;
extern const std::string DeviceHarddisk0PartitionPrefix;
extern const std::string DeviceHarddisk0Partition0;
extern const std::string DeviceHarddisk0Partition1;
extern const std::string DeviceHarddisk0Partition2;
extern const std::string DeviceHarddisk0Partition3;
extern const std::string DeviceHarddisk0Partition4;
extern const std::string DeviceHarddisk0Partition5;
extern const std::string DeviceHarddisk0Partition6;
extern const std::string DeviceHarddisk0Partition7;
extern const std::string DeviceHarddisk0Partition8;
extern const std::string DeviceHarddisk0Partition9;
extern const std::string DeviceHarddisk0Partition10;
extern const std::string DeviceHarddisk0Partition11;
extern const std::string DeviceHarddisk0Partition12;
extern const std::string DeviceHarddisk0Partition13;
extern const std::string DeviceHarddisk0Partition14;
extern const std::string DeviceHarddisk0Partition15;
extern const std::string DeviceHarddisk0Partition16;
extern const std::string DeviceHarddisk0Partition17;
extern const std::string DeviceHarddisk0Partition18;
extern const std::string DeviceHarddisk0Partition19;
extern const std::string DeviceHarddisk0Partition20;
extern const char CxbxDefaultXbeDriveLetter;
extern int CxbxDefaultXbeDriveIndex;
extern std::string CxbxBasePath;
extern HANDLE CxbxBasePathHandle;
const size_t XboxFileInfoStructSizes[xboxkrnl::FileMaximumInformation] = {
0, // (index 0)
sizeof(xboxkrnl::FILE_DIRECTORY_INFORMATION), // FileDirectoryInformation
sizeof(xboxkrnl::FILE_DIRECTORY_INFORMATION), // FileFullDirectoryInformation
sizeof(xboxkrnl::FILE_DIRECTORY_INFORMATION), // FileBothDirectoryInformation
sizeof(xboxkrnl::FILE_BASIC_INFORMATION), // FileBasicInformation
sizeof(xboxkrnl::FILE_STANDARD_INFORMATION), // FileStandardInformation
sizeof(xboxkrnl::FILE_INTERNAL_INFORMATION), // FileInternalInformation
sizeof(xboxkrnl::FILE_EA_INFORMATION), // FileEaInformation
sizeof(xboxkrnl::FILE_ACCESS_INFORMATION), // FileAccessInformation
sizeof(xboxkrnl::FILE_NAME_INFORMATION), // FileNameInformation
sizeof(xboxkrnl::FILE_RENAME_INFORMATION), // FileRenameInformation
sizeof(xboxkrnl::FILE_LINK_INFORMATION), // FileLinkInformation
sizeof(xboxkrnl::FILE_DIRECTORY_INFORMATION), // FileNamesInformation
sizeof(xboxkrnl::FILE_DISPOSITION_INFORMATION), // FileDispositionInformation
sizeof(xboxkrnl::FILE_POSITION_INFORMATION), // FilePositionInformation
sizeof(xboxkrnl::FILE_FULL_EA_INFORMATION), // FileFullEaInformation
sizeof(xboxkrnl::FILE_MODE_INFORMATION), // FileModeInformation
sizeof(xboxkrnl::FILE_ALIGNMENT_INFORMATION), // FileAlignmentInformation
sizeof(xboxkrnl::FILE_ALL_INFORMATION), // FileAllInformation
sizeof(xboxkrnl::FILE_ALLOCATION_INFORMATION), // FileAllocationInformation
sizeof(xboxkrnl::FILE_END_OF_FILE_INFORMATION), // FileEndOfFileInformation
sizeof(xboxkrnl::FILE_NAME_INFORMATION), // FileAlternateNameInformation
sizeof(xboxkrnl::FILE_STREAM_INFORMATION), // FileStreamInformation
sizeof(xboxkrnl::FILE_PIPE_INFORMATION), // FilePipeInformation
sizeof(xboxkrnl::FILE_PIPE_LOCAL_INFORMATION), // FilePipeLocalInformation
sizeof(xboxkrnl::FILE_PIPE_REMOTE_INFORMATION), // FilePipeRemoteInformation
sizeof(xboxkrnl::FILE_MAILSLOT_QUERY_INFORMATION), // FileMailslotQueryInformation
sizeof(xboxkrnl::FILE_MAILSLOT_SET_INFORMATION), // FileMailslotSetInformation
sizeof(xboxkrnl::FILE_COMPRESSION_INFORMATION), // FileCompressionInformation
0, // FileCopyOnWriteInformation
sizeof(xboxkrnl::FILE_COMPLETION_INFORMATION), // FileCompletionInformation
sizeof(xboxkrnl::FILE_MOVE_CLUSTER_INFORMATION), // FileMoveClusterInformation
0, // FileQuotaInformation
sizeof(xboxkrnl::FILE_REPARSE_POINT_INFORMATION), // FileReparsePointInformation
sizeof(xboxkrnl::FILE_NETWORK_OPEN_INFORMATION), // FileNetworkOpenInformation
sizeof(xboxkrnl::FILE_DIRECTORY_INFORMATION), // FileObjectIdInformation
sizeof(xboxkrnl::FILE_TRACKING_INFORMATION), // FileTrackingInformation
0, // FileOleDirectoryInformation
0, // FileContentIndexInformation
0, // FileInheritContentIndexInformation
0 // FileOleInformation
};
class EmuNtObject;
struct NativeObjectAttributes {
wchar_t wszObjectName[160];
NtDll::UNICODE_STRING NtUnicodeString;
NtDll::OBJECT_ATTRIBUTES NtObjAttr;
// This is what should be passed on to Windows
// after CxbxObjectAttributesToNT() has been called :
NtDll::POBJECT_ATTRIBUTES NtObjAttrPtr;
};
NTSTATUS CxbxObjectAttributesToNT(xboxkrnl::POBJECT_ATTRIBUTES ObjectAttributes, NativeObjectAttributes& nativeObjectAttributes, std::string aFileAPIName = "", bool partitionHeader = false);
NTSTATUS CxbxConvertFilePath(std::string RelativeXboxPath, OUT std::wstring &RelativeHostPath, IN OUT NtDll::HANDLE *RootDirectory, std::string aFileAPIName = "", bool partitionHeader = false);
// ******************************************************************
// * Wrapper of a handle object
// ******************************************************************
class EmuHandle
{
public:
EmuHandle(EmuNtObject* ntObject);
NTSTATUS NtClose();
NTSTATUS NtDuplicateObject(PHANDLE TargetHandle, DWORD Options);
EmuNtObject* NtObject;
};
// ******************************************************************
// * An NT fake object
// ******************************************************************
class EmuNtObject
{
public:
EmuNtObject();
HANDLE NewHandle();
NTSTATUS NtClose();
EmuNtObject* NtDuplicateObject(DWORD Options);
protected:
virtual ~EmuNtObject() {};
private:
ULONG RefCount;
};
// ******************************************************************
// * Emulated symbolic link handle
// ******************************************************************
class EmuNtSymbolicLinkObject : public EmuNtObject {
public:
char DriveLetter;
std::string SymbolicLinkName;
bool IsHostBasedPath;
std::string XboxSymbolicLinkPath;
std::string HostSymbolicLinkPath;
HANDLE RootDirectoryHandle;
NTSTATUS Init(std::string aSymbolicLinkName, std::string aFullPath);
~EmuNtSymbolicLinkObject();
};
struct XboxDevice {
std::string XboxDevicePath;
std::string HostDevicePath;
HANDLE HostRootHandle;
};
// ******************************************************************
// * is Handle a 'special' emulated handle?
// ******************************************************************
bool IsEmuHandle(HANDLE Handle);
EmuHandle* HandleToEmuHandle(HANDLE Handle);
HANDLE EmuHandleToHandle(EmuHandle* emuHandle);
CHAR* NtStatusToString(IN NTSTATUS Status);
int CxbxRegisterDeviceHostPath(std::string XboxFullPath, std::string HostDevicePath, bool IsFile = false);
int CxbxDeviceIndexByDevicePath(const char *XboxDevicePath);
XboxDevice *CxbxDeviceByDevicePath(const std::string XboxDevicePath);
char SymbolicLinkToDriveLetter(std::string aSymbolicLinkName);
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByDriveLetter(const char DriveLetter);
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByName(std::string SymbolicLinkName);
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByDevice(std::string DeviceName);
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByRootHandle(HANDLE Handle);
void CleanupSymbolicLinks();
HANDLE CxbxGetDeviceNativeRootHandle(std::string XboxFullPath);
NTSTATUS CxbxCreateSymbolicLink(std::string SymbolicLinkName, std::string FullPath);
std::wstring string_to_wstring(std::string const & src);
std::wstring PUNICODE_STRING_to_wstring(NtDll::PUNICODE_STRING const & src);
std::string PSTRING_to_string(xboxkrnl::PSTRING const & src);
void copy_string_to_PSTRING_to(std::string const & src, const xboxkrnl::PSTRING & dest);
static int NtFileDirectoryInformationSize = sizeof(NtDll::FILE_DIRECTORY_INFORMATION) - 1;
static int NtPathBufferSize = MAX_PATH * sizeof(wchar_t);
// Deletes structs created by the converters
void _CxbxPVOIDDeleter(PVOID *ptr);
// Creates a PVOID variable named var which takes the given value
// and is automatically deleted when it goes out of scope
#define SMART_PVOID(var, value, orig) \
PVOID var = value; \
std::shared_ptr<PVOID> __var_shared_ptr; \
if (nullptr == var) \
{ \
__var_shared_ptr = nullptr; \
var = orig; \
} \
else \
__var_shared_ptr = std::shared_ptr<PVOID>(&var, _CxbxPVOIDDeleter);
// Converts an Xbox FileInformation struct to the NT equivalent.
// Used by NtSetInformationFile.
#define XboxToNTFileInformation(var, i, c, l) SMART_PVOID(var, _XboxToNTFileInformation(i, c, l), i)
PVOID _XboxToNTFileInformation
(
IN PVOID xboxFileInformation,
IN ULONG FileInformationClass,
OUT ULONG *Length
);
// Converts an NT FileInformation struct to the Xbox equivalent.
// Used by NtQueryInformationFile and NtQueryDirectoryFile
NTSTATUS NTToXboxFileInformation
(
IN PVOID nativeFileInformation,
OUT PVOID xboxFileInformation,
IN ULONG FileInformationClass,
IN ULONG Length
);
// Xbox Partition Information
typedef struct
{
UCHAR Name[16];
ULONG Flags;
ULONG LBAStart;
ULONG LBASize;
ULONG Reserved;
} XboxPartitionTableEntry;
typedef struct
{
UCHAR Magic[16];
char Res0[32];
XboxPartitionTableEntry TableEntries[14];
} XboxPartitionTable;
typedef struct _FATX_SUPERBLOCK
{
char Tag[4];
unsigned int VolumeID;
unsigned int ClusterSize;
USHORT FatCopies;
int Resvd;
char Unused[4078];
} FATX_SUPERBLOCK;
XboxPartitionTable CxbxGetPartitionTable();
FATX_SUPERBLOCK CxbxGetFatXSuperBlock(int partitionNumber);
int CxbxGetPartitionNumberFromHandle(HANDLE hFile);
std::string CxbxGetPartitionDataPathFromHandle(HANDLE hFile);
void CxbxFormatPartitionByHandle(HANDLE hFile);
#endif

View File

@ -85,7 +85,7 @@ IMPORT(NtQueueApcThread);
IMPORT(NtReadFile);
IMPORT(NtReleaseMutant);
IMPORT(NtReleaseSemaphore);
IMPORT(NtResumeThread);
IMPORT(NtResumeThread);
IMPORT(NtResetEvent);
IMPORT(NtSetEvent);
IMPORT(NtSetInformationFile);

View File

@ -1468,7 +1468,7 @@ typedef NTSTATUS(NTAPI *FPTR_NtPulseEvent)
IN HANDLE EventHandle,
OUT PLONG PreviousState OPTIONAL
);
// ******************************************************************
// * NtResetEvent
// ******************************************************************
@ -1476,7 +1476,7 @@ typedef NTSTATUS(NTAPI *FPTR_NtResetEvent)
(
IN HANDLE EventHandle,
OUT PLONG PreviousState OPTIONAL
);
);
// ******************************************************************
// * NtCreateMutant
@ -1949,7 +1949,7 @@ EXTERN(NtQueryVolumeInformationFile);
EXTERN(NtQueueApcThread);
EXTERN(NtReadFile);
EXTERN(NtReleaseMutant);
EXTERN(NtReleaseSemaphore);
EXTERN(NtReleaseSemaphore);
EXTERN(NtResetEvent);
EXTERN(NtResumeThread);
EXTERN(NtSetEvent);
@ -2013,6 +2013,6 @@ EXTERN(RtlUpcaseUnicodeChar);
EXTERN(RtlUpcaseUnicodeString);
EXTERN(RtlUpcaseUnicodeToMultiByteN);
EXTERN(RtlUpperString);
EXTERN(RtlUshortByteSwap);
EXTERN(RtlUshortByteSwap);
#endif

View File

@ -318,7 +318,7 @@ uint32_t EmuNVNet_Read(xbaddr addr, int size)
void EmuNVNet_DMAPacketFromGuest()
{
struct RingDesc desc;
bool is_last_packet;
bool is_last_packet;
bool packet_sent = false;
NvNetState_t* s = &NvNetState;
@ -334,7 +334,7 @@ void EmuNVNet_DMAPacketFromGuest()
EmuLog(LOG_LEVEL::DEBUG, "Looking at ring desc %d (%llx): "
"\n Buffer: 0x%x "
"\n Length: 0x%x "
"\n Flags: 0x%x ",
"\n Flags: 0x%x ",
s->tx_ring_index, tx_ring_addr, desc.packet_buffer, desc.length, desc.flags);
s->tx_ring_index += 1;
@ -348,8 +348,8 @@ void EmuNVNet_DMAPacketFromGuest()
memcpy(s->txrx_dma_buf, (void*)(desc.packet_buffer | CONTIGUOUS_MEMORY_BASE), desc.length + 1);
g_NVNet->PCAPSend(s->txrx_dma_buf, desc.length + 1);
packet_sent = true;
packet_sent = true;
/* Update descriptor */
is_last_packet = desc.flags & NV_TX_LASTPACKET;
@ -363,12 +363,12 @@ void EmuNVNet_DMAPacketFromGuest()
break;
}
}
if (packet_sent) {
/* Trigger interrupt */
EmuLog(LOG_LEVEL::DEBUG, "Triggering interrupt");
EmuNVNet_SetRegister(NvRegIrqStatus, NVREG_IRQSTAT_BIT4, 4);
EmuNVNet_UpdateIRQ();
EmuNVNet_UpdateIRQ();
}
}
@ -389,7 +389,7 @@ bool EmuNVNet_DMAPacketToGuest(void* packet, size_t size)
EmuLog(LOG_LEVEL::DEBUG, "Looking at ring descriptor %d (0x%llx): "
"\n Buffer: 0x%x "
"\n Length: 0x%x "
"\n Flags: 0x%x ",
"\n Flags: 0x%x ",
s->rx_ring_index, rx_ring_addr, desc.packet_buffer, desc.length, desc.flags);
s->rx_ring_index += 1;
@ -408,7 +408,7 @@ bool EmuNVNet_DMAPacketToGuest(void* packet, size_t size)
memcpy((void*)(rx_ring_addr | CONTIGUOUS_MEMORY_BASE), &desc, sizeof(desc));
EmuLog(LOG_LEVEL::DEBUG, "Updated ring descriptor: "
"\n Length: 0x%x "
"\n Flags: 0x%x ",
"\n Flags: 0x%x ",
desc.flags, desc.length);
/* Trigger interrupt */
@ -593,18 +593,18 @@ void NVNetDevice::MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigne
return;
}
EmuNVNet_Write(addr, value, size); // For now, forward
// Cache guest MAC address for packet filter
if (addr == NvRegMacAddrA) {
m_GuestMacAddress.bytes[0] = NvNetState.regs[NvRegMacAddrA + 0];
m_GuestMacAddress.bytes[1] = NvNetState.regs[NvRegMacAddrA + 1];
m_GuestMacAddress.bytes[2] = NvNetState.regs[NvRegMacAddrA + 2];
m_GuestMacAddress.bytes[3] = NvNetState.regs[NvRegMacAddrA + 3];
}
else if (addr == NvRegMacAddrB) {
EmuNVNet_Write(addr, value, size); // For now, forward
// Cache guest MAC address for packet filter
if (addr == NvRegMacAddrA) {
m_GuestMacAddress.bytes[0] = NvNetState.regs[NvRegMacAddrA + 0];
m_GuestMacAddress.bytes[1] = NvNetState.regs[NvRegMacAddrA + 1];
m_GuestMacAddress.bytes[2] = NvNetState.regs[NvRegMacAddrA + 2];
m_GuestMacAddress.bytes[3] = NvNetState.regs[NvRegMacAddrA + 3];
}
else if (addr == NvRegMacAddrB) {
m_GuestMacAddress.bytes[4] = NvNetState.regs[NvRegMacAddrB + 0];
m_GuestMacAddress.bytes[5] = NvNetState.regs[NvRegMacAddrB + 1];
m_GuestMacAddress.bytes[5] = NvNetState.regs[NvRegMacAddrB + 1];
}
}
@ -671,7 +671,7 @@ void PrintPacket(void* buffer, size_t length)
size_t payloadLength = length - sizeof(ethernet_header);
// TODO: If we support the EtherType, decode it, otherwise, just dump the raw payload
//switch (ntohs(header->protocol))
//switch (ntohs(header->protocol))
{
// default:
PrintRawPayload(payloadPtr, payloadLength);
@ -688,11 +688,11 @@ bool NVNetDevice::PCAPSend(void* packet, size_t length)
// TODO: Optional
// PrintPacket(packet, length);
// Forward broadcast packets direct to the host PC, as well as over the network
if (memcmp(header->dst.bytes, m_BroadcastMacAddress.bytes, 6) == 0) {
static char pack[65536];
memcpy(pack, packet, length);
memcpy(pack, packet, length);
ethernet_header* _header = (ethernet_header*)pack;
_header->dst = m_HostMacAddress;
pcap_sendpacket((pcap_t*)m_AdapterHandle, (uint8_t*)pack, length);
@ -711,7 +711,7 @@ size_t NVNetDevice::PCAPReceive(void* packet, size_t max_length)
const uint8_t *pkt_data;
if (int res = pcap_next_ex((pcap_t*)m_AdapterHandle, &header, &pkt_data) > 0) {
// Only forward packets that are broadcast or specifically for Cxbx-R's MAC
// Only forward packets that are broadcast or specifically for Cxbx-R's MAC
ethernet_header* e_header = (ethernet_header*)pkt_data;
if (memcmp(e_header->dst.bytes, m_GuestMacAddress.bytes, 6) == 0 || memcmp(e_header->dst.bytes, m_BroadcastMacAddress.bytes, 6) == 0) {
memcpy(packet, pkt_data, header->len);

View File

@ -23,7 +23,7 @@
// *
// ******************************************************************
#pragma once
#include <string>
#include "PCIDevice.h" // For PCIDevice
@ -226,6 +226,6 @@ private:
void* m_AdapterHandle = nullptr;
std::string m_HostAdapterName;
mac_address m_HostMacAddress;
mac_address m_GuestMacAddress = { 0x00, 0x50, 0xF2, 0x00, 0x00, 0x34 };
mac_address m_GuestMacAddress = { 0x00, 0x50, 0xF2, 0x00, 0x00, 0x34 };
mac_address m_BroadcastMacAddress = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
};

View File

@ -28,7 +28,7 @@
#define LOG_PREFIX CXBXR_MODULE::MCPX
#include "MCPXDevice.h"
#include "MCPXDevice.h"
#include "Logging.h"
/* MCPXDevice */

View File

@ -152,4 +152,4 @@ void PCIBus::Reset()
for (auto it = m_Devices.begin(); it != m_Devices.end(); ++it) {
it->second->Reset();
}
}
}

View File

@ -75,4 +75,4 @@ private:
PCIConfigAddressRegister m_configAddressRegister;
};
#endif
#endif

View File

@ -141,4 +141,4 @@ private:
*/
};
#endif
#endif

View File

@ -245,4 +245,4 @@ uint32_t SMBus::MMIORead(int barIndex, uint32_t addr, unsigned size)
void SMBus::MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size)
{
}
}

View File

@ -105,4 +105,4 @@ class SMBus : public PCIDevice {
std::map<uint8_t, SMDevice*> m_Devices;
};
#endif
#endif

View File

@ -58,7 +58,7 @@ void SetLEDSequence(LED::Sequence aLEDSequence)
SMCDevice::SMCDevice(SCMRevision revision, uint8_t av_pack)
{
m_revision = revision;
m_revision = revision;
buffer[SMC_COMMAND_AV_PACK] = av_pack;
}

Some files were not shown because too many files have changed in this diff Show More