port some rendering stuff

This commit is contained in:
ApfelTeeSaft
2025-04-10 14:09:32 +02:00
parent 9dd1632e62
commit 0046d2cb1f
95 changed files with 25495 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.13.35931.197 d17.13
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ani2-on-dx11", "ani2-on-dx11\ani2-on-dx11.vcxproj", "{A5177126-A737-4749-8F5F-31F2BD43EA53}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A5177126-A737-4749-8F5F-31F2BD43EA53}.Debug|x64.ActiveCfg = Debug|x64
{A5177126-A737-4749-8F5F-31F2BD43EA53}.Debug|x64.Build.0 = Debug|x64
{A5177126-A737-4749-8F5F-31F2BD43EA53}.Debug|x86.ActiveCfg = Debug|Win32
{A5177126-A737-4749-8F5F-31F2BD43EA53}.Debug|x86.Build.0 = Debug|Win32
{A5177126-A737-4749-8F5F-31F2BD43EA53}.Release|x64.ActiveCfg = Release|x64
{A5177126-A737-4749-8F5F-31F2BD43EA53}.Release|x64.Build.0 = Release|x64
{A5177126-A737-4749-8F5F-31F2BD43EA53}.Release|x86.ActiveCfg = Release|Win32
{A5177126-A737-4749-8F5F-31F2BD43EA53}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F8391B1D-F50C-4FAB-81AD-A98C26951A2B}
EndGlobalSection
EndGlobal
+422
View File
@@ -0,0 +1,422 @@
0x81,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x84,0x86,0x86,0x86,0x89,0x8e,0x8f,0x8a,0x86,
0x86,0x89,0x88,0x85,0x85,0x88,0x8c,0x8d,0x89,0x85,0x81,0x7c,0x7a,0x7a,0x7a,0x7b,
0x7e,0x7f,0x7f,0x7d,0x7b,0x79,0x76,0x75,0x76,0x78,0x7a,0x7c,0x7c,0x7b,0x79,0x77,
0x77,0x78,0x78,0x78,0x79,0x7b,0x7e,0x7f,0x7f,0x7f,0x7c,0x79,0x78,0x77,0x76,0x79,
0x7c,0x7f,0x80,0x82,0x83,0x83,0x83,0x84,0x84,0x82,0x7e,0x7b,0x7b,0x79,0x78,0x77,
0x79,0x7d,0x7f,0x84,0x8a,0x8e,0x8e,0x8c,0x8a,0x8a,0x8a,0x8b,0x89,0x86,0x82,0x80,
0x7f,0x7d,0x7c,0x7d,0x7f,0x81,0x83,0x86,0x86,0x85,0x82,0x7e,0x7a,0x78,0x7b,0x81,
0x86,0x89,0x8b,0x8a,0x87,0x84,0x7f,0x79,0x73,0x6f,0x6d,0x6d,0x73,0x78,0x7b,0x7d,
0x80,0x81,0x7e,0x7c,0x7b,0x7c,0x7e,0x81,0x85,0x87,0x88,0x87,0x84,0x7e,0x79,0x76,
0x77,0x7b,0x7e,0x7f,0x7e,0x7d,0x7c,0x7c,0x7e,0x80,0x84,0x88,0x8b,0x8a,0x85,0x80,
0x7c,0x7d,0x80,0x81,0x82,0x83,0x82,0x7e,0x7d,0x7f,0x83,0x87,0x88,0x8a,0x88,0x84,
0x7f,0x7a,0x76,0x76,0x7b,0x82,0x8a,0x8d,0x8c,0x89,0x84,0x80,0x7f,0x81,0x81,0x7e,
0x7d,0x7e,0x7c,0x76,0x6d,0x6d,0x78,0x82,0x83,0x81,0x85,0x8a,0x89,0x84,0x7d,0x7b,
0x7a,0x77,0x73,0x71,0x72,0x75,0x78,0x7b,0x7b,0x7c,0x7f,0x83,0x85,0x83,0x82,0x83,
0x82,0x80,0x7e,0x7b,0x7e,0x80,0x7f,0x7f,0x80,0x86,0x8a,0x89,0x8b,0x8b,0x8a,0x86,
0x7f,0x76,0x71,0x71,0x75,0x7a,0x81,0x87,0x88,0x86,0x86,0x83,0x82,0x80,0x7f,0x82,
0x88,0x8e,0x92,0x93,0x90,0x89,0x83,0x7b,0x72,0x6a,0x61,0x5f,0x62,0x66,0x6d,0x76,
0x7f,0x85,0x8e,0x94,0x93,0x8e,0x85,0x7e,0x75,0x71,0x6e,0x6d,0x70,0x76,0x7d,0x85,
0x8b,0x8e,0x92,0x96,0x9b,0x9b,0x94,0x86,0x79,0x6d,0x64,0x5f,0x60,0x65,0x6b,0x73,
0x7b,0x82,0x87,0x8a,0x8e,0x91,0x93,0x94,0x95,0x95,0x93,0x8d,0x86,0x80,0x7a,0x76,
0x74,0x73,0x74,0x75,0x78,0x7c,0x80,0x83,0x85,0x86,0x85,0x86,0x85,0x82,0x80,0x7e,
0x7e,0x7f,0x7e,0x7c,0x78,0x74,0x74,0x75,0x7a,0x7f,0x83,0x87,0x8a,0x8a,0x86,0x82,
0x7e,0x7a,0x76,0x72,0x6e,0x6d,0x6e,0x70,0x74,0x7a,0x82,0x8a,0x91,0x97,0x9a,0x9b,
0x9b,0x96,0x8c,0x80,0x78,0x74,0x71,0x73,0x73,0x70,0x6c,0x6b,0x6e,0x77,0x7a,0x7c,
0x7f,0x84,0x8b,0x93,0x97,0x92,0x8b,0x86,0x82,0x81,0x82,0x7d,0x70,0x66,0x62,0x63,
0x6a,0x74,0x7d,0x86,0x8d,0x8c,0x8b,0x92,0x9d,0xaa,0xb4,0xb4,0xa9,0x98,0x87,0x7b,
0x77,0x7b,0x80,0x7c,0x75,0x6b,0x64,0x65,0x70,0x7d,0x7f,0x75,0x65,0x5c,0x61,0x6e,
0x79,0x7f,0x7c,0x79,0x79,0x7d,0x7f,0x7f,0x7e,0x82,0x86,0x88,0x87,0x84,0x82,0x80,
0x79,0x6d,0x75,0x86,0x8e,0x8c,0x90,0x94,0x91,0x8c,0x86,0x8b,0x8b,0x83,0x76,0x71,
0x78,0x7a,0x6f,0x63,0x61,0x63,0x62,0x62,0x6a,0x70,0x7a,0x79,0x7e,0x81,0x8c,0x8a,
0x86,0x8c,0x97,0x9f,0x94,0x8e,0x8c,0x8d,0x8d,0x91,0x96,0x95,0x8f,0x86,0x80,0x7b,
0x78,0x79,0x79,0x79,0x7c,0x86,0x8f,0x92,0x92,0x91,0x8d,0x84,0x7b,0x75,0x72,0x6d,
0x67,0x60,0x57,0x58,0x63,0x70,0x7c,0x86,0x91,0x99,0x9d,0x9f,0x9f,0x9f,0xa0,0x9e,
0x95,0x8b,0x83,0x75,0x6a,0x62,0x5b,0x59,0x5b,0x5c,0x5f,0x64,0x6b,0x73,0x7b,0x84,
0x8d,0x90,0x93,0x94,0x96,0x99,0x9b,0x96,0x8e,0x85,0x7c,0x75,0x71,0x72,0x72,0x72,
0x70,0x6c,0x64,0x5e,0x5c,0x5f,0x65,0x6f,0x79,0x84,0x8b,0x92,0x99,0xa1,0xa6,0xa8,
0xa8,0xa5,0xa4,0x9f,0x9a,0x95,0x90,0x8c,0x89,0x85,0x7f,0x7b,0x77,0x71,0x6c,0x65,
0x5e,0x59,0x56,0x56,0x5a,0x60,0x68,0x71,0x7b,0x89,0x96,0x9f,0xa6,0xab,0xb0,0xb4,
0xb3,0xb0,0xa9,0x9d,0x8e,0x7b,0x65,0x4d,0x3a,0x2d,0x28,0x2d,0x38,0x47,0x58,0x69,
0x76,0x81,0x8b,0x97,0xa7,0xb5,0xbc,0xba,0xb0,0xa1,0x8e,0x7a,0x6b,0x62,0x5c,0x5d,
0x62,0x65,0x66,0x68,0x6d,0x76,0x83,0x93,0xa3,0xb2,0xb8,0xb9,0xb3,0xa9,0x9e,0x92,
0x89,0x85,0x84,0x81,0x7b,0x6f,0x5d,0x4a,0x37,0x2f,0x31,0x3f,0x57,0x71,0x8a,0x9d,
0xa9,0xad,0xb0,0xb0,0xac,0xa7,0x9e,0x90,0x82,0x77,0x71,0x6f,0x71,0x76,0x7c,0x7d,
0x7a,0x77,0x78,0x7a,0x7e,0x85,0x8d,0x92,0x91,0x8b,0x85,0x7c,0x72,0x69,0x65,0x69,
0x74,0x81,0x8f,0x9a,0x9f,0x9d,0x96,0x8f,0x8a,0x86,0x83,0x7f,0x7d,0x7e,0x79,0x6f,
0x62,0x58,0x53,0x52,0x52,0x59,0x66,0x79,0x8d,0x9f,0xaa,0xad,0xa8,0x9d,0x8f,0x81,
0x75,0x69,0x60,0x5c,0x5c,0x5f,0x67,0x74,0x81,0x8f,0x9a,0xa2,0xa3,0xa0,0x9a,0x92,
0x88,0x80,0x7c,0x79,0x75,0x6e,0x67,0x62,0x63,0x66,0x6d,0x78,0x86,0x92,0x9d,0xa6,
0xad,0xb2,0xb3,0xb0,0xa7,0x9b,0x8a,0x77,0x69,0x5f,0x5a,0x58,0x59,0x5c,0x61,0x66,
0x6a,0x6d,0x70,0x72,0x75,0x78,0x78,0x75,0x70,0x6c,0x69,0x68,0x68,0x6a,0x71,0x7b,
0x88,0x94,0x9f,0xa9,0xae,0xad,0xa6,0x9a,0x8e,0x82,0x7b,0x7b,0x7c,0x81,0x84,0x86,
0x87,0x87,0x87,0x89,0x8c,0x8c,0x8c,0x89,0x86,0x82,0x7f,0x79,0x71,0x68,0x5d,0x55,
0x51,0x52,0x59,0x63,0x6e,0x78,0x81,0x88,0x8c,0x8d,0x8b,0x86,0x7f,0x7a,0x77,0x78,
0x7d,0x85,0x8f,0x97,0x9c,0x9e,0x9d,0x9c,0x9d,0x9e,0x9e,0x9c,0x99,0x95,0x8f,0x88,
0x81,0x7a,0x76,0x72,0x70,0x6e,0x6b,0x68,0x63,0x5e,0x59,0x58,0x5b,0x5c,0x60,0x67,
0x71,0x79,0x7e,0x82,0x83,0x84,0x83,0x7e,0x7c,0x7d,0x82,0x8d,0x9a,0xa3,0xa5,0xa1,
0x9d,0x9a,0x99,0x99,0x97,0x96,0x95,0x91,0x8d,0x89,0x87,0x83,0x7d,0x71,0x62,0x55,
0x4b,0x47,0x48,0x4d,0x58,0x62,0x6a,0x71,0x77,0x7d,0x81,0x88,0x8d,0x91,0x92,0x93,
0x94,0x97,0x9e,0xa7,0xaf,0xb2,0xb2,0xb0,0xaa,0xa3,0xa0,0x9f,0x9c,0x98,0x8f,0x86,
0x7e,0x77,0x70,0x6a,0x66,0x5d,0x50,0x42,0x35,0x2a,0x27,0x2b,0x34,0x42,0x50,0x5e,
0x6d,0x7d,0x8c,0x98,0x9f,0x9e,0x9d,0x9e,0xa4,0xab,0xb2,0xb5,0xb6,0xb4,0xae,0xa3,
0x97,0x8b,0x7e,0x71,0x61,0x52,0x47,0x43,0x44,0x48,0x4e,0x55,0x5e,0x63,0x68,0x6e,
0x74,0x80,0x8a,0x93,0xa0,0xad,0xb5,0xbe,0xc0,0xbb,0xb7,0xae,0xa3,0x99,0x8d,0x85,
0x7b,0x74,0x72,0x6d,0x6a,0x68,0x62,0x5c,0x5b,0x5c,0x5f,0x65,0x6d,0x74,0x7b,0x82,
0x87,0x89,0x8d,0x8d,0x89,0x85,0x82,0x82,0x86,0x8c,0x93,0x98,0x9b,0x9d,0x9a,0x90,
0x83,0x74,0x64,0x56,0x4c,0x44,0x42,0x44,0x49,0x55,0x64,0x72,0x7e,0x8a,0x93,0x99,
0x9e,0xa2,0xa3,0xa4,0xa3,0xa2,0x9d,0x98,0x91,0x88,0x82,0x7d,0x7b,0x7c,0x7d,0x7c,
0x7a,0x78,0x79,0x7b,0x80,0x88,0x8f,0x93,0x95,0x96,0x95,0x93,0x8e,0x86,0x7f,0x79,
0x73,0x6c,0x65,0x61,0x5f,0x5d,0x5e,0x61,0x66,0x69,0x6d,0x72,0x78,0x7e,0x84,0x89,
0x8e,0x94,0x9c,0xa3,0xa8,0xac,0xac,0xa9,0xa2,0x98,0x8f,0x84,0x7b,0x74,0x6e,0x66,
0x5e,0x5a,0x59,0x58,0x58,0x5a,0x5f,0x6a,0x78,0x85,0x92,0x9c,0xa3,0xa8,0xac,0xae,
0xac,0xa5,0x9c,0x91,0x83,0x76,0x69,0x5e,0x55,0x4c,0x45,0x41,0x41,0x44,0x4d,0x5c,
0x6f,0x83,0x96,0xa4,0xac,0xaf,0xae,0xab,0xa5,0x9e,0x94,0x8a,0x80,0x77,0x71,0x6b,
0x67,0x64,0x64,0x65,0x67,0x68,0x6a,0x6e,0x74,0x7a,0x80,0x87,0x8e,0x96,0x9e,0xa6,
0xab,0xac,0xa9,0xa5,0x9e,0x95,0x8b,0x81,0x78,0x70,0x69,0x63,0x5e,0x5a,0x58,0x5c,
0x65,0x70,0x7d,0x88,0x91,0x97,0x9c,0x9e,0x9d,0x99,0x96,0x91,0x8e,0x88,0x7d,0x70,
0x61,0x57,0x52,0x53,0x58,0x60,0x6c,0x75,0x7d,0x83,0x86,0x89,0x8b,0x8d,0x8f,0x91,
0x94,0x96,0x95,0x90,0x88,0x7e,0x73,0x69,0x63,0x60,0x5f,0x5f,0x62,0x67,0x6e,0x76,
0x80,0x88,0x8c,0x8d,0x8d,0x8f,0x95,0x9d,0xa5,0xac,0xaf,0xac,0xa5,0x98,0x8b,0x7f,
0x78,0x73,0x70,0x6f,0x6e,0x6c,0x6b,0x6c,0x6e,0x72,0x78,0x7e,0x85,0x88,0x89,0x85,
0x80,0x7a,0x71,0x6b,0x69,0x6c,0x73,0x7a,0x7f,0x7d,0x75,0x6f,0x6c,0x71,0x79,0x83,
0x8f,0x98,0x9e,0xa1,0x9e,0x95,0x89,0x81,0x7e,0x7c,0x7b,0x79,0x76,0x75,0x73,0x76,
0x7a,0x7c,0x7d,0x7c,0x7e,0x81,0x82,0x83,0x86,0x86,0x8a,0x8c,0x86,0x7d,0x73,0x6c,
0x6f,0x73,0x75,0x76,0x78,0x7a,0x80,0x8a,0x8c,0x8c,0x8f,0x91,0x93,0x92,0x8e,0x88,
0x86,0x87,0x89,0x8a,0x8b,0x8d,0x8d,0x88,0x84,0x80,0x7c,0x77,0x72,0x6f,0x6d,0x6d,
0x6f,0x71,0x71,0x72,0x73,0x71,0x6b,0x6a,0x6f,0x74,0x7c,0x8a,0x96,0x9b,0x9d,0x9e,
0x9a,0x94,0x90,0x8a,0x83,0x7c,0x77,0x72,0x6d,0x6c,0x6c,0x6a,0x68,0x68,0x66,0x61,
0x5e,0x5e,0x62,0x67,0x6e,0x77,0x80,0x8d,0x9c,0xab,0xb8,0xc0,0xc5,0xc2,0xbd,0xb4,
0xa8,0x97,0x85,0x71,0x5d,0x4d,0x42,0x3c,0x38,0x3a,0x3f,0x46,0x51,0x61,0x72,0x87,
0x98,0xa5,0xae,0xb3,0xb2,0xb0,0xaa,0xa3,0x99,0x8c,0x7c,0x6b,0x5b,0x50,0x4a,0x47,
0x47,0x4a,0x53,0x61,0x75,0x8b,0x9f,0xaf,0xba,0xc0,0xc1,0xbe,0xba,0xb6,0xaf,0xa4,
0x92,0x79,0x60,0x49,0x34,0x28,0x25,0x2c,0x3b,0x4f,0x68,0x81,0x9a,0xb1,0xc1,0xc9,
0xcd,0xca,0xbf,0xb0,0x98,0x7d,0x64,0x4f,0x3c,0x2f,0x2e,0x32,0x3a,0x4e,0x69,0x88,
0xa7,0xc4,0xda,0xe3,0xdf,0xd3,0xbd,0x9b,0x78,0x5c,0x47,0x34,0x2b,0x2f,0x3d,0x54,
0x73,0x93,0xaf,0xc8,0xd5,0xd3,0xc6,0xb3,0x9b,0x80,0x65,0x4e,0x3f,0x37,0x3a,0x46,
0x58,0x6e,0x84,0x96,0xa2,0xab,0xb2,0xb1,0xaa,0x9f,0x8f,0x7b,0x67,0x58,0x55,0x57,
0x5e,0x65,0x6c,0x76,0x81,0x8b,0x90,0x8b,0x85,0x82,0x82,0x83,0x85,0x85,0x83,0x7d,
0x78,0x75,0x72,0x6b,0x61,0x56,0x4e,0x4e,0x5b,0x6f,0x83,0x94,0xa3,0xaf,0xb9,0xbb,
0xb4,0xa1,0x84,0x67,0x4f,0x43,0x3e,0x45,0x53,0x68,0x80,0x97,0xaa,0xb3,0xb2,0xaa,
0xa0,0x94,0x87,0x7c,0x72,0x6a,0x67,0x6b,0x74,0x7d,0x85,0x8a,0x8c,0x8b,0x88,0x81,
0x7a,0x75,0x75,0x79,0x7d,0x7e,0x7d,0x7d,0x7c,0x7b,0x78,0x74,0x73,0x77,0x7e,0x85,
0x8f,0x98,0x9f,0xa2,0x9d,0x92,0x85,0x79,0x6e,0x64,0x5b,0x58,0x5d,0x68,0x73,0x7e,
0x88,0x91,0x9c,0xa0,0x9a,0x93,0x90,0x8d,0x89,0x82,0x72,0x5a,0x44,0x40,0x4a,0x5a,
0x6e,0x81,0x92,0xa5,0xb3,0xb3,0xa3,0x90,0x86,0x7f,0x78,0x74,0x72,0x70,0x75,0x80,
0x87,0x86,0x84,0x86,0x86,0x84,0x82,0x82,0x84,0x87,0x84,0x7a,0x6f,0x70,0x7c,0x86,
0x88,0x83,0x7e,0x78,0x73,0x73,0x76,0x7c,0x86,0x90,0x8f,0x86,0x7d,0x78,0x75,0x73,
0x74,0x79,0x77,0x70,0x6a,0x66,0x6a,0x76,0x87,0x95,0x9a,0x99,0x91,0x82,0x76,0x6e,
0x6d,0x6f,0x75,0x7d,0x7e,0x79,0x78,0x80,0x8c,0x99,0xa3,0xa3,0x9d,0x94,0x8c,0x85,
0x7e,0x78,0x75,0x73,0x71,0x74,0x7a,0x81,0x88,0x8e,0x8c,0x83,0x7c,0x7a,0x7e,0x83,
0x83,0x7c,0x70,0x65,0x5e,0x5d,0x5e,0x64,0x6c,0x72,0x79,0x82,0x8d,0x94,0x92,0x8b,
0x84,0x80,0x7e,0x7b,0x79,0x77,0x77,0x77,0x77,0x7a,0x80,0x86,0x8a,0x89,0x87,0x83,
0x82,0x87,0x8e,0x91,0x8f,0x89,0x7f,0x76,0x71,0x74,0x7c,0x81,0x82,0x82,0x87,0x92,
0x9c,0x9f,0x9d,0x98,0x92,0x8a,0x82,0x7a,0x74,0x75,0x7b,0x7f,0x7e,0x7c,0x7b,0x7c,
0x80,0x85,0x88,0x88,0x86,0x82,0x7f,0x7a,0x76,0x74,0x72,0x71,0x72,0x74,0x77,0x7b,
0x80,0x84,0x89,0x8c,0x89,0x80,0x74,0x6a,0x63,0x62,0x66,0x6d,0x76,0x81,0x8b,0x90,
0x8e,0x8a,0x84,0x7e,0x79,0x74,0x6e,0x70,0x73,0x7c,0x84,0x86,0x8d,0x8b,0x87,0x84,
0x79,0x72,0x6b,0x69,0x6e,0x74,0x7c,0x85,0x8c,0x90,0x8e,0x87,0x7e,0x7a,0x75,0x73,
0x73,0x76,0x7b,0x86,0x93,0x9a,0x9c,0x9b,0x94,0x88,0x7f,0x78,0x77,0x76,0x78,0x7a,
0x7c,0x80,0x83,0x8a,0x90,0x94,0x93,0x90,0x88,0x7e,0x73,0x6a,0x64,0x65,0x6c,0x75,
0x7f,0x85,0x87,0x86,0x84,0x85,0x86,0x86,0x88,0x89,0x89,0x87,0x84,0x81,0x7e,0x77,
0x73,0x71,0x73,0x78,0x7e,0x86,0x86,0x7f,0x74,0x6c,0x67,0x65,0x68,0x6f,0x74,0x78,
0x7b,0x7c,0x7d,0x7e,0x82,0x87,0x8c,0x8d,0x8d,0x8a,0x85,0x7f,0x7b,0x7a,0x7a,0x7c,
0x7f,0x85,0x8a,0x8e,0x90,0x92,0x94,0x94,0x95,0x94,0x93,0x90,0x8a,0x84,0x80,0x7e,
0x7e,0x7f,0x7e,0x7b,0x77,0x72,0x6f,0x71,0x76,0x7c,0x80,0x80,0x7d,0x7b,0x77,0x74,
0x75,0x78,0x7d,0x82,0x85,0x85,0x83,0x7e,0x78,0x75,0x75,0x77,0x78,0x79,0x7c,0x7f,
0x83,0x85,0x86,0x86,0x87,0x88,0x8a,0x86,0x80,0x79,0x73,0x73,0x77,0x7b,0x7f,0x7f,
0x80,0x7f,0x7f,0x81,0x85,0x88,0x89,0x88,0x83,0x7e,0x7a,0x79,0x7b,0x7e,0x80,0x81,
0x7e,0x79,0x77,0x75,0x73,0x76,0x7c,0x85,0x8d,0x8e,0x88,0x7d,0x75,0x71,0x76,0x7e,
0x81,0x81,0x83,0x83,0x82,0x80,0x79,0x70,0x6a,0x69,0x6f,0x79,0x87,0x91,0x95,0x93,
0x8e,0x88,0x85,0x81,0x80,0x84,0x86,0x87,0x85,0x7f,0x77,0x6f,0x6a,0x6d,0x76,0x82,
0x8f,0x96,0x94,0x88,0x78,0x6d,0x6a,0x71,0x7a,0x7e,0x7a,0x74,0x71,0x75,0x81,0x8d,
0x96,0x98,0x95,0x90,0x8c,0x8e,0x93,0x95,0x8e,0x87,0x84,0x84,0x87,0x8c,0x8d,0x8c,
0x8b,0x88,0x84,0x7f,0x7c,0x7c,0x7c,0x7a,0x79,0x76,0x75,0x74,0x78,0x7e,0x81,0x81,
0x7c,0x75,0x6b,0x68,0x6a,0x6f,0x71,0x73,0x72,0x70,0x70,0x73,0x77,0x7d,0x86,0x92,
0xa2,0xb0,0xb4,0xad,0xa1,0x91,0x80,0x7a,0x7f,0x84,0x83,0x7f,0x7a,0x79,0x7d,0x82,
0x82,0x7e,0x78,0x73,0x72,0x74,0x76,0x77,0x74,0x71,0x71,0x71,0x72,0x6f,0x6d,0x6e,
0x6f,0x71,0x71,0x71,0x70,0x70,0x70,0x73,0x79,0x7e,0x85,0x8b,0x8d,0x8b,0x89,0x87,
0x88,0x8d,0x91,0x91,0x91,0x90,0x8e,0x8b,0x8a,0x87,0x81,0x78,0x70,0x69,0x66,0x6a,
0x71,0x79,0x7f,0x83,0x84,0x83,0x82,0x83,0x86,0x8d,0x94,0x99,0x9c,0x9b,0x96,0x93,
0x92,0x8f,0x84,0x77,0x6d,0x6a,0x6b,0x6a,0x68,0x65,0x66,0x68,0x6a,0x6c,0x70,0x73,
0x72,0x6f,0x6f,0x72,0x79,0x7f,0x85,0x84,0x82,0x86,0x92,0x98,0x93,0x8d,0x85,0x88,
0x90,0x99,0x9b,0x98,0x92,0x8c,0x86,0x7f,0x79,0x76,0x77,0x76,0x71,0x6b,0x68,0x69,
0x69,0x69,0x6a,0x6c,0x72,0x7a,0x85,0x8e,0x95,0x9b,0x9d,0xa1,0xa4,0xaa,0xaf,0xae,
0xa7,0xa2,0xa2,0x9e,0x95,0x87,0x7a,0x70,0x66,0x59,0x50,0x4f,0x54,0x5a,0x60,0x65,
0x6a,0x71,0x7c,0x86,0x8a,0x8a,0x8c,0x95,0x9c,0x9b,0x94,0x8f,0x8a,0x84,0x7d,0x7a,
0x7c,0x7f,0x7e,0x79,0x72,0x6e,0x6b,0x66,0x5f,0x56,0x51,0x4f,0x50,0x54,0x5d,0x6a,
0x78,0x8f,0xa2,0xae,0xb1,0xac,0xa6,0xa2,0xa3,0xa5,0xa7,0xa8,0xa3,0x91,0x78,0x5f,
0x4f,0x49,0x4e,0x57,0x62,0x6a,0x70,0x6e,0x6c,0x6e,0x75,0x82,0x8e,0x9a,0xa5,0xaf,
0xad,0xa3,0x9b,0x91,0x88,0x81,0x7a,0x78,0x79,0x7a,0x79,0x76,0x76,0x78,0x7c,0x81,
0x87,0x8a,0x8c,0x8d,0x89,0x85,0x80,0x7e,0x7e,0x84,0x87,0x8a,0x8c,0x8c,0x8a,0x86,
0x80,0x7c,0x77,0x70,0x65,0x5a,0x4e,0x49,0x49,0x4d,0x55,0x64,0x79,0x8c,0x9a,0x9f,
0x9e,0x9a,0x91,0x8c,0x87,0x85,0x85,0x84,0x81,0x7f,0x81,0x82,0x86,0x8a,0x8b,0x8c,
0x89,0x84,0x7f,0x7d,0x7d,0x7f,0x84,0x89,0x90,0x96,0x97,0x95,0x90,0x89,0x80,0x79,
0x74,0x71,0x6d,0x6d,0x71,0x71,0x76,0x75,0x76,0x75,0x6e,0x69,0x66,0x69,0x71,0x79,
0x81,0x8b,0x99,0xa1,0xa7,0xa6,0xa5,0x9f,0x99,0x8e,0x80,0x78,0x73,0x74,0x72,0x6f,
0x6f,0x6a,0x69,0x66,0x60,0x5e,0x64,0x6d,0x78,0x83,0x8a,0x8c,0x90,0x98,0x9f,0x9c,
0x93,0x89,0x7d,0x6f,0x6b,0x70,0x75,0x77,0x77,0x76,0x71,0x6a,0x63,0x60,0x66,0x70,
0x7a,0x82,0x89,0x90,0x9b,0xa6,0xa9,0xa9,0xa4,0x9c,0x92,0x8a,0x84,0x82,0x84,0x87,
0x85,0x7b,0x72,0x6f,0x6f,0x73,0x7c,0x85,0x8e,0x96,0x97,0x91,0x86,0x7d,0x77,0x75,
0x71,0x6d,0x66,0x62,0x62,0x67,0x72,0x80,0x8c,0x93,0x97,0x95,0x8c,0x85,0x83,0x86,
0x8a,0x90,0x9b,0xa3,0xa6,0x9d,0x8e,0x87,0x7d,0x75,0x6c,0x64,0x5a,0x5d,0x5d,0x67,
0x6c,0x78,0x82,0x87,0x86,0x7e,0x80,0x7e,0x84,0x88,0x95,0x9a,0x9e,0x92,0x85,0x75,
0x69,0x63,0x64,0x6d,0x74,0x7f,0x85,0x8a,0x89,0x89,0x86,0x82,0x7f,0x7c,0x79,0x76,
0x73,0x6e,0x66,0x61,0x5f,0x62,0x64,0x67,0x6d,0x77,0x84,0x95,0xa1,0xa8,0xa8,0xa5,
0x9f,0x95,0x8f,0x81,0x78,0x6d,0x64,0x61,0x66,0x63,0x5f,0x60,0x67,0x6d,0x75,0x81,
0x84,0x82,0x82,0x83,0x85,0x89,0x8e,0x92,0x92,0x92,0x90,0x90,0x8f,0x8a,0x89,0x87,
0x8a,0x91,0x91,0x8e,0x8a,0x85,0x7e,0x78,0x73,0x71,0x71,0x75,0x77,0x7e,0x83,0x88,
0x8a,0x88,0x87,0x84,0x80,0x7c,0x7b,0x79,0x7b,0x7e,0x85,0x8d,0x95,0x9c,0xa4,0xa5,
0xa1,0x94,0x82,0x6d,0x5a,0x4c,0x44,0x43,0x49,0x54,0x61,0x6b,0x73,0x7c,0x84,0x8c,
0x97,0x9e,0x9e,0x9f,0xa3,0xa0,0x8f,0x80,0x7a,0x7b,0x76,0x66,0x5a,0x5b,0x5e,0x5b,
0x54,0x54,0x5f,0x6e,0x81,0x97,0xae,0xbf,0xca,0xcf,0xcd,0xc2,0xac,0x93,0x7c,0x6b,
0x60,0x5c,0x5d,0x61,0x68,0x6f,0x78,0x86,0x97,0xa2,0xa5,0xa3,0xa4,0xa9,0xac,0xa9,
0x9f,0x93,0x8b,0x82,0x73,0x5d,0x47,0x38,0x33,0x39,0x49,0x5b,0x6b,0x75,0x84,0x99,
0xb0,0xbb,0xb4,0x9b,0x7d,0x65,0x58,0x53,0x50,0x4d,0x4e,0x56,0x65,0x7a,0x8f,0xa0,
0xa9,0xa8,0xa1,0x9d,0x9c,0x9a,0x8f,0x7a,0x61,0x4c,0x40,0x43,0x4c,0x5e,0x6c,0x7c,
0x8d,0xa1,0xb5,0xc4,0xc8,0xbf,0xac,0x93,0x7d,0x6b,0x66,0x6a,0x72,0x78,0x7e,0x83,
0x86,0x85,0x83,0x83,0x7e,0x78,0x73,0x72,0x74,0x71,0x6a,0x62,0x63,0x6b,0x78,0x86,
0x93,0x96,0x91,0x8f,0x91,0x94,0x94,0x93,0x8a,0x81,0x79,0x71,0x69,0x62,0x5d,0x58,
0x55,0x56,0x57,0x61,0x70,0x81,0x92,0x9f,0xa5,0xa3,0x99,0x8b,0x80,0x76,0x6b,0x5f,
0x5a,0x5e,0x66,0x76,0x8b,0xa4,0xb7,0xc0,0xbd,0xad,0x9f,0x8a,0x70,0x5c,0x4e,0x4a,
0x56,0x70,0x94,0xb6,0xcd,0xd4,0xcd,0xb9,0x99,0x75,0x58,0x46,0x44,0x48,0x51,0x64,
0x77,0x87,0x94,0x98,0x94,0x8f,0x86,0x7a,0x71,0x6b,0x6b,0x72,0x7d,0x89,0x90,0x94,
0x95,0x98,0x98,0x94,0x90,0x89,0x7c,0x71,0x6d,0x70,0x77,0x7b,0x76,0x70,0x6a,0x64,
0x63,0x6e,0x75,0x73,0x74,0x78,0x7d,0x7f,0x80,0x84,0x88,0x89,0x8a,0x8a,0x8a,0x8a,
0x8a,0x8c,0x95,0x9e,0xa6,0xa5,0xa4,0xa3,0x9a,0x89,0x76,0x6f,0x6c,0x6c,0x69,0x64,
0x60,0x60,0x69,0x79,0x8a,0x97,0x97,0x8e,0x7b,0x68,0x60,0x6d,0x73,0x7a,0x80,0x8c,
0x90,0x8e,0x91,0x8b,0x89,0x8a,0x94,0x9a,0x9c,0x93,0x80,0x68,0x52,0x4b,0x49,0x54,
0x62,0x6b,0x6d,0x6f,0x71,0x74,0x80,0x86,0x87,0x7f,0x76,0x6b,0x68,0x69,0x6b,0x70,
0x74,0x7c,0x80,0x83,0x89,0x88,0x89,0x87,0x82,0x81,0x80,0x8a,0x91,0x9b,0x9f,0x9a,
0x97,0x8e,0x88,0x83,0x7c,0x7c,0x7d,0x80,0x80,0x7f,0x7b,0x75,0x73,0x70,0x71,0x75,
0x7c,0x82,0x82,0x83,0x80,0x83,0x86,0x89,0x8a,0x8e,0x8d,0x8c,0x8a,0x86,0x87,0x85,
0x7d,0x72,0x6b,0x64,0x61,0x64,0x6b,0x75,0x7e,0x86,0x8b,0x8c,0x8d,0x8e,0x8d,0x86,
0x7c,0x6e,0x60,0x58,0x57,0x5e,0x6c,0x7c,0x8e,0x9f,0xad,0xb7,0xbc,0xbb,0xb9,0xb4,
0xae,0xa7,0x9e,0x96,0x8d,0x86,0x82,0x7e,0x7c,0x79,0x77,0x73,0x6a,0x5f,0x56,0x51,
0x54,0x57,0x5d,0x6a,0x7b,0x8b,0x92,0x91,0x8a,0x7f,0x71,0x64,0x5c,0x5c,0x67,0x7b,
0x8e,0xa0,0xab,0xb1,0xb2,0xad,0xa2,0x95,0x8a,0x7e,0x70,0x69,0x68,0x6f,0x79,0x80,
0x84,0x88,0x82,0x75,0x69,0x60,0x5b,0x59,0x5a,0x5f,0x66,0x6f,0x7a,0x88,0x94,0x99,
0x94,0x86,0x73,0x5f,0x51,0x4c,0x52,0x6c,0x8d,0xab,0xc0,0xc0,0xb3,0xa3,0x8a,0x73,
0x6e,0x73,0x86,0xa4,0xb6,0xbb,0xb8,0xa8,0x98,0x8e,0x81,0x7c,0x79,0x6e,0x6d,0x6f,
0x71,0x83,0x8e,0x8d,0x81,0x69,0x4d,0x36,0x29,0x25,0x2b,0x3b,0x4e,0x60,0x74,0x83,
0x8a,0x8e,0x8b,0x81,0x78,0x74,0x76,0x7d,0x8a,0x93,0x96,0x96,0x96,0x93,0x93,0x91,
0x8a,0x8b,0x8b,0x8d,0x92,0x95,0x97,0x9b,0xa0,0x9f,0x97,0x8d,0x82,0x7f,0x7f,0x7f,
0x7d,0x7c,0x7d,0x7c,0x81,0x86,0x89,0x8b,0x8f,0x90,0x90,0x89,0x81,0x79,0x71,0x6a,
0x69,0x72,0x79,0x7a,0x7b,0x7e,0x82,0x81,0x80,0x7a,0x7a,0x7f,0x85,0x88,0x88,0x87,
0x84,0x81,0x7a,0x71,0x70,0x74,0x74,0x70,0x6c,0x69,0x67,0x67,0x67,0x68,0x6e,0x76,
0x7b,0x7c,0x7a,0x79,0x7b,0x7f,0x82,0x83,0x82,0x82,0x87,0x8b,0x8c,0x8a,0x8a,0x8a,
0x88,0x83,0x7e,0x7b,0x79,0x79,0x78,0x7b,0x7e,0x82,0x80,0x7b,0x7a,0x7b,0x7f,0x86,
0x8c,0x8b,0x86,0x83,0x82,0x82,0x85,0x88,0x89,0x88,0x87,0x88,0x8b,0x90,0x98,0x9c,
0x9c,0x97,0x92,0x8b,0x8a,0x8d,0x92,0x92,0x8d,0x84,0x7c,0x74,0x6f,0x70,0x73,0x77,
0x7c,0x84,0x8b,0x91,0x94,0x8f,0x83,0x74,0x64,0x56,0x4c,0x4a,0x53,0x62,0x71,0x7a,
0x7a,0x76,0x73,0x76,0x7e,0x85,0x8d,0x92,0x96,0x96,0x8e,0x86,0x7b,0x76,0x76,0x72,
0x6d,0x64,0x62,0x64,0x71,0x8b,0x9f,0xa9,0xa1,0x8f,0x80,0x7d,0x84,0x89,0x86,0x7d,
0x75,0x74,0x79,0x83,0x89,0x8f,0x90,0x8b,0x82,0x76,0x6e,0x6d,0x72,0x7e,0x8c,0x98,
0x9e,0x9c,0x96,0x8f,0x88,0x81,0x7a,0x77,0x79,0x7f,0x86,0x8d,0x91,0x91,0x8c,0x85,
0x7c,0x74,0x6b,0x65,0x64,0x69,0x69,0x6a,0x6b,0x6c,0x72,0x76,0x7b,0x7c,0x7a,0x7a,
0x7a,0x7d,0x84,0x8c,0x92,0x93,0x91,0x8a,0x83,0x7c,0x7a,0x7c,0x7f,0x86,0x8a,0x90,
0x90,0x8b,0x7f,0x73,0x68,0x65,0x6a,0x76,0x88,0x92,0x92,0x84,0x6c,0x57,0x4b,0x50,
0x61,0x7b,0x91,0x9d,0x9e,0x95,0x82,0x71,0x66,0x64,0x70,0x85,0x9d,0xad,0xb3,0xac,
0x9f,0x93,0x8f,0x8d,0x8c,0x88,0x7d,0x6a,0x5c,0x50,0x4b,0x4f,0x5a,0x6d,0x80,0x8c,
0x8e,0x8b,0x85,0x81,0x80,0x7f,0x7f,0x80,0x82,0x88,0x8e,0x92,0x92,0x90,0x8f,0x90,
0x8e,0x88,0x86,0x8c,0x91,0x8b,0x85,0x81,0x82,0x83,0x88,0x8e,0x87,0x7d,0x75,0x6b,
0x5e,0x59,0x5a,0x5c,0x61,0x6b,0x7b,0x89,0x93,0x93,0x8e,0x86,0x80,0x7e,0x81,0x85,
0x89,0x88,0x82,0x78,0x72,0x6d,0x6f,0x73,0x75,0x7d,0x85,0x94,0x9d,0xa4,0xa4,0xa3,
0xa1,0xa2,0x9e,0x9e,0xa1,0xa3,0xa0,0x99,0x8e,0x7d,0x6d,0x66,0x64,0x68,0x74,0x84,
0x8d,0x8f,0x8b,0x7d,0x67,0x56,0x4c,0x47,0x49,0x55,0x5a,0x5e,0x69,0x71,0x72,0x7c,
0x82,0x81,0x81,0x85,0x87,0x8d,0x95,0x93,0x8a,0x84,0x7f,0x7d,0x80,0x86,0x8a,0x8e,
0x91,0x90,0x8e,0x88,0x80,0x79,0x7c,0x85,0x90,0x97,0x96,0x8e,0x85,0x82,0x7e,0x71,
0x5b,0x44,0x3b,0x3c,0x45,0x4e,0x57,0x65,0x78,0x88,0x92,0x95,0x90,0x84,0x7e,0x80,
0x88,0x90,0x9e,0xaf,0xb9,0xbc,0xbe,0xbf,0xb7,0xaf,0xa6,0xa0,0x9a,0x8a,0x7d,0x72,
0x6e,0x6a,0x65,0x60,0x59,0x51,0x51,0x5d,0x67,0x67,0x5f,0x5f,0x6b,0x81,0x99,0xa8,
0xac,0xa4,0x97,0x8a,0x7e,0x71,0x64,0x5c,0x59,0x5d,0x62,0x65,0x66,0x6d,0x79,0x86,
0x93,0x9a,0x99,0x97,0x9c,0xac,0xc0,0xd1,0xd7,0xcd,0xb5,0x99,0x82,0x6b,0x56,0x40,
0x2f,0x27,0x25,0x22,0x1e,0x1c,0x22,0x36,0x5a,0x7c,0x8d,0x94,0x9a,0xa0,0xa1,0xa1,
0xa7,0xb2,0xb7,0xb1,0x9e,0x88,0x76,0x6c,0x6a,0x6f,0x79,0x87,0x97,0xa9,0xb2,0xb3,
0xb1,0xb7,0xc3,0xc8,0xc3,0xb3,0x9e,0x88,0x71,0x5a,0x43,0x34,0x34,0x42,0x50,0x5a,
0x5f,0x62,0x6a,0x7c,0x92,0xa5,0xb0,0xb3,0xb7,0xb7,0xb4,0xb1,0xaf,0xa6,0x91,0x73,
0x56,0x3e,0x30,0x2d,0x32,0x3b,0x4a,0x5a,0x6c,0x80,0x8a,0x91,0x96,0x9a,0x99,0x8d,
0x7f,0x6d,0x59,0x4e,0x4b,0x50,0x5a,0x68,0x7c,0x99,0xb6,0xc5,0xc6,0xbd,0xb9,0xbf,
0xcb,0xca,0xae,0x7f,0x50,0x31,0x21,0x1d,0x21,0x27,0x31,0x41,0x56,0x72,0x8a,0xa3,
0xb6,0xc3,0xcf,0xcb,0xb9,0x9c,0x84,0x73,0x6e,0x6d,0x6a,0x63,0x64,0x72,0x7e,0x81,
0x75,0x63,0x50,0x47,0x49,0x56,0x69,0x84,0x9f,0xb5,0xc3,0xc3,0xb7,0xd5,0xe1,0xde,
0xf1,0xd6,0xbf,0xb4,0x90,0x70,0x56,0x3c,0x3a,0x4f,0x63,0x79,0x7b,0x71,0x71,0x74,
0x85,0x96,0x9c,0x94,0x83,0x7c,0x7e,0x7a,0x75,0x72,0x70,0x73,0x7d,0x7e,0x74,0x62,
0x4d,0x35,0x28,0x2b,0x36,0x44,0x51,0x5a,0x5d,0x63,0x73,0x87,0x9e,0xb0,0xb9,0xb8,
0xa7,0x90,0x7b,0x69,0x5f,0x5b,0x5f,0x65,0x69,0x69,0x66,0x65,0x6c,0x79,0x86,0x8f,
0x8e,0x87,0x89,0x94,0xa4,0xb2,0xb2,0xa9,0xa2,0x9d,0x98,0x8f,0x82,0x73,0x6e,0x75,
0x85,0x95,0x9e,0x9e,0x9f,0xa9,0xab,0xa7,0xa1,0x9e,0x9f,0x9f,0x9b,0x95,0x91,0x8a,
0x7e,0x6c,0x5c,0x50,0x47,0x42,0x41,0x45,0x49,0x47,0x45,0x44,0x48,0x56,0x67,0x74,
0x7c,0x80,0x88,0x93,0x9f,0xa8,0xa8,0xa0,0x8e,0x83,0x82,0x89,0x8c,0x8b,0x82,0x7d,
0x7b,0x7a,0x83,0x8e,0x9f,0xae,0xbb,0xc1,0xbf,0xb9,0xa9,0x9b,0x91,0x85,0x76,0x69,
0x59,0x50,0x4b,0x48,0x4c,0x52,0x5a,0x69,0x7c,0x8c,0x9c,0xaa,0xaf,0xab,0x99,0x82,
0x69,0x58,0x4c,0x42,0x37,0x33,0x3b,0x4b,0x64,0x7c,0x96,0xa5,0xad,0xac,0xa2,0x96,
0x8b,0x88,0x8d,0x95,0x99,0x94,0x8a,0x7b,0x6d,0x67,0x65,0x69,0x71,0x7a,0x86,0x8d,
0x92,0x91,0x8e,0x8e,0x8f,0x8d,0x8b,0x89,0x85,0x84,0x7f,0x79,0x71,0x6c,0x6c,0x74,
0x7f,0x88,0x8e,0x92,0x93,0x94,0x90,0x89,0x84,0x81,0x7e,0x75,0x6b,0x66,0x6a,0x75,
0x7e,0x82,0x7e,0x76,0x6c,0x64,0x60,0x63,0x67,0x6c,0x6f,0x70,0x75,0x7d,0x85,0x8c,
0x8f,0x8c,0x87,0x7b,0x73,0x70,0x75,0x7a,0x7f,0x83,0x87,0x89,0x88,0x84,0x7f,0x7d,
0x82,0x8d,0x9c,0xac,0xb6,0xb9,0xb6,0xb3,0xac,0xa4,0x9f,0x9b,0x93,0x8b,0x81,0x78,
0x71,0x68,0x63,0x63,0x6c,0x76,0x7f,0x81,0x7d,0x79,0x74,0x70,0x72,0x71,0x6f,0x6e,
0x68,0x63,0x5e,0x5a,0x53,0x51,0x54,0x5c,0x65,0x6b,0x6b,0x69,0x67,0x67,0x6e,0x79,
0x83,0x8c,0x8f,0x8d,0x88,0x87,0x87,0x8b,0x94,0xa1,0xae,0xb7,0xb9,0xb5,0xaf,0xa5,
0x9d,0x99,0x91,0x88,0x7d,0x71,0x64,0x59,0x55,0x56,0x5b,0x64,0x6e,0x72,0x70,0x69,
0x63,0x61,0x64,0x6c,0x74,0x7e,0x85,0x8b,0x8e,0x95,0x9a,0x9d,0x9e,0xa2,0xa6,0xab,
0xb1,0xb2,0xaf,0xa9,0xa2,0x9b,0x97,0x95,0x96,0x96,0x95,0x8e,0x80,0x70,0x61,0x5b,
0x59,0x59,0x5c,0x59,0x5c,0x61,0x64,0x5d,0x52,0x4e,0x52,0x60,0x6e,0x71,0x6f,0x69,
0x6f,0x7a,0x86,0x8a,0x89,0x8f,0x97,0xa0,0xa2,0xa2,0xa5,0xa8,0xaf,0xb5,0xb6,0xb7,
0xaf,0xa4,0x9b,0x93,0x89,0x80,0x6f,0x5f,0x49,0x39,0x31,0x2c,0x33,0x39,0x44,0x4f,
0x59,0x62,0x6c,0x77,0x86,0x98,0xa6,0xa7,0x9b,0x89,0x7e,0x79,0x74,0x71,0x75,0x79,
0x7c,0x80,0x82,0x84,0x82,0x80,0x85,0x8f,0x99,0x99,0x94,0x92,0x91,0x8b,0x7f,0x6f,
0x63,0x60,0x65,0x73,0x89,0x9e,0xaf,0xb8,0xb5,0xa8,0x94,0x7c,0x67,0x59,0x57,0x5f,
0x6d,0x7a,0x82,0x87,0x8b,0x89,0x8c,0x8f,0x8e,0x90,0x91,0x91,0x93,0x93,0x95,0x94,
0x8c,0x7e,0x67,0x51,0x43,0x3f,0x4a,0x61,0x80,0x9d,0xae,0xae,0xa0,0x8c,0x78,0x69,
0x61,0x60,0x66,0x6f,0x7c,0x8b,0x97,0x9e,0xa0,0x9d,0x98,0x95,0x92,0x92,0x96,0x9a,
0x9b,0x99,0x8f,0x81,0x72,0x64,0x56,0x4b,0x49,0x53,0x6a,0x86,0xa4,0xba,0xc2,0xba,
0xa9,0x8f,0x75,0x5e,0x53,0x52,0x5a,0x69,0x7a,0x87,0x8c,0x8a,0x84,0x80,0x81,0x85,
0x8a,0x8e,0x8b,0x81,0x75,0x6b,0x63,0x61,0x65,0x6d,0x78,0x84,0x8e,0x94,0x97,0x96,
0x93,0x8d,0x85,0x7f,0x7a,0x75,0x73,0x72,0x73,0x78,0x7d,0x7f,0x79,0x6d,0x5d,0x4b,
0x3a,0x2f,0x2f,0x33,0x3f,0x50,0x61,0x6d,0x77,0x81,0x89,0x8d,0x91,0x94,0x97,0x9b,
0x9c,0x9c,0x9e,0x9f,0xa2,0xa7,0xb0,0xb8,0xbd,0xc0,0xc4,0xc6,0xc4,0xbd,0xb0,0xa2,
0x96,0x89,0x75,0x5b,0x46,0x3b,0x3a,0x3c,0x3c,0x45,0x55,0x66,0x7b,0x89,0x8d,0x92,
0x99,0x99,0x96,0x93,0x8e,0x88,0x83,0x82,0x83,0x87,0x88,0x81,0x7d,0x7a,0x76,0x75,
0x77,0x7e,0x89,0x94,0x96,0x93,0x8f,0x88,0x7e,0x75,0x6c,0x64,0x5d,0x5d,0x61,0x65,
0x67,0x67,0x68,0x6b,0x6d,0x71,0x77,0x7c,0x81,0x85,0x87,0x8a,0x8f,0x95,0x9a,0x9d,
0x9f,0x9e,0x99,0x92,0x8f,0x8f,0x90,0x91,0x90,0x8b,0x83,0x7c,0x79,0x7a,0x81,0x8a,
0x92,0x98,0x9c,0x9d,0x9c,0x9a,0x97,0x96,0x94,0x90,0x88,0x7d,0x72,0x66,0x5b,0x54,
0x50,0x4a,0x41,0x35,0x2a,0x26,0x29,0x35,0x47,0x5c,0x72,0x83,0x91,0x9a,0x9f,0xa0,
0xa3,0xa2,0xa0,0x9c,0x98,0x94,0x8e,0x88,0x83,0x80,0x80,0x7e,0x7b,0x7b,0x79,0x79,
0x77,0x72,0x71,0x72,0x76,0x7a,0x7d,0x86,0x90,0x98,0x9f,0xa0,0x9c,0x95,0x8b,0x82,
0x7e,0x80,0x87,0x94,0x9c,0x9d,0x96,0x89,0x7b,0x6e,0x66,0x62,0x61,0x64,0x6a,0x72,
0x79,0x7d,0x81,0x88,0x91,0x9f,0xab,0xb4,0xb6,0xb4,0xad,0xa0,0x8e,0x79,0x65,0x54,
0x47,0x41,0x42,0x4a,0x56,0x63,0x6c,0x75,0x7b,0x81,0x88,0x8e,0x94,0x99,0x95,0x8b,
0x7f,0x78,0x76,0x7c,0x88,0x93,0x9d,0xa6,0xac,0xb0,0xb0,0xad,0xa4,0x97,0x86,0x74,
0x61,0x52,0x4c,0x4c,0x51,0x56,0x57,0x55,0x55,0x53,0x54,0x5c,0x6d,0x82,0x99,0xaa,
0xaf,0xaa,0x9f,0x95,0x8f,0x8e,0x93,0x99,0x9b,0x96,0x8f,0x89,0x89,0x90,0x9c,0xa9,
0xb2,0xb1,0xa7,0x94,0x81,0x70,0x66,0x61,0x62,0x69,0x70,0x77,0x7a,0x77,0x72,0x6c,
0x69,0x68,0x67,0x64,0x61,0x5d,0x58,0x54,0x51,0x50,0x54,0x5d,0x68,0x76,0x86,0x91,
0x9a,0xa1,0xa1,0x99,0x8d,0x80,0x74,0x6e,0x71,0x77,0x7b,0x7e,0x82,0x82,0x80,0x7d,
0x7d,0x7f,0x82,0x80,0x7e,0x7d,0x7a,0x76,0x76,0x79,0x7b,0x7e,0x83,0x8a,0x93,0x9d,
0xa8,0xb1,0xb3,0xae,0xa3,0x95,0x86,0x79,0x71,0x6e,0x6d,0x70,0x76,0x80,0x8d,0x9a,
0xa4,0xad,0xb0,0xb0,0xaa,0x9f,0x92,0x82,0x71,0x65,0x5e,0x5b,0x5b,0x5c,0x5c,0x5f,
0x63,0x68,0x71,0x78,0x80,0x88,0x8b,0x8d,0x88,0x85,0x83,0x82,0x84,0x87,0x8a,0x89,
0x89,0x89,0x87,0x80,0x78,0x71,0x69,0x64,0x61,0x63,0x67,0x68,0x69,0x66,0x69,0x6b,
0x71,0x7b,0x86,0x8f,0x97,0x9a,0x99,0x93,0x8d,0x8a,0x88,0x88,0x8a,0x90,0x99,0xa2,
0xa8,0xac,0xac,0xa8,0xa0,0x97,0x8f,0x89,0x84,0x7f,0x7c,0x78,0x6f,0x66,0x5e,0x57,
0x55,0x56,0x59,0x5d,0x60,0x65,0x68,0x69,0x66,0x61,0x5c,0x5b,0x61,0x6b,0x76,0x7d,
0x80,0x7c,0x75,0x6d,0x65,0x64,0x68,0x70,0x7b,0x89,0x96,0x9f,0xa4,0xa9,0xae,0xb1,
0xaf,0xa8,0x9d,0x8f,0x82,0x76,0x6c,0x63,0x5b,0x55,0x52,0x52,0x56,0x62,0x74,0x85,
0x93,0x9b,0x9d,0x9c,0x9a,0x98,0x96,0x96,0x96,0x98,0x98,0x97,0x94,0x8e,0x8c,0x8c,
0x8f,0x93,0x95,0x94,0x8f,0x8d,0x8b,0x88,0x82,0x79,0x70,0x66,0x5d,0x59,0x5c,0x66,
0x74,0x7e,0x89,0x8d,0x8c,0x87,0x83,0x81,0x7f,0x84,0x8a,0x91,0x94,0x97,0x98,0x96,
0x8f,0x88,0x86,0x8c,0x94,0x9b,0xa0,0xa7,0xa9,0xa4,0x9b,0x91,0x88,0x7f,0x72,0x62,
0x52,0x43,0x39,0x36,0x3c,0x46,0x53,0x61,0x6f,0x78,0x81,0x85,0x87,0x89,0x89,0x87,
0x84,0x84,0x84,0x85,0x86,0x86,0x88,0x88,0x84,0x7d,0x77,0x72,0x72,0x74,0x77,0x78,
0x75,0x71,0x6f,0x72,0x76,0x7b,0x7f,0x82,0x85,0x86,0x88,0x8b,0x91,0x96,0x99,0x99,
0x97,0x93,0x8c,0x87,0x84,0x85,0x88,0x89,0x88,0x84,0x80,0x7b,0x75,0x6e,0x6a,0x6b,
0x6c,0x6c,0x6e,0x6d,0x6f,0x6d,0x68,0x67,0x69,0x6c,0x70,0x75,0x77,0x78,0x79,0x7c,
0x7f,0x81,0x85,0x8a,0x8f,0x92,0x93,0x8f,0x8a,0x84,0x7f,0x7b,0x75,0x72,0x70,0x73,
0x79,0x81,0x88,0x8e,0x92,0x92,0x8f,0x8b,0x89,0x88,0x87,0x88,0x8a,0x8a,0x8a,0x8e,
0x93,0x93,0x8f,0x8a,0x85,0x7f,0x7e,0x80,0x82,0x83,0x83,0x85,0x87,0x8a,0x8c,0x8c,
0x8c,0x8a,0x89,0x88,0x85,0x82,0x7e,0x7a,0x73,0x6d,0x66,0x62,0x62,0x64,0x68,0x70,
0x7c,0x89,0x96,0x9d,0x9e,0x9a,0x92,0x86,0x7a,0x72,0x70,0x73,0x78,0x7b,0x7c,0x7b,
0x78,0x74,0x6e,0x6b,0x6d,0x72,0x74,0x76,0x76,0x77,0x78,0x79,0x7c,0x81,0x8a,0x96,
0xa1,0xaa,0xad,0xa8,0xa1,0x94,0x85,0x78,0x6e,0x6c,0x6e,0x6f,0x6c,0x6c,0x70,0x76,
0x7b,0x7d,0x83,0x89,0x94,0x9f,0xa2,0xa2,0xa1,0x9d,0x97,0x92,0x88,0x80,0x77,0x70,
0x6c,0x6a,0x6b,0x71,0x76,0x7f,0x86,0x8b,0x8d,0x86,0x83,0x77,0x70,0x69,0x6a,0x6b,
0x6d,0x6e,0x6e,0x71,0x74,0x73,0x6d,0x69,0x6b,0x70,0x77,0x7d,0x80,0x83,0x86,0x8a,
0x8e,0x92,0x90,0x8d,0x87,0x7f,0x75,0x67,0x5a,0x4b,0x3e,0x34,0x32,0x37,0x43,0x52,
0x65,0x7c,0x93,0xa7,0xb5,0xbd,0xbf,0xbf,0xbf,0xba,0xb6,0xb3,0xb2,0xab,0x9f,0x91,
0x82,0x72,0x5e,0x4c,0x43,0x45,0x4f,0x5b,0x68,0x76,0x84,0x94,0xa5,0xb6,0xc4,0xcb,
0xce,0xcc,0xc7,0xbd,0xac,0x95,0x7c,0x65,0x53,0x47,0x41,0x41,0x45,0x51,0x63,0x79,
0x8f,0xa1,0xab,0xab,0xa2,0x94,0x88,0x7f,0x79,0x75,0x71,0x6d,0x6c,0x6d,0x70,0x74,
0x7a,0x83,0x8a,0x8b,0x86,0x7b,0x6f,0x66,0x63,0x5f,0x5d,0x5e,0x64,0x6d,0x77,0x7e,
0x80,0x80,0x7b,0x78,0x77,0x74,0x76,0x7c,0x85,0x8b,0x8f,0x92,0x95,0x96,0x98,0x96,
0x94,0x90,0x89,0x80,0x77,0x75,0x76,0x75,0x77,0x7a,0x7d,0x80,0x82,0x88,0x8c,0x8a,
0x84,0x7c,0x79,0x79,0x7c,0x80,0x86,0x8c,0x8e,0x8a,0x86,0x83,0x81,0x7f,0x7c,0x7b,
0x7b,0x7c,0x7e,0x7d,0x7f,0x86,0x8a,0x87,0x80,0x79,0x74,0x6f,0x6c,0x6e,0x71,0x75,
0x7a,0x7d,0x7f,0x80,0x7e,0x7b,0x78,0x75,0x73,0x73,0x77,0x78,0x78,0x79,0x7a,0x7e,
0x7c,0x77,0x78,0x7e,0x87,0x8c,0x8e,0x90,0x91,0x8f,0x8c,0x8a,0x88,0x83,0x7b,0x78,
0x78,0x79,0x7c,0x82,0x8a,0x91,0x96,0x9a,0x9c,0x97,0x89,0x80,0x7d,0x7e,0x7e,0x83,
0x89,0x8b,0x89,0x84,0x83,0x84,0x83,0x81,0x7f,0x80,0x7e,0x7b,0x79,0x79,0x7a,0x7a,
0x7b,0x7c,0x80,0x83,0x85,0x89,0x8a,0x88,0x82,0x7b,0x75,0x72,0x71,0x75,0x7a,0x7d,
0x7f,0x80,0x82,0x81,0x7e,0x7b,0x77,0x73,0x70,0x6f,0x71,0x73,0x75,0x77,0x7b,0x7d,
0x80,0x83,0x86,0x8b,0x91,0x94,0x92,0x8b,0x81,0x79,0x72,0x6e,0x6e,0x72,0x7a,0x83,
0x8a,0x89,0x84,0x7c,0x73,0x6c,0x69,0x6e,0x78,0x87,0x91,0x9b,0xa1,0xa3,0xa0,0x98,
0x8d,0x84,0x7d,0x79,0x79,0x79,0x7a,0x7b,0x7a,0x77,0x77,0x7b,0x7d,0x7d,0x7a,0x77,
0x73,0x71,0x72,0x73,0x73,0x75,0x77,0x78,0x7a,0x7a,0x78,0x78,0x79,0x7b,0x7b,0x7b,
0x7c,0x7e,0x83,0x87,0x88,0x84,0x80,0x7d,0x78,0x75,0x73,0x72,0x74,0x75,0x76,0x76,
0x78,0x7b,0x7e,0x80,0x83,0x88,0x8a,0x90,0x96,0x9b,0xa2,0xaa,0xab,0xa6,0xa4,0x9d,
0x91,0x83,0x7c,0x7a,0x7a,0x7a,0x79,0x7a,0x7d,0x7f,0x81,0x85,0x8b,0x8b,0x85,0x7f,
0x7a,0x75,0x73,0x73,0x76,0x7a,0x7c,0x7e,0x78,0x72,0x6e,0x6c,0x6b,0x69,0x68,0x68,
0x6a,0x6e,0x74,0x7f,0x89,0x94,0x9b,0x97,0x8d,0x81,0x75,0x6d,0x6b,0x6f,0x78,0x80,
0x84,0x82,0x81,0x81,0x82,0x87,0x8e,0x96,0x9d,0xa0,0xa0,0x9e,0x9b,0x97,0x92,0x8e,
0x8b,0x87,0x84,0x82,0x82,0x84,0x8a,0x90,0x95,0x98,0x98,0x92,0x88,0x79,0x6f,0x68,
0x65,0x64,0x63,0x64,0x65,0x6a,0x71,0x78,0x7c,0x7c,0x77,0x6f,0x6a,0x67,0x68,0x6a,
0x6b,0x69,0x68,0x6b,0x71,0x77,0x77,0x72,0x6d,0x69,0x68,0x6b,0x73,0x7d,0x85,0x8c,
0x91,0x94,0x91,0x8c,0x8a,0x89,0x86,0x81,0x82,0x7f,0x7d,0x7f,0x82,0x82,0x81,0x7d,
0x77,0x73,0x73,0x79,0x85,0x91,0x9a,0x9a,0x95,0x8d,0x83,0x7b,0x76,0x79,0x82,0x8e,
0x99,0xa1,0xa4,0xa2,0x98,0x8d,0x81,0x77,0x6d,0x69,0x6c,0x71,0x7d,0x87,0x90,0x92,
0x91,0x8f,0x8a,0x88,0x86,0x81,0x7e,0x7c,0x78,0x72,0x6d,0x67,0x62,0x62,0x65,0x6a,
0x6f,0x77,0x7a,0x7e,0x84,0x8e,0x95,0x98,0x99,0x93,0x88,0x80,0x7c,0x77,0x73,0x6e,
0x6e,0x7c,0x94,0xa8,0xad,0xa1,0x88,0x67,0x4a,0x3d,0x41,0x58,0x7d,0xa8,0xd1,0xef,
0xfc,0xf8,0xdf,0xb7,0x85,0x50,0x25,0x09,0x00,0x0b,0x2a,0x55,0x87,0xb5,0xd4,0xe3,
0xe3,0xd9,0xc3,0xa5,0x83,0x5b,0x3c,0x2e,0x2c,0x37,0x4a,0x5f,0x6f,0x80,0x8f,0x94,
0x96,0x98,0x91,0x89,0x84,0x7a,0x72,0x71,0x74,0x78,0x80,0x82,0x80,0x7c,0x74,0x6a,
0x62,0x5b,0x55,0x54,0x58,0x60,0x6f,0x85,0x9c,0xb1,0xc0,0xc8,0xc4,0xb5,0x9e,0x7f,
0x62,0x4a,0x39,0x32,0x38,0x48,0x5f,0x7c,0x99,0xac,0xb5,0xb9,0xb7,0xad,0x9c,0x88,
0x76,0x6a,0x63,0x60,0x62,0x67,0x6d,0x72,0x75,0x78,0x78,0x79,0x7a,0x7d,0x83,0x8b,
0x93,0x9b,0xa2,0xa5,0xa5,0xa2,0x9c,0x8f,0x80,0x70,0x62,0x57,0x50,0x4d,0x51,0x5c,
0x6b,0x7c,0x8c,0x97,0xa1,0xaa,0xae,0xb0,0xac,0xa4,0x99,0x8c,0x7d,0x6f,0x63,0x5d,
0x5d,0x61,0x6a,0x76,0x83,0x8e,0x94,0x95,0x93,0x8f,0x89,0x86,0x84,0x81,0x81,0x82,
0x83,0x82,0x7e,0x7d,0x79,0x74,0x6e,0x67,0x63,0x63,0x64,0x65,0x6c,0x7a,0x87,0x90,
0x99,0xa0,0xa0,0x9b,0x96,0x8c,0x81,0x78,0x73,0x70,0x70,0x76,0x7d,0x81,0x84,0x82,
0x7e,0x78,0x76,0x7b,0x82,0x90,0x9c,0xa0,0x9d,0x94,0x83,0x70,0x5e,0x4e,0x45,0x45,
0x4e,0x5b,0x6e,0x82,0x92,0xa0,0xa9,0xab,0xaa,0xa3,0x98,0x8a,0x79,0x68,0x5a,0x4f,
0x4c,0x52,0x5e,0x6d,0x7c,0x8a,0x94,0x98,0x95,0x8e,0x85,0x7e,0x7a,0x77,0x79,0x7b,
0x7f,0x83,0x85,0x87,0x86,0x85,0x82,0x7d,0x76,0x73,0x75,0x7a,0x82,0x8d,0x99,0xa3,
0xa7,0xa7,0xa1,0x97,0x8c,0x82,0x7a,0x74,0x70,0x6f,0x70,0x70,0x73,0x77,0x7b,0x7a,
0x77,0x73,0x6c,0x67,0x62,0x61,0x64,0x69,0x6d,0x71,0x78,0x7b,0x79,0x79,0x7a,0x7c,
0x84,0x8e,0x98,0xa0,0xac,0xb5,0xba,0xbd,0xbb,0xb0,0xa6,0x9a,0x92,0x90,0x92,0x95,
0x96,0x95,0x90,0x86,0x79,0x6e,0x63,0x5d,0x59,0x56,0x5c,0x5c,0x5c,0x5e,0x5e,0x5f,
0x5f,0x5e,0x5e,0x5d,0x5f,0x63,0x6a,0x72,0x7b,0x83,0x89,0x90,0x95,0x9c,0xa2,0xa8,
0xad,0xaf,0xaf,0xae,0xad,0xac,0xa9,0xa4,0x9f,0x98,0x8d,0x81,0x77,0x71,0x6f,0x6d,
0x6a,0x67,0x64,0x64,0x62,0x60,0x5e,0x5d,0x5e,0x5f,0x60,0x63,0x66,0x6a,0x6b,0x6c,
0x70,0x77,0x80,0x89,0x91,0x99,0xa1,0xa6,0xa7,0xa2,0x9e,0x98,0x93,0x90,0x8e,0x8d,
0x8a,0x88,0x86,0x82,0x7d,0x77,0x72,0x6c,0x65,0x5f,0x59,0x58,0x58,0x5c,0x5d,0x5e,
0x61,0x65,0x6c,0x75,0x7b,0x81,0x8a,0x8f,0x92,0x92,0x8d,0x89,0x85,0x83,0x81,0x80,
0x83,0x89,0x8f,0x91,0x92,0x90,0x8f,0x8b,0x86,0x80,0x7e,0x80,0x82,0x87,0x8c,0x90,
0x94,0x92,0x8e,0x8b,0x89,0x87,0x83,0x82,0x81,0x84,0x8b,0x92,0x98,0x98,0x95,0x8d,
0x81,0x6f,0x5b,0x49,0x3d,0x38,0x3b,0x46,0x5a,0x75,0x8e,0x9f,0xa5,0xa2,0x99,0x8d,
0x82,0x7a,0x7a,0x84,0x95,0xa8,0xb6,0xbb,0xb6,0xa9,0x97,0x84,0x74,0x6a,0x67,0x6b,
0x75,0x7c,0x7f,0x7d,0x74,0x65,0x54,0x48,0x40,0x40,0x48,0x57,0x66,0x73,0x7d,0x84,
0x8a,0x91,0x98,0xa0,0xab,0xb5,0xbd,0xbf,0xb8,0xac,0xa1,0x99,0x91,0x8a,0x86,0x83,
0x80,0x7f,0x7d,0x7b,0x74,0x6a,0x61,0x57,0x51,0x53,0x5d,0x6a,0x78,0x83,0x88,0x84,
0x7f,0x7d,0x79,0x77,0x7a,0x81,0x85,0x88,0x8c,0x8d,0x8b,0x89,0x88,0x86,0x87,0x8a,
0x8d,0x8e,0x8d,0x8a,0x83,0x7d,0x76,0x72,0x71,0x74,0x7b,0x81,0x88,0x8b,0x8b,0x87,
0x7e,0x72,0x63,0x55,0x4c,0x4b,0x4f,0x55,0x5b,0x5f,0x60,0x61,0x63,0x67,0x6d,0x73,
0x78,0x80,0x87,0x8e,0x96,0x9f,0xa8,0xad,0xab,0xa3,0x9a,0x90,0x87,0x81,0x7d,0x7a,
0x79,0x7d,0x83,0x86,0x85,0x82,0x7c,0x77,0x77,0x7c,0x85,0x8d,0x91,0x93,0x94,0x95,
0x92,0x90,0x8c,0x87,0x80,0x79,0x76,0x77,0x7f,0x8b,0x95,0x9b,0x9b,0x99,0x96,0x91,
0x8d,0x89,0x87,0x87,0x88,0x8b,0x8b,0x86,0x80,0x76,0x6b,0x61,0x5b,0x59,0x5a,0x61,
0x68,0x6e,0x74,0x77,0x7b,0x7d,0x7c,0x7b,0x7b,0x7e,0x86,0x8f,0x96,0x9a,0x9e,0x9f,
0xa0,0x9e,0x97,0x8f,0x83,0x79,0x72,0x6c,0x68,0x65,0x64,0x64,0x67,0x6d,0x73,0x7c,
0x86,0x90,0x99,0x9d,0x9d,0x98,0x91,0x86,0x79,0x6c,0x62,0x5a,0x58,0x5a,0x5f,0x69,
0x78,0x87,0x94,0x9e,0xa2,0xa2,0x9c,0x97,0x91,0x8a,0x88,0x81,0x82,0x80,0x80,0x7d,
0x75,0x6a,0x60,0x57,0x55,0x52,0x55,0x5c,0x67,0x77,0x86,0x94,0xa1,0xaa,0xad,0xad,
0xa6,0x9c,0x8c,0x7b,0x6e,0x62,0x58,0x52,0x50,0x54,0x5c,0x67,0x72,0x7a,0x80,0x83,
0x86,0x89,0x8d,0x92,0x96,0x99,0x9a,0x98,0x92,0x87,0x78,0x70,0x6c,0x6a,0x6e,0x73,
0x7a,0x81,0x85,0x88,0x8a,0x8c,0x8e,0x93,0x96,0x99,0x96,0x9b,0xa3,0xa4,0x98,0x87,
0x7b,0x74,0x72,0x72,0x72,0x73,0x76,0x77,0x74,0x70,0x6f,0x7a,0x8b,0x9b,0xa7,0xad,
0xb0,0xad,0xa6,0xa2,0xa1,0x9d,0x94,0x87,0x78,0x6c,0x62,0x56,0x4b,0x47,0x4c,0x56,
0x61,0x6d,0x75,0x78,0x7b,0x7e,0x80,0x82,0x84,0x85,0x84,0x81,0x7c,0x7a,0x7d,0x7b,
0x76,0x74,0x71,0x70,0x75,0x79,0x7b,0x7f,0x86,0x8c,0x8f,0x89,0x81,0x7a,0x71,0x6a,
0x6a,0x6b,0x6c,0x6f,0x71,0x73,0x75,0x79,0x7e,0x85,0x8a,0x8f,0x96,0x9b,0x9b,0x9a,
0x9c,0xa0,0xa2,0xa3,0xa5,0xa5,0xa2,0x9c,0x95,0x8d,0x84,0x7b,0x71,0x67,0x5d,0x52,
0x4f,0x50,0x52,0x51,0x51,0x57,0x5d,0x65,0x70,0x7f,0x8f,0xa0,0xad,0xb0,0xab,0xa2,
0x9a,0x92,0x8e,0x8c,0x88,0x84,0x80,0x7e,0x7c,0x7c,0x7c,0x7b,0x7c,0x7b,0x76,0x6c,
0x62,0x58,0x53,0x53,0x57,0x60,0x6d,0x80,0x93,0xa3,0xb0,0xb5,0xb5,0xb0,0xa9,0xa0,
0x98,0x91,0x8a,0x81,0x7a,0x74,0x6f,0x6b,0x68,0x63,0x62,0x64,0x65,0x66,0x66,0x68,
0x6a,0x6f,0x76,0x84,0x93,0xa0,0xa9,0xae,0xad,0xa8,0x9d,0x8f,0x83,0x7f,0x80,0x7f,
0x80,0x7f,0x80,0x7f,0x80,0x7f,0x80,0x7f,0x80,0x7f,0x80,0x7f,0x80,0x80,0x80,0x80,

+523
View File
@@ -0,0 +1,523 @@
///////////////////////////////////////////////////////////////////////////////
// File: BlobRenderer.cpp - Modern Windows 11 port
//
// Original Copyright 2001 Pipeworks Software
// Modern Port Copyright (c) 2023
///////////////////////////////////////////////////////////////////////////////
#include "BlobRenderer.h"
#include "RenderObject.h"
#include <algorithm>
#include <random>
using namespace DirectX;
using Microsoft::WRL::ComPtr;
// Random number helpers
namespace {
std::random_device g_rd;
std::mt19937 g_gen(g_rd());
std::uniform_real_distribution<float> g_dist01(0.0f, 1.0f);
std::uniform_real_distribution<float> g_dist11(-1.0f, 1.0f);
float FRand01() {
return g_dist01(g_gen);
}
float FRand11() {
return g_dist11(g_gen);
}
}
///////////////////////////////////////////////////////////////////////////////
// BlobSource methods
///////////////////////////////////////////////////////////////////////////////
float BlobSource::Calculate(int checkAffiliation, const XMFLOAT3& pos) const
{
// Calculate squared distance
float dx = position.x - pos.x;
float dy = position.y - pos.y;
float dz = position.z - pos.z;
float distSq = dx * dx + dy * dy + dz * dz;
// Check if point is within consideration radius
if (distSq > considerationRadiusSq)
return 0.0f;
// Calculate falloff based on distance
float falloff = 1.0f - (distSq / considerationRadiusSq);
// Different affiliations repel each other
float affiliationFactor = (checkAffiliation == affiliation) ? 1.0f : -1.0f;
// Final field contribution
return affiliationFactor * strength * falloff * falloff;
}
///////////////////////////////////////////////////////////////////////////////
// BlobRenderer methods
///////////////////////////////////////////////////////////////////////////////
BlobRenderer::BlobRenderer()
: m_pSources(nullptr)
, m_NumBlobs(0)
, m_Threshold(1.0f)
, m_NumVertices(0)
, m_NumIndices(0)
, m_FieldX(0)
, m_FieldY(0)
, m_FieldZ(0)
, m_FieldXY(0)
{
m_LowerLeftCorner = XMFLOAT3(0.0f, 0.0f, 0.0f);
m_FieldToWorld = XMFLOAT3(1.0f, 1.0f, 1.0f);
m_WorldToField = XMFLOAT3(1.0f, 1.0f, 1.0f);
}
///////////////////////////////////////////////////////////////////////////////
BlobRenderer::~BlobRenderer()
{
Destroy();
}
///////////////////////////////////////////////////////////////////////////////
void BlobRenderer::Destroy()
{
m_pVertexBuffer.Reset();
m_pIndexBuffer.Reset();
m_pVertexShader.Reset();
m_pPixelShader.Reset();
m_pInputLayout.Reset();
m_pConstantBuffer.Reset();
m_Field.clear();
m_VertexIndices.clear();
m_pSources = nullptr;
m_NumBlobs = 0;
m_NumVertices = 0;
m_NumIndices = 0;
m_FieldX = m_FieldY = m_FieldZ = m_FieldXY = 0;
}
///////////////////////////////////////////////////////////////////////////////
void BlobRenderer::Initialize(ID3D11Device* pDevice, const BlobSource* pBlobSources, int numBlobs,
float xySpacing, float zSpacing,
const XMFLOAT3& center, const XMFLOAT3& halfDim)
{
m_pSources = pBlobSources;
m_NumBlobs = numBlobs;
// Calculate field dimensions
m_FieldX = static_cast<int>((halfDim.x * 2.0f / xySpacing) + 2.0f);
m_FieldY = static_cast<int>((halfDim.y * 2.0f / xySpacing) + 2.0f);
m_FieldZ = static_cast<int>((halfDim.z * 2.0f / zSpacing) + 2.0f);
m_FieldXY = m_FieldX * m_FieldY;
// Allocate field and vertex index arrays
m_Field.resize(m_FieldXY * m_FieldZ);
m_VertexIndices.resize((m_FieldXY + 1) * 6);
// Calculate corner of the field and conversion factors
m_LowerLeftCorner.x = center.x - halfDim.x;
m_LowerLeftCorner.y = center.y - halfDim.y;
m_LowerLeftCorner.z = center.z - halfDim.z;
m_FieldToWorld.x = xySpacing;
m_FieldToWorld.y = xySpacing;
m_FieldToWorld.z = zSpacing;
m_WorldToField.x = 1.0f / xySpacing;
m_WorldToField.y = 1.0f / xySpacing;
m_WorldToField.z = 1.0f / zSpacing;
// Create shader resources
CreateShaderResources(pDevice);
}
///////////////////////////////////////////////////////////////////////////////
void BlobRenderer::CreateShaderResources(ID3D11Device* pDevice)
{
// Define vertex input layout
D3D11_INPUT_ELEMENT_DESC layout[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
// Create vertex shader
const char* vsCode = R"(
cbuffer Constants : register(b0)
{
matrix World;
matrix View;
matrix Projection;
};
struct VS_INPUT
{
float3 Position : POSITION;
float3 Normal : NORMAL;
};
struct VS_OUTPUT
{
float4 Position : SV_POSITION;
float3 Normal : NORMAL;
float3 WorldPos : TEXCOORD0;
};
VS_OUTPUT main(VS_INPUT input)
{
VS_OUTPUT output;
// Transform position to world space
float4 worldPos = mul(float4(input.Position, 1.0f), World);
// Transform to clip space
output.Position = mul(worldPos, mul(View, Projection));
// Transform normal to world space
output.Normal = normalize(mul(input.Normal, (float3x3)World));
// Pass world position to pixel shader
output.WorldPos = worldPos.xyz;
return output;
}
)";
// Create pixel shader
const char* psCode = R"(
struct PS_INPUT
{
float4 Position : SV_POSITION;
float3 Normal : NORMAL;
float3 WorldPos : TEXCOORD0;
};
float4 main(PS_INPUT input) : SV_TARGET
{
// Simple lighting calculation
float3 lightDir = normalize(float3(1.0f, -1.0f, 1.0f));
float3 normal = normalize(input.Normal);
// Diffuse lighting
float diffuse = max(0.0f, dot(normal, -lightDir));
// Ambient lighting
float ambient = 0.3f;
// Final color
float3 color = float3(0.2f, 0.6f, 0.8f); // Blue blob color
float lighting = ambient + diffuse * 0.7f;
return float4(color * lighting, 1.0f);
}
)";
// TODO: Compile shaders using D3DCompile and create shader objects
// This would normally be done with D3DCompileFromFile or D3DCompile for runtime compilation
// or by loading pre-compiled shader objects
// Create constant buffer
D3D11_BUFFER_DESC cbDesc = {};
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.ByteWidth = sizeof(XMMATRIX) * 3; // World, View, Projection matrices
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
pDevice->CreateBuffer(&cbDesc, nullptr, &m_pConstantBuffer);
// Create dynamic vertex and index buffers that will be filled during rendering
D3D11_BUFFER_DESC vbDesc = {};
vbDesc.Usage = D3D11_USAGE_DYNAMIC;
vbDesc.ByteWidth = sizeof(BlobVertex) * 65536; // Max vertices
vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
pDevice->CreateBuffer(&vbDesc, nullptr, &m_pVertexBuffer);
D3D11_BUFFER_DESC ibDesc = {};
ibDesc.Usage = D3D11_USAGE_DYNAMIC;
ibDesc.ByteWidth = sizeof(UINT) * 65536 * 3; // Max indices for triangles
ibDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
pDevice->CreateBuffer(&ibDesc, nullptr, &m_pIndexBuffer);
}
///////////////////////////////////////////////////////////////////////////////
void BlobRenderer::Render(ID3D11DeviceContext* pContext)
{
if (!m_pSources || m_NumBlobs == 0)
return;
// Sort blobs by affiliation
int nextAffiliation = m_pSources[0].affiliation;
for (int i = 1; i < m_NumBlobs; i++)
{
nextAffiliation = std::min(nextAffiliation, m_pSources[i].affiliation);
}
// Process each affiliation group separately
for (int affiliation = nextAffiliation; affiliation < m_NumBlobs; affiliation = nextAffiliation)
{
nextAffiliation = m_NumBlobs;
XMFLOAT3 ptMin, ptMax;
bool bUnset = true;
// For this affiliation, find the bounding box
for (int i = 0; i < m_NumBlobs; i++)
{
const BlobSource& bs = m_pSources[i];
// Track the next affiliation
int aff = bs.affiliation;
if (aff > affiliation)
nextAffiliation = std::min(aff, nextAffiliation);
if (aff == affiliation)
{
if (bUnset)
{
bUnset = false;
ptMin = ptMax = bs.position;
ptMin.x -= bs.considerationRadius;
ptMin.y -= bs.considerationRadius;
ptMin.z -= bs.considerationRadius;
ptMax.x += bs.considerationRadius;
ptMax.y += bs.considerationRadius;
ptMax.z += bs.considerationRadius;
}
else
{
ptMin.x = std::min(ptMin.x, bs.position.x - bs.considerationRadius);
ptMin.y = std::min(ptMin.y, bs.position.y - bs.considerationRadius);
ptMin.z = std::min(ptMin.z, bs.position.z - bs.considerationRadius);
ptMax.x = std::max(ptMax.x, bs.position.x + bs.considerationRadius);
ptMax.y = std::max(ptMax.y, bs.position.y + bs.considerationRadius);
ptMax.z = std::max(ptMax.z, bs.position.z + bs.considerationRadius);
}
}
}
// Get field coordinates for the bounding box
int sx, sy, sz, ex, ey, ez;
GetFieldCoords(ptMin, &sx, &sy, &sz);
GetFieldCoords(ptMax, &ex, &ey, &ez);
ex++; ey++; ez++;
// Calculate field dimensions for this region
int lenX = ex - sx + 1;
int lenY = ey - sy + 1;
int lenZ = ez - sz + 1;
int lenXY = lenX * lenY;
int lenXYZ = lenXY * lenZ;
// Skip if region is too large for our field
if (lenX * lenY * lenZ > m_FieldX * m_FieldY * m_FieldZ)
continue;
// Clear the field
std::fill(m_Field.begin(), m_Field.begin() + lenXYZ, 0.0f);
// Populate the field with blob contributions
for (int i = 0; i < m_NumBlobs; i++)
{
const BlobSource& bs = m_pSources[i];
XMFLOAT3 ptStart, ptEnd;
// Calculate bounding box for this blob
ptStart.x = std::max(ptMin.x, bs.position.x - bs.considerationRadius);
ptStart.y = std::max(ptMin.y, bs.position.y - bs.considerationRadius);
ptStart.z = std::max(ptMin.z, bs.position.z - bs.considerationRadius);
ptEnd.x = std::min(ptMax.x, bs.position.x + bs.considerationRadius);
ptEnd.y = std::min(ptMax.y, bs.position.y + bs.considerationRadius);
ptEnd.z = std::min(ptMax.z, bs.position.z + bs.considerationRadius);
// Convert to field coordinates
int bsx, bsy, bsz, bex, bey, bez;
GetFieldCoords(ptStart, &bsx, &bsy, &bsz);
GetFieldCoords(ptEnd, &bex, &bey, &bez);
bex++; bey++; bez++;
// Add blob contribution to field
if (bsx <= bex && bsy <= bey && bsz <= bez)
{
XMFLOAT3 pos, posll;
GetWorldPos(&posll, bsx, bsy, bsz);
pos.z = posll.z;
for (int w = bsz; w <= bez; w++, pos.z += m_FieldToWorld.z)
{
pos.y = posll.y;
for (int v = bsy; v <= bey; v++, pos.y += m_FieldToWorld.y)
{
pos.x = posll.x;
float* pField = &m_Field[w * lenXY + v * lenX + bsx - sx];
for (int u = bsx; u <= bex; u++, pos.x += m_FieldToWorld.x)
{
*(pField++) += bs.Calculate(affiliation, pos);
}
}
}
}
}
// Generate isosurface using marching cubes/tetrahedra
// TODO: Implement the marching cubes or marching tetrahedra algorithm here
// This would:
// 1. Analyze each voxel in the field
// 2. Determine which corners are inside/outside the isosurface (based on threshold)
// 3. Generate triangles for the isosurface
// 4. Store vertices and indices
// 5. Update vertex and index buffers
// Once the geometry is generated, set up the pipeline state and draw
if (m_NumVertices > 0 && m_NumIndices > 0)
{
// Set vertex buffer
UINT stride = sizeof(BlobVertex);
UINT offset = 0;
pContext->IASetVertexBuffers(0, 1, m_pVertexBuffer.GetAddressOf(), &stride, &offset);
// Set index buffer
pContext->IASetIndexBuffer(m_pIndexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
// Set input layout
pContext->IASetInputLayout(m_pInputLayout.Get());
// Set primitive topology
pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// Set shaders
pContext->VSSetShader(m_pVertexShader.Get(), nullptr, 0);
pContext->PSSetShader(m_pPixelShader.Get(), nullptr, 0);
// Update constant buffer with transformation matrices
// TODO: Get actual matrices from the camera system
D3D11_MAPPED_SUBRESOURCE mappedResource;
if (SUCCEEDED(pContext->Map(m_pConstantBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource)))
{
// Define transformation matrices
XMMATRIX world = XMMatrixIdentity();
XMMATRIX view = XMMatrixLookAtLH(
XMVectorSet(0.0f, 0.0f, -5.0f, 1.0f),
XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f),
XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f)
);
XMMATRIX projection = XMMatrixPerspectiveFovLH(XM_PIDIV4, 16.0f / 9.0f, 0.1f, 100.0f);
// Write to constant buffer
XMMATRIX* pMatrices = (XMMATRIX*)mappedResource.pData;
pMatrices[0] = XMMatrixTranspose(world);
pMatrices[1] = XMMatrixTranspose(view);
pMatrices[2] = XMMatrixTranspose(projection);
pContext->Unmap(m_pConstantBuffer.Get(), 0);
}
// Set constant buffer
pContext->VSSetConstantBuffers(0, 1, m_pConstantBuffer.GetAddressOf());
// Draw indexed
pContext->DrawIndexed(m_NumIndices, 0, 0);
}
}
}
///////////////////////////////////////////////////////////////////////////////
void BlobRenderer::AdvanceTime(float elapsedTime, float dt)
{
// Nothing to do here in the base class
// Derived classes might implement blob animation
}
///////////////////////////////////////////////////////////////////////////////
int BlobRenderer::GetFieldCoords(const XMFLOAT3& pos, int* p_x, int* p_y, int* p_z, XMFLOAT3* p_remainder) const
{
float fx = (pos.x - m_LowerLeftCorner.x) * m_WorldToField.x;
float fy = (pos.y - m_LowerLeftCorner.y) * m_WorldToField.y;
float fz = (pos.z - m_LowerLeftCorner.z) * m_WorldToField.z;
*p_x = static_cast<int>(fx);
*p_y = static_cast<int>(fy);
*p_z = static_cast<int>(fz);
if (p_remainder)
{
p_remainder->x = fx - static_cast<float>(*p_x);
p_remainder->y = fy - static_cast<float>(*p_y);
p_remainder->z = fz - static_cast<float>(*p_z);
}
// Return field index
return (*p_z * m_FieldXY) + (*p_y * m_FieldX) + (*p_x);
}
///////////////////////////////////////////////////////////////////////////////
void BlobRenderer::GetWorldPos(XMFLOAT3* pos, int x, int y, int z) const
{
pos->x = m_LowerLeftCorner.x + static_cast<float>(x) * m_FieldToWorld.x;
pos->y = m_LowerLeftCorner.y + static_cast<float>(y) * m_FieldToWorld.y;
pos->z = m_LowerLeftCorner.z + static_cast<float>(z) * m_FieldToWorld.z;
}
///////////////////////////////////////////////////////////////////////////////
// TestBlobRenderer methods
///////////////////////////////////////////////////////////////////////////////
TestBlobRenderer::TestBlobRenderer()
{
// Initialize with default values
}
///////////////////////////////////////////////////////////////////////////////
TestBlobRenderer::~TestBlobRenderer()
{
Destroy();
}
///////////////////////////////////////////////////////////////////////////////
void TestBlobRenderer::CreateTestBlobs(ID3D11Device* pDevice)
{
// Create test blob sources
for (int i = 0; i < NUM_BLOBS; i++)
{
// Random position near origin
m_Sources[i].position = XMFLOAT3(
FRand01() * 0.2f,
FRand01() * 0.2f,
FRand01() * 0.2f
);
// Set properties
m_Sources[i].strength = 1.0f;
m_Sources[i].considerationRadius = 0.09f;
m_Sources[i].considerationRadiusSq = m_Sources[i].considerationRadius * m_Sources[i].considerationRadius;
m_Sources[i].affiliation = 0; // All blobs same affiliation for now
}
// Center and dimensions of the field
XMFLOAT3 center = { 0.0f, 0.0f, 0.0f };
XMFLOAT3 halfDim = { 1.0f, 1.0f, 1.0f };
// Initialize the blob renderer
Initialize(pDevice, m_Sources, NUM_BLOBS, 0.005f, 0.005f, center, halfDim);
}
///////////////////////////////////////////////////////////////////////////////
void TestBlobRenderer::AdvanceTime(float elapsedTime, float dt)
{
// Animate the blobs
for (int i = 0; i < NUM_BLOBS; i++)
{
// Simple animation: move around a little bit
m_Sources[i].position.x += FRand11() * 0.002f * dt;
m_Sources[i].position.y += FRand11() * 0.002f * dt;
m_Sources[i].position.z += FRand11() * 0.002f * dt;
// Constrain to prevent blobs from wandering too far
m_Sources[i].position.x = std::max(-0.5f, std::min(0.5f, m_Sources[i].position.x));
m_Sources[i].position.y = std::max(-0.5f, std::min(0.5f, m_Sources[i].position.y));
m_Sources[i].position.z = std::max(-0.5f, std::min(0.5f, m_Sources[i].position.z));
}
}
+117
View File
@@ -0,0 +1,117 @@
///////////////////////////////////////////////////////////////////////////////
// File: BlobRenderer.h - Modern Windows 11 port
//
// Original Copyright 2001 Pipeworks Software
// Modern Port Copyright (c) 2023
//
// This is an implementation of metaballs (implicit surface rendering)
// using marching cubes/tetrahedra techniques.
///////////////////////////////////////////////////////////////////////////////
#pragma once
#include <d3d11.h>
#include <DirectXMath.h>
#include <vector>
#include <memory>
#include <wrl/client.h>
// Forward declarations
class RenderObject;
///////////////////////////////////////////////////////////////////////////////
// BlobVertex - Vertex structure for blob rendering
///////////////////////////////////////////////////////////////////////////////
struct BlobVertex
{
DirectX::XMFLOAT3 position;
DirectX::XMFLOAT3 normal; // not normalized, will do it in the GPU shader
};
///////////////////////////////////////////////////////////////////////////////
// BlobSource - Defines a metaball (implicit surface source)
///////////////////////////////////////////////////////////////////////////////
class BlobSource
{
public:
DirectX::XMFLOAT3 position;
float strength;
float considerationRadius;
float considerationRadiusSq; // squared for faster distance checks
int affiliation; // affiliation of -1 is never rendered, but repulses
// Calculate field contribution at a point
float Calculate(int affiliation, const DirectX::XMFLOAT3& pos) const;
};
///////////////////////////////////////////////////////////////////////////////
// BlobRenderer - Renders metaballs/implicit surfaces
///////////////////////////////////////////////////////////////////////////////
class BlobRenderer : public RenderObject
{
protected:
const BlobSource* m_pSources;
int m_NumBlobs;
float m_Threshold; // Threshold for surface generation
UINT m_NumVertices;
UINT m_NumIndices;
// D3D11 buffers and resources
Microsoft::WRL::ComPtr<ID3D11Buffer> m_pVertexBuffer;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_pIndexBuffer;
Microsoft::WRL::ComPtr<ID3D11VertexShader> m_pVertexShader;
Microsoft::WRL::ComPtr<ID3D11PixelShader> m_pPixelShader;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_pInputLayout;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_pConstantBuffer;
// Field data for implicit surface generation
std::vector<float> m_Field;
std::vector<int> m_VertexIndices; // Circular FIFO which stores one layer of vertex indices
int m_FieldX, m_FieldY, m_FieldZ; // Field dimensions
int m_FieldXY; // Precomputed m_FieldX * m_FieldY
DirectX::XMFLOAT3 m_LowerLeftCorner; // Corner of the field in world space
DirectX::XMFLOAT3 m_FieldToWorld; // Conversion scale from field to world
DirectX::XMFLOAT3 m_WorldToField; // Conversion scale from world to field
// Helper methods for field and coordinate conversion
int GetFieldCoords(const DirectX::XMFLOAT3& pos, int* p_x, int* p_y, int* p_z, DirectX::XMFLOAT3* p_remainder = nullptr) const;
void GetWorldPos(DirectX::XMFLOAT3* pos, int x, int y, int z) const;
public:
BlobRenderer();
~BlobRenderer();
// RenderObject interface
virtual bool IsVisible() override { return true; }
virtual void Destroy() override;
virtual void Render(ID3D11DeviceContext* pContext) override;
virtual void AdvanceTime(float elapsedTime, float dt) override;
// Initialize the blob renderer
void Initialize(ID3D11Device* pDevice, const BlobSource* pBlobSources, int numBlobs,
float xySpacing, float zSpacing,
const DirectX::XMFLOAT3& center, const DirectX::XMFLOAT3& halfDim);
// Getters/setters
float GetThreshold() const { return m_Threshold; }
void SetThreshold(float threshold) { m_Threshold = threshold; }
};
///////////////////////////////////////////////////////////////////////////////
// TestBlobRenderer - Test implementation with predefined blobs
///////////////////////////////////////////////////////////////////////////////
class TestBlobRenderer : public BlobRenderer
{
protected:
static constexpr int NUM_BLOBS = 6;
BlobSource m_Sources[NUM_BLOBS];
public:
TestBlobRenderer();
~TestBlobRenderer();
virtual void CreateTestBlobs(ID3D11Device* pDevice);
virtual void AdvanceTime(float elapsedTime, float dt) override;
};
+931
View File
@@ -0,0 +1,931 @@
///////////////////////////////////////////////////////////////////////////////
// File: Blobs.cpp - Modern Windows 11 port
//
// Original Copyright 2001 Pipeworks Software
// Modern Port Copyright (c) 2023
///////////////////////////////////////////////////////////////////////////////
#include "Blobs.h"
#include <algorithm>
#include <random>
using namespace DirectX;
using Microsoft::WRL::ComPtr;
// Initialize static members
const LavaLampInterior* LLBlob::spLL = nullptr;
std::mt19937 LavaLampInterior::m_RandomGenerator(std::random_device{}());
// Random number generation
float LavaLampInterior::FRand01()
{
static std::uniform_real_distribution<float> dist(0.0f, 1.0f);
return dist(m_RandomGenerator);
}
float LavaLampInterior::FRand11()
{
static std::uniform_real_distribution<float> dist(-1.0f, 1.0f);
return dist(m_RandomGenerator);
}
///////////////////////////////////////////////////////////////////////////////
// LavaLampInterior methods
///////////////////////////////////////////////////////////////////////////////
LavaLampInterior::LavaLampInterior()
{
m_NumConicSections = 0;
}
///////////////////////////////////////////////////////////////////////////////
LavaLampInterior::~LavaLampInterior()
{
Destroy();
}
///////////////////////////////////////////////////////////////////////////////
void LavaLampInterior::Destroy()
{
// Clean up blob resources
for (int i = 0; i < NUM_LLBLOBS; i++)
{
m_Blobs[i].Destroy();
}
// Release shader resources
m_pVertexShader.Reset();
m_pPixelShader.Reset();
m_pInputLayout.Reset();
m_pConstantBuffer.Reset();
m_pNormCubemap.Reset();
}
///////////////////////////////////////////////////////////////////////////////
void LavaLampInterior::InitializeShaders(ID3D11Device* pDevice)
{
// Define vertex shader code
const char* vsCode = R"(
cbuffer Constants : register(b0)
{
matrix World;
matrix ViewProj;
float4 Constants; // x=0, y=1, z=2, w=0.5
};
struct VS_INPUT
{
float3 Position : POSITION;
};
struct VS_OUTPUT
{
float4 Position : SV_POSITION;
float3 Normal : NORMAL;
float3 WorldPos : TEXCOORD0;
};
VS_OUTPUT main(VS_INPUT input)
{
VS_OUTPUT output;
// Transform position
float4 worldPos = mul(float4(input.Position, 1.0f), World);
output.Position = mul(worldPos, ViewProj);
// For a sphere, normal is the same as position (from center)
output.Normal = normalize(input.Position);
// Pass world position
output.WorldPos = worldPos.xyz;
return output;
}
)";
// Define pixel shader code
const char* psCode = R"(
TextureCube NormalCubeMap : register(t0);
SamplerState LinearSampler : register(s0);
cbuffer LightData : register(b0)
{
float3 LightDir1;
float3 LightDir2;
float4 BlobColor;
float4 AmbientColor;
}
struct PS_INPUT
{
float4 Position : SV_POSITION;
float3 Normal : NORMAL;
float3 WorldPos : TEXCOORD0;
};
float4 main(PS_INPUT input) : SV_TARGET
{
// Get normal from cubemap for more interesting lighting
float3 normal = NormalCubeMap.Sample(LinearSampler, input.Normal).xyz * 2.0f - 1.0f;
normal = normalize(normal);
// Calculate lighting
float light1 = max(0.0f, dot(normal, -LightDir1));
float light2 = max(0.0f, dot(normal, -LightDir2));
// Combine lights
float4 diffuse = BlobColor * (light1 + light2);
float4 final = diffuse + AmbientColor;
return float4(final.rgb, BlobColor.a);
}
)";
// TODO: Compile shaders using D3DCompile
// In a real implementation, we would compile these shaders using D3DCompileFromFile
// or load pre-compiled shader objects
// Create normal cubemap for blob lighting
// This would typically be loaded from a file or generated procedurally
}
///////////////////////////////////////////////////////////////////////////////
void LavaLampInterior::Create(ID3D11Device* pDevice)
{
// Set up the reference to this object for all blobs
LLBlob::spLL = this;
// Define the conic sections that make up the lava lamp shape
m_ConicSectionCenterX = +0.04f;
m_ConicSectionCenterY = -0.082f;
m_NumConicSections = 2;
m_ConicSectionBotZ[0] = -0.47f;
m_ConicSectionBotZ[1] = -0.25f;
m_ConicSectionBotZ[2] = +0.35f;
m_ConicSectionRadius[0] = 0.11f;
m_ConicSectionRadius[1] = 0.25f;
m_ConicSectionRadius[2] = 0.12f;
// Calculate normals for each conic section
for (int i = 0; i < m_NumConicSections; i++)
{
// Calculate slope (dr/dz)
m_ConicSectionSlope[i] = (m_ConicSectionRadius[i + 1] - m_ConicSectionRadius[i]) /
(m_ConicSectionBotZ[i + 1] - m_ConicSectionBotZ[i]);
// Normalize to get normal vector components
float norm = 1.0f / std::sqrt(1.0f + m_ConicSectionSlope[i] * m_ConicSectionSlope[i]);
m_ConicSectionNormalR[i] = norm * -1.0f;
m_ConicSectionNormalZ[i] = norm * m_ConicSectionSlope[i];
}
// Initialize shaders
InitializeShaders(pDevice);
// Create blobs
float bot = m_ConicSectionBotZ[0];
float sx = m_ConicSectionCenterX - 0.1f;
float sy = m_ConicSectionCenterY - 0.1f;
for (int i = 0; i < NUM_LLBLOBS; i++)
{
// Create each blob with a position and color
XMFLOAT3 pos = {
m_ConicSectionCenterX,
m_ConicSectionCenterY,
m_ConicSectionBotZ[m_NumConicSections >> 1]
};
// Calculate colors based on species
XMFLOAT4 color = {
(i & 0x04) ? 0.0f : 1.0f,
(i & 0x02) ? 0.0f : 1.0f,
(i & 0x01) ? 0.0f : 1.0f,
1.0f
};
// Base color for all blobs
XMFLOAT4 baseColor = { 0.724f, 0.732f, 0.556f, 1.0f };
// Blend species color with base color (mostly base)
m_Blobs[i].Create(pos, baseColor);
m_Blobs[i].SetSpecies(i);
}
}
///////////////////////////////////////////////////////////////////////////////
void LavaLampInterior::AdvanceTime(float elapsedTime, float dt)
{
// Clamp dt to avoid instability in physics
dt = std::min(dt, 0.1f);
dt = std::max(dt, 0.0f);
// Update each blob
for (int i = 0; i < NUM_LLBLOBS; i++)
{
m_Blobs[i].AdvanceTime(elapsedTime, dt);
}
// Update group affiliations
RecomputeSpecies();
}
///////////////////////////////////////////////////////////////////////////////
float LavaLampInterior::GetTemperature(float z) const
{
// Temperature gradient - hotter at the bottom, cooler at the top
float dz = -0.5f + (z - m_ConicSectionBotZ[0]) /
(m_ConicSectionBotZ[m_NumConicSections] - m_ConicSectionBotZ[0]);
dz *= 2.6f;
dz *= dz * dz; // Cubic falloff
return std::max(0.0f, std::min(1.0f, 0.5f - dz));
}
///////////////////////////////////////////////////////////////////////////////
bool LavaLampInterior::CollideWithCaps(LLBlob* pllb, float x, float y, float z, float radius) const
{
// Check collision with bottom cap
if (z - radius < m_ConicSectionBotZ[0])
{
XMFLOAT3 pos = { x, y, m_ConicSectionBotZ[0] + radius + 0.001f };
XMFLOAT3 norm = { 0.0f, 0.0f, 1.0f }; // Normal pointing up
pllb->Collided(pos, norm);
return true;
}
// Check collision with top cap
if (z + radius > m_ConicSectionBotZ[m_NumConicSections])
{
XMFLOAT3 pos = { x, y, m_ConicSectionBotZ[m_NumConicSections] - radius - 0.001f };
XMFLOAT3 norm = { 0.0f, 0.0f, -1.0f }; // Normal pointing down
pllb->Collided(pos, norm);
return true;
}
return false;
}
///////////////////////////////////////////////////////////////////////////////
void LavaLampInterior::Collide(LLBlob* pllb, float x, float y, float z, float radius, float dt) const
{
// First check collision with top and bottom caps
if (CollideWithCaps(pllb, x, y, z, radius))
{
// Get updated position after collision
z = pllb->GetPosition().z;
}
// Adjust for lamp center
x -= m_ConicSectionCenterX;
y -= m_ConicSectionCenterY;
// Calculate radial distance from center axis
float r = std::sqrt(x * x + y * y);
// Check collision with conic sections
bool hitWall = false;
for (int i = 0; i < m_NumConicSections; i++)
{
// Skip sections that don't overlap with blob's position
if (m_ConicSectionBotZ[i + 1] < z - radius) continue;
if (m_ConicSectionBotZ[i] > z + radius) break;
// Sphere overlaps the section - calculate distance to surface
float dz = z - m_ConicSectionBotZ[i];
float dr = r - m_ConicSectionRadius[i];
// Calculate overlap with surface
float overlap = radius - (dr * m_ConicSectionNormalR[i] + dz * m_ConicSectionNormalZ[i]);
if (overlap < 0.0f) continue;
// Calculate distance along surface to nearest collision point
float s = dr * m_ConicSectionNormalZ[i] - dz * m_ConicSectionNormalR[i];
if (s < 0.0f) continue;
float height = m_ConicSectionBotZ[i + 1] - m_ConicSectionBotZ[i];
if (s * s > height * height * (1.0f + m_ConicSectionSlope[i] * m_ConicSectionSlope[i])) continue;
// Calculate collision normal
float nz = m_ConicSectionNormalZ[i];
float oo_r = 1.0f / std::max(0.001f, r);
float nx = x * oo_r * m_ConicSectionNormalR[i];
float ny = y * oo_r * m_ConicSectionNormalR[i];
// Adjust position by overlap
x += nx * overlap;
y += ny * overlap;
z += nz * overlap;
// Recompute radius
r = std::sqrt(x * x + y * y);
// Create collision response
XMFLOAT3 pos = {
m_ConicSectionCenterX + x,
m_ConicSectionCenterY + y,
z
};
XMFLOAT3 norm = { nx, ny, nz };
pllb->Collided(pos, norm);
hitWall = true;
}
// Check the section corners if not already hit wall
if (!hitWall)
{
for (int i = 0; i < m_NumConicSections; i++)
{
// Skip sections that don't overlap with blob's position
if (m_ConicSectionBotZ[i + 1] < z - radius) continue;
if (m_ConicSectionBotZ[i] > z + radius) break;
float dz = z - m_ConicSectionBotZ[i];
float dr = r - m_ConicSectionRadius[i];
// Check if point is within sphere
if (dz * dz + dr * dr > radius * radius) continue;
float dist = std::sqrt(dz * dz + dr * dr);
float overlap = radius - dist;
// Calculate normal
float f_norm = 1.0f / std::max(0.001f, dist);
float nz = -dz * f_norm;
float nr = -dr * f_norm;
float oo_r = 1.0f / std::max(0.001f, r);
float nx = x * oo_r * nr;
float ny = y * oo_r * nr;
// Adjust position by overlap
x += nx * overlap;
y += ny * overlap;
z += nz * overlap;
// Recompute radius
r = std::sqrt(x * x + y * y);
// Create collision response
XMFLOAT3 pos = {
m_ConicSectionCenterX + x,
m_ConicSectionCenterY + y,
z
};
XMFLOAT3 norm = { nx, ny, nz };
pllb->Collided(pos, norm);
hitWall = true;
}
}
// Check for collisions with other blobs
for (int i = 0; i < NUM_LLBLOBS; i++)
{
// Skip self
if (&m_Blobs[i] == pllb) continue;
// Calculate vector between blobs
XMFLOAT3 pos1 = pllb->GetPosition();
XMFLOAT3 pos2 = m_Blobs[i].GetPosition();
XMFLOAT3 delta = {
pos2.x - pos1.x,
pos2.y - pos1.y,
pos2.z - pos1.z
};
// Calculate squared distance
float distSq = delta.x * delta.x + delta.y * delta.y + delta.z * delta.z;
// Combined radius
float rad = m_Blobs[i].GetRadius() + pllb->GetRadius();
// Check for overlap
if (distSq > rad * rad) continue;
// Blobs are interacting
pllb->InteractWithBlob(&m_Blobs[i], dt);
}
// Double-check caps to ensure validity
if (CollideWithCaps(pllb, x + m_ConicSectionCenterX, y + m_ConicSectionCenterY, z, radius))
{
// Should never happen with convex hull
z = pllb->GetPosition().z;
}
}
///////////////////////////////////////////////////////////////////////////////
float LavaLampInterior::GetRadius(float z) const
{
// Return 0 if below the bottom
if (z < m_ConicSectionBotZ[0]) return 0.0f;
// Find which section contains this z-value
for (int i = 0; i < m_NumConicSections; i++)
{
if (m_ConicSectionBotZ[i + 1] < z) continue;
// Interpolate radius within this section
float diff = m_ConicSectionBotZ[i + 1] - m_ConicSectionBotZ[i];
float s = (z - m_ConicSectionBotZ[i]) / diff;
return m_ConicSectionRadius[i] + s * (m_ConicSectionRadius[i + 1] - m_ConicSectionRadius[i]);
}
// Above the top
return 0.0f;
}
///////////////////////////////////////////////////////////////////////////////
void LavaLampInterior::RecomputeSpecies()
{
// Store previous species assignments
int prevSpecies[NUM_LLBLOBS];
for (int i = 0; i < NUM_LLBLOBS; i++)
{
prevSpecies[i] = m_Blobs[i].GetSpecies();
m_Blobs[i].SetSpecies(i); // Reset to unique species
}
// Check for blob proximity to merge species
for (int i = 0; i < NUM_LLBLOBS - 1; i++)
{
for (int j = i + 1; j < NUM_LLBLOBS; j++)
{
// Calculate distance between blobs
XMFLOAT3 pos1 = m_Blobs[i].GetPosition();
XMFLOAT3 pos2 = m_Blobs[j].GetPosition();
XMFLOAT3 diff = {
pos1.x - pos2.x,
pos1.y - pos2.y,
pos1.z - pos2.z
};
float distSq = diff.x * diff.x + diff.y * diff.y + diff.z * diff.z;
if (prevSpecies[i] == prevSpecies[j])
{
// Were connected previously
float radii = m_Blobs[i].GetRadius() + m_Blobs[j].GetRadius();
float radiiSq = radii * radii;
if (distSq < 0.9f * 0.9f * radiiSq)
{
// Still touching - maintain same species
m_Blobs[j].SetSpecies(m_Blobs[i].GetSpecies());
}
}
else
{
// Were not connected
float checkRad = std::max(m_Blobs[i].GetRadius(), m_Blobs[j].GetRadius());
checkRad += 0.7f * std::min(m_Blobs[i].GetRadius(), m_Blobs[j].GetRadius());
if (distSq < checkRad * checkRad)
{
// Connect them only if they are in the top or bottom
bool closeToEnd = false;
// Check blob i
float z = m_Blobs[i].GetPosition().z;
float r = m_Blobs[i].GetRadius();
closeToEnd = closeToEnd || (z - m_ConicSectionBotZ[0] < 1.5f * r);
closeToEnd = closeToEnd || (m_ConicSectionBotZ[m_NumConicSections] - z < 1.5f * r);
// Check blob j
z = m_Blobs[j].GetPosition().z;
r = m_Blobs[j].GetRadius();
closeToEnd = closeToEnd || (z - m_ConicSectionBotZ[0] < 1.5f * r);
closeToEnd = closeToEnd || (m_ConicSectionBotZ[m_NumConicSections] - z < 1.5f * r);
if (closeToEnd)
{
m_Blobs[j].SetSpecies(m_Blobs[i].GetSpecies());
}
}
}
}
}
// Ensure consistent species references
for (int i = 0; i < NUM_LLBLOBS; i++)
{
m_Blobs[i].SetSpecies(m_Blobs[m_Blobs[i].GetSpecies()].GetSpecies());
}
// Update blob colors based on species
for (int i = 0; i < NUM_LLBLOBS; i++)
{
int s = m_Blobs[i].GetSpecies();
// Create color based on species
XMFLOAT4 color = {
(s & 0x04) ? 0.0f : 1.0f,
(s & 0x02) ? 0.0f : 1.0f,
(s & 0x01) ? 0.0f : 1.0f,
1.0f
};
// Base color
XMFLOAT4 baseColor = { 0.724f, 0.732f, 0.556f, 1.0f };
// Blend with base color (95% base, 5% species)
XMFLOAT4 finalColor = {
color.x * 0.05f + baseColor.x * 0.95f,
color.y * 0.05f + baseColor.y * 0.95f,
color.z * 0.05f + baseColor.z * 0.95f,
color.w * 0.05f + baseColor.w * 0.95f
};
m_Blobs[i].SetColor(finalColor);
}
}
///////////////////////////////////////////////////////////////////////////////
void LavaLampInterior::Render(ID3D11DeviceContext* pContext)
{
// Set rendering state
// Enable alpha blending
float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
ID3D11BlendState* pPrevBlendState = nullptr;
UINT sampleMask = 0xffffffff;
pContext->OMGetBlendState(&pPrevBlendState, blendFactor, &sampleMask);
// Use additive blending for glow effect
ID3D11BlendState* pBlendState = nullptr;
// TODO: Create or use blend state
pContext->OMSetBlendState(pBlendState, blendFactor, sampleMask);
// Set depth state
ID3D11DepthStencilState* pPrevDepthState = nullptr;
UINT stencilRef = 0;
pContext->OMGetDepthStencilState(&pPrevDepthState, &stencilRef);
// Allow transparent blobs to be visible through each other
ID3D11DepthStencilState* pDepthState = nullptr;
// TODO: Create or use depth state
pContext->OMSetDepthStencilState(pDepthState, 0);
// Set rasterizer state
ID3D11RasterizerState* pPrevRasterState = nullptr;
pContext->RSGetState(&pPrevRasterState);
// Use backface culling
ID3D11RasterizerState* pRasterState = nullptr;
// TODO: Create or use rasterizer state
pContext->RSSetState(pRasterState);
// Set shaders
pContext->VSSetShader(m_pVertexShader.Get(), nullptr, 0);
pContext->PSSetShader(m_pPixelShader.Get(), nullptr, 0);
// Set texture
ID3D11ShaderResourceView* pSRVs[] = { m_pNormCubemap.Get() };
pContext->PSSetShaderResources(0, 1, pSRVs);
// Render each blob
for (int i = 0; i < NUM_LLBLOBS; i++)
{
m_Blobs[i].Render(pContext);
}
// Restore previous render states
pContext->OMSetBlendState(pPrevBlendState, blendFactor, sampleMask);
if (pPrevBlendState) pPrevBlendState->Release();
pContext->OMSetDepthStencilState(pPrevDepthState, stencilRef);
if (pPrevDepthState) pPrevDepthState->Release();
pContext->RSSetState(pPrevRasterState);
if (pPrevRasterState) pPrevRasterState->Release();
// Clear resources
ID3D11ShaderResourceView* pNullSRVs[] = { nullptr };
pContext->PSSetShaderResources(0, 1, pNullSRVs);
}
///////////////////////////////////////////////////////////////////////////////
// LLBlob methods
///////////////////////////////////////////////////////////////////////////////
LLBlob::LLBlob()
: m_NumVertices(0)
, m_NumIndices(0)
, m_Temperature(0.5f)
, m_DeformationInertia(0.3f)
{
m_Acceleration = { 0.0f, 0.0f, 0.0f };
m_Velocity = { 0.0f, 0.0f, 0.0f };
m_Position = { 0.0f, 0.0f, 0.0f };
m_Scale = { 0.9f, 0.9f, 0.9f };
m_BlobColor = { 1.0f, 1.0f, 1.0f, 1.0f };
}
///////////////////////////////////////////////////////////////////////////////
void LLBlob::Destroy()
{
m_pVertexBuffer.Reset();
m_pIndexBuffer.Reset();
}
///////////////////////////////////////////////////////////////////////////////
void LLBlob::CalculateFacePoint(XMFLOAT3* pPos, int face, int u, int v)
{
// Cube faces from -1 to +1
float fu = (u == m_Subdivisions) ? +1.0f : -1.0f + m_DivisionStep * ((float)u);
float fv = (v == m_Subdivisions) ? +1.0f : -1.0f + m_DivisionStep * ((float)v);
// Calculate point on each face
switch (face)
{
case 0: *pPos = { -1.0f, -fu, +fv }; break;
case 1: *pPos = { +fv, -1.0f, -fu }; break;
case 2: *pPos = { -fu, +fv, -1.0f }; break;
case 3: *pPos = { +1.0f, +fu, +fv }; break;
case 4: *pPos = { +fv, +1.0f, +fu }; break;
case 5: *pPos = { +fu, +fv, +1.0f }; break;
}
}
///////////////////////////////////////////////////////////////////////////////
void LLBlob::Create(XMFLOAT3 pos, XMFLOAT4 color)
{
// Store position and color
m_Position = pos;
m_BlobColor = color;
m_Scale = { 0.9f, 0.9f, 0.9f };
m_DeformationInertia = spLL->FRand11() * 0.1f;
// Generate random radius
m_Radius = spLL->FRand01();
m_Radius = 0.5f * (m_Radius * m_Radius + spLL->FRand01());
m_Radius = 0.03f + 0.05f * m_Radius;
m_TemperatureAbsorbance = 0.05f / m_Radius;
// Set initial temperature
m_Temperature = 0.5f + 0.2f * spLL->FRand11();
// Set subdivision level for sphere generation
m_Subdivisions = 4; // 4x4 grid of quads per face
m_DivisionStep = 2.0f / m_Subdivisions;
// Calculate vertex and index counts
m_NumVertices = 6 * (m_Subdivisions + 1) * (m_Subdivisions + 1);
m_NumIndices = 6 * (m_Subdivisions) * (m_Subdivisions) * 2 * 3;
// TODO: Create vertex and index buffers using Direct3D 11
// This would create a cube and then normalize vertices to form a sphere
}
///////////////////////////////////////////////////////////////////////////////
void LLBlob::AdvanceTime(float elapsedTime, float dt)
{
// Calculate ambient temperature
float ambientTemp = spLL->GetTemperature(m_Position.z);
// Adjust blob temperature toward ambient
float scale = 0.002f * m_TemperatureAbsorbance * m_TemperatureAbsorbance * dt;
m_Temperature += scale * (ambientTemp - m_Temperature);
// Apply buoyancy force - blobs lighter than water rise, heavier sink
m_Velocity.z += dt * 1.0f * (m_Temperature - 0.5f);
// Add small random forces
m_Acceleration.x += spLL->FRand11() * dt;
m_Acceleration.y += spLL->FRand11() * dt;
m_Acceleration.z += spLL->FRand11() * dt;
// Clamp acceleration
m_Acceleration.x = std::min(+0.05f, std::max(-0.05f, m_Acceleration.x));
m_Acceleration.y = std::min(+0.05f, std::max(-0.05f, m_Acceleration.y));
m_Acceleration.z = std::min(+0.05f, std::max(-0.05f, m_Acceleration.z));
// Scale acceleration if too large
float accelMagSq = m_Acceleration.x * m_Acceleration.x +
m_Acceleration.y * m_Acceleration.y +
m_Acceleration.z * m_Acceleration.z;
if (accelMagSq > 1.0f)
{
m_Acceleration.x *= 0.96f;
m_Acceleration.y *= 0.96f;
m_Acceleration.z *= 0.96f;
}
// Apply acceleration to velocity
m_Velocity.x += m_Acceleration.x * dt;
m_Velocity.y += m_Acceleration.y * dt;
m_Velocity.z += m_Acceleration.z * dt;
// Apply drag force
float velMagSq = m_Velocity.x * m_Velocity.x +
m_Velocity.y * m_Velocity.y +
m_Velocity.z * m_Velocity.z;
float drag = 1.0f - dt * 120.0f * velMagSq;
m_Velocity.x *= drag;
m_Velocity.y *= drag;
m_Velocity.z *= drag;
// Update position
m_Position.x += m_Velocity.x * dt;
m_Position.y += m_Velocity.y * dt;
m_Position.z += m_Velocity.z * dt;
// Check for collisions
spLL->Collide(this, m_Position.x, m_Position.y, m_Position.z, m_Radius, dt);
// Adjust blob shape (wobble effect)
m_Scale.x += m_DeformationInertia * dt * m_TemperatureAbsorbance;
m_Scale.y += m_DeformationInertia * dt * m_TemperatureAbsorbance;
// Maintain volume by adjusting z-scale
m_Scale.z = 0.9f - (m_Scale.x - 0.9f) * (0.9f + 0.9f) * 0.9f / (0.9f * 0.9f);
// Apply spring force to return to spherical shape
float accel;
if (m_DeformationInertia > 0.0f)
{
accel = 0.91f - m_Scale.x;
}
else
{
accel = 0.89f - m_Scale.x;
}
// Update deformation
m_DeformationInertia += 20.0f * accel * dt;
m_DeformationInertia = std::max(-0.3f, std::min(+0.3f, m_DeformationInertia));
}
///////////////////////////////////////////////////////////////////////////////
void LLBlob::Collided(XMFLOAT3 pos, XMFLOAT3 normal)
{
// Check if collision is valid
XMFLOAT3 diff = {
pos.x - m_Position.x,
pos.y - m_Position.y,
pos.z - m_Position.z
};
float diffMagSq = diff.x * diff.x + diff.y * diff.y + diff.z * diff.z;
if (diffMagSq > 0.5f * m_Radius * m_Radius)
{
// Collision point too far from center - ignore
return;
}
// Calculate reflection of velocity and acceleration
float dotAccel = m_Acceleration.x * normal.x +
m_Acceleration.y * normal.y +
m_Acceleration.z * normal.z;
if (dotAccel < 0.0f)
{
// Reflect acceleration
m_Acceleration.x -= normal.x * dotAccel;
m_Acceleration.y -= normal.y * dotAccel;
m_Acceleration.z -= normal.z * dotAccel;
}
float dotVel = m_Velocity.x * normal.x +
m_Velocity.y * normal.y +
m_Velocity.z * normal.z;
if (dotVel < 0.0f)
{
// Reflect velocity
m_Velocity.x -= normal.x * dotVel;
m_Velocity.y -= normal.y * dotVel;
m_Velocity.z -= normal.z * dotVel;
}
// Set new position
m_Position = pos;
}
///////////////////////////////////////////////////////////////////////////////
void LLBlob::InteractWithBlob(const LLBlob* pllb, float dt)
{
// Calculate mass of other blob
float massB = pllb->m_Radius;
massB *= massB * massB; // Mass proportional to volume
// Calculate vector between blobs
XMFLOAT3 delta = {
pllb->m_Position.x - m_Position.x,
pllb->m_Position.y - m_Position.y,
pllb->m_Position.z - m_Position.z
};
float distSq = delta.x * delta.x + delta.y * delta.y + delta.z * delta.z;
if (distSq < 0.000001f) return; // Too close to calculate
// Calculate relative velocity
XMFLOAT3 deltaV = {
pllb->m_Velocity.x - m_Velocity.x,
pllb->m_Velocity.y - m_Velocity.y,
pllb->m_Velocity.z - m_Velocity.z
};
// Project relative velocity onto separation vector
float dotProduct = deltaV.x * delta.x + deltaV.y * delta.y + deltaV.z * delta.z;
// Interaction depends on species
if (GetSpecies() == pllb->GetSpecies())
{
// Same species - attract more when moving together, less when moving apart
float extremeRad = (m_Radius + pllb->m_Radius);
float attract = massB * dt * 10000.0f * ((dotProduct > 0.0f) ? 1.0f : 0.5f);
// Apply attractive force
m_Velocity.x += delta.x * attract;
m_Velocity.y += delta.y * attract;
m_Velocity.z += delta.z * attract;
// Apply repulsion when very close
extremeRad *= 0.6f;
float extremeRadSq = extremeRad * extremeRad;
float repel = ((1.0f / std::min(extremeRadSq * 0.04f, distSq)) - (1.0f / extremeRadSq)) *
massB * dt * 5.0f;
repel *= ((dotProduct > 0.0f) ? 0.3f : 1.0f);
if (repel > 0.0f)
{
m_Velocity.x -= delta.x * repel;
m_Velocity.y -= delta.y * repel;
m_Velocity.z -= delta.z * repel;
}
}
else
{
// Different species - repel
float extremeRadSq = (m_Radius + pllb->m_Radius);
extremeRadSq *= extremeRadSq;
float repel = ((1.0f / std::min(extremeRadSq * 0.04f, distSq)) - (1.0f / extremeRadSq)) *
massB * dt * 1.0f;
repel *= ((dotProduct > 0.0f) ? 0.3f : 1.0f);
m_Velocity.x -= delta.x * repel;
m_Velocity.y -= delta.y * repel;
m_Velocity.z -= delta.z * repel;
}
}
///////////////////////////////////////////////////////////////////////////////
void LLBlob::Render(ID3D11DeviceContext* pContext)
{
// Create world transformation matrix
XMMATRIX world = XMMatrixScaling(m_Scale.x * m_Radius, m_Scale.y * m_Radius, m_Scale.z * m_Radius) *
XMMatrixTranslation(m_Position.x, m_Position.y, m_Position.z);
// Update constant buffer with world transform and blob color
D3D11_MAPPED_SUBRESOURCE mappedResource;
if (SUCCEEDED(pContext->Map(spLL->m_pConstantBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource)))
{
// First slot in constant buffer is world matrix
XMMATRIX* pMatrix = (XMMATRIX*)mappedResource.pData;
*pMatrix = XMMatrixTranspose(world);
// Update lighting parameters
XMFLOAT3* pLight1 = (XMFLOAT3*)((char*)mappedResource.pData + sizeof(XMMATRIX) * 3);
*pLight1 = { 0.5f, 0.6f, 0.5f };
XMFLOAT3* pLight2 = (XMFLOAT3*)((char*)mappedResource.pData + sizeof(XMMATRIX) * 3 + sizeof(XMFLOAT3));
*pLight2 = { 0.5f, 0.4f, 0.5f };
// Update blob color
XMFLOAT4* pColor = (XMFLOAT4*)((char*)mappedResource.pData + sizeof(XMMATRIX) * 3 + sizeof(XMFLOAT3) * 2);
*pColor = m_BlobColor;
// Update ambient light
XMFLOAT4* pAmbient = (XMFLOAT4*)((char*)mappedResource.pData + sizeof(XMMATRIX) * 3 + sizeof(XMFLOAT3) * 2 + sizeof(XMFLOAT4));
pAmbient->x = m_BlobColor.x * 0.6f;
pAmbient->y = m_BlobColor.y * 0.6f;
pAmbient->z = m_BlobColor.z * 0.6f;
pAmbient->w = m_BlobColor.w;
pContext->Unmap(spLL->m_pConstantBuffer.Get(), 0);
}
// Set constant buffer
pContext->VSSetConstantBuffers(0, 1, spLL->m_pConstantBuffer.GetAddressOf());
pContext->PSSetConstantBuffers(0, 1, spLL->m_pConstantBuffer.GetAddressOf());
// Set vertex and index buffers
UINT stride = sizeof(BlobVertex);
UINT offset = 0;
pContext->IASetVertexBuffers(0, 1, m_pVertexBuffer.GetAddressOf(), &stride, &offset);
pContext->IASetIndexBuffer(m_pIndexBuffer.Get(), DXGI_FORMAT_R16_UINT, 0);
// Draw blob
pContext->DrawIndexed(m_NumIndices, 0, 0);
}
+166
View File
@@ -0,0 +1,166 @@
///////////////////////////////////////////////////////////////////////////////
// File: Blobs.h - Modern Windows 11 port
//
// Original Copyright 2001 Pipeworks Software
// Modern Port Copyright (c) 2023
///////////////////////////////////////////////////////////////////////////////
#pragma once
#include <d3d11.h>
#include <DirectXMath.h>
#include <wrl/client.h>
#include <memory>
#include <vector>
#include <random>
#include "RenderObject.h"
///////////////////////////////////////////////////////////////////////////////
// BlobVertex - Vertex structure for blob rendering
///////////////////////////////////////////////////////////////////////////////
struct BlobVertex
{
DirectX::XMFLOAT3 position;
// Normal is implicit for spheres (position from center)
};
///////////////////////////////////////////////////////////////////////////////
// Forward declaration
///////////////////////////////////////////////////////////////////////////////
class LavaLampInterior;
///////////////////////////////////////////////////////////////////////////////
// LLBlob - Individual blob in the lava lamp
///////////////////////////////////////////////////////////////////////////////
class LLBlob : public RenderObject
{
public:
// Rendering resources
UINT m_NumVertices;
UINT m_NumIndices;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_pVertexBuffer;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_pIndexBuffer;
DirectX::XMFLOAT4 m_BlobColor;
// Position and appearance
DirectX::XMFLOAT3 m_Position;
DirectX::XMFLOAT3 m_Scale;
float m_DeformationInertia;
float m_Radius;
// Physics and behavior
float m_Temperature;
float m_TemperatureAbsorbance;
DirectX::XMFLOAT3 m_Velocity;
DirectX::XMFLOAT3 m_Acceleration;
// Mesh subdivisions
int m_Subdivisions; // Number of quads in a direction for each face
float m_DivisionStep; // Distance on cube face that a division spans
// Group behavior
int m_Species;
// Cube has dimensions from -1 to +1, this calculates points on each face
void CalculateFacePoint(DirectX::XMFLOAT3* pPos, int face, int u, int v);
public:
LLBlob();
void Create(DirectX::XMFLOAT3 pos, DirectX::XMFLOAT4 color);
// RenderObject interface implementation
virtual void Create(ID3D11Device* pDevice) {}
virtual void Destroy() override;
virtual bool IsVisible() override { return true; }
virtual void Render(ID3D11DeviceContext* pContext) override;
virtual void AdvanceTime(float elapsedTime, float dt) override;
// Physics and collision
void Collided(DirectX::XMFLOAT3 pos, DirectX::XMFLOAT3 normal);
void InteractWithBlob(const LLBlob* pllb, float dt);
// Getters/setters
DirectX::XMFLOAT3 GetPosition() const { return m_Position; }
float GetRadius() const { return m_Radius; }
float GetRadiusSq() const { return m_Radius * m_Radius; }
int GetSpecies() const { return m_Species; }
void SetSpecies(int s) { m_Species = s; }
void SetColor(DirectX::XMFLOAT4 color) { m_BlobColor = color; }
const DirectX::XMFLOAT4& GetColor() const { return m_BlobColor; }
// Reference to the containing lava lamp
static const LavaLampInterior* spLL;
// Friend declaration to allow LLBlob to access LavaLampInterior's protected members
friend class LavaLampInterior;
};
///////////////////////////////////////////////////////////////////////////////
// LavaLampInterior - Lava lamp container with multiple blobs
///////////////////////////////////////////////////////////////////////////////
class LavaLampInterior : public RenderObject
{
public:
static constexpr int NUM_LLBLOBS = 64;
LLBlob m_Blobs[NUM_LLBLOBS];
// Rendering resources
Microsoft::WRL::ComPtr<ID3D11VertexShader> m_pVertexShader;
Microsoft::WRL::ComPtr<ID3D11PixelShader> m_pPixelShader;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_pInputLayout;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_pConstantBuffer;
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_pNormCubemap;
// Lava lamp shape definition
static constexpr int MAX_CONIC_SECTIONS = 32;
int m_NumConicSections;
float m_ConicSectionCenterX, m_ConicSectionCenterY;
float m_ConicSectionBotZ[MAX_CONIC_SECTIONS + 1];
float m_ConicSectionRadius[MAX_CONIC_SECTIONS + 1];
float m_ConicSectionSlope[MAX_CONIC_SECTIONS]; // dr/dz
float m_ConicSectionNormalR[MAX_CONIC_SECTIONS]; // -1, normalized
float m_ConicSectionNormalZ[MAX_CONIC_SECTIONS]; // slope, normalized
// Random number generator
static std::mt19937 m_RandomGenerator;
// Private methods
void InitializeShaders(ID3D11Device* pDevice);
public:
LavaLampInterior();
~LavaLampInterior();
// RenderObject interface implementation
virtual bool IsVisible() override { return true; }
virtual void Create(ID3D11Device* pDevice);
virtual void Destroy() override;
virtual void Render(ID3D11DeviceContext* pContext) override;
virtual void AdvanceTime(float elapsedTime, float dt) override;
// Lava lamp container properties
float GetBottom() const { return m_ConicSectionBotZ[0]; }
float GetTop() const { return m_ConicSectionBotZ[m_NumConicSections]; }
// Get radius at a specific height
float GetRadius(float z) const;
// Temperature gradient (1.0 at bottom, 0.0 at top)
float GetTemperature(float z) const;
// Collision detection for blobs
void Collide(LLBlob* pllb, float x, float y, float z, float radius, float dt) const;
bool CollideWithCaps(LLBlob* pllb, float x, float y, float z, float radius) const;
// Group behavior
void RecomputeSpecies();
// Static random number helpers (0.0-1.0 and -1.0-1.0)
static float FRand01();
static float FRand11();
// Make LLBlob a friend class to allow it to access protected members
friend class LLBlob;
};
+253
View File
@@ -0,0 +1,253 @@
/*************************************************************************
* *
* Here live the sound call processing functions *
* *
*************************************************************************/
#include "sos.h"
#include "protos.h"
#include "externs.h"
#include <dsound.h>
extern unsigned char sound_call;
extern struct timer_music music_timers[];
extern unsigned char n_timers;
#ifdef BIGOS
unsigned char restore_volume;
#endif
/*************************************************************************
* *
* New Music Call: *
* Note that if no tracks are specified, this is a silence call *
* *
* 1. Remove all current process for this level *
* 2. For each track in the new sound, create a new process *
* for it. *
* *
*************************************************************************/
void call_silence()
{
struct process *tpp;
struct process *pp;
uchar i;
pp = process_queue->next;
while (pp != NULL) {
tpp = pp->next;
kill_process(pp);
pp = tpp;
}
current_timer_priority = 0;
for (i = 0; i < max_tracks; i++) {
channel_level[i] = 0;
init_track_status(LEVEL_MUSIC,i);
init_track_status(LEVEL_EFFECT,i);
nosound(i);
}
user_silence_function();
}
void call_music()
{
ushort const **track_ptr; /* pointer to addr's of tracks */
uchar i;
ushort mask;
ushort track_map;
marker = 0;
last_music_call = sound_call;
remove_processes_by_level(LEVEL_MUSIC);
track_map = current_call->track_map;
track_ptr = current_call->tbl_ptr;
for (i = 0,mask = 1; i < max_tracks; i++,mask <<= 1) {
if (track_map & mask) { /* got a track to pl*/
init_track_status(LEVEL_MUSIC,i);
create_process((ushort *)*(track_ptr++),LEVEL_MUSIC,i);
if (channel_level[i] < LEVEL_EFFECT) {
nosound(i);
channel_level[i] = LEVEL_MUSIC;
}
}
}
}
void call_play_timer()
{
}
void call_timer()
{
}
void call_end_timer()
{
}
void call_ignore()
{
}
extern flash_yellow();
void call_effect()
{
ushort const **track_ptr; /* pointer to addr's of tracks */
uchar i;
ushort mask;
ushort track_map;
track_ptr = current_call->tbl_ptr;
track_map = current_call->track_map;
for (i = 0,mask = 1; i < max_tracks; i++,mask <<= 1) {
if (track_map & mask) { /* got a track to pl*/
remove_processes_by_level_and_channel(LEVEL_EFFECT,i);
channel_level[i] = LEVEL_EFFECT;
init_track_status(LEVEL_EFFECT,i);
create_process((ushort *)*(track_ptr++),LEVEL_EFFECT,i);
}
}
}
/*************************************************************************
* *
* kill fx on all tracks *
* *
*************************************************************************/
void call_kill_effect()
{
}
/*************************************************************************
* *
* Send a byte to the yamaha *
* WARNING: This routine blocks until it recieves both the *
* address AND data *
* *
*************************************************************************/
#define CALL_WAITING (fifo.fifo_read != fifo.fifo_write)
void call_senddev()
{
#ifdef BIGOS
while (!CALL_WAITING)
;
b_value = get_fifo();
while (!CALL_WAITING)
;
a_value = get_fifo();
send_dev_function();
#endif
}
/*************************************************************************
* *
* VOLUME SOUND CALL *
* byte 1:("type") 3 -> volume call *
* byte 2:("priority") 1 -> music volume; 2 -> fx volume *
* byte 3,4:("track_map") level *
* byte 5,6: not used (MUST BE THERE) *
* *
*************************************************************************/
void call_volume()
{
}
/************************************************************************
* *
* MARK SOUND CALL
* byte 1:("type") 6 -> mark call *
* byte 2:("priority") marker #
* byte 3,4:("track_map") NOT USED *
* byte 5,6: not used (MUST BE THERE) *
* *
*************************************************************************/
void call_mark()
{
marker = current_call->priority;
}
init_track_status(uchar level, uchar channel)
{
struct track_info *ti;
ti = get_track_info_block2(level,channel);
/* ti = get_track_info_block();*/
ti->patch = 0;
ti->loop_level = 0;
ti->mux_level = 0;
ti->transpose = 0;
ti->filtercutoff = 0;
ti->volume = 127; /* */
ti->pan = 0;
}
/*
* stop sound on channel chan
*/
void nosound(uchar chan)
{
if (chan < max_tracks)
silence_functions[chan](chan);
}
/*
* Remove all processes of level, 'level' from process queue
*/
remove_processes_by_level(uchar level)
{
struct process *tpp;
struct process *pp;
pp = process_queue->next;
while (pp != NULL) {
tpp = pp->next;
if (pp->level == level)
kill_process(pp);
pp = tpp;
}
}
void remove_processes_by_level_and_channel(uchar level, uchar channel)
{
struct process *tpp;
struct process *pp;
pp = process_queue->next;
while (pp != NULL) {
tpp = pp->next;
if (pp->level == level) {
if (pp->hard_channel == channel) {
kill_process(pp);
}
}
pp = tpp;
}
}

+460
View File
@@ -0,0 +1,460 @@
///////////////////////////////////////////////////////////////////////////////
// File: CamControl.cpp - Modern Windows 11 port
//
// Copyright 2001 Pipeworks Software (Original)
// Modern Port Copyright (c) 2023
///////////////////////////////////////////////////////////////////////////////
#include "CamControl.h"
#include <random>
#include <algorithm>
using namespace DirectX;
// The camera path data has been preserved from the original Xbox codebase
// but converted to use XMFLOAT3 for position and lookat points
CamControlNodeData CameraController::m_CameraListData[] =
{
// Top, pan down, pull out.
{ 0, +00, +00, {+11.4f, -32.1f, +33.0f}, {+0.0f, +0.0f, +0.0f} },
{ 20, +00, +00, {+13.4f, -37.7f, +25.6f}, {+0.0f, +0.0f, +0.0f} },
{ 40, +00, +00, {+15.6f, -43.9f, +8.8f}, {+0.0f, +0.0f, +0.0f} },
{ 60, +00, +00, {+16.0f, -45.0f, -12.8f}, {+0.0f, +0.0f, +0.0f} },
{ 90, +00, +00, {+18.2f, -51.2f, -29.6f}, {+0.0f, +0.0f, +0.0f} },
// Start low near tube, pause, quickly go up and to the right, pause, pull out.
{ 00, +0, +0, {-55.4f, +19.7f, -31.5f}, {+0.0f, +0.0f, +0.0f} },
{ 30, +0, +0, {-55.4f, +19.7f, -31.5f}, {+0.0f, +0.0f, +0.0f} },
{ 45, +0, +0, {-39.5f, -0.6f, -7.8f}, {+0.0f, +0.0f, +0.0f} },
{ 60, +0, +0, {-4.3f, -35.5f, +16.6f}, {+0.0f, +0.0f, +0.0f} },
{ 70, +0, +0, {+31.1f, -32.6f, +17.6f}, {+0.0f, +0.0f, +0.0f} },
{ 80, +0, +0, {+57.7f, -7.2f, +3.3f}, {+0.0f, +0.0f, +0.0f} },
{ 95, +0, +0, {+70.9f, +1.8f, +3.1f}, {+0.0f, +0.0f, +0.0f} },
// Rotate to left, fairly close.
{ 00, +0, +0, {+34.7f, +25.9f, +12.3f}, {+0.0f, +0.0f, +0.0f} },
{ 25, +0, +0, {+42.3f, +9.3f, +12.3f}, {+0.0f, +0.0f, +0.0f} },
{ 50, +0, +0, {+42.4f, -8.8f, +12.3f}, {+0.0f, +0.0f, +0.0f} },
{ 75, +0, +0, {+34.4f, -26.3f, +12.3f}, {+0.0f, +0.0f, +0.0f} },
{ 95, +0, +0, {+30.7f, -48.1f, +14.3f}, {+0.0f, +0.0f, +0.0f} },
// Start out low, pause, rotate up slightly and pull out.
{ 0, +00, +00, {-50.1f, -0.3f, -51.5f}, {+0.0f, +0.0f, +0.0f} },
{ 25, +00, +00, {-50.1f, -0.3f, -51.5f}, {+0.0f, +0.0f, +0.0f} },
{ 75, +00, +00, {-50.1f, -0.3f, -51.5f}, {+0.0f, +0.0f, +0.0f} },
{ 95, +00, +00, {-62.2f, -0.4f, -12.0f}, {+0.0f, +0.0f, +0.0f} },
};
// Define the number of camera nodes
#define NUM_CC_NODES (sizeof(CameraController::m_CameraListData)/sizeof(CamControlNodeData))
// Static array to store camera list nodes
CamControlNode CameraController::m_CameraList[NUM_CC_NODES];
///////////////////////////////////////////////////////////////////////////////
CameraController::CameraController()
{
m_numNodes = 0;
m_numPaths = 0;
m_curPathNum = -1;
m_curStartNode = 0;
m_curNumNodes = 0;
m_curVariableNodes = 0;
m_fCameraLookatInterpStart = 0.0f;
m_fOOCameraLookatInterpDelta = 0.0f;
// Initialize the matrices
m_xfSlash = XMMatrixIdentity();
}
///////////////////////////////////////////////////////////////////////////////
CameraController::~CameraController()
{
Uninit();
}
///////////////////////////////////////////////////////////////////////////////
void CameraController::Init()
{
m_numNodes = NUM_CC_NODES;
m_numPaths = 0;
m_curPathNum = -1;
// Initialize camera list from the static data
for (int i = 0; i < m_numNodes; i++)
{
// Count paths (new path starts when time is 0)
if (m_CameraListData[i].ucTime == 0)
m_numPaths++;
// Convert time from percentage to seconds
m_CameraList[i].fTime = FINISH_START_TIME * ((float)m_CameraListData[i].ucTime) * 0.01f;
// Copy position and lookat
m_CameraList[i].ptPosition = m_CameraListData[i].ptPosition;
m_CameraList[i].vecLookAt = m_CameraListData[i].vecLookAt;
// Convert tension and bias from -100..100 to -1..1
m_CameraList[i].tension = ((float)m_CameraListData[i].scTension) * 0.01f;
m_CameraList[i].bias = ((float)m_CameraListData[i].scBias) * 0.01f;
}
// Pick a random path to start
PickPath(-1);
}
///////////////////////////////////////////////////////////////////////////////
void CameraController::Uninit()
{
// No special cleanup needed
}
///////////////////////////////////////////////////////////////////////////////
// Get a node (either from camera list or finish nodes)
CamControlNode* CameraController::GetNode(int i)
{
return (i < m_curVariableNodes) ? &m_CameraList[i + m_curStartNode] : &m_FinishNodes[i - m_curVariableNodes];
}
///////////////////////////////////////////////////////////////////////////////
// Get a node (const version)
const CamControlNode* CameraController::GetNode(int i) const
{
return (i < m_curVariableNodes) ? &m_CameraList[i + m_curStartNode] : &m_FinishNodes[i - m_curVariableNodes];
}
///////////////////////////////////////////////////////////////////////////////
// Pick a camera path (negative indicates random)
void CameraController::PickPath(int path)
{
// If path is negative, pick a random path
if (path < 0)
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dist(0, m_numPaths - 1);
path = dist(gen);
}
// Ensure path is in valid range
if (path >= m_numPaths)
path = path % m_numPaths;
m_curPathNum = path;
// Find the start node for this path
int i;
for (i = 0; i < m_numNodes; i++)
{
if (m_CameraList[i].fTime == 0.0f)
{
if (!path) break;
path--;
}
}
m_curStartNode = i;
// Find the end node for this path
for (i = m_curStartNode + 1; i < m_numNodes; i++)
{
if (m_CameraList[i].fTime == 0.0f) break;
}
m_curVariableNodes = i - m_curStartNode;
m_curNumNodes = m_curVariableNodes + NUM_FINISH_NODES;
// Calculate the finish nodes
for (int j = 0; j < NUM_FINISH_NODES; j++)
{
m_FinishNodes[j].fTime = FINISH_START_TIME + FINISH_TRANSITION_TIME * ((float)j) / ((float)(NUM_FINISH_NODES - 1));
m_FinishNodes[j].tension = +0.0f;
m_FinishNodes[j].bias = 0.0f;
}
m_fCameraLookatInterpStart = m_FinishNodes[2].fTime;
m_fOOCameraLookatInterpDelta = 1.0f / (m_FinishNodes[5].fTime - m_fCameraLookatInterpStart);
// Get the last variable node
const CamControlNode* plast = &m_CameraList[m_curStartNode + m_curVariableNodes - 1];
CamControlNode* pthis = &m_FinishNodes[0];
float start_time = plast->fTime;
// Constants for slash animation
const float slash_start_rad = -95.0f;
const float slash_end_rad = 132.14f;
const float cfYPositions[NUM_FINISH_NODES] = { +95.0f, +30.548f, -70.819f, -150.298f, -220.64f, -243.021f, -261.441f, -287.773f };
const float cfZPositions[NUM_FINISH_NODES] = { 0.0f, 0.322f, 1.821f, 2.323f, -11.926f, -39.973f, -60.774f, -90.795f };
const float camera_end_coord_y = cfYPositions[NUM_FINISH_NODES - 1];
const float camera_end_coord_z = cfZPositions[NUM_FINISH_NODES - 1];
const float lookat_offset = slash_end_rad * camera_end_coord_z / camera_end_coord_y;
const float cfSlashDist = slash_end_rad - slash_start_rad;
const float cfMinStartDist = 100.0f;
// First finish node is at the entrance of the slash
pthis->ptPosition = plast->ptPosition;
// Calculate velocity from last two nodes
XMFLOAT3 vel = { 0.0f, 0.0f, 0.0f };
if (m_curVariableNodes >= 2)
{
// Calculate velocity from the last two nodes
XMFLOAT3 p1 = GetNode(m_curVariableNodes - 1)->ptPosition;
XMFLOAT3 p2 = GetNode(m_curVariableNodes - 2)->ptPosition;
float dt = GetNode(m_curVariableNodes - 1)->fTime - GetNode(m_curVariableNodes - 2)->fTime;
// v = (p1 - p2) / dt
vel.x = (p1.x - p2.x) / dt;
vel.y = (p1.y - p2.y) / dt;
vel.z = (p1.z - p2.z) / dt;
}
// Add scaled velocity to position
pthis->ptPosition.x += vel.x * (pthis->fTime - plast->fTime) * 0.7f;
pthis->ptPosition.y += vel.y * (pthis->fTime - plast->fTime) * 0.7f;
pthis->ptPosition.z += vel.z * (pthis->fTime - plast->fTime) * 0.7f;
// Normalize the position
XMVECTOR posVec = XMLoadFloat3(&pthis->ptPosition);
float vel_adj_len = XMVectorGetX(XMVector3Length(posVec));
posVec = XMVector3Normalize(posVec);
// Store slash direction
XMFLOAT3 slash_dir;
XMStoreFloat3(&slash_dir, posVec);
// Adjust position based on slash parameters
float slash_y_offset = std::max(cfMinStartDist - slash_start_rad, vel_adj_len * 1.2f - slash_start_rad);
// Scale position by radius + offset
posVec = XMVectorScale(posVec, slash_y_offset + slash_start_rad);
XMStoreFloat3(&pthis->ptPosition, posVec);
// Set lookat point to origin
pthis->vecLookAt = { 0.0f, 0.0f, 0.0f };
// Calculate slash transform matrix
XMVECTOR origin = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
XMVECTOR up = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
// The shape has negative y going away from core.
// Negative Y is normalized vector from slash_pos to origin
XMVECTOR y_dir = XMLoadFloat3(&slash_dir);
y_dir = XMVectorNegate(y_dir);
// X is y_dir crossed with up and normalized
XMVECTOR x_dir = XMVector3Cross(y_dir, up);
x_dir = XMVector3Normalize(x_dir);
// Z is x_dir cross y_dir
XMVECTOR z_dir = XMVector3Cross(x_dir, y_dir);
// Build the transformation matrix
m_xfSlash = XMMatrixIdentity();
// Set the rotation part of the matrix
m_xfSlash.r[0] = XMVectorSetW(x_dir, 0.0f);
m_xfSlash.r[1] = XMVectorSetW(y_dir, 0.0f);
m_xfSlash.r[2] = XMVectorSetW(z_dir, 0.0f);
// Set the translation part of the matrix
XMVECTOR translation = XMVectorScale(y_dir, -slash_y_offset);
m_xfSlash.r[3] = XMVectorSetW(translation, 1.0f);
// Calculate slash center
XMVECTOR slashCenter = XMVectorScale(y_dir, -(slash_end_rad + slash_y_offset));
XMStoreFloat3(&m_ptSlashCenter, slashCenter);
// Calculate positions for the rest of the finish nodes
float y_basis = slash_end_rad;
for (int j = 1; j < NUM_FINISH_NODES; j++)
{
plast = pthis++;
// Position in slash space
XMVECTOR pt_in_slash = XMVectorSet(0.0f, cfYPositions[j] + y_basis, cfZPositions[j], 1.0f);
// Transform to world space
XMVECTOR worldPos = XMVector3Transform(pt_in_slash, m_xfSlash);
worldPos = XMVectorAdd(worldPos, XMLoadFloat3(&m_ptSlashCenter));
// Store position
XMStoreFloat3(&pthis->ptPosition, worldPos);
// Set lookat point to origin
pthis->vecLookAt = { 0.0f, 0.0f, 0.0f };
}
// Set the final lookat point
XMVECTOR t = XMVectorSet(0.0f, slash_end_rad, 25.0f, 1.0f);
XMVECTOR finalLookAt = XMVector3Transform(t, m_xfSlash);
finalLookAt = XMVectorAdd(finalLookAt, XMLoadFloat3(&m_ptSlashCenter));
XMStoreFloat3(&m_ptFinalLookAt, finalLookAt);
// Set the "m" parameters implicitly for Hermite interpolation
for (int j = 0; j < m_curNumNodes; j++)
{
CamControlNode* pthis = GetNode(j);
// Initialize velocities to zero
pthis->vecVelocity = { 0.0f, 0.0f, 0.0f };
pthis->vecLookAtW = { 0.0f, 0.0f, 0.0f };
if (j > 0)
{
// Calculate velocity contribution from previous node
const CamControlNode* prev = GetNode(j - 1);
float scale = (1.0f - pthis->tension) * (1.0f + pthis->bias) * 0.5f;
// Position velocity
pthis->vecVelocity.x += (pthis->ptPosition.x - prev->ptPosition.x) * scale;
pthis->vecVelocity.y += (pthis->ptPosition.y - prev->ptPosition.y) * scale;
pthis->vecVelocity.z += (pthis->ptPosition.z - prev->ptPosition.z) * scale;
// Lookat velocity
pthis->vecLookAtW.x += (pthis->vecLookAt.x - prev->vecLookAt.x) * scale;
pthis->vecLookAtW.y += (pthis->vecLookAt.y - prev->vecLookAt.y) * scale;
pthis->vecLookAtW.z += (pthis->vecLookAt.z - prev->vecLookAt.z) * scale;
}
if (j < m_curNumNodes - 1)
{
// Calculate velocity contribution from next node
const CamControlNode* next = GetNode(j + 1);
float scale = (1.0f - pthis->tension) * (1.0f - pthis->bias) * 0.5f;
// Position velocity
pthis->vecVelocity.x += (next->ptPosition.x - pthis->ptPosition.x) * scale;
pthis->vecVelocity.y += (next->ptPosition.y - pthis->ptPosition.y) * scale;
pthis->vecVelocity.z += (next->ptPosition.z - pthis->ptPosition.z) * scale;
// Lookat velocity
pthis->vecLookAtW.x += (next->vecLookAt.x - pthis->vecLookAt.x) * scale;
pthis->vecLookAtW.y += (next->vecLookAt.y - pthis->vecLookAt.y) * scale;
pthis->vecLookAtW.z += (next->vecLookAt.z - pthis->vecLookAt.z) * scale;
}
}
}
///////////////////////////////////////////////////////////////////////////////
// Get camera position and lookat point at time t
void CameraController::GetPosition(float t, XMFLOAT3* p_pos, XMFLOAT3* p_look, bool* pb_render_geom, bool* pb_render_slash)
{
// If we're past the stop time, return the final position
if (t > FINISH_STOP_TIME)
{
*p_pos = m_FinishNodes[NUM_FINISH_NODES - 1].ptPosition;
*p_look = m_ptFinalLookAt;
*pb_render_slash = true;
*pb_render_geom = false;
return;
}
// Find which nodes to interpolate between
int i;
for (i = 1; i < m_curNumNodes; i++)
{
if (GetNode(i)->fTime > t) break;
}
// Handle edge cases
if (i == m_curNumNodes)
{
*p_pos = GetNode(m_curNumNodes - 1)->ptPosition;
*p_look = m_ptFinalLookAt;
*pb_render_slash = true;
*pb_render_geom = false;
return;
}
if (i == 0)
{
// Should never happen, but handle it safely
p_pos->x = 0.0f;
p_pos->y = -90.0f;
p_pos->z = 0.0f;
p_look->x = 0.0f;
p_look->y = 0.0f;
p_look->z = 0.0f;
*pb_render_slash = true;
*pb_render_geom = false;
return;
}
// Get the nodes to interpolate between
const CamControlNode* pprev = GetNode(i - 1);
const CamControlNode* pnext = GetNode(i);
// Calculate time deltas for interpolation
float dtc = std::max(0.001f, pnext->fTime - pprev->fTime);
float dtp = std::max(0.001f, (i >= 2) ? pprev->fTime - GetNode(i - 2)->fTime : dtc);
float dtn = std::max(0.001f, (i < m_curNumNodes - 1) ? GetNode(i + 1)->fTime - pnext->fTime : dtc);
// Calculate normalized time for interpolation
float uts = std::min(1.0f, std::max(0.0f, (t - pprev->fTime) / dtc));
float utss = uts * uts;
float utsss = utss * uts;
float frac = -2.0f * utsss + 3.0f * utss;
float s = (t - pprev->fTime) / ((1.0f - frac) * dtp + frac * dtc);
// Hermite interpolation coefficients
float ss = s * s;
float sss = ss * s;
float cA = 2.0f * sss - 3.0f * ss + 1.0f;
float cB = sss - 2.0f * ss + s;
float cC = sss - ss;
float cD = -2.0f * sss + 3.0f * ss;
// Interpolate position
p_pos->x = cA * pprev->ptPosition.x + cB * pprev->vecVelocity.x + cC * pnext->vecVelocity.x + cD * pnext->ptPosition.x;
p_pos->y = cA * pprev->ptPosition.y + cB * pprev->vecVelocity.y + cC * pnext->vecVelocity.y + cD * pnext->ptPosition.y;
p_pos->z = cA * pprev->ptPosition.z + cB * pprev->vecVelocity.z + cC * pnext->vecVelocity.z + cD * pnext->ptPosition.z;
// Interpolate look-at position
p_look->x = cA * pprev->vecLookAt.x + cB * pprev->vecLookAtW.x + cC * pnext->vecLookAtW.x + cD * pnext->vecLookAt.x;
p_look->y = cA * pprev->vecLookAt.y + cB * pprev->vecLookAtW.y + cC * pnext->vecLookAtW.y + cD * pnext->vecLookAt.y;
p_look->z = cA * pprev->vecLookAt.z + cB * pprev->vecLookAtW.z + cC * pnext->vecLookAtW.z + cD * pnext->vecLookAt.z;
// Calculate lookat interpolation with final lookat point
float sl = std::max(0.0f, std::min(1.0f, (t - m_fCameraLookatInterpStart) * m_fOOCameraLookatInterpDelta));
// Smooth interpolation using cosine
float interp = 0.5f * (1.0f - cosf(sl * XM_PI));
// Blend between interpolated lookat and final lookat
XMVECTOR lookVec = XMLoadFloat3(p_look);
XMVECTOR finalLookVec = XMLoadFloat3(&m_ptFinalLookAt);
lookVec = XMVectorScale(lookVec, 1.0f - interp);
finalLookVec = XMVectorScale(finalLookVec, interp);
lookVec = XMVectorAdd(lookVec, finalLookVec);
XMStoreFloat3(p_look, lookVec);
// Set render flags based on current position in animation
*pb_render_slash = (i > m_curVariableNodes - 1);
*pb_render_geom = (i < m_curNumNodes - 1);
}
///////////////////////////////////////////////////////////////////////////////
void CameraController::ButtonPressed()
{
#ifdef INCLUDE_PLACEMENT_DOODAD
// Debug functionality to output camera position for placement tool
XMFLOAT3 pos;
XMFLOAT3 la;
// TODO: Get current camera position from app
//app.theCamera.GetCameraPosition(&pos);
//la = app.GetLookatPoint();
// Output formatted position for copy/paste into camera data array
char buf[1024];
sprintf_s(buf, 1024, " { 0, +00, +00, {%+8.1ff,%+8.1ff,%+8.1ff}, {%+8.1ff,%+8.1ff,%+8.1ff} },\n",
pos.x, pos.y, pos.z, la.x, la.y, la.z);
// Output to debug window
OutputDebugStringA(buf);
#endif
}
+97
View File
@@ -0,0 +1,97 @@
///////////////////////////////////////////////////////////////////////////////
// File: CamControl.h - Modern Windows 11 port
//
// Copyright 2001 Pipeworks Software (Original)
// Modern Port Copyright (c) 2023
///////////////////////////////////////////////////////////////////////////////
#pragma once
#include <DirectXMath.h>
#include <vector>
#include "defines.h"
///////////////////////////////////////////////////////////////////////////////
// CamControlNodeData - data for camera path nodes
///////////////////////////////////////////////////////////////////////////////
struct CamControlNodeData
{
unsigned char ucTime; // Time when the camera arrives here (0 indicates start of new path, 100 is start of finalization)
signed char scTension, scBias; // Tension and bias of point, from -100 to +100
DirectX::XMFLOAT3 ptPosition; // Position of node
DirectX::XMFLOAT3 vecLookAt; // Position the camera looks at
};
///////////////////////////////////////////////////////////////////////////////
// CamControlNode - runtime node with additional data for interpolation
///////////////////////////////////////////////////////////////////////////////
struct CamControlNode
{
float fTime; // Time when the camera arrives here
DirectX::XMFLOAT3 ptPosition; // Position of node
DirectX::XMFLOAT3 vecVelocity; // Velocity at this point (for Hermite interpolation)
DirectX::XMFLOAT3 vecLookAt; // Position the camera looks at
DirectX::XMFLOAT3 vecLookAtW; // Velocity of what the camera looks at
float tension, bias; // Interpolation parameters
};
///////////////////////////////////////////////////////////////////////////////
// CameraController - Manages camera paths and interpolation
//
// The camera system uses a series of paths with Hermite interpolation to create
// smooth camera movement. Each path has a series of nodes with position, lookat
// point, and interpolation parameters.
//
// The finish nodes are:
// 0: before the beginning of the slash, anything before this doesn't need to render the slash
// 1: after exiting slash
// 2: translated down, but still looking at center (but it is eclipsed by slash geometry)
// 3: partly rotated to final position, looking at slash center now
// 4: final position
// 5: final position, with high time value (the endcap)
///////////////////////////////////////////////////////////////////////////////
class CameraController
{
private:
static CamControlNodeData m_CameraListData[];
static CamControlNode m_CameraList[];
static constexpr int NUM_FINISH_NODES = 8;
CamControlNode m_FinishNodes[NUM_FINISH_NODES];
DirectX::XMMATRIX m_xfSlash;
DirectX::XMFLOAT3 m_ptSlashCenter;
DirectX::XMFLOAT3 m_ptFinalLookAt;
int m_numNodes;
int m_numPaths;
int m_curPathNum;
int m_curStartNode;
int m_curNumNodes;
int m_curVariableNodes;
float m_fCameraLookatInterpStart;
float m_fOOCameraLookatInterpDelta;
// Helper method to get a node (either from camera list or finish nodes)
CamControlNode* GetNode(int i);
const CamControlNode* GetNode(int i) const;
public:
CameraController();
~CameraController();
void Init();
void Uninit();
// Called when button is pressed in debug mode
void ButtonPressed();
// Select a camera path (negative indicates random)
void PickPath(int path = -1);
// Get camera position and lookat point at time t
void GetPosition(float t, DirectX::XMFLOAT3* p_pos, DirectX::XMFLOAT3* p_look, bool* pb_render_geom, bool* pb_render_slash);
// Get slash transformation matrix
const DirectX::XMMATRIX& GetSlashTransform() const { return m_xfSlash; }
};
+691
View File
@@ -0,0 +1,691 @@
/*************************************************************************
* *
* This file contains the tables and definitions for *
* the synthesis specific DEVice *
* The device tables are in devtab.c *
**************************************************************************
*
* The following variables and tables must be defined:
*
* max_tracks: 1 byte, max # of synthesis channels
* dev_init: function called to initialize device
* do_watchdog function called to kick watchdog timer
* dtimer_int function called to disable timer interrupt
* etimer_int function called to enable timer interrupt
* send_dev_function:
* function called to send a byte of data to the synthesis
* device (sound call callable)
* The data is in the global, "a_value" and the address is
* in the global, "b_value."
**************************************************************************/
#define _base_
extern struct DSPpatch *Patches[];
extern unsigned short Noise8192[];
#include <dsound.h>
#include "sosdsp.h"
#include "sos.h"
#include "bootsnd.h"
#include <xtl.h>
#include "dsptables.h"
#define MAX_BUFFERS 16
#ifdef STARTUPANIMATION
#pragma data_seg("INIT_RW")
#pragma code_seg("INIT")
#pragma bss_seg("INIT_RW")
#pragma const_seg("INIT_RD")
#pragma comment(linker, "/merge:INIT_RD=INIT")
#pragma comment(linker, "/merge:INIT_RW=INIT")
#endif
LPDIRECTSOUND8 m_pDSound; // DirectSound object
LPDIRECTSOUNDBUFFER8 m_pDSBuffer[MAX_BUFFERS]; // DirectSoundBuffer
extern WCHAR StringBuffer[];
#define MIN(a,b) (((signed) a) < ((signed) b) ? (a) : (b))
/*
* track_status has the necessary items to restore the state of
* a track after a track of a higher level on the same channel
* ends
*/
#define MAX_TRACKS 16
#define MAX_PROCESSES 30
#define MAX_LEVELS 2
uchar channel_level[MAX_TRACKS];/* current level for each chan*/
struct track_info track_status[(MAX_LEVELS) * MAX_TRACKS];
struct process queue_list[MAX_PROCESSES]; /* pre-allocated process packets */
extern struct sound * _base_ current_call; /* pointer to current sound call */
extern uchar sound_call_table;
const unsigned short max_processes = MAX_PROCESSES;
extern uchar a_value, b_value;
unsigned int dsp_address;
unsigned int dsp_data;
extern ushort value_16_bit;
extern uchar current_channel;
extern uchar master_music_volume; /* main attenuation for music */
extern uchar master_effect_volume; /* main attenuation for f/x */
extern uchar music_atten; /* music attenuation */
extern uchar init_call;
extern uchar current_level; /* global level of current process */
extern struct track_info * _base_ ti; /* track info pointer */
extern uchar pan_table[]; /* panning table (8-bit) */
void put_dsp(void);
extern reset_dsp();
void init_dsp(void);
void put_fifo(unsigned char);
const unsigned char max_tracks = MAX_TRACKS;
extern void (* const call_fcns[])();
int volume_dsp(uchar, uchar, uchar *,uchar);
int silence_dsp(uchar);
int note_on_dsp();
int slur_dsp();
int note_off_dsp();
int patch_dsp(unsigned short);
int pan_dsp(uchar , signed char, uchar *);
int vp_filter();
int (* const filter_functions[])() = {
vp_filter,
vp_filter,
vp_filter,
vp_filter,
vp_filter,
vp_filter,
vp_filter,
vp_filter,
vp_filter,
vp_filter,
vp_filter,
vp_filter,
vp_filter,
vp_filter,
vp_filter,
vp_filter
};
int (* const silence_functions[])() = {
silence_dsp,
silence_dsp,
silence_dsp,
silence_dsp,
silence_dsp,
silence_dsp,
silence_dsp,
silence_dsp,
silence_dsp,
silence_dsp,
silence_dsp,
silence_dsp,
silence_dsp,
silence_dsp,
silence_dsp,
silence_dsp,
};
/**************************************************************************
* *
* The note_on functions turn a note on. They assume that *
* the global, "a_value" has the current channel # and that *
* the global "value_16_bit" has the 16 bit pitch (iiiiiiii.ffffffff *
* and "b_value" has the integer part of the pitch *
*************************************************************************/
int (* const note_on_functions[])() = {
note_on_dsp,
note_on_dsp,
note_on_dsp,
note_on_dsp,
note_on_dsp,
note_on_dsp,
note_on_dsp,
note_on_dsp,
note_on_dsp,
note_on_dsp,
note_on_dsp,
note_on_dsp,
note_on_dsp,
note_on_dsp,
note_on_dsp,
note_on_dsp,
};
int (* const slur_functions[])() = {
slur_dsp,
slur_dsp,
slur_dsp,
slur_dsp,
slur_dsp,
slur_dsp,
slur_dsp,
slur_dsp,
slur_dsp,
slur_dsp,
slur_dsp,
slur_dsp,
slur_dsp,
slur_dsp,
slur_dsp,
slur_dsp,
};
/*************************************************************************
* *
* The note_off functions turn a note off. They assume that *
* the global, "a_value" has the current channel. *
*************************************************************************/
int (* const note_off_functions[])() = {
note_off_dsp,
note_off_dsp,
note_off_dsp,
note_off_dsp,
note_off_dsp,
note_off_dsp,
note_off_dsp,
note_off_dsp,
note_off_dsp,
note_off_dsp,
note_off_dsp,
note_off_dsp,
note_off_dsp,
note_off_dsp,
note_off_dsp,
note_off_dsp,
};
int (* const patch_functions[]) () = {
patch_dsp,
patch_dsp,
patch_dsp,
patch_dsp,
patch_dsp,
patch_dsp,
patch_dsp,
patch_dsp,
patch_dsp,
patch_dsp,
patch_dsp,
patch_dsp,
patch_dsp,
patch_dsp,
patch_dsp,
patch_dsp,
};
int (* const volume_functions[])() = {
volume_dsp,
volume_dsp,
volume_dsp,
volume_dsp,
volume_dsp,
volume_dsp,
volume_dsp,
volume_dsp,
volume_dsp,
volume_dsp,
volume_dsp,
volume_dsp,
volume_dsp,
volume_dsp,
volume_dsp,
volume_dsp,
};
int (* const pan_functions[])() = {
pan_dsp,
pan_dsp,
pan_dsp,
pan_dsp,
pan_dsp,
pan_dsp,
pan_dsp,
pan_dsp,
pan_dsp,
pan_dsp,
pan_dsp,
pan_dsp,
pan_dsp,
pan_dsp,
pan_dsp,
pan_dsp,
};
int (* const user_1_var_evf_functions[])() = {
pan_dsp
};
int (* const user_2_var_evf_functions[])() = {
pan_dsp
};
//
// write data from global var dsp_data to x memory space "dsp_address"
//
void put_dsp()
{
// LPVOID pvXramBuffer;
// pvXramBuffer = (LPVOID) (dsp_address);
// memcpy(pvXramBuffer,pvData,dwDataSize);
// *(PDWORD) (GPXMEM + dsp_address) = dsp_data;
}
WriteDSPDatablock
(
DWORD dwDSPAddress,
LPCVOID pvData,
DWORD dwDataSize
)
{
LPVOID pvXramBuffer;
//
// poke directly the XRAM offset
//
pvXramBuffer = (LPVOID) (GPXMEM + dwDSPAddress);
memcpy(pvXramBuffer,pvData,dwDataSize);
return 1;
}
ReadDSPDatablock
(
DWORD dwDSPAddress,
LPVOID pvData,
DWORD dwDataSize
)
{
LPVOID pvXramBuffer;
//
// copy fx data
//
pvXramBuffer = (LPVOID) (GPXMEM + dwDSPAddress);
memcpy(pvData,pvXramBuffer,dwDataSize);
return 1;
}
ReadDSPProgblock
(
DWORD dwDSPAddress,
LPVOID pvData,
DWORD dwDataSize
)
{
LPVOID pvXramBuffer;
//
// copy fx data
//
pvXramBuffer = (LPVOID) (GPPMEM + dwDSPAddress);
memcpy(pvData,pvXramBuffer,dwDataSize);
return 1;
}
// return dsp data
int get_dsp(unsigned int addr)
{
// return( (*PDWORD) (GPXMEM + dsp_address) );
return(1);
}
silence_dsp(unsigned char chan)
{
return(1);
}
note_on_dsp()
{
DWORD dwFreq;
struct DSPpatch *addr;
#if DBG
// dwFreq = pitch_table_dsp[value_16_bit>>8];
// swprintf( StringBuffer, L"Current Pitch: 0x%x", dwFreq);
#endif
dwFreq = (DWORD) ( ((value_16_bit >> 8) - 60) * (4096/12) );
dwFreq += ((((DWORD) value_16_bit & 0xff) * 341) / 255);
// IDirectSoundBuffer_StopEx(m_pDSBuffer[current_channel], 0, DSBSTOPEX_ENVELOPE);
IDirectSoundBuffer_SetPitch(m_pDSBuffer[current_channel], dwFreq);
addr = Patches[ti->patch];
if (addr->LoopEnable)
IDirectSoundBuffer_Play(m_pDSBuffer[current_channel], 0,0,DSBPLAY_LOOPING);
else
IDirectSoundBuffer_Play(m_pDSBuffer[current_channel], 0,0,0);
return(1);
}
slur_dsp()
{
DWORD dwFreq;
dwFreq = (DWORD) ( ((value_16_bit >> 8) - 60) * (4096/12) );
dwFreq += ((((DWORD) value_16_bit & 0xff) * 341) / 255);
#if DBG
// swprintf( StringBuffer, L"Current Pitch Slur: 0x%x", dwFreq);
#endif
IDirectSoundBuffer_SetPitch(m_pDSBuffer[current_channel], dwFreq);
return(1);
}
note_off_dsp()
{
IDirectSoundBuffer_StopEx(m_pDSBuffer[current_channel], 0, DSBSTOPEX_ENVELOPE);
return(1);
}
vp_filter()
{
DSFILTERDESC fdesc;
fdesc.dwMode = DSFILTER_MODE_DLS2;
fdesc.dwQCoefficient = 0;
fdesc.adwCoefficients[0] = ti->filtercutoff + 32768;
fdesc.adwCoefficients[1] = ti->filterres;
fdesc.adwCoefficients[2] = ti->filtercutoff + 32768;
fdesc.adwCoefficients[3] = ti->filterres;
IDirectSoundBuffer_SetFilter(m_pDSBuffer[current_channel], &fdesc);
return(1);
}
patch_dsp(unsigned short pat)
{
struct DSPpatch *addr;
addr = Patches[pat];
IDirectSoundBuffer_SetEG(m_pDSBuffer[current_channel], addr->lpAmpEnvelope);
IDirectSoundBuffer_SetEG(m_pDSBuffer[current_channel], addr->lpMultiEnvelope);
IDirectSoundBuffer_SetBufferData(m_pDSBuffer[current_channel], addr->Start, addr->Length );
IDirectSoundBuffer_SetLoopRegion( m_pDSBuffer[current_channel],0, addr->Length );
IDirectSoundBuffer_SetCurrentPosition(m_pDSBuffer[current_channel], 0 );
return(1);
}
pan_dsp(uchar chan, signed char pan, uchar *patch)
{
uchar mod;
unsigned int vol_mul;
unsigned int tmp;
char tmp_pan;
vol_mul = 0x7fff;
if (current_level >= 1) {
/* mod = master_effect_volume;*/
// vol_mul = volume_table_dsp[master_music_volume];
}
else {
/* mod = 0;*/
// tmp = volume_table_dsp[music_atten];
// vol_mul = volume_table_dsp[master_music_volume];
// vol_mul = (long)((long)tmp * (long)vol_mul) >>15;
}
mod = 0;
tmp_pan = ti->pan >> 3;
tmp_pan += 16; /* set range 0 - 31 */
tmp = 1;
// tmp = volume_table_dsp[MIN(127,ti->volume + mod)];
tmp = (long)((long)tmp * (long)vol_mul) >>15;
/* tmp >>= 7;*/
dsp_data = (long) ((long)tmp * (long)pan_table[tmp_pan]) >> 7;
/* dsp_data = (char)tmp * pan_table[tmp_pan];*/
// a_value = VOLUME_L_ADDRESS(chan);
put_dsp();
dsp_data = (long) ((long)tmp * (long)pan_table[31 - tmp_pan]) >> 7;
/* dsp_data = (char)tmp * pan_table[31 - tmp_pan];*/
// a_value = VOLUME_R_ADDRESS(chan);
put_dsp();
return(1);
}
// initialize stuff for the dsp.
// write sine wave into high x memory.
// also create 16 dsound buffers that we'll use
// for our sounds.
static long holdrand = 1L;
void __cdecl srand(unsigned int seed)
{
holdrand = (long)seed;
}
int __cdecl rand(void)
{
return(((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff);
}
dev_init()
{
DSBUFFERDESC dsbdesc;
WAVEFORMATEX wfFirst;
DWORD dwMixBinMask = DSMIXBIN_FRONT_LEFT | DSMIXBIN_FRONT_RIGHT | DSMIXBIN_FXSEND_0;
long lVolumes[3];
int j;
double dtmp;
double FMc = 4.0;
double FMm = 2.0;
int i;
srand(1003);
for (i = 0; i < 8192; i++) {
Noise8192[i] = (unsigned short) rand();
}
for (i = 0; i < 128; i++) {
Sin128[i] = (unsigned short)(32767*sin(2.0*3.14159*(double)i/128.0));
}
j = 0;
for (i = 0; i < 32768; i++) {
if (i < 16384)
j++;
else
j--;
dtmp = (double)j/16384.0 * sin(FMm * 2.0*3.14159*(double)i/128.0);
FM32768[i] = (unsigned short)(32767*sin(dtmp + FMc * 2.0*3.14159*(double)i/128.0));
}
for (i = 0; i < 128; i++) { // create sawtooth wave
Saw128[i] = (unsigned short) (65536 * ((float)(i-64) /128.0));
}
for (i = 0; i < 0x5540; i++) { // size of glock sound..make 16-bit
ThunEl16[i] = (ThunEl16Data[i]) << 8;
}
for (i = 0,j=0x5540; i < 0x5540; i++,j--) { // size of glock sound..make 16-bit
ReverseThunEl16[i] = ThunEl16[j];
}
for (i = 0; i < 3768; i++) { // size of glock sound..make 16-bit
Glock[i] = (GlockData[i]^0x80) << 8;
}
for (i = 0; i < 6719; i++) { // size of glock sound..make 16-bit
Bubble[i] = (BubbleData[i]^0x80) << 8;
}
if( FAILED( DirectSoundCreate( NULL, &m_pDSound, NULL ) ) )
return (0);
ZeroMemory( &dsbdesc, sizeof( DSBUFFERDESC ) );
dsbdesc.dwSize = sizeof( DSBUFFERDESC );
wfFirst.wFormatTag = WAVE_FORMAT_PCM;
wfFirst.nChannels = 1;
wfFirst.nSamplesPerSec = 48000;
wfFirst.wBitsPerSample = 16;
wfFirst.nBlockAlign = wfFirst.nChannels * wfFirst.wBitsPerSample/8;
wfFirst.nAvgBytesPerSec = wfFirst.nSamplesPerSec * wfFirst.nBlockAlign;
dsbdesc.dwFlags = 0;
dsbdesc.dwBufferBytes = 0;
dsbdesc.lpwfxFormat = &wfFirst;
dsbdesc.dwMixBinMask = dwMixBinMask;
for (i = 0; i < MAX_BUFFERS; i++) {
if (i%2) {
lVolumes[0] = -600;
lVolumes[1] = 0;
lVolumes[2] = -2800;
dwMixBinMask = DSMIXBIN_FRONT_LEFT | DSMIXBIN_FRONT_RIGHT;
dsbdesc.dwMixBinMask = dwMixBinMask;
}
else {
lVolumes[0] = 0;
lVolumes[1] = -600;
lVolumes[2] = -2800;
dwMixBinMask = DSMIXBIN_FRONT_LEFT | DSMIXBIN_FRONT_RIGHT;
dsbdesc.dwMixBinMask = dwMixBinMask;
}
if ((i == 3) || (i == 5)) {
lVolumes[0] = 0;
lVolumes[1] = -100;
lVolumes[2] = 00;
dwMixBinMask = DSMIXBIN_FRONT_LEFT | DSMIXBIN_FRONT_RIGHT | DSMIXBIN_FXSEND_0;
dsbdesc.dwMixBinMask = dwMixBinMask;
}
if( FAILED( DirectSoundCreateBuffer( &dsbdesc, &m_pDSBuffer[i]) ) )
return E_FAIL;
IDirectSoundBuffer_SetMixBinVolumes(m_pDSBuffer[i], dwMixBinMask, lVolumes);
}
// ReadDSPDatablock(0xa00*4, databack, sizeof(databack) );
put_fifo(0x1);
return(1);
}
//
// free dsound buffers and dsound object we created
//
dev_cleanup()
{
int i;
for (i = 0; i < MAX_BUFFERS; i++) {
IDirectSoundBuffer_Release(m_pDSBuffer[i]);
}
IDirectSound_Release(m_pDSound);
}
do_watchdog()
{
}
dtimer_int()
{
}
etimer_int()
{
}
send_dev_function()
{
}
/*************************************************************************
* *
* Adjust the volume of that patch, "patch_addr" on channel, *
* "chan" by the amount volume + whatever the global volume is *
* for "level" *
* *
*************************************************************************/
volume_dsp(
uchar op_level,
uchar sound_level,
uchar *patch_addr,
uchar chan)
{
IDirectSoundBuffer_SetVolume(m_pDSBuffer[current_channel], (-1*op_level*30) + 200);
return(1);
}
call_user_function()
{
}
extern f_end();
user_silence_function()
{
#if DBG
// swprintf( StringBuffer, L"Current Sound: %S", "SilenceFunction");
#endif
}
uchar pan_table[] = {
1,2,3,4,5,6,7,8
};
+488
View File
@@ -0,0 +1,488 @@
/*************************************************************************
* *
* Here live the event functions *
* *
*************************************************************************/
#include "sos.h"
#include "protos.h"
#include "externs.h"
#define c_p current_process /* shorthand */
ushort * ptr; /* pointer to cur. voice data */
unsigned short un_int;
uchar un_char;
int f_MidiNoteOn()
{
return(1);
}
int f_MidiNoteOff()
{
return(1);
}
int f_MidiProgram()
{
return(1);
}
int f_MidiVolume()
{
return(1);
}
int f_MidiTempo()
{
return(1);
}
int f_MidiControl()
{
return(1);
}
int f_MidiEOT()
{
return(1);
}
int f_note()
{
ptr = ++current_process->mem_ptr.i; /* get past func byte */
b_value = (uchar) *(ushort *)ptr++; /* point to delay */
if (b_value & 0x80) { /* 1 byte duration */
dp_word1 = *(uchar *) ptr;
b_value &= 0x7f;
}
else {
dp_word1 = *(unsigned short *)ptr++;
}
current_process->function = *(ptr);
current_process->mem_ptr.i = ptr;
current_process->timer += dp_word1;
ti->pitch = value_16_bit = (b_value << 8) + ti->transpose;
if (current_level == LEVEL_EFFECT) {
ti->pitch += global_fxpose;
}
/* ti->pitch += global_fxpose;*/
value_16_bit = ti->pitch;
if (current_level < channel_level[current_channel])
return(1);
note_on_functions[current_channel]();
return(1);
}
f_gliss()
{
#ifdef GLISS
/*#ifdef BIGOS*/
uchar *tmp_ptr;
tmp_ptr = c_p->mem_ptr.c++;
if (c_p->type == 0) { /* first time */
c_p->type = 1; /* set not first time flag */
c_p->data1 = *c_p->mem_ptr.i++; /* get base pitch */
c_p->mem_ptr.i++; /* pass delta */
c_p->data2 = *c_p->mem_ptr.i; /* get counter */
c_p->mem_ptr.c = tmp_ptr;
}
else {
if (c_p->data2-- == 0) {
c_p->mem_ptr.c = tmp_ptr + 7; /* point to xtra time */
c_p->type = 0;
c_p->timer += *c_p->mem_ptr.i++; /* get xtra time*/
c_p->data1 += *c_p->mem_ptr.i++; /* get xtra frac */
c_p->function = *c_p->mem_ptr.c;
}
else {
c_p->data1 += *(++c_p->mem_ptr.i);
c_p->timer += 4;
c_p->mem_ptr.c = tmp_ptr; /* point back to us */
}
ti->pitch = value_16_bit = c_p->data1 + ti->transpose;
if (current_level < channel_level[current_channel])
return(1);
slur_functions[current_channel]();
}
return(1);
#endif
return(1);
}
int f_rest()
{
/* unsigned int del;*/
ptr = ++current_process->mem_ptr.i;
un_int = *(unsigned short *)ptr++;
current_process->function = *ptr;
current_process->timer += un_int;
current_process->mem_ptr.i = ptr;
if (current_level < channel_level[current_channel])
return(1);
note_off_functions[current_channel]();
return(1);
}
int f_srest()
{
return(1);
}
int f_jumpto()
{
/* uchar *addr;*/
current_process->mem_ptr.i++; /* get past func byte */
ptr = *(ushort **)current_process->mem_ptr.i++; /* point to next func */
current_process->mem_ptr.i = ptr;
current_process->function = *ptr; /* get function */
return(1);
}
int f_loop()
{
ti->loop_counter[ti->loop_level] = *(++c_p->mem_ptr.i);
ti->loop_addr[(ti->loop_level)++] = (ushort *) ++c_p->mem_ptr.i;
c_p->function = *c_p->mem_ptr.i;
return(1);
}
int f_endloop()
{
if (--(ti->loop_counter[ti->loop_level-1]) != 0) {
c_p->mem_ptr.i = (ushort *)ti->loop_addr[ti->loop_level-1];
}
else { /* done looping */
c_p->mem_ptr.i++;
ti->loop_level--;
}
c_p->function = *c_p->mem_ptr.i;
return(1);
}
int f_patch()
{
ushort pat;
ptr = ++current_process->mem_ptr.i; /* get past func byte */
pat = *(ushort *)ptr++; /* point to patch # */
current_process->function = *(ptr);
current_process->mem_ptr.i = ptr;
ti->patch = pat;
ti->pan = ti->volume = 0;
if (current_level < channel_level[current_channel])
return(1);
patch_functions[current_channel](pat);
return(1);
}
int f_pan()
{
ptr = ++current_process->mem_ptr.i; /* get past func byte */
a_value = *(uchar *)ptr++; /* point to pan */
current_process->function = *ptr;
current_process->mem_ptr.i = ptr;
ti->pan = a_value;
if (current_level < channel_level[current_channel])
return(1);
pan_functions[current_channel](current_channel,a_value,ti->patch);
return(1);
}
int f_paninc()
{
/*#ifdef BIGOS */
ptr = ++current_process->mem_ptr.i; /* get past func byte */
a_value = *(char *)ptr++; /* point to pan */
current_process->function = *ptr;
current_process->mem_ptr.i = ptr;
ti->pan += (signed char) a_value;
if (current_level < channel_level[current_channel])
return(1);
pan_functions[current_channel](current_channel,ti->pan,ti->patch);
return(1);
/*#endif*/
}
int f_mux()
{
ti->mux_addr[(ti->mux_level)++] = (ushort *) (++c_p->mem_ptr.c + 2);
c_p->mem_ptr.c = (uchar *)*(ushort *)(c_p->mem_ptr.c);
c_p->function = *c_p->mem_ptr.c;
return(1);
}
int f_demux()
{
/* uchar tmp;*/
un_char = --(ti->mux_level);
c_p->mem_ptr.c = (uchar *)ti->mux_addr[un_char];
c_p->function = *c_p->mem_ptr.c;
return(1);
}
int f_volume()
{
un_char = ti->volume + *(short *)++current_process->mem_ptr.i; /* point to vol */
current_process->function = *++current_process->mem_ptr.i;
ti->volume = un_char;
if (current_level < channel_level[current_channel])
return(1);
volume_functions[current_channel](un_char,current_level,ti->patch,current_channel);
return(1);
}
int f_fxset()
{
c_p->mem_ptr.c++;
global_fxpose = *c_p->mem_ptr.i++;
c_p->function = *c_p->mem_ptr.c;
return(1);
}
int f_xpose()
{
c_p->mem_ptr.i++;
ti->transpose += *c_p->mem_ptr.i++;
c_p->function = *c_p->mem_ptr.i;
return(1);
}
int f_xset()
{
c_p->mem_ptr.i++;
ti->transpose = *c_p->mem_ptr.i++;
c_p->function = *c_p->mem_ptr.i;
return(1);
}
int f_filterinc()
{
c_p->mem_ptr.i++;
ti->filtercutoff += *c_p->mem_ptr.i++;
ti->filterres = *c_p->mem_ptr.i++;
c_p->function = *c_p->mem_ptr.i;
filter_functions[current_channel]();
return(1);
}
int f_filterset()
{
c_p->mem_ptr.i++;
ti->filtercutoff = *c_p->mem_ptr.i++;
ti->filterres = *c_p->mem_ptr.i++;
c_p->function = *c_p->mem_ptr.i;
filter_functions[current_channel]();
return(1);
}
int f_slur()
{
/* unsigned int del;*/
ptr = ++current_process->mem_ptr.i; /* get past func byte */
b_value = (uchar) *(ushort *)ptr++; /* point to delay */
if (b_value & 0x80) { /* 1 byte duration */
dp_word1 = *(uchar *) ptr;
b_value &= 0x7f;
}
else {
dp_word1 = *(unsigned short *)ptr++;
}
current_process->function = *(ptr);
current_process->mem_ptr.i = ptr;
current_process->timer += dp_word1;
ti->pitch = value_16_bit = (b_value << 8) + ti->transpose;
if (current_level == LEVEL_EFFECT) {
ti->pitch += global_fxpose;
}
/* ti->pitch += global_fxpose;*/
value_16_bit = ti->pitch;
if (current_level < channel_level[current_channel])
return(1);
slur_functions[current_channel]();
return(1);
//
}
int f_ring()
{
ptr = ++current_process->mem_ptr.i;
un_int = *(unsigned short *)ptr++;
current_process->function = *ptr;
current_process->timer += un_int;
current_process->mem_ptr.i = ptr;
return(1);
}
f_clockset()
{
current_process->mem_ptr.c++; /* get past func byte */
clock_cntr_value[c_p->level] = *(uchar *)current_process->mem_ptr.c++;/* point to next func */
current_process->function = *current_process->mem_ptr.c;
return(1);
}
f_clockinc()
{
return(1);
}
f_musicclockinc()
{
return(1);
}
/*************************************************************************
* *
* Used to end a track of music or a sound effect *
* *
*************************************************************************/
int f_end()
{
/* un_char = c_p->hard_channel;*/
// nosound(current_channel);
// ti = get_music_info_block();
// remove_processes_by_level_and_channel(LEVEL_EFFECT,current_channel);
// channel_level[current_channel] = LEVEL_MUSIC;
// current_level = LEVEL_MUSIC;
// if (ti->patch == NULL)
// return(0);
// ptr = ti->patch;
// patch_functions[current_channel](ptr);
// pan_functions[current_channel](current_channel,ti->pan,ptr);
// volume_functions[current_channel](ti->volume,current_level,ptr,current_channel);
return(0);
}
int f_mark()
{
#ifdef BIGOS
uchar m_value;
uchar dest;
c_p->mem_ptr.c++;
m_value = *c_p->mem_ptr.c++; /* get marker # */
dest = *c_p->mem_ptr.c++; /* get destination */
c_p->function = *c_p->mem_ptr.c;
if (m_value == marker) {
DINT;
put_fifo(dest);
EINT;
marker = 0;
}
#endif
return(1);
}
int f_sound_call()
{
/*#ifdef BIGOS*/
uchar dest;
c_p->mem_ptr.c++;
dest = *c_p->mem_ptr.c++; /* get destination */
c_p->function = *c_p->mem_ptr.c;
/* DINT;*/
put_fifo(dest);
/* EINT;*/
return(1);
/*#endif*/
}
int f_intvarset()
{
#ifdef BIGOS
uchar index;
c_p->mem_ptr.c++;
index = *c_p->mem_ptr.c++;
int_vars[index] = *(ushort *)c_p->mem_ptr.i++;
c_p->function = *c_p->mem_ptr.c;
return(1);
#endif
return(1);
}
int f_intvarinc()
{
#ifdef BIGOS
uchar index;
c_p->mem_ptr.c++;
index = *c_p->mem_ptr.c++;
int_vars[index] += *(char *)c_p->mem_ptr.c++;
c_p->function = *c_p->mem_ptr.c;
return(1);
#endif
return(1);
}
int f_user_1_var_evf()
{
/*#ifdef BIGOS*/
a_value = *(++c_p->mem_ptr.c); /* get parameter in a_value */
c_p->function = *++c_p->mem_ptr.c;
user_1_var_evf_functions[current_channel]();
return(1);
/*#endif*/
}
int f_user_2_var_evf()
{
a_value = *(++c_p->mem_ptr.c); /* get parameter in a_value */
b_value = *(++c_p->mem_ptr.c); /* get 2nd parameter in b_value */
c_p->function = *++c_p->mem_ptr.c;
user_2_var_evf_functions[current_channel]();
return(1);
}
f_sig()
{
a_value = *(++c_p->mem_ptr.c); /* get parameter in a_value */
c_p->function = *++c_p->mem_ptr.c;
// signal_function();
return(1);
}

+105
View File
@@ -0,0 +1,105 @@
/*************************************************************************
* *
* External Variables *
* *
*************************************************************************/
#define _base_
#ifdef STARTUPANIMATION
#pragma data_seg("INIT_RW")
#pragma code_seg("INIT")
#pragma bss_seg("INIT_RW")
#pragma const_seg("INIT_RD")
#pragma comment(linker, "/merge:INIT_RD=INIT")
#pragma comment(linker, "/merge:INIT_RW=INIT")
#endif //STARTUPANIMATION
extern struct process * _base_ process_queue; /* pointer to process queue */
extern struct sound * _base_ current_call; /* pointer to current sound call */
extern struct sound sound_calls[];
extern struct sound sound_calls2[]; /* alternate sound call table */
extern struct process * _base_ current_process; /* pointer to current s. proc */
extern struct fifo fifo;
extern _base_ uchar hcount; /* counter for oki nmi */
extern _base_ uchar voice_state; /* current nmi voice state */
extern uchar * _base_ voice_data_pointer; /* pointer to cur. voice data */
extern uchar * _base_ voice_data_end; /* pointer to end of v data */
extern _base_ uchar a_value; /* byte for register a data */
extern _base_ uchar b_value; /* byte for register b data */
extern struct track_info * _base_ ti;/* global pointer to current track info*/
extern _base_ ushort value_16_bit; /* tmp value for passing */
extern _base_ short system_clock_music ;/* global music system timer */
extern _base_ uchar system_clock_mlow; /* for 3 byte clocks */
extern _base_ short system_clock_fx; /* global fx system timer */
extern _base_ uchar system_clock_fxlow; /* for 3-byte clocks */
extern _base_ uchar clock_cntr[2]; /* timer count-downer */
extern _base_ uchar clock_cntr_value[2]; /* timer count-downer */
extern _base_ uchar clock_cntr_save; /* save val of clock cntr */
extern _base_ uchar master_music_volume; /* main attenuation for music */
extern _base_ uchar master_effect_volume; /* main attenuation for f/x */
extern _base_ uchar music_atten; /* music attenuateion */
extern _base_ uchar master_music_amd; /* main amp mod depth for music */
extern _base_ uchar master_effect_amd; /* main amp mod depth for effect*/
extern _base_ uchar master_music_pmd; /* main phase mod depth/music */
extern _base_ uchar master_effect_pmd; /* main phase mod depth/effect */
extern _base_ uchar marker;
extern _base_ uchar current_level; /* global level of current process */
extern _base_ uchar current_channel; /* global chan of current process */
extern _base_ ushort int_vars[12]; /* variables 2-byte */
extern _base_ uchar byte_vars[12]; /* variables 1-byte */
extern _base_ uchar dp_byte1; /* temp var */
extern _base_ uchar dp_byte2; /* temp var */
extern _base_ uchar dp_byte3; /* temp var */
extern _base_ uchar dp_byte4; /* temp var */
extern _base_ uchar dp_byte5; /* temp var */
extern _base_ ushort dp_word1; /* temp var */
extern _base_ ushort dp_word2; /* temp var */
extern _base_ ushort dp_word3; /* temp var */
extern _base_ ushort dp_word4; /* temp var */
extern _base_ ushort dp_word5; /* temp var */
extern _base_ uchar last_music_call; /* last music call made */
extern _base_ uchar current_timer_priority; /* priority of last timer call */
extern uchar music_timer_status[];
extern _base_ uchar sos_only;
extern _base_ uchar sound_call_table; /* which soundtable are we on ?*/
extern ushort global_fxpose; /* global transpose value */
extern uchar channel_level[]; /* current level for each chan*/
extern struct track_info track_status[];
extern struct process queue_list[]; /* pre-allocated process packets */
extern const uchar max_tracks; /* from dev.c */
extern void do_watchdog(void); /* from dev.c */
extern dtimer_int(); /* from dev.c */
extern etimer_int(); /* from dev.c */
extern send_dev_function(); /* from dev.c */
extern int (*silence_functions[])(); /* from dev.c */
extern int (*note_on_functions[])(); /* from dev.c */
extern int (*slur_functions[])(); /* from dev.c */
extern int (*note_off_functions[])(); /* from dev.c */
extern int (*patch_functions[])(); /* from dev.c */
extern int (*volume_functions[])(); /* from dev.c */
extern int (*pan_functions[])(); /* from dev.c */
extern int (*filter_functions[])(); /* from dev.c */
extern int dev_init(); /* from dev.c */
extern int dev_cleanup(); /* from dev.c */
extern int (*user_1_var_evf_functions[])(); /* from dev.c */
extern int (*user_2_var_evf_functions[])(); /* from dev.c */
extern int user_silence_function(); /* from dev.c */
extern int signal_function(); /* from dev.c */

+145
View File
@@ -0,0 +1,145 @@
/*************************************************************************
* *
* Function tables for event functions and sound call functions *
* *
*************************************************************************/
#ifdef STARTUPANIMATION
#pragma data_seg("INIT_RW")
#pragma code_seg("INIT")
#pragma bss_seg("INIT_RW")
#pragma const_seg("INIT_RD")
// Tell linker to put bootsound code and data into INIT section
#pragma comment(linker, "/merge:DSOUND=INIT")
#pragma comment(linker, "/merge:INIT_RD=INIT")
#pragma comment(linker, "/merge:INIT_RW=INIT")
#endif //STARTUPANIMATION
extern int f_note(void);
extern int f_rest(void);
extern int f_jumpto(void);
extern int f_loop(void);
extern int f_endloop(void);
extern int f_patch(void);
extern int f_pan(void);
extern int f_mux(void);
extern int f_demux(void);
extern int f_volume(void);
extern int f_xpose(void);
extern int f_xset(void);
extern int f_slur(void);
extern int f_ring(void);
extern int f_clockset(void);
extern int f_end(void);
extern int f_filterset(void);
extern int f_filterinc(void);
extern int f_mark(void);
extern int f_sound_call(void);
extern int f_srest(void);
extern int f_intvarset(void);
extern int f_intvarinc(void);
extern int f_user_1_var_evf(void);
extern int f_user_2_var_evf(void);
extern int f_sig(void);
extern int f_gliss(void);
extern int f_clockinc(void);
extern int f_paninc(void);
extern int f_musicclockinc(void);
extern int f_MidiNoteOn(void);
extern int f_MidiNoteOff(void);
extern int f_MidiProgram(void);
extern int f_MidiVolume(void);
extern int f_MidiTempo(void);
extern int f_MidiControl(void);
extern int f_MidiEOT(void);
extern int f_fxset(void);
extern void call_silence(void);
extern void call_music(void);
extern void call_effect(void);
extern void call_volume(void);
extern void call_senddev(void);
extern void call_mark(void);
extern void call_ignore(void);
extern void call_user_function(void);
extern void call_timer(void);
extern void call_end_timer(void);
extern void call_play_timer(void);
extern void call_kill_effect(void);
int (* const event_fcns[])() = {
f_rest, //0
f_note, //1
f_jumpto, //2
f_loop, //3
f_endloop, //4
f_patch, //5
f_pan, //6
f_mux, //7
f_demux, //8
f_volume, //9
f_xpose, //10
f_xset, //11
f_slur, //12
f_ring, //13
f_clockset, //14
f_end, //15
f_filterinc, //16
f_filterset, //17
f_gliss, //18
f_mark,
f_sound_call,
f_srest,
f_intvarset,
f_intvarinc,
f_user_1_var_evf,
f_user_2_var_evf,
f_sig,
f_clockinc,
f_paninc,
f_musicclockinc,
f_MidiNoteOn, /* 35 */
f_MidiNoteOff, /* 36 */
f_MidiProgram, /* 37 */
f_MidiVolume, /* 38 */
f_MidiTempo, /* 39 */
f_MidiControl, /* 40 */
f_MidiEOT, /* 41 */
f_fxset,
};
/*
* NOTE:
* call music is used for BOTH forground sounds and background music
* This is becuase the code is essentially the same so it saves space
*/
void (* const call_fcns[])() = {
call_silence, /* 0 sound call type 0 (silence)*/
call_music, /* 1 sound call type 1 (music) */
call_effect, /* 2 sound call type 2 (effect) */
call_volume, /* 3 sound call type 3 (volume) */
call_ignore, /* 4 formerly call_oki */
call_senddev, /* 5 send data directly to yamaha chip */
call_mark, /* 6 leave a marker */
call_ignore, /* 7 ignore sound call */
call_user_function, /* 8 user defined function */
call_timer, /* 9 make a music timer call */
call_end_timer, /* 10 stop timer, go back to prev back music */
call_play_timer, /* 11 sound table entry for timer */
call_kill_effect /* 12 kill all forground fx */
};

+54
View File
@@ -0,0 +1,54 @@
#include "sos.h"
#include "error.h"
#include "protos.h"
#ifdef STARTUPANIMATION
#pragma data_seg("INIT_RW")
#pragma code_seg("INIT")
#pragma bss_seg("INIT_RW")
#pragma const_seg("INIT_RD")
#pragma comment(linker, "/merge:INIT_RD=INIT")
#pragma comment(linker, "/merge:INIT_RW=INIT")
#endif //STARTUPANIMATION
struct process * process_queue; /* pointer to process queue */
struct sound * current_call; /* pointer to current sound call*/
struct process * current_process; /* pointer to current s. proc */
struct fifo fifo; /* sound call fifo */
struct track_info * ti; /* global pointer to current track info*/
ushort value_16_bit; /* value to pass to asm routine */
short system_clock_music ;/* global music system timer */
uchar system_clock_mlow; /* for 3 byte clocks */
short system_clock_fx; /* global fx system timer */
uchar system_clock_fxlow; /* for 3-byte clocks */
uchar clock_cntr[2]; /* clock count-downer */
uchar clock_cntr_value[2]; /* clock count-downer reset val */
uchar clock_cntr_save; /* save value of clock count-downer */
ushort global_music_xpose; /* master transposition for mus */
ushort global_effect_xpose; /* master transposition for f/x */
uchar a_value; /* byte for register a data */
uchar b_value; /* byte for register b data */
uchar master_music_volume; /* main attenuation for music */
uchar master_effect_volume; /* main attenuation for f/x */
uchar music_atten; /* music attenuation control */
uchar marker; /* tune transition marker */
uchar current_level; /* global level of current process */
uchar current_channel; /* global chan of current process */
ushort dp_word1; /* temp var */
uchar gtifbtmp; /* temp var for get_info_block */
uchar last_music_call; /* last music call made */
uchar current_timer_priority; /* priority of last timer call */
uchar sos_only; /* 1 to loop forever, 0 to return */
uchar sound_call_table; /* which soundtable are we on ?*/
ushort global_fxpose; /* global transpose value */
+237
View File
@@ -0,0 +1,237 @@
␍ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7f,0x80,0x7f,0x7f,0x81,0x7f,0x7d,0x88,
0x77,0x7a,0xce,0xd2,0x51,0x03,0x39,0xab,0xf2,0xcb,0x58,0x0b,0x31,0xa4,0xf3,0xd1,
0x5f,0x0d,0x2a,0x9c,0xf3,0xd8,0x65,0x0c,0x24,0x98,0xf1,0xda,0x6c,0x10,0x1f,0x90,
0xf1,0xe1,0x73,0x11,0x1b,0x89,0xee,0xe4,0x79,0x15,0x17,0x82,0xeb,0xe9,0x81,0x18,
0x14,0x7b,0xe8,0xed,0x87,0x1b,0x12,0x74,0xe3,0xf3,0x8f,0x1d,0x0d,0x6e,0xe1,0xf2,
0x94,0x24,0x0b,0x69,0xde,0xf2,0x9b,0x2b,0x0a,0x60,0xd6,0xf6,0xa3,0x2e,0x09,0x58,
0xcf,0xf9,0xa9,0x31,0x07,0x53,0xca,0xfa,0xb2,0x38,0x08,0x4d,0xc3,0xf9,0xb9,0x3f,
0x06,0x44,0xbd,0xfc,0xbd,0x43,0x07,0x3e,0xb5,0xf8,0xc5,0x4b,0x02,0x38,0xb5,0xfa,
0xc7,0x4f,0x0a,0x37,0xa8,0xf5,0xd0,0x59,0x09,0x2e,0xa2,0xf7,0xd5,0x60,0x0c,0x27,
0x9a,0xf5,0xda,0x65,0x0c,0x22,0x91,0xf0,0xe0,0x70,0x0e,0x1a,0x8d,0xf2,0xe7,0x76,
0x0e,0x17,0x88,0xef,0xe9,0x7d,0x14,0x14,0x7d,0xeb,0xf0,0x85,0x15,0x0f,0x77,0xe6,
0xf1,0x8e,0x1b,0x09,0x6e,0xe6,0xf6,0x91,0x1c,0x08,0x6b,0xe2,0xf5,0x97,0x20,0x07,
0x66,0xdc,0xf7,0x9f,0x27,0x05,0x5d,0xd9,0xfc,0xa4,0x2a,0x05,0x58,0xd4,0xfd,0xab,
0x31,0x06,0x52,0xcd,0xfe,0xb5,0x37,0x03,0x4c,0xc8,0xfe,0xba,0x3c,0x02,0x46,0xc2,
0xfd,0xbd,0x42,0x03,0x3e,0xba,0xfd,0xc5,0x48,0x03,0x39,0xb5,0xfe,0xcc,0x4f,0x04,
0x33,0xae,0xfd,0xd1,0x54,0x03,0x2c,0xa6,0xfa,0xd5,0x5d,0x06,0x26,0x9f,0xfa,0xdb,
0x63,0x07,0x21,0x99,0xf9,0xe0,0x69,0x0a,0x1e,0x92,0xf6,0xe5,0x70,0x0b,0x18,0x8b,
0xf3,0xe9,0x77,0x0e,0x14,0x84,0xf0,0xed,0x7f,0x12,0x10,0x7c,0xec,0xf0,0x86,0x17,
0x0e,0x75,0xe8,0xf4,0x8d,0x19,0x0b,0x6f,0xe3,0xf6,0x95,0x1e,0x07,0x67,0xde,0xf7,
0x99,0x21,0x06,0x61,0xd9,0xfa,0xa2,0x28,0x04,0x5a,0xd4,0xfd,0xaa,0x2d,0x02,0x53,
0xcf,0xfe,0xb0,0x34,0x03,0x4c,0xc8,0xff,0xb7,0x3a,0x02,0x45,0xc2,0xfe,0xbd,0x41,
0x03,0x3f,0xbc,0xfe,0xc4,0x48,0x03,0x39,0xb6,0xff,0xcb,0x4e,0x02,0x32,0xaf,0xfe,
0xd0,0x54,0x04,0x2d,0xa9,0xfd,0xd5,0x5b,0x05,0x27,0xa1,0xfc,0xda,0x60,0x06,0x23,
0x9a,0xf8,0xdf,0x69,0x0b,0x20,0x93,0xf6,0xe5,0x71,0x0d,0x19,0x8b,0xf4,0xe8,0x76,
0x0f,0x15,0x85,0xf1,0xeb,0x7e,0x13,0x11,0x7e,0xee,0xf0,0x86,0x16,0x0e,0x76,0xe7,
0xf3,0x8d,0x1a,0x0c,0x70,0xe4,0xf7,0x95,0x1e,0x09,0x69,0xdf,0xf8,0x9b,0x22,0x06,
0x62,0xdb,0xfa,0xa1,0x26,0x03,0x5b,0xd6,0xfa,0xa6,0x2d,0x03,0x54,0xd0,0xfc,0xae,
0x32,0x02,0x4d,0xca,0xfe,0xb5,0x39,0x03,0x46,0xc3,0xfe,0xbb,0x3e,0x03,0x40,0xbd,
0xff,0xc3,0x44,0x02,0x3c,0xb8,0xfe,0xc9,0x4d,0x03,0x34,0xb1,0xfd,0xce,0x54,0x04,
0x2d,0xaa,0xff,0xd7,0x5a,0x04,0x28,0xa3,0xfc,0xdb,0x60,0x05,0x23,0x9c,0xf9,0xdf,
0x67,0x08,0x1e,0x95,0xf7,0xe3,0x6e,0x0b,0x1b,0x8d,0xf3,0xe7,0x76,0x0e,0x16,0x87,
0xf0,0xeb,0x7c,0x11,0x13,0x81,0xed,0xef,0x83,0x14,0x0f,0x79,0xe9,0xf3,0x8c,0x19,
0x0e,0x73,0xe5,0xf5,0x93,0x1e,0x0b,0x6c,0xe1,0xf6,0x99,0x23,0x09,0x64,0xdb,0xf9,
0xa0,0x28,0x08,0x5d,0xd6,0xfb,0xa6,0x2c,0x05,0x57,0xd0,0xfb,0xad,0x32,0x05,0x50,
0xca,0xfc,0xb4,0x37,0x02,0x49,0xc4,0xfc,0xb9,0x3d,0x01,0x41,0xbe,0xfc,0xbe,0x42,
0x03,0x3c,0xb7,0xfb,0xc4,0x49,0x03,0x36,0xb2,0xfb,0xc9,0x50,0x05,0x30,0xab,0xfa,
0xcf,0x56,0x07,0x2d,0xa3,0xf7,0xd5,0x5f,0x09,0x27,0x9d,0xf6,0xd9,0x65,0x0c,0x23,
0x95,0xf2,0xde,0x6e,0x0f,0x1e,0x8f,0xf2,0xe3,0x73,0x11,0x1c,0x89,0xee,0xe6,0x7a,
0x14,0x18,0x83,0xeb,0xea,0x81,0x19,0x18,0x7d,0xe7,0xed,0x88,0x1e,0x14,0x75,0xe2,
0xef,0x8f,0x21,0x11,0x6d,0xdd,0xf2,0x95,0x24,0x0e,0x67,0xd8,0xf2,0x9b,0x2c,0x0e,
0x60,0xd3,0xf4,0xa3,0x2f,0x0a,0x59,0xcf,0xf6,0xa7,0x32,0x0a,0x54,0xc8,0xf6,0xae,
0x38,0x09,0x4e,0xc3,0xf6,0xb4,0x3f,0x09,0x46,0xbc,0xf7,0xbb,0x44,0x08,0x41,0xb9,
0xf7,0xbf,0x4a,0x0a,0x3c,0xb1,0xf6,0xc5,0x4f,0x0a,0x38,0xab,0xf4,0xca,0x55,0x0a,
0x32,0xa5,0xf3,0xce,0x5c,0x0d,0x2d,0x9e,0xf1,0xd4,0x63,0x0e,0x28,0x97,0xee,0xd8,
0x6a,0x11,0x24,0x91,0xec,0xdd,0x72,0x14,0x21,0x8a,0xea,0xe1,0x79,0x18,0x1d,0x83,
0xe6,0xe4,0x7f,0x1b,0x19,0x7c,0xe3,0xe8,0x86,0x1e,0x17,0x77,0xe0,0xeb,0x8d,0x22,
0x14,0x71,0xdc,0xec,0x93,0x28,0x12,0x68,0xd8,0xef,0x9a,0x2d,0x10,0x63,0xd3,0xf0,
0xa0,0x31,0x0f,0x5c,0xce,0xf2,0xa5,0x34,0x0f,0x58,0xc9,0xf2,0xac,0x3c,0x0e,0x51,
0xc3,0xf3,0xb2,0x41,0x0d,0x4b,0xbd,0xf3,0xb8,0x46,0x0d,0x44,0xb6,0xf2,0xbe,0x4d,
0x0e,0x3f,0xb0,0xf2,0xc3,0x52,0x0e,0x3b,0xab,0xf1,0xc7,0x59,0x10,0x35,0xa5,0xef,
0xcc,0x5f,0x11,0x30,0x9e,0xee,0xd0,0x65,0x13,0x2c,0x96,0xeb,0xd5,0x6b,0x16,0x28,
0x8f,0xe8,0xd9,0x72,0x18,0x23,0x89,0xe5,0xdc,0x78,0x1c,0x21,0x82,0xe3,0xe1,0x7f,
0x1e,0x1e,0x7d,0xe0,0xe3,0x84,0x22,0x1a,0x76,0xdc,0xe6,0x8b,0x25,0x18,0x70,0xd8,
0xe8,0x91,0x29,0x16,0x6b,0xd5,0xeb,0x98,0x2f,0x15,0x64,0xcf,0xec,0x9e,0x33,0x13,
0x5e,0xca,0xec,0xa3,0x38,0x12,0x56,0xc5,0xee,0xa9,0x3b,0x11,0x52,0xc0,0xef,0xb0,
0x41,0x10,0x4c,0xbc,0xf0,0xb5,0x47,0x12,0x48,0xb6,0xf1,0xbc,0x4e,0x12,0x42,0xaf,
0xef,0xc2,0x53,0x12,0x3d,0xa9,0xed,0xc6,0x59,0x13,0x39,0xa5,0xec,0xca,0x61,0x16,
0x34,0x9d,0xeb,0xcf,0x65,0x16,0x2f,0x97,0xe9,0xd3,0x6b,0x18,0x2c,0x91,0xe6,0xd7,
0x72,0x1a,0x27,0x8a,0xe3,0xda,0x78,0x1e,0x24,0x84,0xe0,0xdc,0x7e,0x21,0x21,0x7d,
0xdc,0xe0,0x84,0x23,0x1d,0x76,0xd8,0xe2,0x88,0x26,0x1a,0x71,0xd5,0xe4,0x8f,0x2b,
0x18,0x6b,0xd1,0xe6,0x95,0x2f,0x18,0x65,0xcd,0xe8,0x9c,0x34,0x16,0x5f,0xc8,0xea,
0xa3,0x3a,0x15,0x5b,0xc5,0xeb,0xa8,0x3e,0x15,0x55,0xbf,0xeb,0xad,0x43,0x15,0x50,
0xbb,0xec,0xb2,0x47,0x14,0x4a,0xb5,0xeb,0xb8,0x4d,0x14,0x45,0xaf,0xea,0xbb,0x51,
0x15,0x41,0xaa,0xe9,0xc1,0x59,0x17,0x3c,0xa4,0xe9,0xc6,0x5e,0x18,0x38,0x9e,0xe7,
0xca,0x64,0x19,0x33,0x98,0xe5,0xce,0x69,0x1a,0x2f,0x92,0xe3,0xd2,0x70,0x1d,0x2c,
0x8d,0xe1,0xd5,0x76,0x21,0x29,0x86,0xde,0xda,0x7d,0x24,0x26,0x80,0xdb,0xdc,0x82,
0x27,0x23,0x7a,0xd8,0xdf,0x88,0x2a,0x20,0x73,0xd4,0xe1,0x8e,0x2d,0x1d,0x6e,0xd0,
0xe2,0x94,0x32,0x1c,0x67,0xcc,0xe5,0x9a,0x35,0x1a,0x62,0xc8,0xe6,0x9e,0x39,0x19,
0x5c,0xc3,0xe7,0xa4,0x3e,0x18,0x58,0xbf,0xe8,0xaa,0x43,0x17,0x52,0xb9,0xe8,0xaf,
0x47,0x16,0x4d,0xb5,0xe8,0xb4,0x4c,0x16,0x47,0xaf,0xe7,0xb9,0x52,0x17,0x43,0xaa,
0xe8,0xbf,0x58,0x18,0x3e,0xa4,0xe7,0xc4,0x5e,0x1a,0x3b,0xa0,0xe5,0xc8,0x64,0x1c,
0x36,0x9a,0xe3,0xcb,0x69,0x1d,0x32,0x94,0xe2,0xcf,0x6f,0x20,0x2e,0x8e,0xdf,0xd3,
0x75,0x22,0x2b,0x88,0xdd,0xd7,0x7b,0x25,0x28,0x82,0xda,0xd9,0x81,0x28,0x25,0x7c,
0xd7,0xdb,0x86,0x2c,0x24,0x77,0xd3,0xde,0x8c,0x2f,0x21,0x71,0xd0,0xdf,0x90,0x32,
0x20,0x6b,0xcb,0xe1,0x97,0x36,0x1e,0x65,0xc7,0xe3,0x9c,0x3a,0x1c,0x60,0xc3,0xe4,
0xa2,0x3f,0x1c,0x5b,0xbe,0xe4,0xa7,0x44,0x1b,0x55,0xb9,0xe4,0xab,0x48,0x1a,0x4f,
0xb4,0xe4,0xb1,0x4d,0x1a,0x4b,0xaf,0xe4,0xb5,0x51,0x1b,0x46,0xa9,0xe4,0xbb,0x57,
0x1b,0x42,0xa6,0xe3,0xbf,0x5d,0x1d,0x3e,0x9f,0xe2,0xc3,0x62,0x1e,0x3a,0x9a,0xe0,
0xc7,0x68,0x20,0x35,0x95,0xdf,0xcb,0x6d,0x22,0x33,0x8f,0xdd,0xce,0x72,0x24,0x2f,
0x89,0xdb,0xd3,0x7a,0x27,0x2c,0x84,0xd8,0xd6,0x7f,0x2a,0x29,0x7e,0xd6,0xd9,0x85,
0x2e,0x27,0x78,0xd2,0xdc,0x8a,0x30,0x25,0x73,0xce,0xdc,0x8f,0x33,0x22,0x6d,0xca,
0xde,0x94,0x37,0x21,0x67,0xc6,0xdf,0x9a,0x3b,0x1f,0x61,0xc2,0xe1,0xa0,0x3f,0x1e,
0x5d,0xbe,0xe1,0xa5,0x44,0x1e,0x58,0xb9,0xe2,0xaa,0x49,0x1d,0x52,0xb4,0xe2,0xaf,
0x4d,0x1d,0x4e,0xaf,0xe2,0xb3,0x52,0x1d,0x49,0xaa,0xe1,0xb8,0x57,0x1e,0x44,0xa4,
0xe0,0xbd,0x5d,0x1e,0x40,0x9f,0xdf,0xc1,0x61,0x1f,0x3b,0x9a,0xde,0xc4,0x67,0x22,
0x38,0x94,0xdc,0xc8,0x6b,0x23,0x34,0x8f,0xd9,0xca,0x71,0x25,0x31,0x89,0xd7,0xce,
0x77,0x27,0x2d,0x84,0xd5,0xd2,0x7d,0x2b,0x2c,0x7e,0xd2,0xd5,0x83,0x2e,0x29,0x79,
0xcf,0xd8,0x8a,0x32,0x27,0x73,0xcc,0xda,0x8f,0x35,0x25,0x6e,0xc9,0xdc,0x94,0x38,
0x23,0x69,0xc5,0xdd,0x99,0x3c,0x22,0x64,0xc1,0xde,0x9f,0x41,0x21,0x5e,0xbd,0xdf,
0xa3,0x44,0x21,0x5a,0xb9,0xe0,0xa9,0x4a,0x20,0x55,0xb4,0xe0,0xae,0x4f,0x21,0x50,
0xaf,0xe0,0xb2,0x53,0x21,0x4c,0xaa,0xde,0xb6,0x58,0x21,0x47,0xa5,0xde,0xba,0x5d,
0x21,0x42,0xa0,0xdd,0xbe,0x62,0x23,0x3e,0x9a,0xdc,0xc2,0x67,0x25,0x3b,0x95,0xda,
0xc7,0x6d,0x27,0x38,0x90,0xd8,0xc9,0x72,0x29,0x34,0x8a,0xd6,0xcc,0x77,0x2a,0x30,
0x84,0xd3,0xcf,0x7c,0x2d,0x2e,0x7f,0xd1,0xd2,0x82,0x30,0x2b,0x79,0xcd,0xd4,0x87,
0x33,0x2a,0x75,0xca,0xd7,0x8d,0x37,0x28,0x6f,0xc7,0xd8,0x92,0x3a,0x27,0x6a,0xc3,
0xda,0x97,0x3e,0x25,0x65,0xbf,0xdb,0x9d,0x41,0x24,0x60,0xbc,0xdc,0xa1,0x46,0x23,
0x5b,0xb7,0xdc,0xa6,0x4a,0x23,0x56,0xb3,0xdd,0xab,0x4f,0x23,0x52,0xae,0xdd,0xb0,
0x54,0x24,0x4e,0xaa,0xdd,0xb5,0x59,0x25,0x4b,0xa6,0xdc,0xb8,0x5e,0x25,0x46,0xa1,
0xdb,0xbc,0x63,0x27,0x42,0x9b,0xda,0xc0,0x68,0x28,0x3e,0x95,0xd7,0xc3,0x6c,0x29,
0x3a,0x90,0xd6,0xc7,0x72,0x2b,0x38,0x8b,0xd3,0xc9,0x76,0x2d,0x35,0x86,0xd1,0xcc,
0x7b,0x2f,0x32,0x81,0xce,0xce,0x80,0x32,0x2f,0x7c,0xcb,0xd0,0x86,0x35,0x2d,0x76,
0xc8,0xd3,0x8a,0x38,0x2c,0x72,0xc5,0xd4,0x90,0x3c,0x2a,0x6c,0xc1,0xd5,0x94,0x3f,
0x29,0x68,0xbd,0xd6,0x99,0x43,0x28,0x62,0xb9,0xd7,0x9e,0x47,0x27,0x5e,0xb6,0xd8,
0xa3,0x4b,0x27,0x5a,0xb2,0xd9,0xa8,0x50,0x27,0x55,0xad,0xd9,0xac,0x54,0x27,0x50,
0xa8,0xd8,0xb0,0x58,0x27,0x4d,0xa4,0xd7,0xb4,0x5d,0x28,0x49,0x9f,0xd6,0xb8,0x62,
0x29,0x45,0x9b,0xd6,0xbc,0x66,0x2a,0x42,0x96,0xd5,0xc0,0x6c,0x2c,0x3e,0x91,0xd3,
0xc2,0x71,0x2e,0x3c,0x8c,0xd1,0xc6,0x76,0x30,0x38,0x87,0xcf,0xc8,0x7a,0x32,0x36,
0x82,0xcc,0xcb,0x7f,0x34,0x33,0x7d,0xc9,0xcd,0x83,0x36,0x30,0x78,0xc7,0xcf,0x89,
0x3a,0x2f,0x73,0xc4,0xd1,0x8e,0x3d,0x2d,0x6e,0xc0,0xd3,0x93,0x41,0x2d,0x69,0xbc,
0xd3,0x98,0x44,0x2b,0x64,0xb9,0xd4,0x9c,0x47,0x29,0x5f,0xb5,0xd5,0xa1,0x4c,0x29,
0x5c,0xb1,0xd6,0xa5,0x50,0x29,0x57,0xad,0xd6,0xaa,0x54,0x29,0x53,0xa8,0xd5,0xae,
0x58,0x29,0x4e,0xa4,0xd5,0xb2,0x5d,0x2a,0x4b,0x9f,0xd4,0xb5,0x61,0x2b,0x47,0x9b,
0xd3,0xb9,0x66,0x2c,0x44,0x97,0xd3,0xbd,0x6b,0x2e,0x41,0x92,0xd2,0xc1,0x71,0x30,
0x3e,0x8d,0xd0,0xc4,0x76,0x32,0x3c,0x88,0xcd,0xc6,0x7b,0x35,0x39,0x83,0xcb,0xc8,
0x7f,0x37,0x37,0x7f,0xc9,0xcb,0x84,0x3a,0x34,0x79,0xc6,0xcd,0x88,0x3c,0x32,0x75,
0xc2,0xce,0x8d,0x3f,0x31,0x6f,0xbf,0xd0,0x92,0x42,0x2f,0x6b,0xbb,0xd1,0x97,0x46,
0x2e,0x66,0xb8,0xd2,0x9b,0x49,0x2d,0x62,0xb4,0xd3,0x9f,0x4d,0x2c,0x5d,0xb0,0xd3,
0xa4,0x50,0x2b,0x59,0xac,0xd3,0xa7,0x55,0x2b,0x54,0xa7,0xd3,0xac,0x59,0x2c,0x50,
0xa3,0xd2,0xb0,0x5d,0x2c,0x4c,0x9e,0xd2,0xb3,0x62,0x2d,0x49,0x9a,0xd1,0xb7,0x66,
0x2f,0x46,0x96,0xd0,0xba,0x6b,0x30,0x43,0x91,0xcf,0xbd,0x6f,0x31,0x40,0x8d,0xcd,
0xc1,0x74,0x33,0x3d,0x88,0xcb,0xc3,0x79,0x35,0x3b,0x83,0xc8,0xc6,0x7e,0x38,0x39,
0x7f,0xc6,0xc8,0x82,0x3a,0x37,0x7b,0xc4,0xca,0x87,0x3d,0x34,0x76,0xc1,0xcc,0x8c,
0x40,0x33,0x71,0xbe,0xcd,0x90,0x43,0x31,0x6c,0xba,0xcf,0x95,0x46,0x30,0x68,0xb7,
0xd0,0x9a,0x4a,0x30,0x64,0xb4,0xd0,0x9e,0x4e,0x2f,0x60,0xb0,0xd1,0xa2,0x51,0x2f,
0x5b,0xac,0xd0,0xa5,0x55,0x2e,0x57,0xa7,0xd1,0xaa,0x59,0x2f,0x53,0xa3,0xd0,0xad,
0x5e,0x30,0x4f,0x9f,0xd0,0xb1,0x62,0x30,0x4c,0x9b,0xcf,0xb5,0x66,0x31,0x49,0x97,
0xce,0xb8,0x6a,0x32,0x46,0x92,0xcc,0xbb,0x6f,0x34,0x43,0x8e,0xcb,0xbe,0x73,0x35,
0x40,0x89,0xc9,0xc0,0x78,0x37,0x3d,0x84,0xc6,0xc3,0x7d,0x39,0x3b,0x7f,0xc4,0xc5,
0x81,0x3c,0x39,0x7b,0xc2,0xc7,0x86,0x3f,0x37,0x77,0xbf,0xc9,0x8b,0x42,0x36,0x73,
0xbc,0xca,0x8f,0x45,0x34,0x6e,0xb9,0xcc,0x94,0x48,0x33,0x6a,0xb6,0xcd,0x98,0x4b,
0x33,0x66,0xb3,0xce,0x9c,0x4f,0x32,0x62,0xb0,0xce,0xa0,0x53,0x32,0x5e,0xac,0xcf,
0xa4,0x56,0x31,0x5a,0xa8,0xce,0xa8,0x5a,0x32,0x56,0xa4,0xcf,0xac,0x5e,0x32,0x52,
0x9f,0xce,0xaf,0x62,0x32,0x4e,0x9a,0xcc,0xb1,0x65,0x33,0x4b,0x96,0xcb,0xb5,0x6a,
0x34,0x48,0x92,0xca,0xb8,0x6e,0x35,0x45,0x8e,0xc9,0xbb,0x73,0x37,0x42,0x8a,0xc7,
0xbd,0x77,0x39,0x40,0x85,0xc4,0xbf,0x7b,0x3b,0x3d,0x81,0xc2,0xc2,0x80,0x3e,0x3c,
0x7d,0xc1,0xc4,0x84,0x40,0x3a,0x78,0xbe,0xc6,0x89,0x43,0x39,0x74,0xbc,0xc8,0x8d,
0x46,0x37,0x70,0xb9,0xc9,0x91,0x49,0x36,0x6c,0xb6,0xca,0x96,0x4c,0x36,0x68,0xb3,
0xcb,0x9a,0x50,0x35,0x64,0xaf,0xcb,0x9d,0x53,0x34,0x60,0xab,0xcc,0xa2,0x56,0x34,
0x5c,0xa8,0xcb,0xa5,0x5a,0x34,0x58,0xa4,0xcc,0xa8,0x5e,0x34,0x55,0xa0,0xcb,0xac,
0x62,0x35,0x51,0x9b,0xca,0xb0,0x66,0x36,0x4e,0x98,0xca,0xb3,0x6a,0x37,0x4c,0x94,
0xc8,0xb6,0x6e,0x39,0x49,0x8f,0xc7,0xb8,0x72,0x3a,0x46,0x8b,0xc5,0xbb,0x76,0x3b,
0x43,0x86,0xc3,0xbd,0x7a,0x3d,0x41,0x82,0xc1,0xbf,0x7f,0x3f,0x3e,0x7d,0xbe,0xc1,
0x83,0x42,0x3d,0x7a,0xbc,0xc3,0x88,0x44,0x3b,0x75,0xb9,0xc4,0x8b,0x46,0x39,0x71,
0xb7,0xc6,0x8f,0x49,0x39,0x6d,0xb4,0xc7,0x93,0x4c,0x37,0x69,0xb1,0xc8,0x98,0x50,
0x37,0x66,0xae,0xc9,0x9c,0x53,0x37,0x62,0xab,0xc9,0x9f,0x57,0x37,0x5e,0xa7,0xc9,
0xa3,0x5b,0x37,0x5b,0xa4,0xca,0xa7,0x5e,0x37,0x58,0xa0,0xc9,0xaa,0x62,0x37,0x54,
0x9c,0xc8,0xad,0x66,0x38,0x51,0x98,0xc7,0xb0,0x6a,0x39,0x4d,0x94,0xc6,0xb3,0x6d,
0x3a,0x4b,0x90,0xc5,0xb6,0x72,0x3c,0x48,0x8b,0xc3,0xb8,0x75,0x3d,0x46,0x87,0xc1,
0xba,0x79,0x3f,0x44,0x83,0xc0,0xbd,0x7e,0x41,0x42,0x80,0xbe,0xbf,0x82,0x44,0x40,
0x7b,0xbb,0xc1,0x86,0x46,0x3e,0x77,0xb9,0xc2,0x8a,0x48,0x3d,0x73,0xb6,0xc3,0x8e,
0x4b,0x3c,0x6f,0xb3,0xc4,0x92,0x4e,0x3b,0x6c,0xb0,0xc5,0x96,0x50,0x3a,0x68,0xad,
0xc6,0x99,0x54,0x39,0x64,0xaa,0xc6,0x9d,0x57,0x39,0x60,0xa6,0xc6,0xa0,0x5a,0x39,
0x5d,0xa2,0xc6,0xa4,0x5e,0x39,0x59,0x9f,0xc6,0xa7,0x61,0x39,0x56,0x9b,0xc5,0xaa,
0x65,0x3a,0x53,0x97,0xc4,0xad,0x69,0x3b,0x50,0x94,0xc3,0xb0,0x6d,0x3c,0x4d,0x90,
0xc3,0xb3,0x71,0x3e,0x4b,0x8c,0xc1,0xb6,0x75,0x3f,0x49,0x89,0xc0,0xb8,0x79,0x42,
0x47,0x85,0xbe,0xbb,0x7d,0x43,0x45,0x81,0xbc,0xbc,0x81,0x45,0x42,0x7c,0xba,0xbe,
0x84,0x47,0x41,0x78,0xb7,0xbf,0x89,0x4a,0x40,0x75,0xb5,0xc0,0x8c,0x4c,0x3e,0x71,
0xb2,0xc1,0x8f,0x4e,0x3d,0x6d,0xaf,0xc2,0x93,0x51,0x3c,0x69,0xac,0xc2,0x96,0x54,
0x3b,0x65,0xa9,0xc3,0x9a,0x57,0x3b,0x62,0xa6,0xc3,0x9e,0x5b,0x3c,0x5f,0xa2,0xc3,
0xa1,0x5e,0x3c,0x5c,0x9f,0xc3,0xa4,0x61,0x3c,0x58,0x9b,0xc2,0xa7,0x65,0x3d,0x56,
0x98,0xc2,0xaa,0x69,0x3d,0x53,0x94,0xc1,0xad,0x6c,0x3f,0x50,0x90,0xc0,0xb0,0x70,
0x40,0x4e,0x8d,0xbf,0xb2,0x74,0x42,0x4c,0x89,0xbd,0xb5,0x78,0x43,0x4a,0x86,0xbc,
0xb7,0x7c,0x45,0x48,0x82,0xba,0xb8,0x7f,0x46,0x46,0x7e,0xb7,0xba,0x83,0x49,0x44,
0x7a,0xb5,0xbc,0x87,0x4b,0x43,0x76,0xb3,0xbd,0x8a,0x4e,0x43,0x74,0xb1,0xbe,0x8e,
0x50,0x42,0x70,0xae,0xbe,0x91,0x53,0x41,0x6c,0xab,0xbf,0x95,0x56,0x40,0x69,0xa8,
0xbf,0x98,0x58,0x3f,0x65,0xa5,0xc0,0x9b,0x5c,0x40,0x62,0xa1,0xbf,0x9e,0x5f,0x40,
0x5f,0x9e,0xbf,0xa1,0x62,0x40,0x5c,0x9b,0xbe,0xa4,0x65,0x40,0x59,0x97,0xbe,0xa7,
0x69,0x41,0x56,0x94,0xbd,0xaa,0x6c,0x42,0x54,0x91,0xbd,0xac,0x70,0x43,0x52,0x8d,
0xbb,0xae,0x73,0x45,0x50,0x8a,0xba,0xb0,0x77,0x46,0x4d,0x86,0xb8,0xb2,0x7a,0x47,
0x4c,0x83,0xb6,0xb4,0x7e,0x49,0x4a,0x80,0xb5,0xb6,0x81,0x4c,0x49,0x7c,0xb3,0xb7,
0x85,0x4e,0x47,0x78,0xb0,0xb8,0x88,0x50,0x47,0x75,0xae,0xb9,0x8c,0x53,0x46,0x72,
0xac,0xba,0x8f,0x55,0x45,0x6f,0xa9,0xbb,0x92,0x58,0x45,0x6c,0xa7,0xbb,0x96,0x5a,
0x44,0x68,0xa3,0xbb,0x98,0x5d,0x44,0x65,0xa0,0xbb,0x9b,0x60,0x44,0x62,0x9d,0xbb,
0x9e,0x63,0x44,0x5f,0x9a,0xbb,0xa1,0x66,0x45,0x5d,0x97,0xba,0xa3,0x69,0x45,0x5a,
0x94,0xb9,0xa6,0x6c,0x46,0x58,0x91,0xb9,0xa8,0x70,0x47,0x56,0x8d,0xb8,0xab,0x73,
0x48,0x53,0x8a,0xb7,0xad,0x77,0x49,0x52,0x87,0xb5,0xaf,0x7a,0x4b,0x50,0x84,0xb4,
0xb0,0x7d,0x4d,0x4f,0x81,0xb2,0xb1,0x80,0x4f,0x4d,0x7e,0xb0,0xb3,0x83,0x50,0x4c,
0x7a,0xae,0xb4,0x86,0x52,0x4a,0x76,0xab,0xb5,0x89,0x54,0x49,0x73,0xa9,0xb6,0x8c,
0x57,0x49,0x70,0xa7,0xb6,0x8f,0x59,0x48,0x6d,0xa4,0xb7,0x93,0x5c,0x48,0x6b,0xa2,
0xb7,0x96,0x5e,0x48,0x68,0x9f,0xb8,0x99,0x61,0x48,0x65,0x9c,0xb7,0x9b,0x64,0x48,
0x62,0x9a,0xb7,0x9e,0x67,0x49,0x60,0x97,0xb7,0xa1,0x6b,0x49,0x5e,0x94,0xb6,0xa3,
0x6d,0x4a,0x5b,0x91,0xb6,0xa5,0x70,0x4b,0x5a,0x8e,0xb5,0xa8,0x73,0x4c,0x58,0x8b,
0xb4,0xaa,0x76,0x4d,0x55,0x88,0xb2,0xab,0x79,0x4e,0x54,0x85,0xb1,0xac,0x7c,0x4f,
0x52,0x81,0xaf,0xad,0x7f,0x51,0x51,0x7e,0xad,0xaf,0x81,0x53,0x4f,0x7b,0xab,0xb0,
0x84,0x54,0x4e,0x78,0xa9,0xb1,0x88,0x56,0x4d,0x75,0xa7,0xb2,0x8b,0x59,0x4d,0x73,
0xa5,0xb3,0x8e,0x5b,0x4d,0x70,0xa3,0xb3,0x91,0x5e,0x4c,0x6d,0xa0,0xb3,0x93,0x60,
0x4c,0x6a,0x9e,0xb3,0x96,0x62,0x4c,0x68,0x9b,0xb3,0x98,0x65,0x4c,0x65,0x99,0xb3,
0x9b,0x68,0x4c,0x63,0x96,0xb3,0x9d,0x6a,0x4d,0x61,0x93,0xb2,0x9f,0x6d,0x4d,0x5e,
0x90,0xb2,0xa1,0x70,0x4e,0x5d,0x8e,0xb1,0xa3,0x73,0x4f,0x5b,0x8b,0xb0,0xa5,0x76,
0x50,0x59,0x88,0xaf,0xa7,0x78,0x51,0x58,0x85,0xad,0xa9,0x7c,0x53,0x56,0x83,0xad,
0xaa,0x7e,0x54,0x55,0x80,0xab,0xab,0x81,0x56,0x54,0x7d,0xa9,0xac,0x84,0x57,0x52,
0x7a,0xa7,0xad,0x86,0x59,0x51,0x77,0xa5,0xae,0x89,0x5b,0x50,0x74,0xa3,0xae,0x8c,
0x5d,0x50,0x71,0xa1,0xaf,0x8e,0x5f,0x4f,0x6f,0x9e,0xaf,0x90,0x61,0x4f,0x6c,0x9c,
0xaf,0x93,0x63,0x4f,0x6a,0x9a,0xb0,0x96,0x65,0x4f,0x68,0x98,0xb0,0x98,0x68,0x4f,
0x65,0x95,0xaf,0x9a,0x6b,0x50,0x64,0x93,0xaf,0x9c,0x6e,0x51,0x62,0x90,0xae,0x9e,
0x70,0x51,0x60,0x8e,0xae,0xa0,0x73,0x53,0x5f,0x8c,0xad,0xa2,0x75,0x53,0x5d,0x89,
0xac,0xa4,0x78,0x54,0x5b,0x86,0xab,0xa5,0x7b,0x55,0x5a,0x83,0xa9,0xa6,0x7d,0x57,
0x59,0x81,0xa8,0xa8,0x80,0x58,0x58,0x7e,0xa7,0xa9,0x82,0x5a,0x56,0x7c,0xa5,0xaa,
0x85,0x5b,0x56,0x79,0xa3,0xab,0x88,0x5d,0x55,0x77,0xa2,0xab,0x8a,0x5f,0x54,0x74,
0x9f,0xab,0x8c,0x61,0x54,0x71,0x9d,0xac,0x8e,0x63,0x53,0x6f,0x9b,0xac,0x90,0x64,
0x53,0x6d,0x99,0xac,0x93,0x67,0x53,0x6b,0x97,0xab,0x95,0x69,0x53,0x68,0x94,0xab,
0x97,0x6b,0x54,0x66,0x92,0xab,0x99,0x6e,0x54,0x65,0x90,0xab,0x9b,0x70,0x55,0x63,
0x8e,0xaa,0x9d,0x73,0x56,0x62,0x8b,0xa9,0x9e,0x75,0x56,0x60,0x89,0xa9,0xa0,0x77,
0x57,0x5e,0x86,0xa7,0xa1,0x7a,0x58,0x5d,0x84,0xa6,0xa3,0x7d,0x5a,0x5c,0x81,0xa5,
0xa4,0x7f,0x5b,0x5b,0x7f,0xa4,0xa5,0x81,0x5c,0x5a,0x7d,0xa2,0xa6,0x84,0x5e,0x59,
0x7a,0xa1,0xa7,0x86,0x5f,0x58,0x78,0x9f,0xa7,0x88,0x61,0x58,0x76,0x9e,0xa8,0x8b,
0x63,0x57,0x73,0x9b,0xa8,0x8c,0x65,0x57,0x71,0x9a,0xa8,0x8f,0x67,0x57,0x70,0x98,
0xa9,0x91,0x69,0x57,0x6e,0x96,0xa9,0x93,0x6a,0x57,0x6c,0x94,0xa8,0x95,0x6d,0x57,
0x6a,0x92,0xa8,0x97,0x6f,0x58,0x68,0x90,0xa8,0x98,0x71,0x59,0x67,0x8e,0xa7,0x9a,
0x73,0x59,0x65,0x8b,0xa6,0x9b,0x75,0x59,0x63,0x88,0xa5,0x9c,0x77,0x5a,0x62,0x86,
0xa4,0x9e,0x79,0x5b,0x60,0x84,0xa3,0x9f,0x7c,0x5c,0x5f,0x82,0xa2,0xa0,0x7e,0x5e,
0x5e,0x80,0xa1,0xa1,0x80,0x5f,0x5d,0x7e,0xa0,0xa2,0x82,0x60,0x5d,0x7c,0x9e,0xa3,
0x84,0x61,0x5c,0x79,0x9d,0xa3,0x86,0x63,0x5b,0x77,0x9b,0xa4,0x88,0x64,0x5b,0x75,
0x9a,0xa4,0x8b,0x66,0x5b,0x73,0x98,0xa5,0x8d,0x68,0x5b,0x72,0x96,0xa5,0x8e,0x6a,
0x5b,0x70,0x95,0xa5,0x90,0x6b,0x5b,0x6e,0x93,0xa5,0x92,0x6d,0x5b,0x6d,0x91,0xa5,
0x94,0x6f,0x5b,0x6b,0x8f,0xa4,0x95,0x71,0x5b,0x69,0x8d,0xa4,0x97,0x73,0x5c,0x68,
0x8b,0xa3,0x98,0x75,0x5d,0x66,0x89,0xa2,0x99,0x77,0x5d,0x65,0x87,0xa1,0x9b,0x79,
0x5e,0x64,0x85,0xa1,0x9c,0x7b,0x5f,0x63,0x83,0x9f,0x9d,0x7d,0x60,0x61,0x80,0x9e,
0x9e,0x7f,0x61,0x61,0x7e,0x9d,0x9e,0x81,0x62,0x60,0x7c,0x9c,0x9f,0x83,0x63,0x5f,
0x7b,0x9b,0xa0,0x85,0x65,0x5f,0x79,0x99,0xa0,0x87,0x66,0x5e,0x77,0x98,0xa0,0x89,
0x68,0x5e,0x75,0x96,0xa1,0x8b,0x69,0x5e,0x74,0x95,0xa1,0x8d,0x6b,0x5e,0x72,0x93,
0xa1,0x8e,0x6d,0x5e,0x71,0x92,0xa1,0x90,0x6e,0x5e,0x6f,0x90,0xa1,0x91,0x70,0x5f,
0x6d,0x8e,0xa1,0x93,0x72,0x5f,0x6c,0x8c,0xa0,0x94,0x74,0x5f,0x6b,0x8b,0xa0,0x95,
0x76,0x60,0x69,0x89,0x9f,0x96,0x77,0x61,0x68,0x87,0x9e,0x98,0x79,0x61,0x67,0x85,
0x9e,0x99,0x7b,0x62,0x66,0x83,0x9d,0x99,0x7d,0x64,0x66,0x81,0x9b,0x9a,0x7f,0x65,
0x65,0x7f,0x9a,0x9a,0x80,0x66,0x65,0x7e,0x99,0x9a,0x82,0x67,0x65,0x7c,0x97,0x9a,
0x83,0x69,0x64,0x7a,0x95,0x9a,0x85,0x6a,0x64,0x79,0x94,0x9a,0x86,0x6b,0x64,0x78,
0x92,0x9a,0x88,0x6d,0x64,0x76,0x91,0x9a,0x89,0x6f,0x65,0x75,0x8f,0x9a,0x8a,0x70,
0x65,0x74,0x8e,0x99,0x8b,0x72,0x66,0x73,0x8c,0x99,0x8c,0x73,0x67,0x72,0x8b,0x98,
0x8d,0x75,0x67,0x71,0x89,0x98,0x8e,0x76,0x68,0x70,0x88,0x97,0x8f,0x78,0x69,0x70,
0x87,0x96,0x90,0x79,0x6a,0x70,0x85,0x96,0x90,0x7b,0x6b,0x6f,0x84,0x94,0x90,0x7c,
0x6b,0x6f,0x83,0x93,0x91,0x7d,0x6c,0x6e,0x81,0x92,0x91,0x7e,0x6d,0x6e,0x80,0x91,
0x91,0x7f,0x6e,0x6e,0x7f,0x90,0x91,0x80,0x6f,0x6e,0x7e,0x8f,0x91,0x82,0x70,0x6e,
0x7d,0x8e,0x91,0x83,0x71,0x6e,0x7c,0x8d,0x91,0x84,0x73,0x6f,0x7b,0x8c,0x91,0x84,
0x74,0x6f,0x7a,0x8b,0x90,0x85,0x75,0x6f,0x79,0x8a,0x90,0x86,0x76,0x6f,0x79,0x89,
0x8f,0x86,0x77,0x70,0x80,0x80,0x80,0x80,0x80

+435
View File
@@ -0,0 +1,435 @@
///////////////////////////////////////////////////////////////////////////////
// File: GreenFog.cpp
//
// Copyright 2001 Pipeworks Software
///////////////////////////////////////////////////////////////////////////////
#include "precomp.h"
#include "xbs_math.h"
#include "xbs_app.h"
#include "qrand.h"
#include "GreenFog.h"
#include "tex_gen.h"
///////////////////////////////////////////////////////////////////////////////
#define PLASMA_SIZE (256)
// 1024x512 appears to be only .1 fps slower than 512x256.
#define INTENSITY_TEX_X (1024)
#define INTENSITY_TEX_Y (512)
//MTS#define INTENSITY_TEX_X (512)
//MTS#define INTENSITY_TEX_Y (256)
const float MUL_SCALE = 0.005f;
const float MAIN_FOG_RAD = 40.0f;
///////////////////////////////////////////////////////////////////////////////
void GreenFog::Init()
{
pQuadVB = NULL;
pIntensityQuadVB = NULL;
for (int i=0; i<NUM_PLASMAS; i++) pPlasmaTexture[i] = NULL;
pIntensityTextureU = pIntensityTextureR = NULL;
pIntensityZ = NULL;
dwFogPShader = dwFogVShader = 0;
}
///////////////////////////////////////////////////////////////////////////////
void GreenFog::create()
{
destroy();
const float f_plasma_dim = ((float)PLASMA_SIZE);
gpd3dDev->CreateTexture(INTENSITY_TEX_X, INTENSITY_TEX_Y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, 0, &pIntensityTextureU);
gpd3dDev->CreateTexture(INTENSITY_TEX_X, INTENSITY_TEX_Y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, 0, &pIntensityTextureR);
gpd3dDev->CreateDepthStencilSurface(INTENSITY_TEX_X,INTENSITY_TEX_Y,D3DFMT_LIN_D24S8, D3DMULTISAMPLE_2_SAMPLES_MULTISAMPLE_LINEAR , &pIntensityZ);
gpd3dDev->CreateVertexBuffer(4*sizeof(GreenFogVertexBuffer), 0, 0, 0, &pQuadVB);
GreenFogVertexBuffer* p_verts;
pQuadVB->Lock(0, 0, (BYTE**) &p_verts, 0);
Set(&p_verts[0].pos, -1.0f, -1.0f, 1.0f);
Set(&p_verts[1].pos, -1.0f, +1.0f, 1.0f);
Set(&p_verts[2].pos, +1.0f, +1.0f, 1.0f);
Set(&p_verts[3].pos, +1.0f, -1.0f, 1.0f);
p_verts[0].tu0 = 0.0f; p_verts[0].tv0 = 1.0f;
p_verts[1].tu0 = 0.0f; p_verts[1].tv0 = 0.0f;
p_verts[2].tu0 = 1.0f; p_verts[2].tv0 = 0.0f;
p_verts[3].tu0 = 1.0f; p_verts[3].tv0 = 1.0f;
for (int i=0; i<4; i++)
{
p_verts[i].tv1 = -(2.0f*p_verts[i].tu0 - 1.0f) * 640.0f/f_plasma_dim;
p_verts[i].tu1 = -(2.0f*p_verts[i].tv0 - 1.0f) * 480.0f/f_plasma_dim;
//MTS p_verts[i].tu1 = (2.0f*p_verts[i].tu0 - 1.0f) * 640.0f/f_plasma_dim;
//MTS p_verts[i].tv1 = (2.0f*p_verts[i].tv0 - 1.0f) * 480.0f/f_plasma_dim;
}
pQuadVB->Unlock();
// These are used to render the backdrop.
gpd3dDev->CreateVertexBuffer(4*sizeof(BaseStream), 0, 0, 0, &pIntensityQuadVB);
BaseStream* p_bs_verts;
pIntensityQuadVB->Lock(0, 0, (BYTE**) &p_bs_verts, 0);
Set(&p_bs_verts[0].p, -1.0f, -1.0f, 1.0f);
Set(&p_bs_verts[1].p, -1.0f, +1.0f, 1.0f);
Set(&p_bs_verts[2].p, +1.0f, +1.0f, 1.0f);
Set(&p_bs_verts[3].p, +1.0f, -1.0f, 1.0f);
pIntensityQuadVB->Unlock();
DWORD dwShaderVertexDecl[] =
{
D3DVSD_STREAM( 0 ),
D3DVSD_REG( 0, D3DVSDT_FLOAT3 ), // position
D3DVSD_REG( 1, D3DVSDT_FLOAT2 ), // intensity texture
D3DVSD_REG( 2, D3DVSDT_FLOAT2 ), // plasma 0
D3DVSD_END()
};
#ifndef BINARY_RESOURCE
dwFogPShader = gApp.loadPixelShader( "d:\\shaders\\greenfog.xpu" );
dwFogVShader = gApp.loadVertexShader( "d:\\shaders\\greenfog.xvu", dwShaderVertexDecl );
#else // BINARY_RESOURCE
dwFogPShader = gApp.loadPixelShader( g_greenfog_xpu );
dwFogVShader = gApp.loadVertexShader( g_greenfog_xvu, dwShaderVertexDecl );
#endif // BINARY_RESOURCE
restart(); // renders the texture
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void GreenFog::destroy()
{
#define XBS_RESOURCE_RELEASE(a) if (a) a->Release(); a = NULL;
XBS_RESOURCE_RELEASE(pQuadVB);
XBS_RESOURCE_RELEASE(pIntensityQuadVB);
for (int i=0; i<NUM_PLASMAS; i++) { XBS_RESOURCE_RELEASE(pPlasmaTexture[i]); }
XBS_RESOURCE_RELEASE(pIntensityTextureU);
XBS_RESOURCE_RELEASE(pIntensityTextureR);
XBS_RESOURCE_RELEASE(pIntensityZ);
#undef XBS_RESOURCE_RELEASE
if (dwFogPShader) gpd3dDev->DeletePixelShader( dwFogPShader );
if (dwFogVShader) gpd3dDev->DeleteVertexShader( dwFogVShader );
dwFogPShader = dwFogVShader = 0;
}
///////////////////////////////////////////////////////////////////////////////
void GreenFog::advanceTime(float fElapsedTime, float fDt)
{
renderIntensityTexture();
}
///////////////////////////////////////////////////////////////////////////////
void GreenFog::render(bool b_cmp_to_one)
{
int i;
gpd3dDev->SetVertexShader( dwFogVShader );
gpd3dDev->SetPixelShader ( dwFogPShader );
// Swap render and update textures.
LPDIRECT3DTEXTURE8 p_swap = pIntensityTextureR;
pIntensityTextureR = pIntensityTextureU;
pIntensityTextureU = p_swap;
// Use what was the update(d) texture.
gpd3dDev->SetTexture(0, pIntensityTextureR);
gpd3dDev->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
gpd3dDev->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
gpd3dDev->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_NONE );
gpd3dDev->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
for (i=0; i<NUM_PLASMAS; i++)
{
gpd3dDev->SetTexture(i+1, pPlasmaTexture[i]);
gpd3dDev->SetTextureStageState( i+1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
gpd3dDev->SetTextureStageState( i+1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
gpd3dDev->SetTextureStageState( i+1, D3DTSS_MIPFILTER, D3DTEXF_NONE );
gpd3dDev->SetTextureStageState( i+1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
gpd3dDev->SetTextureStageState( i+1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
}
gpd3dDev->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
//MTS gpd3dDev->SetRenderState( D3DRS_ZFUNC, D3DCMP_GREATEREQUAL );
gpd3dDev->SetRenderState( D3DRS_ZFUNC, (b_cmp_to_one) ? D3DCMP_EQUAL : D3DCMP_ALWAYS );
gpd3dDev->SetRenderState( D3DRS_ALPHAREF, 0x00000001 );
gpd3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
gpd3dDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
gpd3dDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
//MTS gpd3dDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE ); // Just render intensity
//MTS gpd3dDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO ); // Just render intensity
gpd3dDev->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
D3DVECTOR4 val[2*NUM_PLASMAS];
float f_intensity = max(0.0f, gApp.getBlobIntensity() * 0.7f - 0.1f);
Set(&val[0], 0.0f*f_intensity, f_intensity, 0.0f*f_intensity, 1.0f);
float f_glow = 0.75f * max(0.0f, min(1.0f, (gApp.getElapsedTime() - GLOW_FADE_SCREEN_START) * GLOW_FADE_SCREEN_MUL));
//MTS Set(&val[1], f_glow*0.625f, f_glow*1.0f, f_glow*0.0625f, 0.0f);
Set(&val[1], f_glow*0.625f, f_glow, f_glow * 0.4f, 0.0f);
gpd3dDev->SetPixelShaderConstant(0, &val[0], 2);
D3DVECTOR4 origin, origin_scr;
Set(&origin, 0.0f, 0.0f, 0.0f, 1.0f);
TransformPoint(origin, gApp.theCamera.getWTP(), &origin_scr);
Scale(&origin_scr, 1.0f / origin_scr.w);
const float f_plasma_dim = ((float)PLASMA_SIZE);
// Set the transforms for the plasma texture coordinates.
for (i=0; i<NUM_PLASMAS; i++)
{
float rad = 0.6f * (((float)(NUM_PLASMAS-i-1)) / ((float)NUM_PLASMAS) - 0.2f);
float x_mul = 0.5f * gApp.getCameraRadiusFromBlob() * MUL_SCALE;
float y_mul = 1.0f * gApp.theCamera.getAspectRatio() * gApp.getCameraRadiusFromBlob() * MUL_SCALE;
float x_add = rad * gApp.getCameraTheta() - origin_scr.x * x_mul * 640.0f/f_plasma_dim;
float y_add = -rad * gApp.getCameraPhi() + origin_scr.y * y_mul * 480.0f/f_plasma_dim;
// I don't know why y_mul is 1.0f* and x_mul is 0.5f*, but it looks less stretched in y this way.
Set(&val[2*i+0], y_add, x_add, 0.0f, 0.0f);
Set(&val[2*i+1], -y_mul, -x_mul, 1.0f, 1.0f);
//MTS Set(&val[2*i+0], x_add, y_add, 0.0f, 0.0f);
//MTS Set(&val[2*i+1], x_mul, y_mul, 1.0f, 1.0f);
}
gpd3dDev->SetVertexShaderConstant(0, &val[0], 2*NUM_PLASMAS);
gpd3dDev->SetStreamSource(0, pQuadVB, sizeof(GreenFogVertexBuffer));
gpd3dDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
gpd3dDev->SetPixelShader (NULL);
gpd3dDev->SetVertexShader(NULL);
for (i=0; i<1+NUM_PLASMAS; i++) gpd3dDev->SetTexture(i, NULL);
// Render fade to yellow.
f_glow = max(0.0f, min(1.0f, (gApp.getElapsedTime() - GLOW_FADE_CIRCLE_START) * GLOW_FADE_CIRCLE_MUL));
if (gApp.getElapsedTime() < BLOB_STATIC_END_TIME)
{
float t = gApp.getElapsedTime();
f_glow = (t < BLOB_STATIC_END_TIME * 0.2f) ? (t / (BLOB_STATIC_END_TIME*0.2f)) : (1.0f - (t-BLOB_STATIC_END_TIME * 0.2f)/BLOB_STATIC_END_TIME);
}
int alpha = max(0, min( 255, (int) ((255.0f * f_glow))));
//MTS alpha >>= 1;
alpha = min(196, alpha*2);
if (alpha)
{
//MTS DWORD glow_factor = 0x00a0ff10 | (alpha << 24);
DWORD glow_factor = 0x00A0FF60 | (alpha << 24);
gpd3dDev->SetRenderState(D3DRS_TEXTUREFACTOR, glow_factor);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TFACTOR);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_TEXTURE);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
gpd3dDev->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE);
gpd3dDev->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TFACTOR);
gpd3dDev->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_TEXTURE);
gpd3dDev->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_MODULATE);
// Correct center.
float x_mul = gApp.getCameraRadiusFromBlob() * MUL_SCALE;
float y_mul = gApp.getCameraRadiusFromBlob() * MUL_SCALE * gApp.theCamera.getAspectRatio();
D3DVECTOR4 origin, origin_screen;
Set(&origin, 0.0f, 0.0f, 0.0f, 1.0f);
TransformPoint(origin, gApp.theCamera.getWTP(), &origin_screen);
Scale(&origin_screen, 1.0f / origin_screen.w);
//origin_screen.x = 0.5f - x_mul * origin_screen.x;
//origin_screen.y = 0.5f - y_mul * origin_screen.y;
D3DMATRIX mat_tex;
float mul = 0.33f / f_glow;
if (gApp.getElapsedTime() < BLOB_STATIC_END_TIME)
{
mul = gApp.getCameraRadiusFromBlob() * BLOB_STATIC_END_TIME / (gApp.getElapsedTime() * 8.0f);
}
SetScale(mul, mul, 1.0f, &mat_tex);
mat_tex._31 = 0.5f*(1.0f-mul) - 0.5f * origin_screen.x * mul * 1.33f;
mat_tex._32 = 0.5f*(1.0f-mul) + 0.5f * origin_screen.y * mul;
D3DMATRIX iden,scaled;
SetIdentity(&iden);
SetScale(1.0f / mul, 1.0f / mul, 0.0f, &scaled);
scaled._43 = 1.0f;
gpd3dDev->SetTransform(D3DTS_WORLD, &scaled);
gpd3dDev->SetTransform(D3DTS_VIEW, &iden);
gpd3dDev->SetTransform(D3DTS_PROJECTION, &iden);
gpd3dDev->SetTexture(0,gApp.pGlowMap);
gpd3dDev->SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX2);
gpd3dDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
}
gpd3dDev->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
gpd3dDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
gpd3dDev->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
}
///////////////////////////////////////////////////////////////////////////////
void GreenFog::restart()
{
int tffonp = 255 / NUM_PLASMAS;
for (int i=0; i<NUM_PLASMAS; i++)
{
if (pPlasmaTexture[i]) pPlasmaTexture[i]->Release();
}
CreateIntensityTexture_8Bit(pPlasmaTexture, NUM_PLASMAS, PLASMA_SIZE, 5 * tffonp, gApp.rand(),
((tffonp*3)/4) << 8, 255/max(1,NUM_PLASMAS-0));
}
///////////////////////////////////////////////////////////////////////////////
void GreenFog::renderIntensityTexture()
{
// Get camera position and render geometry into background.
// Store old render targets.
LPDIRECT3DSURFACE8 pOldRT,pOldZ;
gpd3dDev->GetRenderTarget(&pOldRT);
gpd3dDev->GetDepthStencilSurface(&pOldZ);
// Leave the camera position where it is.
LPDIRECT3DSURFACE8 p_update_surf;
pIntensityTextureU->GetSurfaceLevel(0, &p_update_surf);
gpd3dDev->SetRenderTarget(p_update_surf, pIntensityZ);
if( gpd3dDev->BeginScene() == D3D_OK )
{
gpd3dDev->Clear(0,NULL,
D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET,
0xffff0000,
1.f,
0 );
// Render a backdrop.
gpd3dDev->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
gpd3dDev->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
gpd3dDev->SetRenderState( D3DRS_ALPHAREF, 0x00000001 );
gpd3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
gpd3dDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
gpd3dDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
gpd3dDev->SetVertexShader(gApp.dwVShader[st_Depth]);
gpd3dDev->SetPixelShader (gApp.dwPShader[st_Depth]);
//#define Z_ADD c16
//#define Z_MUL c17
//#define POS_MUL c18
//#define POS_SHIFT c19
D3DVECTOR4 val[4];
float max_color_dist = 2.0f * MAIN_FOG_RAD;
float z_mul = 1.0f; // set later on for the geometry case, this is just the backdrop
float z_add = 0.0f;
Set(&val[0], z_mul, z_mul, z_mul, 1.0f );
Set(&val[1], z_add, z_add, z_add, 1.0f );
float x_mul = gApp.getCameraRadiusFromBlob() * MUL_SCALE;
float y_mul = gApp.getCameraRadiusFromBlob() * MUL_SCALE * gApp.theCamera.getAspectRatio();
Set(&val[2], x_mul, y_mul, 0.0f, 1.0f);
D3DVECTOR4 origin;
Set(&origin, 0.0f, 0.0f, 0.0f, 1.0f);
TransformPoint(origin, gApp.theCamera.getWTP(), &val[3]);
Scale(&val[3], 1.0f / val[3].w);
val[3].x = 0.5f - val[2].x * val[3].x;
val[3].y = 0.5f - val[2].y * val[3].y;
val[3].z = 0.5f;
val[3].w = 0.0f;
// If looking at origin, then Set(&val[3], 0.5f, 0.5f, 0.5f, 0.0f);
//MTS Set(&val[3], 0.5f, 0.5f, 0.5f, 0.0f);
gpd3dDev->SetVertexShaderConstant(16, &val[0], 4);
D3DMATRIX iden;
SetIdentity(&iden);
iden._43 = 1.0f;
iden._44 = 0.0f;
gpd3dDev->SetVertexShaderConstant(0, &iden, 4);
gpd3dDev->SetStreamSource(0, pIntensityQuadVB, sizeof(BaseStream));
gpd3dDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
gpd3dDev->SetRenderState( D3DRS_ZWRITEENABLE, TRUE);
gpd3dDev->SetRenderState( D3DRS_ZENABLE, TRUE);
z_add = MAIN_FOG_RAD - gApp.getCameraRadiusFromBlob();
z_mul = 1.0f / max_color_dist;
Set(&val[0], z_mul, z_mul, z_mul, 1.0f );
Set(&val[1], z_add, z_add, z_add, 1.0f );
gpd3dDev->SetVertexShaderConstant(16, &val, 2);
gApp.sceneGeom.renderZ();
// Without NULLing the pixel shader, the shields aren't transparent. Dunno why.
gpd3dDev->SetPixelShader (NULL);
gpd3dDev->SetVertexShader(NULL);
// Clear stencil and depth buffer, but not the "target", or ARGB values.
gpd3dDev->Clear(0,NULL,
D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER,
0xffffffff,
1.f,
0 );
gpd3dDev->EndScene();
}
else
{
int a = 0;
}
gpd3dDev->SetRenderTarget(pOldRT,pOldZ);
p_update_surf->Release();
pOldRT->Release();
pOldZ->Release();
}
///////////////////////////////////////////////////////////////////////////////
+54
View File
@@ -0,0 +1,54 @@
///////////////////////////////////////////////////////////////////////////////
// File: GreenFog.h
//
// Copyright 2001 Pipeworks Software
///////////////////////////////////////////////////////////////////////////////
#ifndef GREENFOG_H
#define GREENFOG_H
class GreenFog
{
public:
void Init();
void UnInit() { destroy(); }
void create();
void destroy();
void advanceTime(float fElapsedTime, float fDt);
void render(bool b_cmp_to_one);
void restart();
LPDIRECT3DVERTEXBUFFER8 borrowScreenQuad() { return pQuadVB; }
protected:
enum { NUM_PLASMAS = 3 };
LPDIRECT3DVERTEXBUFFER8 pQuadVB;
LPDIRECT3DVERTEXBUFFER8 pIntensityQuadVB;
LPDIRECT3DTEXTURE8 pPlasmaTexture[NUM_PLASMAS];
LPDIRECT3DTEXTURE8 pIntensityTextureR; // for rendering (swapped in render)
LPDIRECT3DTEXTURE8 pIntensityTextureU; // for updating
LPDIRECT3DSURFACE8 pIntensityZ;
DWORD dwFogPShader, dwFogVShader;
void renderIntensityTexture();
};
///////////////////////////////////////////////////////////////////////////////
struct GreenFogVertexBuffer
{
D3DVECTOR pos;
FLOAT tu0, tv0; // texture coordinate in intensity lookup
FLOAT tu1, tv1; // texture coordinate in plasma, which wraps
};
#endif // GREENFOG_H
+41
View File
@@ -0,0 +1,41 @@
#define F_NOTE 1
#define F_REST 0
#define F_JUMPTO 2
#define F_LOOP 3
#define F_ENDLOOP 4
#define F_PATCH 5
#define F_PAN 6
#define F_MUX 7
#define F_DEMUX 8
#define F_VOLUME 9
#define F_XPOSE 10
#define F_XSET 11
#define F_SLUR 12
#define F_RING 13
#define F_CLOCKSET 14
#define F_END 15
#define F_FILTERINC 16
#define F_FILTERSET 17
#define note(pitch,dur) F_NOTE,pitch,dur
#define rest(dur) F_REST,dur
#define jumpto(label) F_JUMPTO,label
#define loop(n) F_LOOP,n
#define endloop F_ENDLOOP
#define patch(num) F_PATCH,num
#define pan(value) F_PAN,value
#define mux(label) F_MUX,label
#define demux F_DEMUX
#define volume(val) F_VOLUME,val
#define xpose(val) F_XPOSE,val
#define xset(val) F_XSET,val
#define slur(pitch,dur) F_SLUR,pitch,dur
#define ring(dur) F_RING,dur
#define clockset(val) F_CLOCKSET,val
#define sosend F_END
#define finc(f,res) F_FILTERINC,f,res
#define fset(f,res) F_FILTERSET,f,res
+82
View File
@@ -0,0 +1,82 @@
/*************************************************************************
* *
* Routines for process creation and control *
* *
*************************************************************************/
#include "error.h"
#include "sos.h"
#include "protos.h"
#include "externs.h"
extern int (*event_fcns[])();
/*
* return a new process or NULL if error
* Put the process in the process queue
*/
struct process *pp;
int create_process(
ushort *mem_ptr, /* pointer to event list */
uchar level, /* sound level */
uchar channel) /* channel for this process */
{
struct process *tpp;
pp = get_process_packet();
pp->mem_ptr.i = mem_ptr; /* get event-list pointer */
pp->level = level; /* get level */
pp->timer = 0; /* timer for process */
pp->hard_channel = channel; /* get hardware channel */
pp->function = *mem_ptr; /* get function byte */
pp->type = 0; /* clear type field */
pp->prev = process_queue; /* put process at head of q */
if (level == 0)
pp->prev_timer = system_clock_music; /* make us current */
else
pp->prev_timer = system_clock_fx; /* make us current */
pp->next = tpp = process_queue->next;
if (tpp != (struct process *)NULL) {
tpp->prev = pp;
}
process_queue->next = pp;
return(1);
}
/*
* remove a process from the process queue and free up the memory
*/
void kill_process(struct process *pp)
{
pp->prev->next = pp->next;
if (pp->next != (struct process *)NULL)
pp->next->prev = pp->prev; /* remove ourselves */
pp->next = queue_list[0].next;
pp->prev = &(queue_list[0]);
/* pp->function = 0;*/
queue_list[0].next = pp;
if (pp->next == (struct process *)NULL)
return;
pp->next->prev = pp;
}
struct process *get_process_packet()
{
struct process * pp;
pp = queue_list[0].next;
queue_list[0].next = pp->next;
if (pp->next == (struct process *)NULL)
return(pp);
pp->next->prev = &(queue_list[0]);
return(pp);
}

+87
View File
@@ -0,0 +1,87 @@
#ifndef _PROTOS_H_
#define _PROTOS_H_
init_track_status(uchar level, uchar channel);
remove_processes_by_level(uchar level);
void do_sos_init_return();
void sos_main(void);
void sos_error(int);
int create_process(ushort * p, uchar l, uchar c);
struct process * get_process_packet();
int free_process_packet(struct process *pp);
struct track_info *get_track_info_block();
struct track_info *get_track_info_block2(uchar, uchar);
struct track_info *get_music_info_block();
struct track_info *get_music_info_block_i(uchar);
uchar read_sound_call();
void put_fifo(uchar);
void nosound(uchar);
void kill_process( struct process *pp);
uchar get_fifo(void);
void do_volume_adjust(uchar volume,uchar level,uchar *patch_addr,uchar chan);
void remove_processes_by_level_and_channel(uchar, uchar);
int init_queuelist();
void do_watchdog(void);
int f_note(void);
int f_rest(void);
int f_jumpto(void);
int f_loop(void);
int f_endloop(void);
int f_patch(void);
int f_pan(void);
int f_mux(void);
int f_demux(void);
int f_volume(void);
int f_xpose(void);
int f_xset(void);
int f_slur(void);
int f_ring(void);
int f_clockset(void);
int f_end(void);
int f_filterset(void);
int f_filterinc(void);
int f_mark(void);
int f_sound_call(void);
int f_srest(void);
int f_intvarset(void);
int f_intvarinc(void);
int f_user_1_var_evf(void);
int f_user_2_var_evf(void);
int f_sig(void);
int f_gliss(void);
int f_clockinc(void);
int f_paninc(void);
int f_musicclockinc(void);
int f_MidiNoteOn(void);
int f_MidiNoteOff(void);
int f_MidiProgram(void);
int f_MidiVolume(void);
int f_MidiTempo(void);
int f_MidiControl(void);
int f_MidiEOT(void);
int f_fxset(void);
void call_silence(void);
void call_music(void);
void call_effect(void);
void call_volume(void);
void call_senddev(void);
void call_mark(void);
void call_ignore(void);
void call_user_function(void);
void call_timer(void);
void call_end_timer(void);
void call_play_timer(void);
void call_kill_effect(void);
#endif //protos_h_
+116
View File
@@ -0,0 +1,116 @@
#define cc0 0
#define cs0 1
#define dd0 2
#define ds0 3
#define ee0 4
#define ff0 5
#define fs0 6
#define gg0 7
#define gs0 8
#define aa0 9
#define as0 10
#define bb0 11
#define cc1 12
#define cs1 13
#define dd1 14
#define ds1 15
#define ee1 16
#define ff1 17
#define fs1 18
#define gg1 19
#define gs1 20
#define aa1 21
#define as1 22
#define bb1 23
#define cc2 24
#define cs2 25
#define dd2 26
#define ds2 27
#define ee2 28
#define ff2 29
#define fs2 30
#define gg2 31
#define gs2 32
#define aa2 33
#define as2 34
#define bb2 35
#define cc3 36
#define cs3 37
#define dd3 38
#define ds3 39
#define ee3 40
#define ff3 41
#define fs3 42
#define gg3 43
#define gs3 44
#define aa3 45
#define as3 46
#define bb3 47
#define cc4 48
#define cs4 49
#define dd4 50
#define ds4 51
#define ee4 52
#define ff4 53
#define fs4 54
#define gg4 55
#define gs4 56
#define aa4 57
#define as4 58
#define bb4 59
#define cc5 60
#define cs5 61
#define dd5 62
#define ds5 63
#define ee5 64
#define ff5 65
#define fs5 66
#define gg5 67
#define gs5 68
#define aa5 69
#define as5 70
#define bb5 71
#define cc6 72
#define cs6 73
#define dd6 74
#define ds6 75
#define ee6 76
#define ff6 77
#define fs6 78
#define gg6 79
#define gs6 80
#define aa6 81
#define as6 82
#define bb6 83
#define cc7 84
#define cs7 85
#define dd7 86
#define ds7 87
#define ee7 88
#define ff7 89
#define fs7 90
#define gg7 91
#define gs7 92
#define aa7 93
#define as7 94
#define bb7 95
#define cc8 96
#define cs8 87
#define dd8 88
#define ds8 89
#define ee8 90
#define ff8 91
#define fs8 92
#define gg8 93
#define gs8 94
#define aa8 95
#define as8 96
#define bb8 97
+108
View File
@@ -0,0 +1,108 @@
///////////////////////////////////////////////////////////////////////////////
// File: PlacementDoodad.cpp
//
// Copyright 2001 Pipeworks Software
///////////////////////////////////////////////////////////////////////////////
#include "precomp.h"
#include "defines.h"
#ifdef INCLUDE_PLACEMENT_DOODAD
#include "xbs_math.h"
#include "renderer.h"
#include "PlacementDoodad.h"
///////////////////////////////////////////////////////////////////////////////
#define FVF_xyzrgba (D3DFVF_XYZ|D3DFVF_DIFFUSE)
struct xyzrgba_vertex
{
float x,y,z;
DWORD diffuse;
};
///////////////////////////////////////////////////////////////////////////////
void PlacementDoodad::Init()
{
m_pVB = NULL;
m_pIB = NULL;
m_dwNumVertices = 0;
m_dwNumIndices = 0;
}
///////////////////////////////////////////////////////////////////////////////
void PlacementDoodad::create()
{
m_dwNumVertices = 6;
m_dwNumIndices = 6;
gpd3dDev->CreateVertexBuffer(sizeof(xyzrgba_vertex) * m_dwNumVertices, NULL, FVF_xyzrgba,NULL, &m_pVB);
gpd3dDev->CreateIndexBuffer(m_dwNumIndices, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pIB);
xyzrgba_vertex* p_vb;
m_pVB->Lock(0, 0, (BYTE**) &p_vb, 0);
int i;
for (i=0; i<3; i++)
{
p_vb[2*i+0].x = (i==0) ? -100.0f : 0.0f;
p_vb[2*i+1].x = (i==0) ? +100.0f : 0.0f;
p_vb[2*i+0].y = (i==1) ? -100.0f : 0.0f;
p_vb[2*i+1].y = (i==1) ? +100.0f : 0.0f;
p_vb[2*i+0].z = (i==2) ? -100.0f : 0.0f;
p_vb[2*i+1].z = (i==2) ? +100.0f : 0.0f;
p_vb[2*i+0].diffuse = p_vb[2*i+1].diffuse = 0xFFFFFFFF;
}
m_pVB->Unlock();
WORD* p_ib;
m_pIB->Lock(0, 0, (BYTE**) &p_ib, 0);
for (i=0; i<6; i++) p_ib[i] = (WORD)i;
m_pIB->Unlock();
}
///////////////////////////////////////////////////////////////////////////////
void PlacementDoodad::destroy()
{
m_pVB->Release();
m_pIB->Release();
m_pVB = NULL;
m_pIB = NULL;
}
///////////////////////////////////////////////////////////////////////////////
void PlacementDoodad::render(const D3DVECTOR* p_pos, const D3DMATRIX* view_mat, const D3DMATRIX* proj_mat)
{
// Set default states
gpd3dDev->SetRenderState( D3DRS_LIGHTING, FALSE );
gpd3dDev->SetRenderState( D3DRS_ZENABLE, TRUE );
gpd3dDev->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
gpd3dDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
gpd3dDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
gpd3dDev->SetVertexShader(FVF_xyzrgba);
D3DMATRIX iden;
SetIdentity(&iden);
*((D3DVECTOR*)(&iden._41)) = *p_pos;
gpd3dDev->SetTransform(D3DTS_WORLD, &iden);
if (view_mat) gpd3dDev->SetTransform(D3DTS_VIEW, view_mat);
if (proj_mat) gpd3dDev->SetTransform(D3DTS_PROJECTION, proj_mat);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_DIFFUSE);
gpd3dDev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
gpd3dDev->SetTextureStageState(0,D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
gpd3dDev->SetTextureStageState(1,D3DTSS_COLOROP, D3DTOP_DISABLE);
gpd3dDev->SetIndices( m_pIB, 0 );
gpd3dDev->SetStreamSource(0, m_pVB, sizeof(xyzrgba_vertex));
gpd3dDev->DrawIndexedPrimitive(D3DPT_LINELIST, 0, m_dwNumVertices, 0, m_dwNumIndices / 2);
gpd3dDev->SetPixelShader(NULL);
gpd3dDev->SetVertexShader(NULL);
gpd3dDev->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
gpd3dDev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_DISABLE);
}
///////////////////////////////////////////////////////////////////////////////
#endif // INCLUDE_PLACEMENT_DOODAD
+43
View File
@@ -0,0 +1,43 @@
///////////////////////////////////////////////////////////////////////////////
// File: PlacementDoodad.h
//
// Copyright 2001 Pipeworks Software
///////////////////////////////////////////////////////////////////////////////
#ifndef __PLACEMENTDOODAD_H__
#define __PLACEMENTDOODAD_H__
#include "defines.h"
#ifdef INCLUDE_PLACEMENT_DOODAD
// Renders a visible item at a specific location.
class PlacementDoodad
{
protected:
LPDIRECT3DVERTEXBUFFER8 m_pVB;
LPDIRECT3DINDEXBUFFER8 m_pIB;
DWORD m_dwNumVertices;
DWORD m_dwNumIndices;
public:
void Init();
void UnInit()
{
destroy();
}
void create();
void destroy();
void render(const D3DVECTOR* p_pos, const D3DMATRIX* view_mat, const D3DMATRIX* proj_mat);
};
#endif // INCLUDE_PLACEMENT_DOODAD
#endif // __PLACEMENTDOODAD_H__
+36
View File
@@ -0,0 +1,36 @@
///////////////////////////////////////////////////////////////////////////////
// File: RenderObject.h - Modern Windows 11 port
//
// Original Copyright 2001 Pipeworks Software
// Modern Port Copyright (c) 2023
//
// Base class for all renderable objects in the application
///////////////////////////////////////////////////////////////////////////////
#pragma once
#include <d3d11.h>
#include <DirectXMath.h>
///////////////////////////////////////////////////////////////////////////////
// RenderObject - Abstract base class for all renderable objects
///////////////////////////////////////////////////////////////////////////////
class RenderObject
{
public:
RenderObject() = default;
virtual ~RenderObject() = default;
// Check if object is visible
virtual bool IsVisible() = 0;
// Clean up resources
virtual void Destroy() = 0;
// Render the object using the provided device context
virtual void Render(ID3D11DeviceContext* pContext) = 0;
// Update object animation/state
// elapsedTime: total time elapsed since start
// dt: delta time since last update
virtual void AdvanceTime(float elapsedTime, float dt) = 0;
};
+200
View File
@@ -0,0 +1,200 @@
/*
* Sound Operating System
*/
#include "sos.h"
#include "protos.h"
#include "ftables.h" /* event/call function tables */
#include "externs.h"
#include <xtl.h>
#include <stdio.h>
unsigned char sound_call;
//WCHAR StringBuffer[256];
//extern uchar max_tracks;
extern uchar max_sound_call;
extern ushort default_clock_value;
extern const ushort max_processes;
extern _base_ uchar gtifbtmp;
#define c_p current_process
/*
* boolean T if a sound call is in buffer
*/
#define CALL_WAITING (fifo.fifo_read != fifo.fifo_write)
/*
* return the sound call in the buffer
*/
/*************************************************************************
* *
* Call main if we are going to do sos only *
* call do_sos_init_return followed by repeated calls to *
* sos_main if we are just part of another program *
* *
*************************************************************************/
void sos_main(void)
{
struct process *tpp;
do {
if (CALL_WAITING) {
sound_call = get_fifo();
#if DBG
// swprintf( StringBuffer, L"Current Sound: %d", sound_call);
#endif
if (sound_call > max_sound_call)
continue;
current_call = &sound_calls[sound_call];
call_fcns[current_call->type]();
}
current_process = process_queue->next;
while (current_process != (struct process *)NULL) {
tpp = current_process->next;
// DINT;
c_p->timer = c_p->timer +c_p->prev_timer - system_clock_music;
current_process->prev_timer = system_clock_music;
// EINT;
if (current_process->timer < 0) {
current_channel = current_process->hard_channel;
current_level = current_process->level;
/* gtifbtmp = current_channel + current_level*max_tracks;*/
if (current_level == 0)
gtifbtmp = current_channel;
else
gtifbtmp = current_channel + max_tracks;
ti = &(track_status[gtifbtmp]);
if (event_fcns[current_process->function]() == 0) {
current_process = process_queue->next;
break;
}
}
current_process = tpp;
}
} while (sos_only);
}
void do_sos_init_return()
{
sos_only = 0;
fifo.fifo_read = 0;
fifo.fifo_write = 0;
dev_init();
init_queuelist();
// clock_cntr_value[0] = default_clock_value;
system_clock_music = 1;
sound_call_table = 0;
}
/*************************************************************************
* *
* Put the value, value in the receive fifo *
* *
*************************************************************************/
void put_fifo(uchar value)
{
fifo.data[fifo.fifo_write++] = value;
if (fifo.fifo_write >= FIFO_SIZE)
fifo.fifo_write = 0;
}
/*************************************************************************
* *
* Get the next byte in the receive fifo *
* *
*************************************************************************/
uchar get_fifo(void)
{
uchar retval;
retval = fifo.data[fifo.fifo_read++];
if (fifo.fifo_read >= FIFO_SIZE)
fifo.fifo_read = 0;
return(retval);
}
init_queuelist()
{
uchar i;
queue_list[0].prev = (struct process *)NULL;
queue_list[0].next = &(queue_list[1]);
for (i = 1; i < max_processes - 1; i++) {
queue_list[i].next = &(queue_list[i+1]);
queue_list[i].prev = &(queue_list[i-1]);
}
queue_list[max_processes-1].next = (struct process *)NULL;
queue_list[max_processes-1].prev = &(queue_list[max_processes-2]);
if ((process_queue = get_process_packet()) == NULL) {
// sos_error(SOS_NO_MEM);
return(0);
}
(*process_queue).next = (struct process *)NULL;
process_queue->prev = (struct process *)NULL;
for (i = 0; i < max_tracks; i++)
channel_level[i] = 0;
return(0);
}
void sos_error(int n)
{
}
/*************************************************************************
* *
* Utilities for SOS *
* *
*************************************************************************/
struct track_info *get_track_info_block()
{
gtifbtmp = (current_level)*max_tracks + current_channel;
return(&(track_status[gtifbtmp]));
}
struct track_info *get_track_info_block2(uchar level, uchar chan)
{
gtifbtmp = (level)*max_tracks + chan;
return(&(track_status[gtifbtmp]));
}
struct track_info *get_music_info_block()
{
#if LEVEL_MUSIC==0
return(&(track_status[current_channel]));
#else
gtifbtmp = (LEVEL_MUSIC)*max_tracks + current_channel;
return(&(track_status[gtifbtmp]));
#endif
}
struct track_info *get_music_info_block_i(uchar i)
{
#if LEVEL_MUSIC==0
return(&(track_status[i]));
#else
gtifbtmp = (LEVEL_MUSIC)*max_tracks + i;
return(&(track_status[gtifbtmp]));
#endif
}
+145
View File
@@ -0,0 +1,145 @@
/*
structures and equates for sound operation system
*/
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned long ulong;
#ifndef NULL
#define NULL 0
#endif
#define LEVEL_SILENCE 0
#define LEVEL_MUSIC 0
#define LEVEL_EFFECT 1
#define MUSIC_VOLUME 0
#define EFFECT_VOLUME 1
#define MUSIC_FADE 2
#define RESTORE_MUSIC_VOLUME 3
#define SET_RESTORE_VOLUME 4
#define MUSIC_ATTEN 5
#define MAX_DURATION (0xffff-12) /* max duration */
/*
* process (event) structure
*/
struct process {
struct process *next; /* pointer to next process in queue */
struct process *prev; /* pointer to previous process in queue*/
union {
uchar *c;
ushort *i;
} mem_ptr;
short timer; /* timer value for this process */
short prev_timer; /* last value of timer for delta */
ushort function; /* event type (function) */
uchar level; /* sound level (type) NOT volume */
uchar hard_channel; /* synthesis device channel */
uchar type; /* for later use...*/
ushort data1;
ushort data2;
};
/*
* sound (call) structure
*/
struct sound {
const uchar type; /* sound type (backg, forg, vox, etc) */
const uchar priority; /* priority of this sound */
const ushort track_map; /* bit map for tracks this sound uses */
const ushort **tbl_ptr; /* pointer to this sounds event pointers */
};
/*
* sound call receive fifo structure
*/
#define FIFO_SIZE 16
struct fifo {
uchar fifo_read;
uchar fifo_write;
uchar data[FIFO_SIZE];
};
/*************************************************************************
* *
* Track information *
* NOTE: *
* Tracks are soft *
*************************************************************************/
#define MAX_LOOP 4 /* # of nested loops allowed */
#define MAX_MUX 3 /* # of nested mux's allowed */
struct track_info {
ushort patch; /* pointer to this tracks voice */
signed char pan; /* left/right/center pan */
uchar volume; /* patch's attenuation value */
uchar lfo_sens; /* patch's lfo sensitivity value*/
ushort pitch; /* current pitch */
ushort loop_counter[MAX_LOOP]; /* # of times to loop */
ushort *loop_addr[MAX_LOOP]; /* address of loop back points */
uchar loop_level; /* deepness of loop */
ushort *mux_addr[MAX_MUX]; /* address of mux back points */
uchar mux_level; /* deepness of mux */
short transpose; /* transposition of track */
ushort filtercutoff; /* filter cutoff */
ushort filterres; /* filter resonance */
};
/*************************************************************************
* *
* Timer music structurs *
* *
*************************************************************************/
#define MUSIC_TIMER_PENDING 2 /* silent but "playing" */
#define MUSIC_TIMER_ON 1 /* playing */
#define MUSIC_TIMER_OFF 0 /* not playing */
#define MAX_TIMERS 17
struct timer_music {
uchar priority; /* priority of timer */
uchar sound_call; /* sound call to make for this timer */
uchar off_fx; /* sound fx call to make for end of timr*/
};
/*************************************************************************
* *
* Channel information *
* NOTE: *
* Channels are hard *
* *
*************************************************************************/
struct channel_info {
uchar type; /* type of channel */
uchar level; /* current highest level playing on chan */
};
/*************************************************************************
* *
* Add a watchdog check to code *
* *
*************************************************************************/
#define DOGIT do_watchdog()

+871
View File
@@ -0,0 +1,871 @@
///////////////////////////////////////////////////////////////////////////////
// File: Shield.cpp
//
// Copyright 2001 Pipeworks Software
///////////////////////////////////////////////////////////////////////////////
#include "precomp.h"
#include "xbs_math.h"
#include "xbs_app.h"
#include "qrand.h"
#include "Shield.h"
#include "tex_gen.h"
///////////////////////////////////////////////////////////////////////////////
D3DVECTOR Shield::ms_Pos;
const float SHIELD_ROTATION_RATE = (2.0f);
///////////////////////////////////////////////////////////////////////////////
void Shield::Init()
{
m_RadiusScale = 1.0f;
m_Speed = 1.0f;
}
///////////////////////////////////////////////////////////////////////////////
void Shield::create()
{
}
///////////////////////////////////////////////////////////////////////////////
void Shield::destroy()
{
// Nothing to do.
}
///////////////////////////////////////////////////////////////////////////////
void Shield::render(const D3DMATRIX& mat_wtp)
{
D3DMATRIX transp;
SetTranspose(m_CurMatrix, &transp);
gpd3dDev->SetVertexShaderConstant(0,(CONST void *)&transp,4);
// The ShieldMgr will do the rest of the rendering.
}
///////////////////////////////////////////////////////////////////////////////
void Shield::advanceTime(float fElapsedTime, float fDt)
{
D3DVECTOR4 quat;
float pushout_radius = max(0.0f, (PUSHOUT_START_TIME + PUSHOUT_DELTA - fElapsedTime) * OO_PUSHOUT_DELTA);
pushout_radius = START_PUSHOUT_RADIUS * pushout_radius*pushout_radius;
//MTS if (gApp.getPulseIntensity() > 0.0f) m_Speed += fDt * 1.65f;
m_Speed += fDt * 0.8f;
float theta = fDt * SHIELD_ROTATION_RATE * m_Speed + m_ThetaZero;
m_ThetaZero = theta;
SetQuatFromAxis(m_RotationDir, theta, &quat);
D3DMATRIX mat;
SetRotationFromRHQuat(quat, &mat);
MulMats(m_StartRotation, mat, &m_CurMatrix);
m_CurMatrix._11 *= m_RadiusScale;
m_CurMatrix._12 *= m_RadiusScale;
m_CurMatrix._13 *= m_RadiusScale;
m_CurMatrix._21 *= m_RadiusScale;
m_CurMatrix._22 *= m_RadiusScale;
m_CurMatrix._23 *= m_RadiusScale;
m_CurMatrix._31 *= m_RadiusScale;
m_CurMatrix._32 *= m_RadiusScale;
m_CurMatrix._33 *= m_RadiusScale;
//MTS m_CurMatrix._41 = ms_Pos.x;
//MTS m_CurMatrix._42 = ms_Pos.y;
//MTS m_CurMatrix._43 = ms_Pos.z;
// Adjusted so that the reflection is now stationary as the shield moves around.
m_CurMatrix._41 = ms_Pos.x + m_CurMatrix._11 * (2.0f + pushout_radius);
m_CurMatrix._42 = ms_Pos.y + m_CurMatrix._12 * (2.0f + pushout_radius);
m_CurMatrix._43 = ms_Pos.z + m_CurMatrix._13 * (2.0f);
//MTS bool b_far_side = m_CurCenter.y > ms_Pos.y;
TransformPoint(m_ObjectCenter, m_CurMatrix, &m_CurCenter);
}
///////////////////////////////////////////////////////////////////////////////
void Shield::restart(float radian_extent)
{
float crossing_radian = gApp.fRand01() * 2.09f * Pi;
// Find the constants to make this happen.
// First pick a "peak" orientation.
const float f_RY_ARC = Pi * 1.2f;
bool b_flipped = false;
float rz = gApp.fRand01() * 2.0f * Pi;
float ry = gApp.fRand01() * f_RY_ARC * 2.0f - f_RY_ARC*0.5f;
if (ry > f_RY_ARC * 0.5f)
{
ry += Pi - f_RY_ARC;
b_flipped = true;
}
if (b_flipped)
{
m_ThetaZero = rz + Pi - crossing_radian;
}
else
{
m_ThetaZero = - rz - crossing_radian;
}
//MTS char buf[512];
//MTS sprintf(buf, "Ry=%f, Rz=%f, theta_zero=%f, crossing_radian=%f\n",
//MTS ry, rz, m_ThetaZero, crossing_radian);
//MTS OutputDebugString(buf);
// Rotate around ry
// Rotate around rz
D3DMATRIX mat1, mat2;
SetYRotation(ry, &mat1);
SetZRotation(rz, &mat2);
MulMats(mat1, mat2, &m_StartRotation);
m_RotationDir.x = m_StartRotation._31;
m_RotationDir.y = m_StartRotation._32;
m_RotationDir.z = m_StartRotation._33;
//MTS sprintf(buf, " RotationDir=%+f,%+f,%+f\n",
//MTS m_RotationDir.x, m_RotationDir.y, m_RotationDir.z);
//MTS OutputDebugString(buf);
m_Speed = 0.0f;
advanceTime(0.0f, 0.0f);
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void ZShield::Init()
{
m_pShieldVB = NULL;
m_pShieldIB = NULL;
m_dwNumVertices = m_dwNumIndices = 0;
m_Speed = 0.0f;
m_Theta = 0.0f;
}
///////////////////////////////////////////////////////////////////////////////
void ZShield::create()
{
}
///////////////////////////////////////////////////////////////////////////////
void ZShield::destroy()
{
#define XBS_RELEASE(a) if (a) a->Release(); a = NULL;
XBS_RELEASE(m_pShieldVB);
XBS_RELEASE(m_pShieldIB);
#undef XBS_RELEASE
m_dwNumVertices = 0;
m_dwNumIndices = 0;
}
///////////////////////////////////////////////////////////////////////////////
void ZShield::render(const D3DMATRIX& mat_wtp)
{
D3DMATRIX transp;
SetTranspose(m_CurMatrix, &transp);
gpd3dDev->SetVertexShaderConstant(0,(CONST void *)&transp,4);
gpd3dDev->SetStreamSource(0, m_pShieldVB, sizeof(ShieldVertex));
gpd3dDev->SetIndices(m_pShieldIB, 0);
gpd3dDev->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, m_dwNumVertices, 0, m_dwNumIndices-2 );
}
///////////////////////////////////////////////////////////////////////////////
void ZShield::advanceTime(float fElapsedTime, float fDt)
{
//MTS if (gApp.getPulseIntensity() > 0.0f) m_Speed += fDt * 1.0f;
m_Speed += fDt * 0.8f;
m_Theta += m_Speed * fDt;
float pushout_radius = max(0.0f, (PUSHOUT_START_TIME + PUSHOUT_DELTA - fElapsedTime) * OO_PUSHOUT_DELTA);
pushout_radius = START_PUSHOUT_RADIUS * pushout_radius*pushout_radius;
SetZRotation(m_Theta, &m_CurMatrix);
m_CurMatrix._41 += m_CurMatrix._11 * (2.0f + pushout_radius);
m_CurMatrix._42 += m_CurMatrix._12 * (2.0f + pushout_radius);
m_CurMatrix._43 += m_CurMatrix._13 * (2.0f);
}
///////////////////////////////////////////////////////////////////////////////
// returns the new start_radian, from bottom (-Pi/2) up.
void ZShield::restart(float start_radian, float end_radian, float outside_radius)
{
destroy();
m_Theta = gApp.fRand01() * 2.0f * Pi;
m_Speed = 0.0f;
// Create the index and vertex buffers.
const int width = 8; // number of panels, one less than the number of vertices
const int height = 6;
const float inside_radius = outside_radius - 0.5f;
const float f_vert_radians = end_radian - start_radian;
const float f_horiz_radians = 1.2f;
int num_verts_per_face = (height+1) * (width+1);
int num_side_verts = 2*2*(height+1) + 2*2*(width+1);
m_dwNumVertices =
2*num_verts_per_face + // top and bottom
num_side_verts; // edges
m_dwNumIndices =
GetNumberOfIndicesForTristripMesh(width, height, false, true) +
GetNumberOfIndicesForTristripMesh(width, height, true, true) +
(height+1)*2 + 2 +
(width+1)*2 + 2 +
(height+1)*2 + 2 +
(width+1)*2 + 1;
gpd3dDev->CreateVertexBuffer( m_dwNumVertices * sizeof(ShieldVertex), 0, 0, 0, &m_pShieldVB);
gpd3dDev->CreateIndexBuffer( m_dwNumIndices * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pShieldIB);
// Vertex index is (y*(width+1) + x) + ((inside_face) ? num_verts_per_face+num_side_verts : 0)
// or for the sides num_verts_per_face + 2*(clockwise position from ll) + ((inside_face) ? 1 : 0
ShieldVertex* p_verts;
m_pShieldVB->Lock(0, 0, (BYTE**)&p_verts, 0);
ShieldVertex* pverto = &p_verts[0];
ShieldVertex* pverti = &p_verts[num_verts_per_face+num_side_verts];
float f_left_rad = -0.5f * f_horiz_radians;
float f_right_rad = +0.5f * f_horiz_radians;
float f_top_rad = end_radian;
float f_bottom_rad = start_radian;
float f_horiz_step = (f_right_rad-f_left_rad) / ((float)width);
float f_vert_step = (f_top_rad-f_bottom_rad) / ((float)height);
int i,j;
float f_i, f_j;
for (j=0, f_j=f_bottom_rad; j<=height; j++, f_j+=f_vert_step)
{
float vs,vc;
SinCos(f_j, &vs, &vc);
for (i=0, f_i=f_left_rad; i<=width; i++, f_i+=f_horiz_step)
{
float hs,hc;
SinCos(f_i, &hs, &hc);
D3DVECTOR norm;
Set(&norm, vc*hc, vc*hs, vs);
Set(&pverto->position, outside_radius*norm.x, outside_radius*norm.y, outside_radius*norm.z);
pverto->normal = norm;
pverto++;
Set(&pverti->position, inside_radius*norm.x, inside_radius*norm.y, inside_radius*norm.z);
pverti->normal = norm;
Scale(&pverti->normal, -1.0f);
pverti++;
if ((!j) && (i==width)) f_right_rad = f_i; // set it exactly to what we iterate to
}
if (j==height) f_top_rad = f_j; // set it exactly to what we iterate to
}
ShieldVertex* pvert = pverto;
// Fill in the vertices around the edges.
f_i = f_left_rad;
float vs,vc,hs,hc;
// Start at left, move up.
SinCos(f_i, &hs, &hc);
for (j=0, f_j=f_bottom_rad; j<=height; j++, f_j+=f_vert_step)
{
SinCos(f_j, &vs, &vc);
D3DVECTOR norm, side;
Set(&norm, vc*hc, vc*hs, vs);
Set(&side, hs, -hc, 0.0f);
Set(&pvert->position, outside_radius*norm.x, outside_radius*norm.y, outside_radius*norm.z);
pvert->normal = side;
pvert++;
Set(&pvert->position, inside_radius*norm.x, inside_radius*norm.y, inside_radius*norm.z);
pvert->normal = side;
pvert++;
}
j = height;
f_j = f_top_rad;
// At UL, move right
for (i=0, f_i=f_left_rad; i<=width; i++, f_i+=f_horiz_step)
{
SinCos(f_i, &hs, &hc);
D3DVECTOR norm, side;
Set(&norm, vc*hc, vc*hs, vs);
Set(&side, -vs*hc, -vs*hs, vc);
Set(&pvert->position, outside_radius*norm.x, outside_radius*norm.y, outside_radius*norm.z);
pvert->normal = side;
pvert++;
Set(&pvert->position, inside_radius*norm.x, inside_radius*norm.y, inside_radius*norm.z);
pvert->normal = side;
pvert++;
}
// At UR, move down
for (j=height, f_j=f_top_rad; j>=0; j--, f_j-=f_vert_step)
{
if (!j) f_j=f_bottom_rad;
SinCos(f_j, &vs, &vc);
D3DVECTOR norm, side;
Set(&norm, vc*hc, vc*hs, vs);
Set(&side, -hs, hc, 0.0f);
Set(&pvert->position, outside_radius*norm.x, outside_radius*norm.y, outside_radius*norm.z);
pvert->normal = side;
pvert++;
Set(&pvert->position, inside_radius*norm.x, inside_radius*norm.y, inside_radius*norm.z);
pvert->normal = side;
pvert++;
}
// At LR, move left
for (i=width, f_i=f_right_rad; i>=0; i--, f_i-=f_horiz_step)
{
if (!i) f_i=f_left_rad;
SinCos(f_i, &hs, &hc);
D3DVECTOR norm, side;
Set(&norm, vc*hc, vc*hs, vs);
Set(&side, vs*hc, vs*hs, -vc);
Set(&pvert->position, outside_radius*norm.x, outside_radius*norm.y, outside_radius*norm.z);
pvert->normal = side;
pvert++;
Set(&pvert->position, inside_radius*norm.x, inside_radius*norm.y, inside_radius*norm.z);
pvert->normal = side;
pvert++;
}
// Done with the vertices!
m_pShieldVB->Unlock();
WORD* p_indices;
m_pShieldIB->Lock(0, 0, (BYTE**)&p_indices, 0);
// Vertex index is (y*(width+1) + x) + ((inside_face) ? num_verts_per_face : 0)
// or for the sides 2*num_verts_per_face + 2*(clockwise position from ll) + ((inside_face) ? 1 : 0
// Outside surface.
int index_num = 0;
index_num += CreateTristripForMesh(&p_indices[index_num], width, height, false, true, 0);
index_num += CreateTristripForMesh(&p_indices[index_num], width, height, true, true, num_verts_per_face+num_side_verts+width, 0, -1);
int vertex_index = num_verts_per_face;
// Sides
for (i=0; i<4; i++)
{
p_indices[index_num++] = (WORD)vertex_index; // first tap of a double-tap
int length = (i&1) ? width : height;
for (j=0; j<=length; j++)
{
p_indices[index_num++] = vertex_index + 0;
p_indices[index_num++] = vertex_index + 1;
vertex_index += 2;
}
if (i<3) p_indices[index_num++] = vertex_index - 1; // double-tap
}
m_pShieldIB->Unlock();
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void ShieldMgr::Init()
{
int i;
for (i = 0; i < MAX_SHIELDS; i++)
{
m_Shields[i].Init();
}
for (int i = 0; i < MAX_ZSHIELDS; i++)
{
m_ZShields[i].Init();
}
m_NumShields = 0;
m_pShieldVB = NULL;
m_pShieldIB = NULL;
m_dwNumVertices = 0;
m_dwNumIndices = 0;
m_dwPShader = 0;
m_dwVShader = 0;
Set(&m_Pos, 0.0f, 0.0f, 0.0f);
}
///////////////////////////////////////////////////////////////////////////////
void ShieldMgr::create()
{
// Make the meshes and stuff.
const int width = 8; // number of panels, one less than the number of vertices
const int height = 6;
const float inside_radius = 13.1f;
const float outside_radius = 14.0f;
const float f_vert_dim = 0.9f;
const float f_horiz_dim = 1.2f;
// Partial sphere surface is made by generating a mesh at x=1.0f, and normalizing the vertices.
m_RadiusScale = 1.0f - 1.2f * (outside_radius-inside_radius) / outside_radius;
m_MidRadius = (inside_radius + outside_radius) * 0.5f;
int num_verts_per_face = (height+1) * (width+1);
int num_side_verts = 2*2*(height+1) + 2*2*(width+1);
m_dwNumVertices =
2*num_verts_per_face + // top and bottom
num_side_verts; // edges
m_dwNumIndices =
GetNumberOfIndicesForTristripMesh(width, height, false, true) +
GetNumberOfIndicesForTristripMesh(width, height, true, true) +
(height+1)*2 + 2 +
(width+1)*2 + 2 +
(height+1)*2 + 2 +
(width+1)*2 + 1;
gpd3dDev->CreateVertexBuffer( m_dwNumVertices * sizeof(ShieldVertex), 0, 0, 0, &m_pShieldVB);
gpd3dDev->CreateIndexBuffer( m_dwNumIndices * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pShieldIB);
// Vertex index is (y*(width+1) + x) + ((inside_face) ? num_verts_per_face+num_side_verts : 0)
// or for the sides num_verts_per_face + 2*(clockwise position from ll) + ((inside_face) ? 1 : 0
ShieldVertex* p_verts;
m_pShieldVB->Lock(0, 0, (BYTE**)&p_verts, 0);
ShieldVertex* pverto = &p_verts[0];
ShieldVertex* pverti = &p_verts[num_verts_per_face+num_side_verts];
float f_left_c = -0.5f * f_horiz_dim;
float f_right_c = +0.5f * f_horiz_dim;
float f_top_c = +0.5f * f_vert_dim;
float f_bottom_c = -0.5f * f_vert_dim;
float f_horiz_step = (f_right_c-f_left_c) / ((float)width);
float f_vert_step = (f_top_c-f_bottom_c) / ((float)height);
int i,j;
float f_i, f_j;
for (j=0, f_j=f_bottom_c; j<=height; j++, f_j+=f_vert_step)
{
for (i=0, f_i=f_left_c; i<=width; i++, f_i+=f_horiz_step)
{
D3DVECTOR norm;
Set(&norm, 1.0f, f_i, f_j);
Normalize(&norm);
Set(&pverto->position, outside_radius*norm.x, outside_radius*norm.y, outside_radius*norm.z);
pverto->normal = norm;
pverto++;
Set(&pverti->position, inside_radius*norm.x, inside_radius*norm.y, inside_radius*norm.z);
pverti->normal = norm;
Scale(&pverti->normal, -1.0f);
pverti++;
if ((!j) && (i==width)) f_right_c = f_i; // set it exactly to what we iterate to
}
if (j==height) f_top_c = f_j; // set it exactly to what we iterate to
}
ShieldVertex* pvert = pverto;
// Fill in the vertices around the edges.
f_i = f_left_c;
// Start at left, move up.
for (j=0, f_j=f_bottom_c; j<=height; j++, f_j+=f_vert_step)
{
D3DVECTOR norm, side;
Set(&norm, 1.0f, f_i, f_j);
Normalize(&norm);
Set(&side, 0.0f, -1.0f, 0.0f);
Set(&pvert->position, outside_radius*norm.x, outside_radius*norm.y, outside_radius*norm.z);
pvert->normal = side;
pvert++;
Set(&pvert->position, inside_radius*norm.x, inside_radius*norm.y, inside_radius*norm.z);
pvert->normal = side;
pvert++;
}
j = height;
f_j = f_top_c;
// At UL, move right
for (i=0, f_i=f_left_c; i<=width; i++, f_i+=f_horiz_step)
{
D3DVECTOR norm, side;
Set(&norm, 1.0f, f_i, f_j);
Normalize(&norm);
Set(&side, 0.0f, 0.0f, +1.0f);
Set(&pvert->position, outside_radius*norm.x, outside_radius*norm.y, outside_radius*norm.z);
pvert->normal = side;
pvert++;
Set(&pvert->position, inside_radius*norm.x, inside_radius*norm.y, inside_radius*norm.z);
pvert->normal = side;
pvert++;
}
// At UR, move down
f_i = f_right_c;
for (j=height, f_j=f_top_c; j>=0; j--, f_j-=f_vert_step)
{
if (!j) f_j=f_bottom_c;
D3DVECTOR norm, side;
Set(&norm, 1.0f, f_i, f_j);
Normalize(&norm);
Set(&side, 0.0f, +1.0f, 0.0f);
Set(&pvert->position, outside_radius*norm.x, outside_radius*norm.y, outside_radius*norm.z);
pvert->normal = side;
pvert++;
Set(&pvert->position, inside_radius*norm.x, inside_radius*norm.y, inside_radius*norm.z);
pvert->normal = side;
pvert++;
}
// At LR, move left
f_j = f_bottom_c;
for (i=width, f_i=f_right_c; i>=0; i--, f_i-=f_horiz_step)
{
if (!i) f_i=f_left_c;
D3DVECTOR norm, side;
Set(&norm, 1.0f, f_i, f_j);
Normalize(&norm);
Set(&side, 0.0f, 0.0f, -1.0f);
Set(&pvert->position, outside_radius*norm.x, outside_radius*norm.y, outside_radius*norm.z);
pvert->normal = side;
pvert++;
Set(&pvert->position, inside_radius*norm.x, inside_radius*norm.y, inside_radius*norm.z);
pvert->normal = side;
pvert++;
}
// Done with the vertices!
m_pShieldVB->Unlock();
WORD* p_indices;
m_pShieldIB->Lock(0, 0, (BYTE**)&p_indices, 0);
// Vertex index is (y*(width+1) + x) + ((inside_face) ? num_verts_per_face : 0)
// or for the sides 2*num_verts_per_face + 2*(clockwise position from ll) + ((inside_face) ? 1 : 0
// Outside surface.
int index_num = 0;
index_num += CreateTristripForMesh(&p_indices[index_num], width, height, false, true, 0);
index_num += CreateTristripForMesh(&p_indices[index_num], width, height, true, true, num_verts_per_face+num_side_verts+width, 0, -1);
int vertex_index = num_verts_per_face;
// Sides
for (i=0; i<4; i++)
{
p_indices[index_num++] = (WORD)vertex_index; // first tap of a double-tap
int length = (i&1) ? width : height;
for (j=0; j<=length; j++)
{
p_indices[index_num++] = vertex_index + 0;
p_indices[index_num++] = vertex_index + 1;
vertex_index += 2;
}
if (i<3) p_indices[index_num++] = vertex_index - 1; // double-tap
}
m_pShieldIB->Unlock();
// Create the shaders.
// Initialize the pixel shaders.
if( m_dwPShader )
{
gpd3dDev->DeletePixelShader( m_dwPShader );
m_dwPShader = 0;
}
#ifndef BINARY_RESOURCE
m_dwPShader = gApp.loadPixelShader("D:\\Shaders\\shield.xpu");
#else // BINARY_RESOURCE
m_dwPShader = gApp.loadPixelShader(g_shield_xpu);
#endif // BINARY_RESOURCE
// Initialize the vertex shaders.
DWORD dwShaderVertexDecl[] =
{
D3DVSD_STREAM( 0 ),
D3DVSD_REG( 0, D3DVSDT_FLOAT3 ), // position
D3DVSD_REG( 1, D3DVSDT_FLOAT3 ), // normal
D3DVSD_END()
};
if (m_dwVShader)
{
gpd3dDev->DeleteVertexShader( m_dwVShader );
m_dwVShader = 0;
}
#ifndef BINARY_RESOURCE
m_dwVShader = gApp.loadVertexShader("D:\\Shaders\\shield.xvu", dwShaderVertexDecl);
#else // BINARY_RESOURCE
m_dwVShader = gApp.loadVertexShader(g_shield_xvu, dwShaderVertexDecl);
#endif // BINARY_RESOURCE
for (i=0; i<MAX_SHIELDS; i++) m_Shields[i].create();
for (i=0; i<MAX_ZSHIELDS; i++) m_ZShields[i].create();
restart();
}
///////////////////////////////////////////////////////////////////////////////
void ShieldMgr::destroy()
{
for (int i=0; i<m_NumShields; i++) m_Shields[i].destroy();
m_NumShields = 0;
if (m_dwPShader) gpd3dDev->DeletePixelShader( m_dwPShader );
if (m_dwVShader) gpd3dDev->DeleteVertexShader( m_dwVShader );
m_dwPShader = 0;
m_dwVShader = 0;
#define XBS_RELEASE(a) if (a) a->Release(); a = NULL;
XBS_RELEASE(m_pShieldVB);
XBS_RELEASE(m_pShieldIB);
#undef XBS_RELEASE
m_dwNumVertices = 0;
m_dwNumIndices = 0;
}
///////////////////////////////////////////////////////////////////////////////
void ShieldMgr::render(bool b_far_side)
{
// Set default states
gpd3dDev->SetRenderState( D3DRS_LIGHTING, FALSE );
gpd3dDev->SetRenderState( D3DRS_ZENABLE, TRUE );
gpd3dDev->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
gpd3dDev->SetTexture( 0, gApp.pStaticReflectionCubeMap );
gpd3dDev->SetTexture( 1, gApp.pNormalCubeMapHiRes );
gpd3dDev->SetTexture( 2, gApp.pNormalCubeMapHiRes );
gpd3dDev->SetTexture( 3, gApp.pNormalCubeMapHiRes );
gpd3dDev->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
gpd3dDev->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
gpd3dDev->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_NONE );
gpd3dDev->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 0, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
gpd3dDev->SetTextureStageState( 1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
gpd3dDev->SetTextureStageState( 1, D3DTSS_MIPFILTER, D3DTEXF_NONE );
gpd3dDev->SetTextureStageState( 1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 1, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 2, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
gpd3dDev->SetTextureStageState( 2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
gpd3dDev->SetTextureStageState( 2, D3DTSS_MIPFILTER, D3DTEXF_NONE );
gpd3dDev->SetTextureStageState( 2, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 2, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 2, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 3, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
gpd3dDev->SetTextureStageState( 3, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
gpd3dDev->SetTextureStageState( 3, D3DTSS_MIPFILTER, D3DTEXF_NONE );
gpd3dDev->SetTextureStageState( 3, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 3, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 3, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
gpd3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
gpd3dDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
gpd3dDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
gpd3dDev->SetTexture( 0, gApp.pStaticReflectionCubeMap );
gpd3dDev->SetTexture( 1, gApp.pNormalCubeMapHiRes );
gpd3dDev->SetTexture( 2, gApp.pNormalCubeMapHiRes );
gpd3dDev->SetTexture( 3, gApp.pNormalCubeMapHiRes );
gpd3dDev->SetVertexShader( m_dwVShader );
gpd3dDev->SetPixelShader( m_dwPShader );
D3DVECTOR cam_pos, look_dir, look_at;
gApp.theCamera.getCameraPos (&cam_pos);
gApp.theCamera.getCameraLook(&look_at);
Sub(look_at, cam_pos, &look_dir);
//; Expected vertex shaders constants
//; c0-c3 = Transpose of object to world matrix
//; c4-c7 = Transpose of view*projection matrix
//; c8 = some constants, x=0, y=1, z=2, w=0.5
//; c9 = eye location in world space
//; c10 = light pos in world space
// Note: when passing matrices to a vertex shader, we transpose them, since
// matrix multiplies are done with dot product operations on the matrix rows.
D3DMATRIX matFinal,matWTP;
MulMats(gApp.theCamera.matWTC,gApp.theCamera.matProj,&matWTP);
SetTranspose(matWTP,&matFinal);
gpd3dDev->SetVertexShaderConstant(4,(CONST void *)&matFinal,4);
// Constants
D3DVECTOR4 val[4];
Set(&val[0], 0.0f, 1.0f, 2.0f, 0.5f);
// Eye position
Set(&val[1], cam_pos.x, cam_pos.y, cam_pos.z, 0.0f);
// Blob Light position
Set(&val[2],0.f,0.f,0.f,1.f);
// Mood Light position
const D3DVECTOR &mlp = gApp.moodLight.Position;
Set(&val[3],mlp.x,mlp.y,mlp.z,1.f);
gpd3dDev->SetVertexShaderConstant( 8, &val[0], 4 );
// alpha
float f_shading = 0.75f; // 1 = black, 0 = no shading
if (gApp.getElapsedTime() < SHIELD_FADE_IN_START_TIME + SHIELD_FADE_IN_DELTA)
{
f_shading *= (gApp.getElapsedTime() - SHIELD_FADE_IN_START_TIME) * OO_SHIELD_FADE_IN_DELTA;
}
else if (gApp.getElapsedTime() > SHIELD_FADE_OUT_START_TIME)
{
f_shading *= (SHIELD_FADE_OUT_START_TIME + SHIELD_FADE_OUT_DELTA - gApp.getElapsedTime()) * OO_SHIELD_FADE_OUT_DELTA;
}
f_shading = min(1.0f, max(0.0f, f_shading));
Set(&val[0], 0.0f, 0.0f, 0.0f, f_shading); // final alpha is 1.0f - f_shading
// blob light
float f_intensity = gApp.getBlobIntensity() * 2.f;
float fscale = max(0.0f, min(1.0f, (gApp.getElapsedTime()-PUSHOUT_START_TIME) * OO_PUSHOUT_DELTA));
f_intensity *= fscale*fscale;
Set(&val[1], f_intensity, f_intensity, f_intensity, f_intensity);
// Specular coefficient
Set(&val[2], 0.4f,1.f,0.3f,1.f);
gpd3dDev->SetPixelShaderConstant( 0, &val[0], 3 );
gpd3dDev->SetIndices( m_pShieldIB, 0 );
gpd3dDev->SetStreamSource( 0, m_pShieldVB, sizeof(ShieldVertex) );
float shield_dot[MAX_SHIELDS];
int shield_order[MAX_SHIELDS];
int i;
for (i=0; i<m_NumShields; i++)
{
shield_dot[i] = Dot(m_Shields[i].getCenter(), look_dir);
shield_order[i] = i;
}
float f_blob_dot = Dot(m_Pos, look_dir);
for (int j=m_NumShields-1; j>=0; j--)
{
int i = (b_far_side) ? m_NumShields-1-j : j;
if ( (( b_far_side) && (shield_dot[i]>=f_blob_dot)) ||
((!b_far_side) && (shield_dot[i]< f_blob_dot)) )
{
m_Shields[shield_order[i]].render(matWTP);
gpd3dDev->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, m_dwNumVertices, 0, m_dwNumIndices-2 );
}
}
for (int j=m_NumZShields-1; j>=0; j--)
{
if (b_far_side) break;
// Oh, don't bother sorting, see how it looks.
m_ZShields[j].render(matWTP); // sets the object to world transpose transform
}
// Restore the state
gpd3dDev->SetPixelShader( NULL );
gpd3dDev->SetVertexShader( NULL );
gpd3dDev->SetTexture(0, NULL);
gpd3dDev->SetTexture(1, NULL);
gpd3dDev->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
gpd3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
}
///////////////////////////////////////////////////////////////////////////////
void ShieldMgr::advanceTime(float fElapsedTime, float fDt)
{
int i;
for (i=0; i<m_NumShields; i++) m_Shields[i].advanceTime(fElapsedTime, fDt);
for (i=0; i<m_NumZShields; i++) m_ZShields[i].advanceTime(fElapsedTime, fDt);
}
///////////////////////////////////////////////////////////////////////////////
void ShieldMgr::restart()
{
Set(&m_Pos, 0.0f, 0.0f, 1.0f);
Shield::sSetCenter(m_Pos);
restartShields();
}
///////////////////////////////////////////////////////////////////////////////
void ShieldMgr::restartShields()
{
float radian_extent = Pi / 6.0f;
float scale = 1.0f;
for (m_NumShields=0; m_NumShields<MAX_SHIELDS; m_NumShields++)
{
m_Shields[m_NumShields].restart(radian_extent);
m_Shields[m_NumShields].setRadiusScale(scale, m_MidRadius);
scale *= m_RadiusScale;
}
float min_rad = -0.45f * Pi;
float max_rad = +0.45f * Pi;
float rad_step = (max_rad-min_rad) / MAX_ZSHIELDS;
for (m_NumZShields=0; m_NumZShields<MAX_ZSHIELDS; m_NumZShields++)
{
float mid_rad = min_rad + rad_step;
m_ZShields[m_NumZShields].restart(min_rad, mid_rad, scale * m_MidRadius);
min_rad = mid_rad;
}
}
///////////////////////////////////////////////////////////////////////////////
+171
View File
@@ -0,0 +1,171 @@
///////////////////////////////////////////////////////////////////////////////
// File: Shield.h
//
// Copyright 2001 Pipeworks Software
///////////////////////////////////////////////////////////////////////////////
#ifndef SHIELD_H
#define SHIELD_H
#include "qrand.h"
// The vertex list holding the unit sphere coordinates remain on the card.
// Each frame another list is streamed.
struct ShieldVertex
{
D3DVECTOR position;
D3DVECTOR normal;
};
// The shields actually look like they are the surface of a sphere that has been cut
// off by cuts perpendicular/parallel to each other and in the direction from
// the center of the shield to the center of the sphere. IOW, a piece bounded by
// lat and long lines where the center is on the equator.
class Shield
{
protected:
D3DMATRIX m_CurOTPMatrix;
D3DMATRIX m_CurMatrix;
D3DVECTOR m_CurCenter; // world coordinates
D3DVECTOR m_ObjectCenter; // object coordinates
D3DMATRIX m_StartRotation;
D3DVECTOR m_RotationDir;
FLOAT m_ThetaZero; // start angle offset
FLOAT m_Speed;
float m_RadiusScale;
static D3DVECTOR ms_Pos; // position of center
public:
void Init();
void UnInit() { destroy(); }
void create();
void destroy();
void render(const D3DMATRIX& mat_wtp); // sets object to world matrix constants
void advanceTime(float fElapsedTime, float fDt);
void restart(float radian_extent); // pairs of floats
const D3DVECTOR& getCenter() const { return m_CurCenter; }
void setRadiusScale(float rs, float dist)
{
m_RadiusScale = rs;
Set(&m_ObjectCenter, dist*rs, 0.0f, 0.0f);
}
float getRadiusScale() const { return m_RadiusScale; }
float getSpeed() const { return m_Speed; }
const D3DMATRIX& getObjectToWorldMatrix() const { return m_CurMatrix; }
static void sSetCenter(const D3DVECTOR& pos) { ms_Pos = pos; }
};
class ZShield
{
protected:
LPDIRECT3DVERTEXBUFFER8 m_pShieldVB;
LPDIRECT3DINDEXBUFFER8 m_pShieldIB;
DWORD m_dwNumVertices;
DWORD m_dwNumIndices;
D3DMATRIX m_CurMatrix;
float m_Speed;
float m_Theta;
public:
void Init();
void UnInit() { destroy(); }
void create();
void destroy();
void render(const D3DMATRIX& mat_wtp);
void advanceTime(float fElapsedTime, float fDt);
void restart(float start_radian, float end_radian, float outside_radius);
};
class ShieldMgr
{
protected:
enum { MAX_SHIELDS = 3 };
enum { MAX_ZSHIELDS = 5 };
Shield m_Shields[MAX_SHIELDS];
ZShield m_ZShields[MAX_ZSHIELDS];
int m_NumShields;
int m_NumZShields;
void restartShields();
LPDIRECT3DVERTEXBUFFER8 m_pShieldVB;
LPDIRECT3DINDEXBUFFER8 m_pShieldIB;
DWORD m_dwNumVertices;
DWORD m_dwNumIndices;
DWORD m_dwVShader;
DWORD m_dwPShader;
D3DVECTOR m_Pos; // position of center
float m_RadiusScale;
float m_MidRadius; // assumes full scale
public:
void Init();
void UnInit()
{
int i;
for (i = 0; i < MAX_SHIELDS; i++)
{
m_Shields[i].UnInit();
}
for (int i = 0; i < MAX_ZSHIELDS; i++)
{
m_ZShields[i].UnInit();
}
destroy();
}
void create();
void destroy();
void advanceTime(float fElapsedTime, float fDt); // resets if fElapsedTime is zero
void render(bool b_far_side);
void restart();
};
#endif // SHIELD_H
File diff suppressed because it is too large Load Diff
+987
View File
@@ -0,0 +1,987 @@
///////////////////////////////////////////////////////////////////////////////
// File: VBlob.cpp
//
// Copyright 2001 Pipeworks Software
///////////////////////////////////////////////////////////////////////////////
#include "precomp.h"
#include "xbs_math.h"
#include "xbs_app.h"
#include "qrand.h"
#include "VBlob.h"
#include "tex_gen.h"
///////////////////////////////////////////////////////////////////////////////
const float MIN_SPAWN_MAGN = (0.5f);
#define BLOBLET_DIM (8)
#define BLOB_DIM (32)
///////////////////////////////////////////////////////////////////////////////
QRand VBlob::m_QRand;
VBlob* gpVBlob;
///////////////////////////////////////////////////////////////////////////////
void VBlob::Init()
{
int i;
for (i = 0; i < MAX_BLOBBUMPS; i++)
{
m_BlobBumps[i].Init();
}
for (i = 0; i < MAX_BLOBLETS; i++)
{
m_Bloblets[i].Init();
}
m_QRand.Init();
m_pBlobletVB = m_pBlobVBConst = m_pBlobVBChangingR = m_pBlobVBChangingU = NULL;
m_pBlobletIB = m_pBlobIB = NULL;
m_pUnitSphereNormals = NULL;
m_dwNumBlobletVertices = m_dwNumBlobletIndices = m_NumVertsPerFace = m_dwNumVertices = m_dwNumIndices = 0;
m_dwVShaderBlob = m_dwVShaderBloblet = 0;
m_dwPShaderBlob = m_dwPShaderBloblet = 0;
m_NumBlobBumps = m_NumBloblets = 0;
Set(&m_BlobColor, 0.25f, 1.0f, 0.15f, 1.0f);
Set(&m_Pos, 0.0f, 0.0f, 0.0f);
Set(&m_Scale, 1.0f, 1.0f, 1.0f);
m_fRadius = 2.3f;
}
///////////////////////////////////////////////////////////////////////////////
void VBlob::create()
{
gpVBlob = this;
gpd3dDev->CreateVertexBuffer(4 * sizeof(float)*5, 0, 0, 0, &pHaloQuadVB);
//MTS generateUnitSphere(2, &m_pBlobletVB, &m_pBlobletIB, NULL, &m_dwNumBlobletVertices, &m_dwNumBlobletIndices);
generateUnitSphere(BLOBLET_DIM, &m_pBlobletVB, &m_pBlobletIB, NULL, &m_dwNumBlobletVertices, &m_dwNumBlobletIndices);
generateUnitSphere(BLOB_DIM, &m_pBlobVBConst, &m_pBlobIB, &m_pUnitSphereNormals, &m_dwNumVertices, &m_dwNumIndices);
gpd3dDev->CreateVertexBuffer(m_dwNumVertices * sizeof(VBlobChangingVertex), 0, 0, 0, &m_pBlobVBChangingR);
gpd3dDev->CreateVertexBuffer(m_dwNumVertices * sizeof(VBlobChangingVertex), 0, 0, 0, &m_pBlobVBChangingU);
m_NumVertsPerFace = m_dwNumVertices / 6;
restart();
// Initialize the pixel shaders.
if( m_dwPShaderBlob )
{
gpd3dDev->DeletePixelShader( m_dwPShaderBlob );
m_dwPShaderBlob = 0;
}
#ifndef BINARY_RESOURCE
m_dwPShaderBlob = gApp.loadPixelShader("D:\\Shaders\\VBlob.xpu");
#else // BINARY_RESOURCE
m_dwPShaderBlob = gApp.loadPixelShader(g_vblob_xpu);
#endif // BINARY_RESOURCE
if( m_dwPShaderBloblet )
{
gpd3dDev->DeletePixelShader( m_dwPShaderBloblet );
m_dwPShaderBloblet = 0;
}
#ifndef BINARY_RESOURCE
m_dwPShaderBloblet = gApp.loadPixelShader("D:\\Shaders\\VBloblet.xpu");
#else // BINARY_RESOURCE
m_dwPShaderBloblet = gApp.loadPixelShader(g_vbloblet_xpu);
#endif // BINARY_RESOURCE
// Initialize the vertex shaders.
DWORD dwBlobShaderVertexDecl[] =
{
D3DVSD_STREAM( 0 ),
D3DVSD_REG( 0, D3DVSDT_FLOAT3 ), // unit sphere normal
D3DVSD_STREAM( 1 ),
D3DVSD_REG( 1, D3DVSDT_FLOAT4 ), // vertex normal, w is displacement
D3DVSD_END()
};
if (m_dwVShaderBlob)
{
gpd3dDev->DeleteVertexShader( m_dwVShaderBlob );
m_dwVShaderBlob = 0;
}
#ifndef BINARY_RESOURCE
m_dwVShaderBlob = gApp.loadVertexShader("D:\\Shaders\\VBlob.xvu", dwBlobShaderVertexDecl);
#else // BINARY_RESOURCE
m_dwVShaderBlob = gApp.loadVertexShader(g_vblob_xvu, dwBlobShaderVertexDecl);
#endif // BINARY_RESOURCE
DWORD dwBlobletShaderVertexDecl[] =
{
D3DVSD_STREAM( 0 ),
D3DVSD_REG( 0, D3DVSDT_FLOAT3 ), // unit sphere normal
D3DVSD_END()
};
if (m_dwVShaderBloblet)
{
gpd3dDev->DeleteVertexShader( m_dwVShaderBloblet );
m_dwVShaderBloblet = 0;
}
#ifndef BINARY_RESOURCE
m_dwVShaderBloblet = gApp.loadVertexShader("D:\\Shaders\\VBloblet.xvu", dwBlobletShaderVertexDecl);
#else // BINARY_RESOURCE
m_dwVShaderBloblet = gApp.loadVertexShader(g_vbloblet_xvu, dwBlobletShaderVertexDecl);
#endif // BINARY_RESOURCE
}
///////////////////////////////////////////////////////////////////////////////
void VBlob::destroy()
{
m_pBlobletVB->Release();
m_pBlobletIB->Release();
m_pBlobVBConst->Release();
m_pBlobVBChangingR->Release();
m_pBlobVBChangingU->Release();
m_pBlobIB->Release();
MemFree(m_pUnitSphereNormals);
pHaloQuadVB->Release();
if (m_dwPShaderBlob) gpd3dDev->DeletePixelShader(m_dwPShaderBlob);
if (m_dwPShaderBloblet) gpd3dDev->DeletePixelShader(m_dwPShaderBloblet);
if (m_dwVShaderBlob) gpd3dDev->DeleteVertexShader(m_dwVShaderBlob);
if (m_dwVShaderBloblet) gpd3dDev->DeleteVertexShader(m_dwVShaderBloblet);
m_pBlobletVB = NULL;
m_pBlobletIB = NULL;
m_pBlobVBConst = NULL;
m_pBlobVBChangingU = m_pBlobVBChangingR = NULL;
m_pBlobIB = NULL;
m_pUnitSphereNormals = NULL;
}
///////////////////////////////////////////////////////////////////////////////
void VBlob::render()
{
// Set default states
gpd3dDev->SetRenderState( D3DRS_LIGHTING, FALSE );
gpd3dDev->SetRenderState( D3DRS_ZENABLE, TRUE );
gpd3dDev->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
gpd3dDev->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
gpd3dDev->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_NONE );
gpd3dDev->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 0, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
gpd3dDev->SetTextureStageState( 1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
gpd3dDev->SetTextureStageState( 1, D3DTSS_MIPFILTER, D3DTEXF_NONE );
gpd3dDev->SetTextureStageState( 1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
gpd3dDev->SetTextureStageState( 1, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
gpd3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
gpd3dDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
gpd3dDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
// Render halo after blob, but before bloblets.
gpd3dDev->SetVertexShader(D3DFVF_XYZ|D3DFVF_TEX1);
gpd3dDev->SetPixelShader(NULL);
D3DMATRIX id_mat;
SetIdentity(&id_mat);
gpd3dDev->SetTransform(D3DTS_WORLD,&id_mat);
gpd3dDev->SetTransform(D3DTS_VIEW,&gApp.theCamera.matWTC);
gpd3dDev->SetTransform(D3DTS_PROJECTION,&gApp.theCamera.matProj);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_TFACTOR);
gpd3dDev->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1);
gpd3dDev->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TFACTOR);
gpd3dDev->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE);
float cur_rad = m_fRadius * (1.0f + 1.3f * fast_sqrt(gApp.getPulseIntensity()));
DWORD dw_alpha;
float f_alpha = min(gApp.getBlobIntensity(),1.f) * 255.f;
__asm
{
cvttss2si eax, f_alpha
shl eax,24
mov dw_alpha,eax
};
DWORD dw_tf = 0x00a0ff40 | dw_alpha;
gpd3dDev->SetRenderState( D3DRS_TEXTUREFACTOR,dw_tf);
gpd3dDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
gpd3dDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
gpd3dDev->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
gpd3dDev->SetTexture(0,gApp.pGlowMap);
struct _decalvert
{
D3DVECTOR p;
float u,v;
};
_decalvert * phalo_verts = NULL;
pHaloQuadVB->Lock(0,sizeof(_decalvert) * 4, (BYTE **)&phalo_verts,NULL);
float f_rad = cur_rad * 5.2f;
D3DMATRIX & ctw = gApp.theCamera.matCTW;
Sub(*(D3DVECTOR *)&ctw._21,*(D3DVECTOR *)&ctw._11,&phalo_verts[0].p);
Scale(&phalo_verts[0].p,f_rad);
phalo_verts[0].u = 0.f;
phalo_verts[0].v = 1.f;
Add(*(D3DVECTOR *)&ctw._21,*(D3DVECTOR *)&ctw._11,&phalo_verts[1].p);
Scale(&phalo_verts[1].p,f_rad);
phalo_verts[1].u = 1.f;
phalo_verts[1].v = 1.f;
Sub(*(D3DVECTOR *)&ctw._11,*(D3DVECTOR *)&ctw._21,&phalo_verts[2].p);
Scale(&phalo_verts[2].p,f_rad);
phalo_verts[2].u = 1.f;
phalo_verts[2].v = 0.f;
Set(&phalo_verts[3].p,-ctw._11-ctw._21,-ctw._12-ctw._22,-ctw._13-ctw._23);
Scale(&phalo_verts[3].p,f_rad);
phalo_verts[3].u = 0.f;
phalo_verts[3].v = 0.f;
pHaloQuadVB->Unlock();
gpd3dDev->SetStreamSource( 0, pHaloQuadVB, sizeof(_decalvert));
gpd3dDev->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);
// Restore state
gpd3dDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
gpd3dDev->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
//MTS gpd3dDev->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );
gpd3dDev->SetTexture( 0, gApp.pNormalCubeMapLoRes );
gpd3dDev->SetTexture( 1, gApp.pNormalCubeMapLoRes );
gpd3dDev->SetVertexShader( m_dwVShaderBlob );
gpd3dDev->SetPixelShader( m_dwPShaderBlob );
// Note: when passing matrices to a vertex shader, we transpose them, since
// matrix multiplies are done with dot product operations on the matrix rows.
D3DMATRIX matFinal,matTmp;
MulMats(gApp.theCamera.matWTC,gApp.theCamera.matProj,&matTmp);
SetTranspose(matTmp,&matFinal);
gpd3dDev->SetVertexShaderConstant(4,(CONST void *)&matFinal,4);
//; Expected vertex shaders constants
//; c0-c3 = Transpose of world matrix
//; c4-c7 = Transpose of view*projection matrix
//; c8 = some constants, x=0, y=1, z=2, w=0.5
//; c9 = eye location
//; c10 = blob scaling
//; c11 = 1/ blob scaling
//; c12 = blob center
D3DVECTOR4 val[5];
// Constants
Set(&val[0], 0.0f, 1.0f, 2.0f, 0.5f);
// Eye position
gApp.theCamera.getCameraPos(&val[1]);
// Scaling
Set(&val[2], cur_rad*m_Scale.x, cur_rad*m_Scale.y, cur_rad*m_Scale.z, 1.0f);
// 1 / blob scaling
val[3].x = 1.0f / val[2].x;
val[3].y = 1.0f / val[2].y;
val[3].z = 1.0f / val[2].z;
// Blob center.
//MTS float f_jitter_mag = (gApp.getElapsedTime() - BLOB_JITTER_START) * OO_BLOB_JITTER_DELTA;
//MTS f_jitter_mag *= f_jitter_mag;
//MTS float cOffsets[3] = { 0.2f, 0.7f, 4.2f };
//MTS float cScales[3] = { 20.0f, 28.0f, 44.0f };
D3DVECTOR4 cur_pos;
//MTS cur_pos.x = m_Pos.x + f_jitter_mag * sinf((gApp.getElapsedTime() - cOffsets[0])*cScales[0]);
//MTS cur_pos.y = m_Pos.y + f_jitter_mag * sinf((gApp.getElapsedTime() - cOffsets[1])*cScales[1]);
//MTS cur_pos.z = m_Pos.z + f_jitter_mag * sinf((gApp.getElapsedTime() - cOffsets[2])*cScales[2]);
cur_pos.x = m_Pos.x;
cur_pos.y = m_Pos.y;
cur_pos.z = m_Pos.z;
cur_pos.w = 0.0f;
Set(&val[4], cur_pos.x, cur_pos.y, cur_pos.z, 0.0f);
gpd3dDev->SetVertexShaderConstant( 8, &val, 5 );
// Make the object to World transform. Transpose it.
D3DMATRIX matT, mat;
SetIdentity( &mat );
mat.m[0][0] = m_Scale.x * cur_rad;
mat.m[1][1] = m_Scale.y * cur_rad;
mat.m[2][2] = m_Scale.z * cur_rad;
mat.m[3][0] = cur_pos.x;
mat.m[3][1] = cur_pos.y;
mat.m[3][2] = cur_pos.z;
SetTranspose( mat, &matT );
gpd3dDev->SetVertexShaderConstant( 0, &matT, 4 );
// Expected pixel shader constants
//; c0 = base blob color
//; c1 = ambient color
// Blob color
val[0] = m_BlobColor;
float f_color_intensity = BLOB_BASE_INTENSITY + 4.0f * (1.2f * gApp.getBaseBlobIntensity() + 0.8f * gApp.getPulseIntensity() );
//MTS f_color_intensity *= min(1.0f, gApp.getElapsedTime() * OO_BLOB_STATIC_END_TIME);
f_color_intensity *= min(1.0f, gApp.getElapsedTime() * 4.0f);
Scale(&val[0], f_color_intensity);
// Ambient light
val[1] = m_BlobColor;
Scale(&val[1], 0.0f);
gpd3dDev->SetPixelShaderConstant( 0, &val[0], 2 );
gpd3dDev->SetIndices( m_pBlobIB, 0 );
gpd3dDev->SetStreamSource( 0, m_pBlobVBConst, sizeof(VBlobConstantVertex) );
// Get the Update vertex buffer and use it to render.
swapChangingVertices();
gpd3dDev->SetStreamSource( 1, m_pBlobVBChangingR, sizeof(VBlobChangingVertex) );
gpd3dDev->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, m_dwNumVertices, 0, m_dwNumIndices-2 );
// Render the bloblets.
gpd3dDev->SetVertexShader( m_dwVShaderBloblet );
gpd3dDev->SetPixelShader( m_dwPShaderBloblet );
gpd3dDev->SetVertexShaderConstant(4,(CONST void *)&matFinal,4);
// Constants
Set(&val[0], 0.0f, 1.0f, 2.0f, 0.5f);
// Eye position
gApp.theCamera.getCameraPos(&val[1]);
gpd3dDev->SetVertexShaderConstant( 8, &val, 2 );
// Bloblet color
val[0] = m_BlobColor;
Scale(&val[0], 0.3f * gApp.getBlobIntensity());
// Ambient light
val[1] = m_BlobColor;
Scale(&val[1], 0.2f);
Set(&val[2], 2.0f, 2.0f, 2.0f, 2.0f);
// 1/val is the level of brightness that is full alpha
gpd3dDev->SetPixelShaderConstant( 0, &val, 3 );
gpd3dDev->SetIndices( m_pBlobletIB, 0 );
gpd3dDev->SetStreamSource( 0, m_pBlobletVB, sizeof(VBlobConstantVertex) );
for (int i=0; i<m_NumBloblets; i++)
{
//; c9 = eye location
//; c10 = blob center
//; c11 = direction of scaling
//; c12 = scaling perpendicular to direction
//; c13 = parallel minus perpendicular scaling multiplied by scaling direction
VBloblet* p_bloblet = &m_Bloblets[i];
// Bloblet center.
Set(&val[0], p_bloblet->vPosition.x, p_bloblet->vPosition.y, p_bloblet->vPosition.z, 0.0f);
// Direction of scaling.
Set(&val[1], p_bloblet->vDirection.x, p_bloblet->vDirection.y, p_bloblet->vDirection.z, 1.0f);
// Scaling perpendicular to direction
float fval = p_bloblet->fRadius / fast_sqrt(p_bloblet->fWobble);
Set(&val[2], fval, fval, fval, 1.0f);
// Parallel minus perpendicular scaling multiplied by scaling direction
fval = p_bloblet->fRadius * p_bloblet->fWobble - fval;
Set(&val[3], fval*p_bloblet->vDirection.x, fval*p_bloblet->vDirection.y, fval*p_bloblet->vDirection.z, 1.0f);
gpd3dDev->SetVertexShaderConstant( 10, &val, 4 );
gpd3dDev->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, m_dwNumBlobletVertices, 0, m_dwNumBlobletIndices-2 );
}
// Restore the state
gpd3dDev->SetPixelShader( NULL );
gpd3dDev->SetVertexShader( NULL );
gpd3dDev->SetTexture(0, NULL);
gpd3dDev->SetTexture(1, NULL);
gpd3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
}
///////////////////////////////////////////////////////////////////////////////
void VBlob::zeroChangingVertices()
{
VBlobChangingVertex* p_verts;
const D3DVECTOR* p_us_normals = m_pUnitSphereNormals;
m_pBlobVBChangingU->Lock(0, 0, (BYTE**)&p_verts, 0); // D3DLOCK_DISCARD not on XBox!
for (int face=0; face<6; face++)
{
for (int i=0; i<m_NumVertsPerFace; i++, p_verts++, p_us_normals++)
{
p_verts->normal.x = p_us_normals->x;
p_verts->normal.y = p_us_normals->y;
p_verts->normal.z = p_us_normals->z;
p_verts->normal.w = 1.0f;
}
}
m_pBlobVBChangingU->Unlock();
}
///////////////////////////////////////////////////////////////////////////////
void VBlob::prepareChangingVertices()
{
VBlobChangingVertex* p_verts;
const D3DVECTOR* p_us_normals = m_pUnitSphereNormals;
m_pBlobVBChangingU->Lock(0, 0, (BYTE**)&p_verts, 0); // D3DLOCK_DISCARD not on XBox!
/*
// For spiky blobs mark 2.
const float cA = 1.0f;
const float cB = 0.1f;
const float cD = 1.0f / ( (1.0f/cB) - (1.0f / (cA+cB)) );
const float cE = cA / cD;
const float cF = cB / cD;
const float cG = - cD / (cA+cB);
float sd_frac = max(1.0f, gApp.getElapsedTime() / 6.0f);
float bd_frac = 1.0f - sd_frac;
*/
for (int face=0; face<6; face++)
{
const VBlobBump* vp_blobs_of_interest[MAX_BLOBBUMPS];
int i;
int num_boi = 0;
for (i=0; i<m_NumBlobBumps; i++)
{
if (m_BlobBumps[i].facesOfInterest & (1<<face))
{
vp_blobs_of_interest[num_boi++] = &m_BlobBumps[i];
}
}
for (int i=0; i<m_NumVertsPerFace; i++, p_verts++)
{
const D3DVECTOR& us_normal = *(p_us_normals++);
D3DVECTOR4& accum_normal = p_verts->normal;
//MTS D3DVECTOR4 accum_normal;
Set(&accum_normal, us_normal.x, us_normal.y, us_normal.z, 0.0f);
for (int j=num_boi-1; j>=0; j--)
{
const VBlobBump* p_blob = vp_blobs_of_interest[j];
D3DVECTOR delta;
Sub(us_normal, p_blob->vPosition, &delta);
//MTS float dist2 = Length2(delta);
float dist2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z;
//MTS float dist2 = Distance2(us_normal, p_blob->vPosition);
if (dist2 < p_blob->fRadius2)
{
//MTS if ((p_blob->facesOfInterest & (1<<face)) == 0)
//MTS {
//MTS int a = 0;
//MTS }
float dist2_mo = dist2 * p_blob->fOORadius2 - 1.0f;
float displacement = m_fRadius*p_blob->fMagnitude * dist2_mo*dist2_mo;
/*
// Spiky blob bumps mark 2.
float bumpy_displacement = m_fRadius*p_blob->fMagnitude * dist2_mo*dist2_mo;
float spiky_displacement = m_fRadius * p_blob->fMagnitude * ( 1.0f / (cE*dist2*p_blob->fOORadius2 + cF) + cG );
spiky_displacement *= 1.3f;
float displacement = bd_frac*bumpy_displacement + sd_frac*spiky_displacement;
*/
float perturb_amount = -4.0f * p_blob->fMagnitude * p_blob->fOORadius2 * dist2_mo;
// lnorm = us_normal + perturb_amount*(us_normal - p_blob->vPosition)
// This should make it faster, but VTune suggests it doesn't. Maybe in Release...
//MTS D3DVECTOR lnorm;
//MTS float oppa = 1.0f + perturb_amount;
//MTS lnorm.x = us_normal.x * oppa - perturb_amount * p_blob->vPosition.x;
//MTS lnorm.y = us_normal.y * oppa - perturb_amount * p_blob->vPosition.y;
//MTS lnorm.z = us_normal.z * oppa - perturb_amount * p_blob->vPosition.z;
D3DVECTOR lnorm = us_normal;
//MTS Set(&lnorm, 0.0f, 0.0f, 0.0f);
//MTS D3DVECTOR delta;
//MTS Sub(us_normal, p_blob->vPosition, &delta);
AddScaled(&lnorm, delta, perturb_amount);
QuickNormalize(&lnorm);
accum_normal.x += lnorm.x;
accum_normal.y += lnorm.y;
accum_normal.z += lnorm.z;
accum_normal.w += displacement;
}
}
p_verts->normal = accum_normal;
}
}
m_pBlobVBChangingU->Unlock();
}
///////////////////////////////////////////////////////////////////////////////
void VBlob::advanceTime(float fElapsedTime, float fDt)
{
if (fElapsedTime < BLOB_STATIC_END_TIME)
{
if (fElapsedTime - fDt > BLOB_STATIC_END_TIME)
{
zeroChangingVertices();
swapChangingVertices();
zeroChangingVertices();
}
return;
}
for (int i=0; i<m_NumBloblets; i++)
{
if (!m_Bloblets[i].update(fElapsedTime, fDt))
{
//MTS m_Bloblets[i] = m_Bloblets[--m_NumBloblets];
//MTS i--;
// better notify the bump that owned it...
}
}
for (int i=0; i<m_NumBlobBumps; i++)
{
if (m_BlobBumps[i].update(
fElapsedTime,
fDt,
(m_NumBloblets<MAX_BLOBLETS) ? &m_Bloblets[m_NumBloblets] : NULL)
)
{
m_NumBloblets++;
}
}
//MTS m_pBlobVBChangingU->BlockUntilNotBusy(); // this causes it to block here, rather than in prepareChangingVertices
prepareChangingVertices();
}
///////////////////////////////////////////////////////////////////////////////
void VBlob::restart()
{
m_NumBloblets = 0;
m_NumBlobBumps = 0;
while (m_NumBlobBumps<MAX_BLOBBUMPS)
{
if (m_BlobBumps[m_NumBlobBumps++].create(
-0.3f,
(m_NumBloblets < MAX_BLOBLETS) ? &m_Bloblets[m_NumBloblets] : NULL
)) // pass negative time so the blobs get a head start
{
m_NumBloblets++;
}
}
zeroChangingVertices();
swapChangingVertices();
zeroChangingVertices();
}
///////////////////////////////////////////////////////////////////////////////
void VBlob::getLightForPosition(D3DVECTOR* p_light_pos, float* p_intensity, D3DVECTOR position)
{
float total_weights = 0.0f;
D3DVECTOR av_pos;
float av_intensity = 0.0f;
Set(&av_pos, 0.0f, 0.0f, 0.0f);
float light_intensity = gApp.getBlobIntensity();
{
float dist2 = Distance2(position, m_Pos);
float dist4 = dist2 * dist2;
float weight = 1.0f / dist2;
av_intensity += 4.0f * light_intensity * weight;
AddScaled(&av_pos, m_Pos, weight);
total_weights += weight;
}
for (int i=0; i<m_NumBloblets; i++)
{
float dist2 = Distance2(position, m_Bloblets[i].vPosition);
float dist4 = dist2 * dist2;
float weight = 1.0f / dist2;
av_intensity += light_intensity * weight;
AddScaled(&av_pos, m_Bloblets[i].vPosition, weight);
total_weights += weight;
}
float oo_total_weights = 1.0f / total_weights;
Set(p_light_pos, oo_total_weights * av_pos.x, oo_total_weights * av_pos.y, oo_total_weights * av_pos.z);
*p_intensity = oo_total_weights * av_intensity;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool VBlob::generateUnitSphere( int resolution,
LPDIRECT3DVERTEXBUFFER8* pp_vb,
LPDIRECT3DINDEXBUFFER8* pp_ib,
D3DVECTOR** pp_us,
DWORD* num_verts, DWORD* num_indices)
{
int subdiv = max(1, resolution / 2);
float f_division_step = 2.0f / ((float)subdiv);
*num_verts = 6*(subdiv+1)*(subdiv+1);
*num_indices = 6*GetNumberOfIndicesForTristripMesh(subdiv,subdiv) + 2*5; // 5 double-taps
gpd3dDev->CreateVertexBuffer( *num_verts * sizeof(VBlobConstantVertex), 0, 0, 0, pp_vb);
gpd3dDev->CreateIndexBuffer( *num_indices * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, pp_ib);
if (pp_us) *pp_us = (D3DVECTOR*)MemAlloc(sizeof(D3DVECTOR)*(*num_verts));
VBlobConstantVertex* p_verts;
WORD* p_indices;
(*pp_vb)->Lock(0, 0, (BYTE**)&p_verts, 0);
(*pp_ib)->Lock(0, 0, (BYTE**)&p_indices, 0);
D3DVECTOR* p_us = ((pp_us) ? *pp_us : NULL);
// Create vertices.
VBlobConstantVertex* p_vert = &p_verts[0];
for (int k=0; k<6; k++)
{
for (int j=0; j<=subdiv; j++)
{
for (int i=0; i<=subdiv; i++)
{
D3DVECTOR& pos = p_vert->unit_sphere_normal;
float fu = ((i==subdiv) ? +1.0f : (-1.0f + f_division_step * ((float)i)));
float fv = ((j==subdiv) ? +1.0f : (-1.0f + f_division_step * ((float)j)));
switch(k)
{
case 0: Set(&pos, -1.0f, -fu, +fv); break;
case 1: Set(&pos, +fv, -1.0f, -fu); break;
case 2: Set(&pos, -fu, +fv, -1.0f); break;
case 3: Set(&pos, +1.0f, +fu, +fv); break;
case 4: Set(&pos, +fv, +1.0f, +fu); break;
case 5: Set(&pos, +fu, +fv, +1.0f); break;
}
Normalize(&pos);
if (p_us)
{
*p_us = pos;
p_us++;
}
p_vert++;
}
}
}
// Create indices.
int j = 0;
for (int i=0; i<6; i++)
{
j += CreateTristripForMesh(&p_indices[j], subdiv, subdiv, (i>0), (i<5), i*(subdiv+1)*(subdiv+1));
}
(*pp_ib)->Unlock();
(*pp_vb)->Unlock();
return true;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void VBlobBump::Init()
{
pMyBloblet = NULL;
}
///////////////////////////////////////////////////////////////////////////////
void VBlobBump::UnInit()
{
}
///////////////////////////////////////////////////////////////////////////////
// randomly creates a blob bump
bool VBlobBump::create(float cur_time, VBloblet* p_bloblet)
{
if (cur_time < 0.0f) pMyBloblet = NULL;
vDirection.x = VBlob::fRand11();
vDirection.y = VBlob::fRand11();
vDirection.z = VBlob::fRand11();
if (Length2(vDirection) < 0.001f)
{
vDirection.x = VBlob::fRand11();
vDirection.y = VBlob::fRand11();
vDirection.z = 1.0f;
}
Set(&vPosition, 0.0f, 0.0f, 0.0f);
QuickNormalize(&vDirection);
float time_prog = max(0.0f, (cur_time-BLOB_STATIC_END_TIME) * OO_MAX_INTENSITY_DELTA);
float rad_mag_rand = VBlob::fRand01();
fRadius = rad_mag_rand * 0.4f + 0.4f;
fRadius2 = fRadius*fRadius;
fOORadius2 = 1.0f / fRadius2;
fMagnitude = 0.0f;
recalculateFacesOfInterest();
fStartTime = cur_time + 0.4f * VBlob::fRand01();
fMaxMagnitude = (1.0f - rad_mag_rand) * 0.5f + 0.2f;
fMaxMagnitude *= 0.5f + 0.5f * time_prog;
if (!pMyBloblet) pMyBloblet = p_bloblet;
if (pMyBloblet)
{
// Paired with a bloblet.
float f_main_rad = gpVBlob->getRadius();
pMyBloblet->fRadius = (VBlob::fRand01()+1.0f) * 0.25f * f_main_rad * fRadius;
pMyBloblet->vDirection = vDirection;
pMyBloblet->fMaxDist = f_main_rad * (5.0f + VBlob::fRand11() * 2.0f);
pMyBloblet->fMaxDist *= 0.6f;
pMyBloblet->fStartTime = (cur_time<-1.0f) ? -VBlob::fRand01() * 0.3f : cur_time;
float period = 0.8f + 0.3f * VBlob::fRand01();
period *= 1.0f / 0.6f;
pMyBloblet->fTimeMultiple = 2.0f * Pi / period;
pMyBloblet->fWobble = 1.2f;
pMyBloblet->fWobbleDirection = 0.0f;
bStillAttachedToBloblet = (cur_time-fStartTime < 0.4f*period);
// Set my properties from the bloblet.
pMyBloblet->update(cur_time, 0.0f);
update(cur_time, 0.0f, NULL);
}
else
{
// Not paired with a bloblet.
float sequence_len = fMaxMagnitude * 0.3f + VBlob::fRand01() * 0.3f;
fTimeMul = Pi / sequence_len;
fTimeMul *= time_prog*0.2f + 0.8f;
if (cur_time < -1.0f) fStartTime = -VBlob::fRand01() * Pi / fTimeMul;
}
return (pMyBloblet!=NULL);
}
///////////////////////////////////////////////////////////////////////////////
// returns true if it initialized a new Bloblet
bool VBlobBump::update(float elapsed_time, float dt, VBloblet* p_bloblet)
{
if (pMyBloblet)
{
float f_b_mag = (fast_fabs(pMyBloblet->fCurDist) + pMyBloblet->fRadius) / gpVBlob->getRadius();
fMagnitude = min( 2.0f, max(0.0f, f_b_mag - 1.0f) );
if (bStillAttachedToBloblet)
{
if (fMagnitude > 0.8f)
{
// Lost attachment
bStillAttachedToBloblet = false;
//MTS fMaxMagnitude = max(0.0f, fMagnitude - 2.0f * pMyBloblet->fRadius / gpVBlob->getRadius());
fMaxMagnitude = fMagnitude;
float sequence_len = 0.3f * fMagnitude;
fTimeMul = 2.0f * Pi / sequence_len;
fStartTime = elapsed_time - 0.25f * sequence_len;
pMyBloblet->fWobble = max(0.6f, min(0.8f, fMagnitude-0.5f)); // more wobble when there is less energy
pMyBloblet->fWobbleDirection = 0.0f;
}
else
{
// Still attached.
if ( (Dot(vDirection, pMyBloblet->vDirection) < 0.0f) != pMyBloblet->bFarSide)
{
// Must reverse direction.
Scale(&vDirection, -1.0f);
vPosition = vDirection;
recalculateFacesOfInterest();
}
return false;
}
}
// May have just lost attachment.
if (!bStillAttachedToBloblet)
{
if (f_b_mag < 0.9f)
{
// Blob is inside sphere, reattach.
bStillAttachedToBloblet = true;
}
}
}
float t = (elapsed_time - fStartTime) * fTimeMul;
if (t>Pi)
{
if (pMyBloblet==NULL)
{
return create(elapsed_time, p_bloblet);
}
fMagnitude = 0.0f;
return false;
}
if (t<0.0f) return false;
float sin_val = fast_sin(t);
fMagnitude = fMaxMagnitude * sin_val;
//MTS vPosition.x = vDirection.x * sin_val;
//MTS vPosition.y = vDirection.y * sin_val;
//MTS vPosition.z = vDirection.z * sin_val;
vPosition = vDirection;
recalculateFacesOfInterest();
//MTS if ((bNotYetSpawned) && (t > 0.5f * Pi) && (p_bloblet))
//MTS {
//MTS bNotYetSpawned = false;
//MTS
//MTS float f_main_rad = gpVBlob->getRadius();
//MTS p_bloblet->fRadius = 0.7f * f_main_rad * fRadius;
//MTS
//MTS float displ = f_main_rad * (1.0f + fMagnitude) - p_bloblet->fRadius;
//MTS p_bloblet->vPosition = gpVBlob->getCenter();
//MTS p_bloblet->vPosition.x += vDirection.x * displ;
//MTS p_bloblet->vPosition.y += vDirection.y * displ;
//MTS p_bloblet->vPosition.z += vDirection.z * displ;
//MTS
//MTS
//MTS
//MTS
//MTS
//MTS float vel = f_main_rad * (fMagnitude-MIN_SPAWN_MAGN) * 100.0f + 20.0f;
//MTS p_bloblet->vVelocity.x = vDirection.x * vel;
//MTS p_bloblet->vVelocity.y = vDirection.y * vel;
//MTS p_bloblet->vVelocity.z = vDirection.z * vel;
//MTS
//MTS p_bloblet->vAttachedTo = gpVBlob->getCenter();
//MTS
//MTS
//MTS // Set up a spring as per 2001.05.01 of my notes.
//MTS
//MTS // Use a spring model for now. Period is 2*Pi/sqrt(k/m), so k/m = (2*Pi/period)^2
//MTS float sequence_time_mul = 5.0f;
//MTS p_bloblet->fRestoreForceConstant = 2.0f * Pi / (sequence_time_mul*(elapsed_time - fStartTime));
//MTS p_bloblet->fRestoreForceConstant *= p_bloblet->fRestoreForceConstant;
//MTS
//MTS p_bloblet->fEndDist2 = f_main_rad - p_bloblet->fRadius;
//MTS p_bloblet->fEndDist2 *= p_bloblet->fEndDist2;
//MTS
//MTS return true;
//MTS }
return false;
}
///////////////////////////////////////////////////////////////////////////////
void VBlobBump::recalculateFacesOfInterest()
{
// Bitfield indicating the faces (0,1,2,4,5) <-> (-x,-y,-z,+x,+y,+z) the blob points most be checked with.
facesOfInterest = ((vDirection.x - fRadius < -0.57735f) ? 0x0001 : 0) +
((vDirection.y - fRadius < -0.57735f) ? 0x0002 : 0) +
((vDirection.z - fRadius < -0.57735f) ? 0x0004 : 0) +
((vDirection.x + fRadius > +0.57735f) ? 0x0008 : 0) +
((vDirection.y + fRadius > +0.57735f) ? 0x0010 : 0) +
((vDirection.z + fRadius > +0.57735f) ? 0x0020 : 0) ;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
const float WOBBLE_ACCEL = (1000.0f);
// returns false if it should be deleted
bool VBloblet::update(float elapsed_time, float dt)
{
fWobble = min(2.0f, max(0.5f, fWobble + fWobbleDirection * dt));
if (fWobbleDirection > 0.0f)
{
if ((fWobble < 0.95f) || (fWobble > 1.0f))
{
fWobbleDirection -= (fWobble-1.0f) * dt * WOBBLE_ACCEL;
}
}
else
{
if ((fWobble < 1.0f) || (fWobble > 1.05f))
{
fWobbleDirection -= (fWobble-1.0f) * dt * WOBBLE_ACCEL;
}
}
float time_prog = max(0.0f, (elapsed_time-BLOB_STATIC_END_TIME) * OO_MAX_INTENSITY_DELTA);
float t = fTimeMultiple * (elapsed_time - fStartTime);
t *= 1.4f * (1.0f + elapsed_time / 10.0f); // speed up over time
float s = fast_sin(t);
float sm = fast_fabs(s);
sm = 1.0f - (1.0f-sm)*fast_sqrt(1.0f-sm);
s = (s>0.0f) ? sm : -sm;
fCurDist = fMaxDist * s * time_prog;
bFarSide = (fCurDist<0.0f);
vPosition = gpVBlob->getCenter();
AddScaled(&vPosition, vDirection, fCurDist);
return (fast_fabs(fCurDist) + fRadius < gpVBlob->getRadius() * 0.5f);
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
+249
View File
@@ -0,0 +1,249 @@
///////////////////////////////////////////////////////////////////////////////
// File: VBlob.h
//
// Copyright 2001 Pipeworks Software
///////////////////////////////////////////////////////////////////////////////
#ifndef VBLOB_H
#define VBLOB_H
#include "qrand.h"
// The vertex list holding the unit sphere coordinates remain on the card.
// Each frame another list is streamed.
struct VBlobConstantVertex
{
D3DVECTOR unit_sphere_normal;
};
struct VBlobChangingVertex
{
D3DVECTOR4 normal; // not normalized (do it in the GPU); w is the displacement due to bumps
};
// Bloblets need to be able to be copied.
class VBloblet
{
public:
void Init() { fWobble = 1.0f; fWobbleDirection = 0.0f; }
void UnInit() {}
void set(float rad, float x, float y, float z)
{
fRadius = rad;
Set(&vPosition, x, y, z);
}
// Perturbation is normal * fMagnitude * f( (r*r)/(fRadius*fRadius) ).
// f(r/R) will start at a peak of 1 (at r=0) and fall to 0 as r goes to R. The
// slope at 0 and 1 will be 0.
// The perturbation needs to be applied in code so the normals can be accumulated.
float fRadius;
D3DVECTOR vPosition;
bool bFarSide;
D3DVECTOR vDirection;
float fStartTime;
float fTimeMultiple;
float fMaxDist; // in world units
float fCurDist; // fMaxDist * sin(...)
float fWobble;
float fWobbleDirection;
bool update(float elapsed_time, float dt); // returns false if it consents to be deleted
};
class VBlobBump
{
public:
void Init();
void UnInit();
void set(float rad, float mag, float x, float y, float z)
{
fRadius = rad;
fRadius2 = fRadius*fRadius;
fOORadius2 = 1.0f / fRadius2;
fMagnitude = mag;
Set(&vPosition, x, y, z);
}
// Perturbation is normal * fMagnitude * f( (r*r)/(fRadius*fRadius) ).
// f(r/R) will start at a peak of 1 (at r=0) and fall to 0 as r goes to R. The
// slope at 0 and 1 will be 0.
// The perturbation needs to be applied in code so the normals can be accumulated.
float fRadius, fRadius2, fOORadius2;
float fMagnitude; // wrt unit sphere
D3DVECTOR vPosition;
int facesOfInterest; // bitfield indicating the three faces (0,1,2,4,5) <-> (-x,-y,-z,+x,+y,+z) the blob points most toward
// returns true if it initialized a new Bloblet
bool create(float cur_time, VBloblet* p_bloblet); // randomly creates a blob bump
bool update(float elapsed_time, float dt, VBloblet* p_bloblet);
protected:
// Positioning data.
D3DVECTOR vDirection; // normalized
float fStartTime;
float fTimeMul;
float fMaxMagnitude;
VBloblet* pMyBloblet;
bool bStillAttachedToBloblet;
void recalculateFacesOfInterest();
};
class VBlob
{
protected:
LPDIRECT3DVERTEXBUFFER8 m_pBlobletVB; // VBlobConstantVertex, for the emerging blobs, lower tesselation
LPDIRECT3DINDEXBUFFER8 m_pBlobletIB;
LPDIRECT3DVERTEXBUFFER8 pHaloQuadVB;
LPDIRECT3DVERTEXBUFFER8 m_pBlobVBConst; // VBlobConstantVertex
LPDIRECT3DVERTEXBUFFER8 m_pBlobVBChangingR; // VBlobChangingVertex (rendering version) (swapped in render)
LPDIRECT3DVERTEXBUFFER8 m_pBlobVBChangingU; // VBlobChangingVertex (updating version)
LPDIRECT3DINDEXBUFFER8 m_pBlobIB;
D3DVECTOR* m_pUnitSphereNormals;
DWORD m_dwNumVertices, m_dwNumBlobletVertices;
DWORD m_dwNumIndices, m_dwNumBlobletIndices;
int m_NumVertsPerFace;
DWORD m_dwVShaderBlob, m_dwVShaderBloblet;
DWORD m_dwPShaderBlob, m_dwPShaderBloblet;
D3DVECTOR4 m_BlobColor;
D3DVECTOR m_Pos; // position of center
D3DVECTOR m_Scale;
FLOAT m_fRadius;
// BlobBumps work in unit-sphere space.
enum { MAX_BLOBBUMPS = 32 };
VBlobBump m_BlobBumps[MAX_BLOBBUMPS];
int m_NumBlobBumps;
enum { MAX_BLOBLETS = 8 };
VBloblet m_Bloblets[MAX_BLOBLETS];
int m_NumBloblets;
static QRand m_QRand;
// Creates a VBlobConstantVertex vertex buffer. Creates WORD index buffer.
static bool generateUnitSphere(
int resolution,
LPDIRECT3DVERTEXBUFFER8* pp_vb,
LPDIRECT3DINDEXBUFFER8* pp_ib,
D3DVECTOR** pp_us,
DWORD* num_verts, DWORD* num_indices);
void prepareChangingVertices();
void zeroChangingVertices(); // zeros bumps in m_pBlobVBChangingU
inline void swapChangingVertices()
{
LPDIRECT3DVERTEXBUFFER8 temp = m_pBlobVBChangingR;
m_pBlobVBChangingR = m_pBlobVBChangingU;
m_pBlobVBChangingU = temp;
}
public:
void Init();
void UnInit()
{
int i;
for (i = 0; i < MAX_BLOBBUMPS; i++)
{
m_BlobBumps[i].UnInit();
}
for (i = 0; i < MAX_BLOBLETS; i++)
{
m_Bloblets[i].UnInit();
}
destroy();
}
void create();
void destroy();
void render();
void advanceTime(float fElapsedTime, float fDt);
void restart();
float getRadius() const { return m_fRadius; }
const D3DVECTOR& getCenter() const { return m_Pos; }
void getLightForPosition(D3DVECTOR* p_light_pos, float* p_intensity, D3DVECTOR position);
static inline float fRand01();
static inline float fRand11();
};
extern VBlob* gpVBlob;
#define LLI_RAND_MAX 0x00010000
#define LLI_RAND_MASK 0x0000FFFF
float VBlob::fRand01()
{
static float mul = 1.0f / ((float)LLI_RAND_MAX);
return ((float)(m_QRand.Rand()&LLI_RAND_MASK)) * mul;
}
float VBlob::fRand11()
{
static float mul = 2.0f / ((float)LLI_RAND_MAX);
return (((float)(m_QRand.Rand()&LLI_RAND_MASK)) * mul) - 1.0f;
}
#endif // VBLOB_H
+148
View File
@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{a5177126-a737-4749-8f5f-31f2bd43ea53}</ProjectGuid>
<RootNamespace>ani2ondx11</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="BlobRenderer.h" />
<ClInclude Include="Blobs.h" />
<ClInclude Include="CamControl.h" />
<ClInclude Include="camera.h" />
<ClInclude Include="defines.h" />
<ClInclude Include="fastmath.h" />
<ClInclude Include="RenderObject.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="BlobRenderer.cpp" />
<ClCompile Include="Blobs.cpp" />
<ClCompile Include="CamControl.cpp" />
<ClCompile Include="camera.cpp" />
<ClCompile Include="fastmath.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="fastmath.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="camera.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="defines.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CamControl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="BlobRenderer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RenderObject.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Blobs.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="fastmath.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="camera.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="BlobRenderer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Blobs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CamControl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
+296
View File
@@ -0,0 +1,296 @@
/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
animate.c
Abstract:
Startup animation implementation.
--*/
#include <stddef.h>
#pragma code_seg("INIT")
#pragma data_seg("INIT_RW")
#pragma const_seg("INIT_RD")
#include "ntos.h"
#include "stdio.h"
#include "stdlib.h"
#include "wtypes.h"
#include "ani.h"
// Tell linker to put startup animation code and data into INIT section
#pragma comment(linker, "/merge:INIT_RD=INIT")
#pragma comment(linker, "/merge:INIT_RW=INIT")
#pragma comment(linker, "/merge:D3D=INIT")
#pragma comment(linker, "/merge:D3D_RD=INIT")
#pragma comment(linker, "/merge:D3D_RW=INIT")
#pragma comment(linker, "/merge:XGRPH=INIT")
#pragma comment(linker, "/merge:XGRPH_RD=INIT")
// We always want to link with the animation code, so that we can
// keep the build from breaking. Thats why we use a global to
// decide whether to run the animation or not. The global tricks
// the linker into linking in all the code the animation uses.
#ifdef NOANI
BOOL gBootAnimation_DoAnimation = FALSE;
#else
BOOL gBootAnimation_DoAnimation = TRUE;
#endif
#ifdef BOOTSOUND
BOOL gBootAnimation_DoSound = TRUE;
#else
BOOL gBootAnimation_DoSound = FALSE;
#endif
// Background animation thread.
HANDLE g_hThread;
// Entrypoing into the animation thread.
VOID AnipStartAnimationThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext);
// Main animation routine as defined in the animation library.
VOID AnipRunAnimation();
#define CONTIGUOUS_BLOCK_SIZE (5 * 1024 * 1024 / 2)
#define AGP_APERTURE_BYTES (64*1024*1024)
#define INSTANCE_MEM_MAXSIZE (20*1024)
#define NV_INSTANCE_SIZE (INSTANCE_MEM_MAXSIZE)
//------------------------------------------------------------------------
// Starts the animation which will run on a background thread. This API
// returns immediately.
//
BOOL g_bShortVersion;
void AniStartAnimation(BOOLEAN fShort)
{
NTSTATUS Status;
if (gBootAnimation_DoAnimation){
g_bShortVersion = fShort;
Status = PsCreateSystemThreadEx(&g_hThread,
0,
0x4000, // Stack size, 16K
0,
NULL,
NULL,
NULL,
FALSE,
FALSE,
AnipStartAnimationThread);
if (!NT_SUCCESS(Status))
{
// RIP(("AniStartAnimation - Unable to create thread."));
g_hThread = NULL;
}
}
}
//------------------------------------------------------------------------
// Shut down the animation. This will block until the animation finishes.
//
void AniTerminateAnimation()
{
if (g_hThread)
{
NTSTATUS Status;
#if DBG
int start = NtGetTickCount();
#endif
// Wait for it to go away.
Status = NtWaitForSingleObjectEx(g_hThread, KernelMode, FALSE, NULL);
#if DBG
DbgPrint("Boot animation wait %d\n", NtGetTickCount() - start);
if (Status == STATUS_TIMEOUT)
{
//RIP(("AniTerminateAnimation - Animation is stuck!"));
}
#endif
NtClose(g_hThread);
g_hThread = NULL;
}
}
void AnipBreak()
{
#if DBG
_asm int 3;
#endif
}
#if DBG
int gcMemAllocsContiguous = 0;
#endif
//------------------------------------------------------------------------
// Blocks until the animation has completed (until the animation is ready
// to display the Microsoft logo).
//
void AniBlockOnAnimation(void)
{
extern KEVENT g_EventLogoWaiting;
NTSTATUS status;
PETHREAD ThreadObject;
PVOID WaitObjects[2];
KWAIT_BLOCK WaitBlocks[2];
if (g_hThread)
{
status = ObReferenceObjectByHandle(g_hThread, &PsThreadObjectType,
(PVOID*)&ThreadObject);
if (NT_SUCCESS(status))
{
WaitObjects[0] = ThreadObject;
WaitObjects[1] = &g_EventLogoWaiting;
KeWaitForMultipleObjects(2, WaitObjects, WaitAny, Executive,
KernelMode, FALSE, NULL, WaitBlocks);
ObDereferenceObject(ThreadObject);
}
}
}
//------------------------------------------------------------------------
// MemAllocContiguous
//
void *MemAllocContiguous(size_t Size, DWORD Alignment)
{
#if DBG
gcMemAllocsContiguous++;
#endif
return MmAllocateContiguousMemoryEx(
Size,
0,
AGP_APERTURE_BYTES - NV_INSTANCE_SIZE,
Alignment,
PAGE_READWRITE | PAGE_WRITECOMBINE);
}
//------------------------------------------------------------------------
// MemFreeContiguous
//
void MemFreeContiguous(void *pv)
{
#if DBG
if (gcMemAllocsContiguous <= 0)
{
AnipBreak();
}
gcMemAllocsContiguous--;
#endif
MmFreeContiguousMemory(pv);
}
//------------------------------------------------------------------------
// Main animation procedure. Defers to the startup animation library.
//
VOID AnipStartAnimationThread(
PKSTART_ROUTINE StartRoutine,
PVOID StartContext
)
{
AnipRunAnimation();
// Make this thread go away.
PsTerminateSystemThread(0);
}
///////////////////////////////////////////////////////////////////////////////
// Defined so we don't have to pull libc in
typedef void (__cdecl *_PVFV)(void);
int __cdecl atexit(_PVFV func)
{
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Define a couple of debug-only methods used in XGRAPHICS that normally
// are implemented in XTL.
#ifdef STARTUPANIMATION
long __cdecl _ftol2(float x)
{
DWORD result[2];
unsigned short oldcw;
unsigned short newcw;
_asm
{
fstcw [oldcw] ; get control word
fwait ; synchronize
mov ax, [oldcw] ; round mode saved
or ah, 0ch ; set chop rounding mode
mov [newcw], ax ; back to memory
fldcw [newcw] ; reset rounding
fistp qword ptr [result] ; store chopped integer
fldcw [oldcw] ; restore rounding
mov eax, dword ptr [result]
mov edx, dword ptr [result+4]
}
}
#define D_EXP(x) ((unsigned short *)&(x)+3)
#define D_HI(x) ((unsigned long *)&(x)+1)
#define D_LO(x) ((unsigned long *)&(x))
#define IS_D_QNAN(x) ((*D_EXP(x) & 0x7ff8) == 0x7ff8)
#define IS_D_SNAN(x) ((*D_EXP(x) & 0x7ff8) == 0x7ff0 && \
(*D_HI(x) << 13 || *D_LO(x)))
int __cdecl _isnan(double x)
{
if (IS_D_SNAN(x) || IS_D_QNAN(x)) {
return 1;
}
return 0;
}
VOID
XDebugError(PCHAR Module, PCHAR Format, ...)
{
_asm int 3;
}
void Sleep(DWORD Milliseconds)
{
_asm int 3;
}
VOID
OutputDebugStringA(
IN LPCSTR lpOutputString
)
{
DbgPrint((PSTR)lpOutputString);
}
#endif
+6
View File
@@ -0,0 +1,6 @@
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the components of NT OS/2
#
!INCLUDE $(NTMAKEENV)\makefile.def
+25
View File
@@ -0,0 +1,25 @@
TARGETNAME=Bootscreen
TARGETPATH=obj
TARGETTYPE=PROGRAM
UMTYPE=xboxapp
NOT_UNICODE=1
# USE_LIBCNTPR = 1
C_DEFINES=$(C_DEFINES) /DBINARY_RESOURCE
INCLUDES=$(BASEDIR)\private\atg\samples\common\include;$(BASEDIR)\public\xdk\inc;$(BASEDIR)\private\ntos\inc;$(INCLUDES);$(BASEDIR)\private\inc;$(BASEDIR)\public\sdk\inc
XE_FLAGS = $(XE_FLAGS) /TESTID:0x00112233 /TESTNAME:"Xbox Startup Sequence" /INITFLAGS:0x00000000
LINKLIBS = \
$(SDK_LIB_PATH)\d3d8$(D).lib \
$(SDK_LIB_PATH)\xgraphics$(D).lib\
$(SDK_LIB_PATH)\bootsnd_app$(D).lib
!include ..\sources.inc
SOURCES=$(SOURCES) \
bootsound.cpp\
xbinput.cpp
+9
View File
@@ -0,0 +1,9 @@
struct DSPpatch {
unsigned short *Start; // address of start of sample
unsigned short Length; // length of sample
unsigned short LoopStart; // bytes from beg of sound to loop point
unsigned short LoopLength; // bytes form loop start to loop end
unsigned short LoopEnable; // loop sound? T or F
LPDSENVELOPEDESC lpAmpEnvelope;
LPDSENVELOPEDESC lpMultiEnvelope;
};
+123
View File
@@ -0,0 +1,123 @@
//depot/xbox/private/ntos/ani2/bootsound.cpp#7 - edit change 15970 (text)
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*/
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <stddef.h>
#include <ntos.h>
#include <pci.h>
#ifdef __cplusplus
}
#endif // __cplusplus
#include "xtl.h"
#include "xdbg.h"
#include "bootsound.h"
#ifdef STARTUPANIMATION
#pragma data_seg("INIT_RW")
#pragma code_seg("INIT")
#pragma bss_seg("INIT_RW")
#pragma const_seg("INIT_RD")
// Tell linker to put bootsound code and data into INIT section
#pragma comment(linker, "/merge:DSOUND=INIT")
#pragma comment(linker, "/merge:INIT_RD=INIT")
#pragma comment(linker, "/merge:INIT_RW=INIT")
#endif //STARTUPANIMATION
#if DBG
EXTERN_C g_dwDirectSoundPoolMemoryUsage;
EXTERN_C g_dwDirectSoundPhysicalMemoryUsage;
#endif
EXTERN_C SHORT system_clock_music;
KTIMER g_BootSoundTimer;
KDPC g_BootSoundDpc;
VOID
BootSoundDpc(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
)
{
system_clock_music++;
sos_main();
return;
}
void BootSound_Start(){
LARGE_INTEGER dueTime;
dueTime.QuadPart = 0;
do_sos_init_return();
KeInitializeTimerEx(&g_BootSoundTimer,NotificationTimer);
KeInitializeDpc(&g_BootSoundDpc,BootSoundDpc,NULL);
KeSetTimerEx(&g_BootSoundTimer,
dueTime,
5,
&g_BootSoundDpc);
}
//
// here's our main sos worker thread. This needs to get called regularly
// it does all the sequencing and writing to the sound chip to make noise
//
// not true...we create a worker thread instead in the init routine
void BootSound_Stop(void){
KeCancelTimer(&g_BootSoundTimer);
//
// free dsound objects
//
dev_cleanup();
#if DBG
//
// check if we leaked any mem
//
ASSERT(g_dwDirectSoundPoolMemoryUsage == 0);
ASSERT(g_dwDirectSoundPhysicalMemoryUsage == 0);
#endif
}
extern "C" int _cdecl _purecall(
void
)
{
_asm int 3; return 0;
}
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*/
extern "C" do_sos_init_return(void);
extern "C" sos_main(void);
extern "C" put_fifo(unsigned char);
extern "C" dev_cleanup(void);
#ifdef __cplusplus
extern "C" {
#endif
// All boot sound functions must be called at passive level
void BootSound_Start(); // Call once to start boot sound
void BootSound_Stop(void); // Call once to stop boot sound
#ifdef __cplusplus
};
#endif
+264
View File
@@ -0,0 +1,264 @@
//
// camera.cpp - Modern Windows 11 port
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001, Pipeworks Software Inc. (Original)
// Modern Port Copyright (c) 2023
// All rights reserved
#include "camera.h"
using namespace DirectX;
///////////////////////////////////////////////////////////////////////////////
Camera::Camera()
{
m_bClipPlanesValid = false;
m_bViewProjMatrixValid = false;
m_ClipPlanes.resize(6); // 6 frustum planes
Init();
}
///////////////////////////////////////////////////////////////////////////////
Camera::~Camera()
{
Uninit();
}
///////////////////////////////////////////////////////////////////////////////
void Camera::Init()
{
m_bClipPlanesValid = false;
m_bViewProjMatrixValid = false;
// Initialize with identity matrices
m_mCameraToWorld = XMMatrixIdentity();
m_mWorldToCamera = XMMatrixIdentity();
m_mProjection = XMMatrixIdentity();
// Default camera values
m_vPosition = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
m_vLookAt = XMVectorSet(0.0f, 0.0f, 1.0f, 1.0f);
m_vUp = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
m_fNearPlane = 0.1f;
m_fFarPlane = 1000.0f;
m_fAspectRatio = 16.0f / 9.0f;
m_fFieldOfView = XM_PIDIV4; // 45 degrees
}
///////////////////////////////////////////////////////////////////////////////
void Camera::Uninit()
{
// Clean up any resources
}
///////////////////////////////////////////////////////////////////////////////
void Camera::LookAt(const XMFLOAT3& camPos, const XMFLOAT3& lookPt, const XMFLOAT3& up)
{
LookAt(XMLoadFloat3(&camPos), XMLoadFloat3(&lookPt), XMLoadFloat3(&up));
}
///////////////////////////////////////////////////////////////////////////////
void Camera::LookAt(FXMVECTOR camPos, FXMVECTOR lookPt, FXMVECTOR up)
{
m_vPosition = camPos;
m_vLookAt = lookPt;
m_vUp = up;
// Create the view matrix (world to camera space)
m_mWorldToCamera = XMMatrixLookAtLH(camPos, lookPt, up);
// Create the inverse (camera to world space)
m_mCameraToWorld = XMMatrixInverse(nullptr, m_mWorldToCamera);
m_bClipPlanesValid = false;
m_bViewProjMatrixValid = false;
}
///////////////////////////////////////////////////////////////////////////////
void Camera::SetProjection(float fovInRadiansY, float aspectRatio, float nearPlane, float farPlane)
{
m_fFieldOfView = fovInRadiansY;
m_fAspectRatio = aspectRatio;
m_fNearPlane = nearPlane;
m_fFarPlane = farPlane;
// Create the projection matrix
m_mProjection = XMMatrixPerspectiveFovLH(fovInRadiansY, aspectRatio, nearPlane, farPlane);
m_bClipPlanesValid = false;
m_bViewProjMatrixValid = false;
}
///////////////////////////////////////////////////////////////////////////////
void Camera::Translate(FXMVECTOR relativeVector)
{
// Get the current position from the matrix
XMVECTOR position = m_mCameraToWorld.r[3];
// Add the translation
position = XMVectorAdd(position, relativeVector);
// Update the position in the matrix
m_mCameraToWorld.r[3] = position;
// Update the inverse matrix
m_mWorldToCamera = XMMatrixInverse(nullptr, m_mCameraToWorld);
// Update the camera position vector
m_vPosition = position;
m_bClipPlanesValid = false;
m_bViewProjMatrixValid = false;
}
///////////////////////////////////////////////////////////////////////////////
void Camera::SetCameraToWorldMatrix(FXMMATRIX ctw)
{
m_mCameraToWorld = ctw;
m_mWorldToCamera = XMMatrixInverse(nullptr, m_mCameraToWorld);
// Extract the position from the matrix
m_vPosition = m_mCameraToWorld.r[3];
m_bClipPlanesValid = false;
m_bViewProjMatrixValid = false;
}
///////////////////////////////////////////////////////////////////////////////
void Camera::SetWorldToCameraMatrix(FXMMATRIX wtc)
{
m_mWorldToCamera = wtc;
m_mCameraToWorld = XMMatrixInverse(nullptr, m_mWorldToCamera);
// Extract the position from the inverse matrix
m_vPosition = m_mCameraToWorld.r[3];
m_bClipPlanesValid = false;
m_bViewProjMatrixValid = false;
}
///////////////////////////////////////////////////////////////////////////////
bool Camera::SphereVisibilityCheck(FXMVECTOR pos, float radius)
{
// Quick near/far plane check
XMVECTOR centerToEye = XMVectorSubtract(pos, m_vPosition);
float distanceAlongView = XMVectorGetX(XMVector3Dot(centerToEye, m_mWorldToCamera.r[2]));
if (distanceAlongView + radius < m_fNearPlane || distanceAlongView - radius > m_fFarPlane)
{
return false;
}
// Check against the frustum planes
if (!m_bClipPlanesValid)
{
UpdateClipPlanes();
}
// Test against each frustum plane
for (const auto& plane : m_ClipPlanes)
{
// Calculate signed distance from sphere center to plane
float distance = XMVectorGetX(XMVector3Dot(pos, plane)) - XMVectorGetW(plane);
// If the sphere is completely behind any plane, it's outside the frustum
if (distance < -radius)
{
return false;
}
}
// If we get here, the sphere is visible
return true;
}
///////////////////////////////////////////////////////////////////////////////
void Camera::UpdateClipPlanes()
{
// Get the view-projection matrix
XMMATRIX viewProj = GetViewProjectionMatrix();
// Extract the 6 planes from the view-projection matrix
// Left, right, top, bottom, near, far
m_ClipPlanes[0] = XMVectorSet(viewProj.r[0].m128_f32[3] + viewProj.r[0].m128_f32[0],
viewProj.r[1].m128_f32[3] + viewProj.r[1].m128_f32[0],
viewProj.r[2].m128_f32[3] + viewProj.r[2].m128_f32[0],
viewProj.r[3].m128_f32[3] + viewProj.r[3].m128_f32[0]);
m_ClipPlanes[1] = XMVectorSet(viewProj.r[0].m128_f32[3] - viewProj.r[0].m128_f32[0],
viewProj.r[1].m128_f32[3] - viewProj.r[1].m128_f32[0],
viewProj.r[2].m128_f32[3] - viewProj.r[2].m128_f32[0],
viewProj.r[3].m128_f32[3] - viewProj.r[3].m128_f32[0]);
m_ClipPlanes[2] = XMVectorSet(viewProj.r[0].m128_f32[3] - viewProj.r[0].m128_f32[1],
viewProj.r[1].m128_f32[3] - viewProj.r[1].m128_f32[1],
viewProj.r[2].m128_f32[3] - viewProj.r[2].m128_f32[1],
viewProj.r[3].m128_f32[3] - viewProj.r[3].m128_f32[1]);
m_ClipPlanes[3] = XMVectorSet(viewProj.r[0].m128_f32[3] + viewProj.r[0].m128_f32[1],
viewProj.r[1].m128_f32[3] + viewProj.r[1].m128_f32[1],
viewProj.r[2].m128_f32[3] + viewProj.r[2].m128_f32[1],
viewProj.r[3].m128_f32[3] + viewProj.r[3].m128_f32[1]);
m_ClipPlanes[4] = XMVectorSet(viewProj.r[0].m128_f32[2],
viewProj.r[1].m128_f32[2],
viewProj.r[2].m128_f32[2],
viewProj.r[3].m128_f32[2]);
m_ClipPlanes[5] = XMVectorSet(viewProj.r[0].m128_f32[3] - viewProj.r[0].m128_f32[2],
viewProj.r[1].m128_f32[3] - viewProj.r[1].m128_f32[2],
viewProj.r[2].m128_f32[3] - viewProj.r[2].m128_f32[2],
viewProj.r[3].m128_f32[3] - viewProj.r[3].m128_f32[2]);
// Normalize all the planes
for (auto& plane : m_ClipPlanes)
{
XMVECTOR normal = XMVectorSet(
XMVectorGetX(plane),
XMVectorGetY(plane),
XMVectorGetZ(plane),
0.0f
);
float normalLength = XMVectorGetX(XMVector3Length(normal));
float invLength = 1.0f / normalLength;
plane = XMVectorScale(plane, invLength);
}
m_bClipPlanesValid = true;
}
///////////////////////////////////////////////////////////////////////////////
float Camera::GetPixelScaleForZ(float z) const
{
// Calculate the scale of a pixel at distance z
float tanHalfFov = tanf(m_fFieldOfView * 0.5f);
return z * tanHalfFov * 2.0f / (m_fAspectRatio * 720.0f); // Assuming 720p height
}
///////////////////////////////////////////////////////////////////////////////
XMMATRIX Camera::GetViewProjectionMatrix()
{
if (!m_bViewProjMatrixValid)
{
m_mViewProjMatrix = XMMatrixMultiply(m_mWorldToCamera, m_mProjection);
m_bViewProjMatrixValid = true;
}
return m_mViewProjMatrix;
}
///////////////////////////////////////////////////////////////////////////////
void Camera::GetCameraPosition(XMFLOAT3* pPos) const
{
XMStoreFloat3(pPos, m_vPosition);
}
///////////////////////////////////////////////////////////////////////////////
void Camera::GetCameraLookAt(XMFLOAT3* pLook) const
{
XMStoreFloat3(pLook, m_vLookAt);
}
+76
View File
@@ -0,0 +1,76 @@
//
// camera.h - Modern Windows 11 port
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001, Pipeworks Software Inc. (Original)
// Modern Port Copyright (c) 2023
// All rights reserved
#pragma once
#include <DirectXMath.h>
#include <vector>
///////////////////////////////////////////////////////////////////////////////
class Camera
{
private:
// Frustum planes for culling
std::vector<DirectX::XMVECTOR> m_ClipPlanes;
bool m_bClipPlanesValid;
float m_fNearPlane;
float m_fFarPlane;
float m_fAspectRatio;
float m_fFieldOfView;
bool m_bViewProjMatrixValid;
DirectX::XMVECTOR m_vPosition;
DirectX::XMVECTOR m_vLookAt;
DirectX::XMVECTOR m_vUp;
DirectX::XMMATRIX m_mViewProjMatrix;
public:
// Matrices
DirectX::XMMATRIX m_mCameraToWorld; // Was matCTW
DirectX::XMMATRIX m_mWorldToCamera; // Was matWTC
DirectX::XMMATRIX m_mProjection; // Was matProj
Camera();
~Camera();
void Init();
void Uninit();
// Sets up the camera view
void LookAt(const DirectX::XMFLOAT3& camPos, const DirectX::XMFLOAT3& lookPt, const DirectX::XMFLOAT3& up);
void LookAt(DirectX::FXMVECTOR camPos, DirectX::FXMVECTOR lookPt, DirectX::FXMVECTOR up);
// Sets up projection matrix
void SetProjection(float fovInRadiansY, float aspectRatio, float nearPlane, float farPlane);
// Movement functions
void Translate(DirectX::FXMVECTOR relativeVector);
// Matrix setters directly
void SetCameraToWorldMatrix(DirectX::FXMMATRIX ctw);
void SetWorldToCameraMatrix(DirectX::FXMMATRIX wtc);
// Visibility checking
bool SphereVisibilityCheck(DirectX::FXMVECTOR position, float radius);
void UpdateClipPlanes();
// Helper functions
float GetPixelScaleForZ(float z) const;
DirectX::XMMATRIX GetViewProjectionMatrix();
// Accessors
void GetCameraPosition(DirectX::XMFLOAT3* pPos) const;
void GetCameraLookAt(DirectX::XMFLOAT3* pLook) const;
DirectX::XMVECTOR GetCameraPositionVector() const { return m_vPosition; }
DirectX::XMVECTOR GetCameraLookAtVector() const { return m_vLookAt; }
float GetFarPlane() const { return m_fFarPlane; }
float GetNearPlane() const { return m_fNearPlane; }
float GetAspectRatio() const { return m_fAspectRatio; }
float GetFieldOfView() const { return m_fFieldOfView; }
};
+87
View File
@@ -0,0 +1,87 @@
//
// defines.h - Modern Windows 11 port
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001, Pipeworks Software Inc. (Original)
// Modern Port Copyright (c) 2023
// All rights reserved
#pragma once
#include <DirectXMath.h>
// Comment this out in the final build
//#define DEBUG_BUILD
// Animation timing constants
constexpr float DEMO_TOTAL_TIME = 8.0f;
constexpr float FINAL_HOLD_TIME = 2.0f;
constexpr float FINISH_TRANSITION_TIME = 0.8f;
// Text animation constants
constexpr float TEXT_ANIM_START_TIME = (DEMO_TOTAL_TIME - FINAL_HOLD_TIME);
constexpr float TEXT_ANIM_LEN = 0.25f;
// Blob animation constants
constexpr float BLOB_STATIC_END_TIME = 0.6f;
constexpr float OO_BLOB_STATIC_END_TIME = (1.0f / BLOB_STATIC_END_TIME);
constexpr float BLOB_ZERO_INTENSE_END_TIME = (BLOB_STATIC_END_TIME + 0.5f);
constexpr float BLOB_BASE_INTENSITY = 0.3f;
// Finish animation constants
constexpr float FINISH_START_TIME = (DEMO_TOTAL_TIME - FINAL_HOLD_TIME - FINISH_TRANSITION_TIME);
constexpr float FINISH_STOP_TIME = (DEMO_TOTAL_TIME - FINAL_HOLD_TIME);
constexpr float OO_FINISH_DELTA = (1.0f / FINISH_TRANSITION_TIME);
// Intensity animation constants
constexpr float MAX_INTENSITY_TIME = (FINISH_START_TIME - 0.0f);
constexpr float MAX_INTENSITY_DELTA = (MAX_INTENSITY_TIME - BLOB_ZERO_INTENSE_END_TIME);
constexpr float OO_MAX_INTENSITY_DELTA = (1.0f / MAX_INTENSITY_DELTA);
constexpr float DEMO_START_INTENSITY = 0.0f;
// Blob pulse animation constants
constexpr float BLOB_PULSE_START = (BLOB_STATIC_END_TIME);
constexpr float BLOB_PULSE_END = (FINISH_STOP_TIME - 0.4f);
constexpr float BLOB_PULSE_ELAPSED = (BLOB_PULSE_END - BLOB_PULSE_START);
// Blob jitter animation constants
constexpr float BLOB_JITTER_START = (BLOB_STATIC_END_TIME);
constexpr float BLOB_JITTER_DELTA = (FINISH_START_TIME);
constexpr float OO_BLOB_JITTER_DELTA = (1.0f / BLOB_JITTER_DELTA);
// Scene animation constants
constexpr float SCENE_ANIM_LEN = 4.5f;
constexpr float SCENE_ANIM_START_TIME = (BLOB_STATIC_END_TIME + 0.25f);
// Push-out animation constants
constexpr float START_PUSHOUT_RADIUS = 0.0f;
constexpr float PUSHOUT_START_TIME = 0.5f;
constexpr float PUSHOUT_DELTA = 2.7f;
constexpr float OO_PUSHOUT_DELTA = (1.0f / PUSHOUT_DELTA);
// Shield animation constants
constexpr float SHIELD_FADE_IN_START_TIME = (BLOB_STATIC_END_TIME);
constexpr float SHIELD_FADE_IN_DELTA = 1.2f;
constexpr float OO_SHIELD_FADE_IN_DELTA = (1.0f / SHIELD_FADE_IN_DELTA);
constexpr float SHIELD_FADE_OUT_START_TIME = (FINISH_START_TIME - 0.1f);
constexpr float SHIELD_FADE_OUT_DELTA = (FINISH_TRANSITION_TIME * 0.2f);
constexpr float OO_SHIELD_FADE_OUT_DELTA = (1.0f / SHIELD_FADE_OUT_DELTA);
// Glow animation constants
constexpr float GLOW_FADE_CIRCLE_START = (FINISH_START_TIME - 0.5f);
constexpr float GLOW_FADE_CIRCLE_MUL = (1.0f / 0.3f);
constexpr float GLOW_FADE_SCREEN_START = (GLOW_FADE_CIRCLE_START + 0.3f);
constexpr float GLOW_FADE_SCREEN_MUL = (1.0f / 0.25f);
// Slash gradient animation constants
constexpr float SLASH_GRADIENT_TRANSITION_START = (FINISH_START_TIME - 0.5f);
constexpr float SLASH_GRADIENT_TRANSITION_END = (FINISH_STOP_TIME);
constexpr float SLASH_GRADIENT_TRANSITION_MUL = (1.0f / (SLASH_GRADIENT_TRANSITION_END - SLASH_GRADIENT_TRANSITION_START));
// Scene detail settings
constexpr float SCENE_LO_DETAIL_START = (FINISH_START_TIME);
// Feature flags
#ifdef DEBUG_BUILD
#define INCLUDE_PLACEMENT_DOODAD
#define INCLUDE_INPUT
#endif
+1
View File
@@ -0,0 +1 @@
DIRS=lib
+56
View File
@@ -0,0 +1,56 @@
#ifdef STARTUPANIMATION
#pragma data_seg("INIT_RW")
#pragma code_seg("INIT")
#pragma bss_seg("INIT_RW")
#pragma const_seg("INIT_RD")
// Tell linker to put bootsound code and data into INIT section
#pragma comment(linker, "/merge:DSOUND=INIT")
#pragma comment(linker, "/merge:INIT_RD=INIT")
#pragma comment(linker, "/merge:INIT_RW=INIT")
#endif //STARTUPANIMATION
unsigned const short pitch_table_dsp[] = {
0x80
};
unsigned short FM32768[32768];
unsigned short Sin128[128];
unsigned short Saw128[128];
unsigned short Noise8192[8192];
unsigned short ThunEl16[0x5540]; // size from thunel16k.equ
unsigned short ReverseThunEl16[0x5540]; // reversed version
unsigned const char ThunEl16Data[] = {
#include "thunel16.x00"
};
unsigned short Glock[3768]; // size from glock.equ
unsigned const char GlockData[] = {
#include "glock.x00"
};
unsigned short Bubble[6719]; // size from bubble.equ
unsigned const char BubbleData[] = {
#include "Bubble.x00"
};
+142
View File
@@ -0,0 +1,142 @@
/*--
Original Copyright (c) 2000 Microsoft Corporation - Xbox SDK
Module Name:
fastmath.cpp
--*/
#include "fastmath.h"
#include <algorithm>
namespace FastMath
{
//----------------------------------------------------------------------------
// atan
float Atan(float x)
{
return std::atanf(x);
}
//----------------------------------------------------------------------------
// atan2
float Atan2(float y, float x)
{
return std::atan2f(y, x);
}
//----------------------------------------------------------------------------
// acos
float Acos(float x)
{
return std::acosf(x);
}
//----------------------------------------------------------------------------
// asin
float Asin(float x)
{
return std::asinf(x);
}
//----------------------------------------------------------------------------
// log - natural logarithm
float Log(float x)
{
return std::logf(x);
}
//----------------------------------------------------------------------------
// log10
float Log10(float x)
{
return std::log10f(x);
}
//----------------------------------------------------------------------------
// exp
float Exp(float x)
{
return std::expf(x);
}
//----------------------------------------------------------------------------
// Compute both sin and cos together for efficiency
void SinCos(float x, SinCosPair* result)
{
// DirectXMath doesn't have a combined sincos function
// So we'll compute them separately
result->fSin = Sin(x);
result->fCos = Cos(x);
}
//----------------------------------------------------------------------------
// sin
float Sin(float x)
{
return DirectX::XMScalarSin(x);
}
//----------------------------------------------------------------------------
// cos
float Cos(float x)
{
return DirectX::XMScalarCos(x);
}
//----------------------------------------------------------------------------
// tan
float Tan(float x)
{
return std::tanf(x);
}
//----------------------------------------------------------------------------
// pow
float Pow(float x, float y)
{
return std::powf(x, y);
}
//----------------------------------------------------------------------------
// hypot - compute sqrt(x*x + y*y) without intermediate overflow
float Hypot(float x, float y)
{
return std::hypotf(x, y);
}
//----------------------------------------------------------------------------
// ceil
float Ceil(float x)
{
return std::ceilf(x);
}
//----------------------------------------------------------------------------
// floor
float Floor(float x)
{
return std::floorf(x);
}
//----------------------------------------------------------------------------
// tanh
float Tanh(float x)
{
return std::tanhf(x);
}
//----------------------------------------------------------------------------
// cosh
float Cosh(float x)
{
return std::coshf(x);
}
//----------------------------------------------------------------------------
// sinh
float Sinh(float x)
{
return std::sinhf(x);
}
}
+156
View File
@@ -0,0 +1,156 @@
/*--
Original Copyright (c) 1999 - 2000 Microsoft Corporation - Xbox SDK Framework
Module Name:
FastMath.h
Abstract:
General math support including fast replacements for the standard math
library. Modern version uses DirectXMath and SIMD intrinsics.
Revision History:
Original Xbox implementation by Microsoft
Modern port to Windows 11 with DirectXMath
--*/
#pragma once
#include <DirectXMath.h>
#include <DirectXPackedVector.h>
#include <cmath>
#include <immintrin.h>
#include <cfloat>
//------------------------------------------------------------------------------
// Constants
constexpr float PI = 3.14159265358979323846f; // Pi
constexpr float PI_MUL_2 = 6.28318530717958623200f; // 2 * Pi
constexpr float PI_DIV_2 = 1.57079632679489655800f; // Pi / 2
constexpr float PI_DIV_4 = 0.78539816339744827900f; // Pi / 4
constexpr float INV_PI = 0.31830988618379069122f; // 1 / Pi
constexpr float DEGTORAD = 0.01745329251994329547f; // Degrees to Radians
constexpr float RADTODEG = 57.29577951308232286465f; // Radians to Degrees
constexpr float FLOAT_SMALL = 1.0e-6f; // Small number for floats
constexpr float FLOAT_HUGE = 1.0e+38f; // Huge number for floats
constexpr float FLOAT_EPSILON = 1.0e-5f; // Tolerance for floats
constexpr float FLOAT_INFINITY = FLT_MAX; // Infinity value for float
//----------------------------------------------------------------------------
// Define a C++ structure to hold a pair of floats for sin/cos operations
struct SinCosPair
{
float fCos;
float fSin;
};
//----------------------------------------------------------------------------
// Fast math replacement functions, optimized using SIMD instructions
namespace FastMath
{
// Trigonometric functions
float Atan(float x);
float Atan2(float y, float x);
float Acos(float x);
float Asin(float x);
void SinCos(float x, SinCosPair* result);
float Sin(float x);
float Cos(float x);
float Tan(float x);
// Logarithmic and exponential functions
float Log(float x);
float Log10(float x);
float Exp(float x);
float Pow(float x, float y);
// Square root and inverse square root
float Sqrt(float x);
float InverseSqrt(float x);
// Absolute value
float Abs(float x);
// Additional functions not in original but useful
float Hypot(float x, float y);
float Ceil(float x);
float Floor(float x);
float Tanh(float x);
float Cosh(float x);
float Sinh(float x);
// Vector operations using DirectXMath
DirectX::XMVECTOR VectorAdd(DirectX::XMVECTOR v1, DirectX::XMVECTOR v2);
DirectX::XMVECTOR VectorSubtract(DirectX::XMVECTOR v1, DirectX::XMVECTOR v2);
DirectX::XMVECTOR VectorMultiply(DirectX::XMVECTOR v1, DirectX::XMVECTOR v2);
DirectX::XMVECTOR VectorDivide(DirectX::XMVECTOR v1, DirectX::XMVECTOR v2);
DirectX::XMVECTOR VectorCross(DirectX::XMVECTOR v1, DirectX::XMVECTOR v2);
float VectorDot(DirectX::XMVECTOR v1, DirectX::XMVECTOR v2);
DirectX::XMVECTOR VectorNormalize(DirectX::XMVECTOR v);
float VectorLength(DirectX::XMVECTOR v);
float VectorLengthSquared(DirectX::XMVECTOR v);
}
// Inline implementations for the most critical functions
inline float FastMath::Abs(float x)
{
return std::fabsf(x);
}
inline float FastMath::Sqrt(float x)
{
return DirectX::XMVectorGetX(DirectX::XMVectorSqrt(DirectX::XMVectorReplicate(x)));
}
inline float FastMath::InverseSqrt(float x)
{
return DirectX::XMVectorGetX(DirectX::XMVectorReciprocalSqrt(DirectX::XMVectorReplicate(x)));
}
inline DirectX::XMVECTOR FastMath::VectorAdd(DirectX::XMVECTOR v1, DirectX::XMVECTOR v2)
{
return DirectX::XMVectorAdd(v1, v2);
}
inline DirectX::XMVECTOR FastMath::VectorSubtract(DirectX::XMVECTOR v1, DirectX::XMVECTOR v2)
{
return DirectX::XMVectorSubtract(v1, v2);
}
inline DirectX::XMVECTOR FastMath::VectorMultiply(DirectX::XMVECTOR v1, DirectX::XMVECTOR v2)
{
return DirectX::XMVectorMultiply(v1, v2);
}
inline DirectX::XMVECTOR FastMath::VectorDivide(DirectX::XMVECTOR v1, DirectX::XMVECTOR v2)
{
return DirectX::XMVectorDivide(v1, v2);
}
inline DirectX::XMVECTOR FastMath::VectorCross(DirectX::XMVECTOR v1, DirectX::XMVECTOR v2)
{
return DirectX::XMVector3Cross(v1, v2);
}
inline float FastMath::VectorDot(DirectX::XMVECTOR v1, DirectX::XMVECTOR v2)
{
return DirectX::XMVectorGetX(DirectX::XMVector3Dot(v1, v2));
}
inline DirectX::XMVECTOR FastMath::VectorNormalize(DirectX::XMVECTOR v)
{
return DirectX::XMVector3Normalize(v);
}
inline float FastMath::VectorLength(DirectX::XMVECTOR v)
{
return DirectX::XMVectorGetX(DirectX::XMVector3Length(v));
}
inline float FastMath::VectorLengthSquared(DirectX::XMVECTOR v)
{
return DirectX::XMVectorGetX(DirectX::XMVector3LengthSq(v));
}
+6
View File
@@ -0,0 +1,6 @@
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the components of NT OS/2
#
!INCLUDE $(NTMAKEENV)\makefile.def
+16
View File
@@ -0,0 +1,16 @@
MAJORCOMP=ntos
MINORCOMP=ani
TARGETNAME=ani
TARGETPATH=$(BASEDIR)\private\ntos\obj
TARGETTYPE=LIBRARY
INCLUDES=$(BASEDIR)\private\inc\aug01;$(BASEDIR)\public\xdk\inc;$(BASEDIR)\private\ntos\inc;$(INCLUDES);$(BASEDIR)\private\inc
C_DEFINES=$(C_DEFINES) /DSTARTUPANIMATION /DBINARY_RESOURCE /D_NTSYSTEM_ /DBOOTSOUND
!include ..\sources.inc
SOURCES=$(SOURCES) \
bootsound.cpp \
animate.c
File diff suppressed because it is too large Load Diff
+588
View File
@@ -0,0 +1,588 @@
//
// logo_renderer.cpp
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001, Pipeworks Software Inc.
// All rights reserved
#include "precomp.h"
#include "xbs_app.h"
#include "logo_renderer.h"
#include "logo_geometry.h"
#include "text_geometry.h"
#include "tm_pixels.h"
#include "renderer.h"
#include "tex_gen.h"
#include "xbs_app.h"
///////////////////////////////////////////////////////////////////////////////
float * LogoRenderer::decompressPosData(short *pdata,int ncount,float f_oo_scale,float f_delta)
{
float * p_data = (float *)MemAlloc(ncount * sizeof(float) * 3);
for(int i = 0; i < ncount * 3;i++)
{
p_data[i] = ( (float)pdata[i] ) * f_oo_scale + f_delta;
}
return p_data;
}
///////////////////////////////////////////////////////////////////////////////
float * LogoRenderer::decompressPosTexData(short *pdata,int ncount,
float f_oo_pos_scale,float f_pos_delta,
float f_oo_tex_scale,float f_tex_delta )
{
float * p_data = (float *)MemAlloc(ncount * sizeof(float) * 5);
for(int i = 0; i < ncount*5;i+=5)
{
p_data[i ] = ( (float)pdata[i ] ) * f_oo_pos_scale + f_pos_delta;
p_data[i+1] = ( (float)pdata[i+1] ) * f_oo_pos_scale + f_pos_delta;
p_data[i+2] = ( (float)pdata[i+2] ) * f_oo_pos_scale + f_pos_delta;
p_data[i+3] = ( (float)pdata[i+3] ) * f_oo_tex_scale + f_tex_delta;
p_data[i+4] = ( (float)pdata[i+4] ) * f_oo_tex_scale + f_tex_delta;
}
return p_data;
}
///////////////////////////////////////////////////////////////////////////////
WORD * LogoRenderer::decompressIndexData(char *pdata,int ncount)
{
WORD * p_data = (WORD *)MemAlloc(ncount * sizeof(WORD));
p_data[0] = (WORD)pdata[0];
char * pbytes = pdata;
for(int i = 1; i < ncount; i++)
{
if(pbytes[i] == 126)
{
char hi = pbytes[i+1];
char lo = pbytes[i+2];
p_data[i] = ((((short)hi)&0xff)<<8) | (((short)lo)&0xff);
p_data[i] += p_data[i-1];
pbytes += 2;
}
else
{
p_data[i] = p_data[i-1] + pbytes[i];
}
}
return p_data;
}
///////////////////////////////////////////////////////////////////////////////
void LogoRenderer::create()
{
decompressData();
createSlash();
createText();
createTMs();
pSlashTexture = NULL;
#ifndef BINARY_RESOURCE
dwInteriorPShader = gApp.loadPixelShader ("d:\\shaders\\slash_interior.xpu");
#else // BINARY_RESOURCE
dwInteriorPShader = gApp.loadPixelShader ( g_slash_interior_xpu );
#endif // BINARY_RESOURCE
DWORD dwDecl[] =
{
D3DVSD_STREAM( 0 ),
D3DVSD_REG( 0, D3DVSDT_FLOAT3 ),
D3DVSD_REG( 1, D3DVSDT_FLOAT2 ),
D3DVSD_END()
};
#ifndef BINARY_RESOURCE
dwInteriorVShader = gApp.loadVertexShader("d:\\shaders\\slash_interior.xvu",dwDecl);
#else // BINARY_RESOURCE
dwInteriorVShader = gApp.loadVertexShader ( g_slash_interior_xvu,dwDecl );
#endif // BINARY_RESOURCE
}
///////////////////////////////////////////////////////////////////////////////
void LogoRenderer::decompressData()
{
indices_xboxlogolip_0 = decompressIndexData(indices_xboxlogolip_0C,index_count_xboxlogolip_0);
verts_xboxlogolip_0 = decompressPosTexData(verts_xboxlogolip_0C,
vertex_count_xboxlogolip_0,
xbl_OO_POS_SCALE,xbl_POS_DELTA,
xbl_OO_TEX_SCALE,xbl_TEX_DELTA );
indices_xboxlogosurface_0 = decompressIndexData(indices_xboxlogosurface_0C,index_count_xboxlogosurface_0);
verts_xboxlogosurface_0 = decompressPosTexData(verts_xboxlogosurface_0C,
vertex_count_xboxlogosurface_0,
xbl_OO_POS_SCALE,xbl_POS_DELTA,
xbl_OO_TEX_SCALE,xbl_TEX_DELTA );
indices_xboxlogosurfacetop_0 = decompressIndexData(indices_xboxlogosurfacetop_0C,index_count_xboxlogosurfacetop_0);
verts_xboxlogosurfacetop_0 = decompressPosTexData(verts_xboxlogosurfacetop_0C,
vertex_count_xboxlogosurfacetop_0,
xbl_OO_POS_SCALE,xbl_POS_DELTA,
xbl_OO_TEX_SCALE,xbl_TEX_DELTA );
indices_xboxlogointerior_0 = decompressIndexData(indices_xboxlogointerior_0C,index_count_xboxlogointerior_0);
verts_xboxlogointerior_0 = decompressPosTexData(verts_xboxlogointerior_0C,
vertex_count_xboxlogointerior_0,
xbl_OO_POS_SCALE,xbl_POS_DELTA,
xbl_OO_TEX_SCALE,xbl_TEX_DELTA );
indices_tm_slash_0 = decompressIndexData(indices_tm_slash_0C,index_count_tm_slash_0);
verts_tm_slash_0 = decompressPosTexData(verts_tm_slash_0C,
vertex_count_tm_slash_0,
xbl_OO_POS_SCALE,xbl_POS_DELTA,
xbl_OO_TEX_SCALE,xbl_TEX_DELTA );
indices_tm_wordmark_0 = decompressIndexData(indices_tm_wordmark_0C,index_count_tm_wordmark_0);
verts_tm_wordmark_0 = decompressPosTexData(verts_tm_wordmark_0C,
vertex_count_tm_wordmark_0,
xbl_OO_POS_SCALE,xbl_POS_DELTA,
xbl_OO_TEX_SCALE,xbl_TEX_DELTA );
indices_text_0 = decompressIndexData(indices_text_0C,index_count_text_0);
verts_text_0 = decompressPosData(verts_text_0C,vertex_count_text_0,xbt_OO_POS_SCALE,xbt_POS_DELTA );
}
///////////////////////////////////////////////////////////////////////////////
void LogoRenderer::createSlash()
{
xbl_vertex *pv = NULL;
nLipIndices = index_count_xboxlogolip_0;
nLipVerts = vertex_count_xboxlogolip_0;
pLipIndices = indices_xboxlogolip_0;
gpd3dDev->CreateVertexBuffer(sizeof(xbl_vertex) * nLipVerts,NULL,FVF_xbl,NULL,&pLipVB);
pLipVB->Lock(0,0,(BYTE **)&pv,0);
memcpy(pv,verts_xboxlogolip_0,sizeof(xbl_vertex) * nLipVerts);
pLipVB->Unlock();
pLipTex = CreateGradientTexture(16,128,0xff000100,0xff4b9b4b);
nSurfaceIndices = index_count_xboxlogosurface_0;
nSurfaceVerts = vertex_count_xboxlogosurface_0;
pSurfaceIndices = indices_xboxlogosurface_0;
gpd3dDev->CreateVertexBuffer(sizeof(xbl_vertex) * nSurfaceVerts,NULL,FVF_xbl,NULL,&pSurfaceVB);
pSurfaceVB->Lock(0,0,(BYTE **)&pv,0);
memcpy(pv,verts_xboxlogosurface_0,sizeof(xbl_vertex) * nSurfaceVerts);
pSurfaceVB->Unlock();
pSurfaceTex = CreateHighlightTexture(256,6,false,0.5f,0.5f);
nSurfaceTopIndices = index_count_xboxlogosurfacetop_0;
nSurfaceTopVerts = vertex_count_xboxlogosurfacetop_0;
pSurfaceTopIndices = indices_xboxlogosurfacetop_0;
gpd3dDev->CreateVertexBuffer(sizeof(xbl_vertex) * nSurfaceVerts,NULL,FVF_xbl,NULL,&pSurfaceTopVB);
pSurfaceTopVB->Lock(0,0,(BYTE **)&pv,0);
memcpy(pv,verts_xboxlogosurfacetop_0,sizeof(xbl_vertex) * nSurfaceTopVerts);
// HACK to enforce border color.
for(int i=0; i < (int)nSurfaceTopVerts;i++)
{
if(fast_fabs(pv[i].v0-1.f) <= 0.01f)
pv[i].v0 = -1.f;
}
pSurfaceTopVB->Unlock();
pSurfaceTopTex = CreateGradientTexture(16,128,0xff000000,0xffffffff);
nInteriorIndices = index_count_xboxlogointerior_0;
nInteriorVerts = vertex_count_xboxlogointerior_0;
pInteriorIndices = indices_xboxlogointerior_0;
gpd3dDev->CreateVertexBuffer(sizeof(xbl_vertex) * nInteriorVerts,NULL,FVF_xbl,NULL,&pInteriorVB);
pInteriorVB->Lock(0,0,(BYTE **)&pv,0);
memcpy(pv,verts_xboxlogointerior_0,sizeof(xbl_vertex) * nInteriorVerts);
pInteriorVB->Unlock();
}
///////////////////////////////////////////////////////////////////////////////
void LogoRenderer::createText()
{
xbt_vertex *pv;
nText_Verts = vertex_count_text_0;
nText_Indices = index_count_text_0;
pText_Indices = indices_text_0;
gpd3dDev->CreateVertexBuffer(sizeof(xbt_vertex) * nText_Verts,NULL,FVF_xbt,NULL,&pText_VB);
pText_VB->Lock(0,0,(BYTE **)&pv,0);
memcpy(pv,verts_text_0,sizeof(xbt_vertex) * nText_Verts);
pText_VB->Unlock();
SetIdentity(&matText_Anim);
bRenderText = false;
}
///////////////////////////////////////////////////////////////////////////////
void LogoRenderer::createTMs()
{
xbl_vertex *pv;
nSlashTM_Verts = vertex_count_tm_slash_0;
nSlashTM_Indices = index_count_tm_slash_0;
pSlashTM_Indices = indices_tm_slash_0;
gpd3dDev->CreateVertexBuffer(sizeof(xbl_vertex) * nSlashTM_Verts,NULL,FVF_xbl,NULL,&pSlashTM_VB);
pSlashTM_VB->Lock(0,0,(BYTE **)&pv,0);
memcpy(pv,verts_tm_slash_0,sizeof(xbl_vertex) * nSlashTM_Verts);
pSlashTM_VB->Unlock();
nTextTM_Verts = vertex_count_tm_wordmark_0;
nTextTM_Indices = index_count_tm_wordmark_0;
pTextTM_Indices = indices_tm_wordmark_0;
gpd3dDev->CreateVertexBuffer(sizeof(xbl_vertex) * nTextTM_Verts,NULL,FVF_xbl,NULL,&pTextTM_VB);
pTextTM_VB->Lock(0,0,(BYTE **)&pv,0);
memcpy(pv,verts_tm_wordmark_0,sizeof(xbl_vertex) * nTextTM_Verts);
pTextTM_VB->Unlock();
gpd3dDev->CreateTexture( 16,16,1,0,D3DFMT_A8R8G8B8,0,&pTMTex);
D3DLOCKED_RECT rc;
pTMTex->LockRect(0,&rc,NULL,0);
XGSwizzleRect( tm_pixels,
0,
NULL,
rc.pBits,
16,
16,
NULL,
sizeof(DWORD) );
pTMTex->UnlockRect(0);
fTMAlpha = 0.f;
}
///////////////////////////////////////////////////////////////////////////////
void LogoRenderer::createSlashSurface()
{
bool b_want_wordmark = (gApp.getElapsedTime() >= TEXT_ANIM_START_TIME + TEXT_ANIM_LEN);
if (pSlashTexture && (b_want_wordmark == bHasWordmark)) return;
LPDIRECT3DSURFACE8 pSlashSurface;
LPDIRECT3DSURFACE8 pSlashDepthBuf;
D3DFORMAT fmt = D3DFMT_A8R8G8B8;
DWORD mst = D3DMULTISAMPLE_2_SAMPLES_MULTISAMPLE_LINEAR;
int x_dim = 1024;
int y_dim = 1024;
gpd3dDev->CreateRenderTarget(x_dim, y_dim, fmt, mst, TRUE, &pSlashSurface);
gpd3dDev->CreateDepthStencilSurface(x_dim,y_dim,D3DFMT_LIN_D24S8, mst, &pSlashDepthBuf);
if (!pSlashTexture) gpd3dDev->CreateTexture(x_dim, y_dim, 1, 0, fmt, 0, &pSlashTexture);
LPDIRECT3DSURFACE8 pOldRT,pOldZ;
gpd3dDev->GetRenderTarget(&pOldRT);
gpd3dDev->GetDepthStencilSurface(&pOldZ);
gpd3dDev->SetRenderTarget(pSlashSurface, pSlashDepthBuf);
if( gpd3dDev->BeginScene() == D3D_OK )
{
gpd3dDev->Clear(0,NULL,
D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL,
0xff000000,
1.f,
0 );
bool b_old_render_text = bRenderText;
bRenderText = b_want_wordmark;
render(gApp.camController.getSlashTransform(), true);
bRenderText = b_old_render_text;
gpd3dDev->EndScene();
LPDIRECT3DSURFACE8 p_tex_surf;
pSlashTexture->GetSurfaceLevel(0, &p_tex_surf);
gpd3dDev->CopyRects(pSlashSurface, NULL, 0, p_tex_surf, NULL);
p_tex_surf->Release();
bHasWordmark = b_want_wordmark;
}
pSlashSurface->Release();
pSlashDepthBuf->Release();
gpd3dDev->SetRenderTarget(pOldRT,pOldZ);
pOldRT->Release();
pOldZ->Release();
}
///////////////////////////////////////////////////////////////////////////////
void LogoRenderer::destroy()
{
pLipVB->Release();
pLipTex->Release();
pSurfaceVB->Release();
pSurfaceTex->Release();
pSurfaceTopVB->Release();
pSurfaceTopTex->Release();
pInteriorVB->Release();
pText_VB->Release();
pSlashTM_VB->Release();
pTextTM_VB->Release();
pTMTex->Release();
pSlashTexture->Release();
MemFree(indices_xboxlogolip_0);
MemFree(verts_xboxlogolip_0);
MemFree(indices_xboxlogosurface_0);
MemFree(verts_xboxlogosurface_0);
MemFree(indices_xboxlogosurfacetop_0);
MemFree(verts_xboxlogosurfacetop_0);
MemFree(indices_xboxlogointerior_0);
MemFree(verts_xboxlogointerior_0);
MemFree(indices_tm_wordmark_0);
MemFree(verts_tm_wordmark_0);
MemFree(indices_tm_slash_0);
MemFree(verts_tm_slash_0);
MemFree(indices_text_0);
MemFree(verts_text_0);
gpd3dDev->DeleteVertexShader(dwInteriorVShader);
gpd3dDev->DeletePixelShader (dwInteriorPShader);
}
///////////////////////////////////////////////////////////////////////////////
void LogoRenderer::advanceTime(float fElapsedTime, float fDt)
{
if(fElapsedTime >= TEXT_ANIM_START_TIME)
{
bRenderText = true;
int n_samples = sizeof(pos_anim_text)/sizeof( D3DVECTOR );
float f_norm_pos = (fElapsedTime - TEXT_ANIM_START_TIME) / TEXT_ANIM_LEN;
float f_pos = f_norm_pos * (n_samples-1);
int pos_idx;
__asm
{
cvttss2si eax, f_pos
mov pos_idx, eax
}
if(f_norm_pos <= 0.f)
{
matText_Anim._41 = pos_anim_text[0].x;
matText_Anim._42 = pos_anim_text[0].y;
matText_Anim._43 = pos_anim_text[0].z;
}
else if(f_norm_pos >= 1.f)
{
int last_pos = n_samples - 1;
matText_Anim._41 = pos_anim_text[last_pos].x;
matText_Anim._42 = pos_anim_text[last_pos].y;
matText_Anim._43 = pos_anim_text[last_pos].z;
}
else
{
float f_frac = f_pos - ((float)pos_idx);
D3DVECTOR &s = pos_anim_text[pos_idx];
D3DVECTOR &e = pos_anim_text[pos_idx+1];
matText_Anim._41 = s.x * (1.f-f_frac) + e.x * f_frac;
matText_Anim._42 = s.y * (1.f-f_frac) + e.y * f_frac;
matText_Anim._43 = s.z * (1.f-f_frac) + e.z * f_frac;
}
fTMAlpha = (fElapsedTime - (TEXT_ANIM_START_TIME)) / (TEXT_ANIM_LEN);
fTMAlpha = max(0.f,min(1.f,fTMAlpha));
fTMAlpha *= 255.f;
}
else
{
bRenderText = false;
fTMAlpha = 0.f;
}
if (fElapsedTime >= FINISH_STOP_TIME)
{
createSlashSurface();
}
}
///////////////////////////////////////////////////////////////////////////////
void LogoRenderer::render(const D3DMATRIX &mat_otw, bool b_force_3d_render)
{
gpd3dDev->SetVertexShader(FVF_xbl);
gpd3dDev->SetPixelShader (NULL);
if (b_force_3d_render || (gApp.getElapsedTime() < FINISH_STOP_TIME))
{
Camera &cam = gApp.theCamera;
gpd3dDev->SetTransform(D3DTS_WORLD,&mat_otw);
gpd3dDev->SetTransform(D3DTS_VIEW,&cam.matWTC);
gpd3dDev->SetTransform(D3DTS_PROJECTION,&cam.matProj);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
gpd3dDev->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE);
gpd3dDev->SetTextureStageState(0,D3DTSS_ADDRESSU, D3DTADDRESS_BORDER );
gpd3dDev->SetTextureStageState(0,D3DTSS_ADDRESSV, D3DTADDRESS_BORDER );
gpd3dDev->SetTextureStageState(0,D3DTSS_BORDERCOLOR, 0xff000000 );
gpd3dDev->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
gpd3dDev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
gpd3dDev->SetRenderState(D3DRS_CULLMODE,D3DCULL_CW);
gpd3dDev->SetStreamSource(0,pLipVB,sizeof(xbl_vertex));
gpd3dDev->SetTexture(0,pLipTex);
gpd3dDev->DrawIndexedVertices(D3DPT_TRIANGLELIST,nLipIndices,pLipIndices);
gpd3dDev->SetStreamSource(0,pSurfaceVB,sizeof(xbl_vertex));
gpd3dDev->SetTexture(0,pSurfaceTex);
gpd3dDev->DrawIndexedVertices(D3DPT_TRIANGLELIST,nSurfaceIndices,pSurfaceIndices);
gpd3dDev->SetStreamSource(0,pSurfaceTopVB,sizeof(xbl_vertex));
gpd3dDev->SetTexture(0,pSurfaceTopTex);
gpd3dDev->DrawIndexedVertices(D3DPT_TRIANGLELIST,nSurfaceTopIndices,pSurfaceTopIndices);
gpd3dDev->SetStreamSource(0,pInteriorVB,sizeof(xbl_vertex));
float fmag = -1.0f + 2.0f * (gApp.getElapsedTime() - SLASH_GRADIENT_TRANSITION_START) * SLASH_GRADIENT_TRANSITION_MUL;
float w1 = max(0.f, min(1.f,-fmag));
float w3 = max(0.f, min(1.f,+fmag));
float w2 = max(0.f, min(1.f,1.f - w1 - w3));
gpd3dDev->SetVertexShader(dwInteriorVShader);
gpd3dDev->SetPixelShader (dwInteriorPShader);
D3DMATRIX mat_final,tmp;
MulMats(mat_otw,cam.getWTP(),&tmp);
SetTranspose(tmp,&mat_final);
gpd3dDev->SetVertexShaderConstant(0,(void *)&mat_final,4);
D3DVECTOR4 vals[5];
if(fmag < 0.f)
{
Set(&vals[0],0.81568f,1.f,0.5921f,1.f);
Set(&vals[1],0.81568f,1.f,0.5921f,1.f);
Set(&vals[2],0.81568f,1.f,0.5294f,1.f);
Set(&vals[3],0.81568f,1.f,0.5294f,1.f);
Set(&vals[4],w1,w1,w1,1.f);
}
else
{
Set(&vals[0],0.81568f,1.f,0.5294f,1.f);
Set(&vals[1],0.81568f,1.f,0.5294f,1.f);
Set(&vals[2],0.796f,0.8745f,0.0039f,1.f);
Set(&vals[3],0.1294f,0.4168f,0.0901f,1.f);
Set(&vals[4],w2,w2,w2,1.f);
}
gpd3dDev->SetVertexShaderConstant(4,(void *)&vals,5);
gpd3dDev->DrawIndexedVertices(D3DPT_TRIANGLELIST,nInteriorIndices,pInteriorIndices);
}
else
{
gpd3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);
gpd3dDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
gpd3dDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
gpd3dDev->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
D3DMATRIX iden;
SetIdentity(&iden);
gpd3dDev->SetTransform(D3DTS_WORLD, &iden);
gpd3dDev->SetTransform(D3DTS_VIEW, &iden);
gpd3dDev->SetTransform(D3DTS_PROJECTION, &iden);
gpd3dDev->SetRenderState(D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_TEXTURE);
gpd3dDev->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1);
gpd3dDev->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TFACTOR);
gpd3dDev->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_TFACTOR);
gpd3dDev->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE);
gpd3dDev->SetTextureStageState(0,D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
gpd3dDev->SetTexture(0,pSlashTexture);
gpd3dDev->SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX2);
gpd3dDev->SetStreamSource(0, gApp.greenFog.borrowScreenQuad(), sizeof(GreenFogVertexBuffer));
gpd3dDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
gpd3dDev->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
// Prepare for rendering text...
gpd3dDev->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
gpd3dDev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
gpd3dDev->SetRenderState(D3DRS_CULLMODE,D3DCULL_CW);
gpd3dDev->SetRenderState( D3DRS_ZWRITEENABLE,TRUE );
gpd3dDev->SetTextureStageState(0,D3DTSS_ADDRESSU, D3DTADDRESS_BORDER );
gpd3dDev->SetTextureStageState(0,D3DTSS_ADDRESSV, D3DTADDRESS_BORDER );
gpd3dDev->SetTextureStageState(0,D3DTSS_BORDERCOLOR, 0xff000000 );
gpd3dDev->SetTransform(D3DTS_WORLD,&mat_otw);
gpd3dDev->SetTransform(D3DTS_VIEW,&gApp.theCamera.matWTC);
gpd3dDev->SetTransform(D3DTS_PROJECTION,&gApp.theCamera.matProj);
}
if(bRenderText && !bHasWordmark)
{
gpd3dDev->SetVertexShader(FVF_xbl);
gpd3dDev->SetPixelShader (NULL);
gpd3dDev->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
DWORD dw_alpha;
float f_alpha = fTMAlpha;
__asm
{
cvttss2si eax, f_alpha
shl eax,24
mov dw_alpha,eax
}
gpd3dDev->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
gpd3dDev->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
gpd3dDev->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
gpd3dDev->SetRenderState(D3DRS_TEXTUREFACTOR,dw_alpha);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_TFACTOR);
gpd3dDev->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_MODULATE);
gpd3dDev->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
gpd3dDev->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_TFACTOR);
gpd3dDev->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE);
gpd3dDev->SetTexture(0,pTMTex);
gpd3dDev->SetStreamSource(0,pSlashTM_VB,sizeof(xbl_vertex));
gpd3dDev->DrawIndexedVertices(D3DPT_TRIANGLELIST,nSlashTM_Indices,pSlashTM_Indices);
gpd3dDev->SetStreamSource(0,pTextTM_VB,sizeof(xbl_vertex));
gpd3dDev->DrawIndexedVertices(D3DPT_TRIANGLELIST,nTextTM_Indices,pTextTM_Indices);
gpd3dDev->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
gpd3dDev->SetRenderState(D3DRS_TEXTUREFACTOR,0xff62ca13);
gpd3dDev->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TFACTOR);
D3DMATRIX anim_otw;
D3DMATRIX flip;
SetXRotation(Pi/2.f,&flip);
D3DMATRIX tmp;
MulMats(flip,matText_Anim,&tmp);
MulMats(tmp,mat_otw,&anim_otw);
gpd3dDev->SetVertexShader(FVF_xbt);
gpd3dDev->SetTransform(D3DTS_WORLD,&anim_otw);
gpd3dDev->SetStreamSource(0,pText_VB,sizeof(xbt_vertex));
gpd3dDev->DrawIndexedVertices(D3DPT_TRIANGLELIST,nText_Indices,pText_Indices);
gpd3dDev->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
}
gpd3dDev->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW);
}
+105
View File
@@ -0,0 +1,105 @@
///////////////////////////////////////////////////////////////////////////////
// File: logo_renderer.h
//
// Copyright 2001 Pipeworks Software
///////////////////////////////////////////////////////////////////////////////
#ifndef __LOGO_RENDERER_H__
#define __LOGO_RENDERER_H__
class LogoRenderer
{
private:
LPDIRECT3DVERTEXBUFFER8 pLipVB;
WORD *pLipIndices;
DWORD nLipVerts;
DWORD nLipIndices;
LPDIRECT3DTEXTURE8 pLipTex;
LPDIRECT3DVERTEXBUFFER8 pSurfaceVB;
WORD *pSurfaceIndices;
DWORD nSurfaceVerts;
DWORD nSurfaceIndices;
LPDIRECT3DTEXTURE8 pSurfaceTex;
LPDIRECT3DVERTEXBUFFER8 pSurfaceTopVB;
WORD *pSurfaceTopIndices;
DWORD nSurfaceTopVerts;
DWORD nSurfaceTopIndices;
LPDIRECT3DTEXTURE8 pSurfaceTopTex;
LPDIRECT3DVERTEXBUFFER8 pInteriorVB;
WORD *pInteriorIndices;
DWORD nInteriorVerts;
DWORD nInteriorIndices;
bool bRenderText;
LPDIRECT3DVERTEXBUFFER8 pText_VB;
WORD *pText_Indices;
DWORD nText_Verts;
DWORD nText_Indices;
D3DMATRIX matText_Anim;
LPDIRECT3DVERTEXBUFFER8 pSlashTM_VB;
WORD *pSlashTM_Indices;
DWORD nSlashTM_Verts;
DWORD nSlashTM_Indices;
LPDIRECT3DVERTEXBUFFER8 pTextTM_VB;
WORD *pTextTM_Indices;
DWORD nTextTM_Verts;
DWORD nTextTM_Indices;
LPDIRECT3DTEXTURE8 pTMTex;
float fTMAlpha;
DWORD dwInteriorPShader;
DWORD dwInteriorVShader;
void createSlash();
void createText();
void createTMs();
LPDIRECT3DTEXTURE8 pSlashTexture;
bool bHasWordmark;
void createSlashSurface(); // don't call until camera is in final position
// Decompressed slash data.
WORD * indices_xboxlogolip_0;
float * verts_xboxlogolip_0;
WORD * indices_xboxlogosurface_0;
float * verts_xboxlogosurface_0;
WORD * indices_xboxlogosurfacetop_0;
float * verts_xboxlogosurfacetop_0;
WORD * indices_xboxlogointerior_0;
float * verts_xboxlogointerior_0;
WORD * indices_tm_wordmark_0;
float * verts_tm_wordmark_0;
WORD * indices_tm_slash_0;
float * verts_tm_slash_0;
// Decompressed wordmark data.
WORD * indices_text_0;
float * verts_text_0;
void decompressData();
float * decompressPosData(short *pdata,int ncount,float f_oo_pos_scale,float f_pos_delta );
float * decompressPosTexData(short *pdata,int ncount,float f_oo_pos_scale,float f_pos_delta,
float f_oo_tex_scale,float f_tex_delta );
WORD * decompressIndexData(char *pdata,int ncount);
public:
void create();
void destroy();
void advanceTime(float fElapsedTime, float fDt);
void render(const D3DMATRIX &mat_otw, bool b_force_3d_render = false);
};
#endif // __LOGO_RENDERER_H__
+303
View File
@@ -0,0 +1,303 @@
#ifdef STARTUPANIMATION
#include "ntos.h"
#include "precomp.h"
#include "mslogo.h"
#include "renderer.h"
#include "xbs_app.h"
#include "xbs_math.h"
#pragma pack(1)
typedef struct _IMAGE_RUN1 {
UINT fOne : 1;
UINT Size : 3;
UINT Intensity : 4;
} IMAGE_RUN1;
typedef struct _IMAGE_RUN2 {
UINT fOne : 1;
UINT fTwo : 1;
UINT Size : 10;
UINT Intensity : 4;
} IMAGE_RUN2;
#pragma pack()
// MS Logo sync event
extern "C" {
INITIALIZED_KEVENT(g_EventLogo, NotificationEvent, FALSE);
INITIALIZED_KEVENT(g_EventLogoWaiting, NotificationEvent, FALSE);
}
IDirect3DVertexBuffer8 *g_pVBMicrosoftLogo;
IDirect3DTexture8* g_pTexMicrosoftLogo;
PBYTE g_ImageLogo;
UINT g_ImageLogoSize;
typedef struct _TheVerts {
float x,y,z,w;
float u, v;
} TheVerts;
const TheVerts Verts[] =
{
{270.0f, 400.0f, 0.5f, 1.0f, 0.0f, 0.0f},
{370.0f, 417.0f, 0.5f, 1.0f, 100.0f, 17.0f},
{270.0f, 417.0f, 0.5f, 1.0f, 0.0f, 17.0f},
{370.0f, 400.0f, 0.5f, 1.0f, 100.0f, 0.0f},
{370.0f, 417.0f, 0.5f, 1.0f, 100.0f, 17.0f},
{270.0f, 400.0f, 0.5f, 1.0f, 0.0f, 0.0f},
};
BOOL InitVB(IDirect3DDevice8 *pDev)
{
IDirect3DVertexBuffer8 *pVB;
void *pVerts;
if (FAILED(IDirect3DDevice8_CreateVertexBuffer(pDev,
sizeof(Verts),
D3DUSAGE_WRITEONLY,
D3DFVF_XYZRHW | D3DFVF_TEX1,
D3DPOOL_MANAGED,
&pVB)))
{
return FALSE;
}
g_pVBMicrosoftLogo = pVB;
IDirect3DVertexBuffer8_Lock(pVB, 0, sizeof(Verts), (BYTE **)(&pVerts), 0);
memcpy((void*)pVerts, (void*)Verts, sizeof(Verts));
IDirect3DVertexBuffer8_Unlock(pVB);
return TRUE;
}
const float F_15 = 15.0f;
const float F_P_5 = 0.5f;
COLORREF ColorFromIntensity(UINT intensity4bits)
{
UINT Base = 0xCC;
UINT cr = (UINT)((Base * intensity4bits) / F_15 + F_P_5);
return D3DCOLOR_ARGB(0xFF, cr, cr, cr);
}
BOOL InitTexture(IDirect3DDevice8 *pDev)
{
IDirect3DTexture8* pTex;
D3DLOCKED_RECT lock;
UINT x = 0, i, j;
DWORD dwLine;
DWORD dwAddr;
IMAGE_RUN1 *pRun1;
IMAGE_RUN2 *pRun2;
UINT Size;
UINT Intensity;
if (FAILED(IDirect3DDevice8_CreateTexture(pDev,
100,
17,
1,
0,
D3DFMT_LIN_X8R8G8B8,
0,
&pTex)))
{
return FALSE;
}
g_pTexMicrosoftLogo = pTex;
IDirect3DTexture8_LockRect(pTex, 0, &lock, NULL, 0);
dwLine = (DWORD)lock.pBits;
dwAddr = dwLine;
i = 0;
while(i < g_ImageLogoSize)
{
Size = 0;
Intensity = 0;
pRun1 = (IMAGE_RUN1*)&g_ImageLogo[i];
if (pRun1->fOne)
{
Size = pRun1->Size;
Intensity = pRun1->Intensity;
i += 1;
}
else
{
pRun2 = (IMAGE_RUN2*)&g_ImageLogo[i];
if (pRun2->fTwo)
{
Size = pRun2->Size;
Intensity = pRun2->Intensity;
i += 2;
}
}
for (j = 0; j < Size; j++)
{
if (Intensity == 0)
{
*(DWORD*)dwAddr = 0xFF000000;
}
else
{
*(DWORD*)dwAddr = ColorFromIntensity(Intensity);
}
if (x >= 99)
{
x = 0;
dwLine += lock.Pitch;
dwAddr = dwLine;
}
else
{
x++;
dwAddr += sizeof(DWORD);
}
}
}
IDirect3DTexture8_UnlockRect(pTex, 0);
return TRUE;
}
void UnInitMicrosoftLogo()
{
if (g_ImageLogo != NULL)
{
MemFree(g_ImageLogo);
}
if (g_pVBMicrosoftLogo != NULL)
{
g_pVBMicrosoftLogo->Release();
}
if (g_pTexMicrosoftLogo != NULL)
{
g_pTexMicrosoftLogo->Release();
}
}
void RenderMicrosoftLogo()
{
if (g_ImageLogo == NULL)
{
return;
}
if (!InitVB(gpd3dDev) || !InitTexture(gpd3dDev))
{
UnInitMicrosoftLogo();
return;
}
IDirect3DDevice8 *pDev = gpd3dDev;
IDirect3DSurface8 *pSurface;
pDev->GetBackBuffer(-1, D3DBACKBUFFER_TYPE_MONO, &pSurface);
pDev->SetRenderTarget(pSurface, NULL);
const DWORD RenderStates[] =
{
D3DRS_FILLMODE, D3DFILL_SOLID,
D3DRS_BACKFILLMODE, D3DFILL_SOLID,
D3DRS_CULLMODE, D3DCULL_NONE,
D3DRS_DITHERENABLE, TRUE,
D3DRS_ALPHATESTENABLE, FALSE,
D3DRS_ALPHABLENDENABLE, FALSE,
D3DRS_FOGENABLE, FALSE,
D3DRS_EDGEANTIALIAS, FALSE,
D3DRS_STENCILENABLE, FALSE,
D3DRS_LIGHTING, FALSE,
D3DRS_MULTISAMPLEMASK, 0xffffffff,
D3DRS_LOGICOP, D3DLOGICOP_NONE,
D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALL,
D3DRS_YUVENABLE, FALSE,
};
const DWORD TextureStates[] =
{
D3DTSS_COLOROP, D3DTOP_SELECTARG1,
D3DTSS_COLORARG1, D3DTA_TEXTURE,
D3DTSS_ALPHAOP, D3DTOP_DISABLE,
D3DTSS_TEXCOORDINDEX, 0,
D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP,
D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP,
D3DTSS_COLORKEYOP, D3DTCOLORKEYOP_DISABLE,
D3DTSS_COLORSIGN, 0,
D3DTSS_ALPHAKILL, D3DTALPHAKILL_DISABLE,
D3DTSS_MINFILTER, D3DTEXF_LINEAR,
D3DTSS_MAGFILTER, D3DTEXF_LINEAR,
};
int i;
for (i = 0; i < sizeof(RenderStates) / (sizeof(DWORD) * 2); i++)
{
pDev->SetRenderState((D3DRENDERSTATETYPE)RenderStates[2*i],
RenderStates[2*i + 1]);
}
for (i = 0; i < sizeof(TextureStates) / (sizeof(DWORD) * 2); i++)
{
pDev->SetTextureStageState(0,
(D3DTEXTURESTAGESTATETYPE)TextureStates[2*i],
TextureStates[2*i + 1]);
}
IDirect3DDevice8_SetStreamSource(pDev, 0, g_pVBMicrosoftLogo, sizeof(Verts[0]));
IDirect3DDevice8_SetVertexShader(pDev, D3DFVF_XYZRHW | D3DFVF_TEX1);
IDirect3DDevice8_SetTexture(pDev, 0, (D3DBaseTexture*)g_pTexMicrosoftLogo);
IDirect3DDevice8_DrawPrimitive(pDev,
D3DPT_TRIANGLELIST,
0,
2);
pSurface->Release();
UnInitMicrosoftLogo();
pDev->PersistDisplay();
}
extern "C"
VOID AniSetLogo(PVOID pv, ULONG Size)
{
if (KeReadStateEvent(&g_EventLogo) == 0)
{
if (gpd3dDev != NULL && pv != NULL && Size <= PAGE_SIZE)
{
g_ImageLogo = (PBYTE)MemAlloc(Size);
if (g_ImageLogo != NULL)
{
memcpy(g_ImageLogo, pv, Size);
g_ImageLogoSize = Size;
}
}
KeSetEvent(&g_EventLogo, EVENT_INCREMENT, FALSE);
}
}
void WaitOnMicrosoftLogo()
{
// Signal the initialization thread that we're waiting for the logo. Note
// that this returns with the dispatcher database lock held, which the
// following wait call will release. This avoids an unnecessary context
// switch.
KeSetEvent(&g_EventLogoWaiting, EVENT_INCREMENT, TRUE);
KeWaitForSingleObject(&g_EventLogo, Executive, KernelMode, FALSE, NULL);
RenderMicrosoftLogo();
}
#endif // STARTUPANIMATION
+7
View File
@@ -0,0 +1,7 @@
#ifndef __MSLOGO_H__
#define __MSLOGO_H__
void WaitOnMicrosoftLogo();
#endif
+89
View File
@@ -0,0 +1,89 @@
#pragma once
#ifdef STARTUPANIMATION
#pragma code_seg("INIT")
#pragma data_seg("INIT_RW")
#pragma bss_seg("INIT_RW")
#pragma const_seg("INIT_RD")
extern "C"
{
#include <ntos.h>
#include <nturtl.h>
};
#endif // STARTUPANIMATION
#include <xtl.h>
#include <xgraphics.h>
#include <stdio.h>
#ifdef _DEBUG
extern int gcMemAllocs;
#ifdef STARTUPANIMATION
extern "C" int gcMemAllocsContiguous;
#endif // STARTUPANIMATION
#endif
inline void* MemAlloc(UINT cBytes)
{
#ifdef _DEBUG
gcMemAllocs++;
#endif
#ifndef STARTUPANIMATION
void* p = LocalAlloc(LMEM_FIXED, cBytes);
if (p)
{
ZeroMemory(p, cBytes);
}
return p;
#else // STARTUPANIMATION
void* p = ExAllocatePoolWithTag(cBytes, 'KD3D');
if (p)
{
// Last-minute hack to fix start-up animation hangs [andrewgo]
ZeroMemory(p, cBytes);
}
return p;
#endif // STARTUPANIMATION
}
inline void* MemAllocNoZero(ULONG cBytes)
{
return MemAlloc(cBytes);
}
inline void MemFree(void* pv)
{
#ifdef _DEBUG
if (gcMemAllocs <= 0)
{
__asm int 3;
}
gcMemAllocs--;
#endif
#ifndef STARTUPANIMATION
LocalFree(pv);
#else // STARTUPANIMATION
ExFreePool(pv);
#endif // STARTUPANIMATION
}
#ifdef STARTUPANIMATION
extern "C"
void *MemAllocContiguous(size_t Size, DWORD Alignment);
extern "C"
void MemFreeContiguous(void *pv);
#endif // STARTUPANIMATION
#ifdef BINARY_RESOURCE
#include "shaders.h"
#endif // BINARY_RESOURCE
#include "fastmath.h"
+158
View File
@@ -0,0 +1,158 @@
//
// prim_types.h
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001, Pipeworks Software Inc.
// All rights reserved
#ifndef __PRIM_TYPES_H__
#define __PRIM_TYPES_H__
enum PrimitiveTypes
{
pt_Sphere = 0,
pt_Cylinder = 1,
pt_Box = 2,
pt_Torus = 3,
pt_Cone = 4,
pt_SurfOfRev = 5,
pt_NoTypes = 6
};
const float OO_PRIM_TRANS_SCALE_X = 0.004131f;
const float OO_PRIM_TRANS_SCALE_Y = 0.008252f;
const float OO_PRIM_TRANS_SCALE_Z = 0.004421f;
const float PRIM_TRANS_DELTA_X = -27.844984f;
const float PRIM_TRANS_DELTA_Y = -0.228729f;
const float PRIM_TRANS_DELTA_Z = 0.497086f;
struct SphereInst
{
short tx,ty,tz;
char idVersion;
char idPosAnim;
char idRotAnim;
float fRad;
};
struct SphereVers
{
char nSegs;
};
struct CylinderInst
{
char idQuat;
short tx,ty,tz;
char idVersion;
char idPosAnim;
char idRotAnim;
float fRad;
float fHalfHeight;
};
struct CylinderVers
{
char nHeightSeg;
char nSides;
};
struct BoxInst
{
char idQuat;
short tx,ty,tz;
char idVersion;
char idPosAnim;
char idRotAnim;
float fLen;
float fHeight;
float fWidth;
};
struct TorusInst
{
char idQuat;
short tx,ty,tz;
char idVersion;
char idPosAnim;
char idRotAnim;
float fRad1;
};
struct TorusVers
{
float fRatio;
char nSegs;
char nSides;
};
struct ConeInst
{
char idQuat;
short tx,ty,tz;
char idVersion;
char idPosAnim;
char idRotAnim;
};
struct ConeVers
{
float fRad1;
float fRad2;
float fHeight;
char nHeightSeg;
char nSides;
};
#define MAX_SOR_PTS 19
struct SurfOfRevInst
{
char idQuat;
short tx,ty,tz;
char idVersion;
char idPosAnim;
char idRotAnim;
};
struct SurfOfRevPt
{
float x,y,z;
char flags;
};
struct SurfOfRevVers
{
SurfOfRevPt pts[MAX_SOR_PTS];
float ax,ay,az;
float px,py,pz;
char nSegs;
char nPts;
};
enum SurfOfRevPtFlags
{
sr_Smooth = 1
};
#define MAX_POS_SAMPLES 30
#define NUM_POS_SEQ 32
const float OO_POS_ANIM_SCALE_X = 0.002755f;
const float OO_POS_ANIM_SCALE_Y = 0.002755f;
const float OO_POS_ANIM_SCALE_Z = 0.002440f;
const float POS_ANIM_DELTA_X = -0.159046f;
const float POS_ANIM_DELTA_Y = -0.741611f;
const float POS_ANIM_DELTA_Z = 2.155624f;
struct PosAnimSeq
{
char posIds[MAX_POS_SAMPLES*3];
};
#define MAX_ROT_SAMPLES 30
#define NUM_ROT_SEQ 29
struct RotAnimSeq
{
char quatIds[MAX_ROT_SAMPLES*3];
};
#endif // __PRIM_TYPES_H__
+38
View File
@@ -0,0 +1,38 @@
//
// qrand.cpp
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001, Pipeworks Software Inc.
#include "precomp.h"
#include "qrand.h"
int QRand::Rand(int scale)
{
_asm
{
mov edi,this
mov eax,[edi]
mov ebx,eax
ror eax,13
sub ebx,11
sub eax,ebx
mov [edi],eax
mul scale
mov eax,edx
}
}
int QRand::Rand()
{
_asm
{
mov edi,this
mov eax,[edi]
mov ebx,eax
ror eax,13
sub ebx,11
sub eax,ebx
mov [edi],eax
}
}
+25
View File
@@ -0,0 +1,25 @@
//
// qrand.cpp
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001, Pipeworks Software Inc.
// All rights reserved
#ifndef __QRAND__
#define __QRAND__
class QRand
{
private:
int seed;
public:
void Init(int initSeed=0x76543210) { seed = initSeed; }
void SetSeed(int newSeed) { seed = newSeed; }
int Rand(int scale);
int Rand();
};
#endif //__QRAND__
+136
View File
@@ -0,0 +1,136 @@
//
// renderer.cpp
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001, Pipeworks Software Inc.
// All rights reserved
#include "precomp.h"
#include "renderer.h"
#include "xbs_app.h"
#ifdef STARTUPANIMATION
#include "mslogo.h"
extern "C" {
#include "av.h"
}
#endif // STARTUPANIMATION
IDirect3DDevice8 *gpd3dDev = NULL;
///////////////////////////////////////////////////////////////////////////////
void Renderer::Init()
{
pD3D8 = NULL;
pD3DDev8 = NULL;
}
///////////////////////////////////////////////////////////////////////////////
void Renderer::UnInit()
{
}
///////////////////////////////////////////////////////////////////////////////
bool Renderer::init(int width,int height)
{
pD3D8 = Direct3DCreate8(D3D_SDK_VERSION);
if(!pD3D8)
return false;
const int size_mul = 2;
const int kick_mul = 2;
pD3D8->SetPushBufferSize(size_mul * 512 * 1024, kick_mul * 32 * 1024);
ZeroMemory( &d3dPresentParams, sizeof(d3dPresentParams) );
d3dPresentParams.BackBufferWidth = width;
d3dPresentParams.BackBufferHeight = height;
d3dPresentParams.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dPresentParams.BackBufferCount = 1;
d3dPresentParams.EnableAutoDepthStencil = TRUE;
d3dPresentParams.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dPresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dPresentParams.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES_SUPERSAMPLE_HORIZONTAL_LINEAR;
// d3dPresentParams.MultiSampleType = D3DMULTISAMPLE_NONE;
// No VSync.
// d3dPresentParams.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
if (gApp.bWideScreen)
{
d3dPresentParams.Flags |= D3DPRESENTFLAG_WIDESCREEN;
}
#ifdef STARTUPANIMATION
// Always do interlaced output on an HDTV.
ULONG AvInfo;
AvSendTVEncoderOption(NULL, AV_QUERY_AV_CAPABILITIES, 0, &AvInfo);
if ((AvInfo & AV_PACK_MASK) == AV_PACK_HDTV)
{
d3dPresentParams.Flags |= D3DPRESENTFLAG_INTERLACED;
}
#endif
if( pD3D8->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
NULL,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dPresentParams,
&pD3DDev8 ) != D3D_OK )
{
#ifndef STARTUPANIMATION
OutputDebugString("Could not initalize Xbox Video!\n");
#endif // STARTUPANIMATION
return false;
}
for( int i=0; i<4; i++ )
{
pD3DDev8->SetTextureStageState( i, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
pD3DDev8->SetTextureStageState( i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
pD3DDev8->SetTextureStageState( i, D3DTSS_MIPFILTER, D3DTEXF_NONE );
pD3DDev8->SetTextureStageState( i, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
pD3DDev8->SetTextureStageState( i, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
pD3DDev8->SetTextureStageState( i, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP );
pD3DDev8->SetTextureStageState( i, D3DTSS_MAXANISOTROPY,4);
}
gpd3dDev = pD3DDev8;
#ifdef STARTUPANIMATION
gpd3dDev->Clear(0,NULL,
D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET,
0x00000000,
1.f,
0 );
gpd3dDev->Present(NULL,NULL,NULL,NULL);
// This delay should allow the TV enough time to lock and ensure
// that the picture doesn't roll on the first few frames of the
// animation.
for (i = 0; i < 4; i++)
{
gpd3dDev->BlockUntilVerticalBlank();
}
#endif // STARTUPANIMATION
return true;
}
///////////////////////////////////////////////////////////////////////////////
void Renderer::shutdown()
{
if( pD3DDev8 )
{
pD3DDev8->Release();
gpd3dDev = NULL;
}
if( pD3D8 )
{
pD3D8->Release();
}
}
+32
View File
@@ -0,0 +1,32 @@
//
// renderer.h
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001, Pipeworks Software Inc.
// All rights reserved
#ifndef __RENDERER_H__
#define __RENDERER_H__
///////////////////////////////////////////////////////////////////////////////
class Renderer
{
private:
IDirect3D8 *pD3D8;
IDirect3DDevice8 *pD3DDev8;
D3DPRESENT_PARAMETERS d3dPresentParams;
public:
void Init();
void UnInit();
bool init(int width,int height);
void shutdown();
};
extern IDirect3DDevice8 *gpd3dDev;
///////////////////////////////////////////////////////////////////////////////
#endif // __RENDERER_H__
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+225
View File
@@ -0,0 +1,225 @@
//
// scene_renderer.h
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001, Pipeworks Software Inc.
// All rights reserved
#ifndef __SCENE_RENDERER_H__
#define __SCENE_RENDERER_H__
#include "xbs_math.h"
#include "prim_types.h"
///////////////////////////////////////////////////////////////////////////////
enum ShaderTypes
{
st_Phong = 0,
st_Bump = 1,
st_Depth = 2,
st_ShadowMap = 3,
st_NoTypes = 4,
};
///////////////////////////////////////////////////////////////////////////////
struct BaseStream
{
D3DVECTOR p;
};
///////////////////////////////////////////////////////////////////////////////
struct BumpStream
{
FLOAT u,v;
D3DVECTOR s;
D3DVECTOR t;
D3DVECTOR n;
};
///////////////////////////////////////////////////////////////////////////////
struct PhongStream
{
D3DVECTOR s;
D3DVECTOR t;
D3DVECTOR n;
};
///////////////////////////////////////////////////////////////////////////////
struct PrimitiveVersionRecord
{
DWORD dwVertexStart;
DWORD dwVertexCount;
DWORD dwIndexStart;
DWORD dwPrimCount;
DWORD dwIndexCount;
DWORD dwParameter;
};
///////////////////////////////////////////////////////////////////////////////
struct PrimitiveInstanceRecord
{
unsigned short idxVersion;
short idxPosAnim;
short idxRotAnim;
D3DMATRIX matOffset;
D3DMATRIX matInvOffset;
D3DMATRIX matScale;
D3DVECTOR4 vObjScale;
D3DMATRIX matScaleOffset;
bool bHiZ;
};
///////////////////////////////////////////////////////////////////////////////
class PrimitiveSet
{
private:
LPDIRECT3DVERTEXBUFFER8 pBaseStream;
LPDIRECT3DVERTEXBUFFER8 pExtraStream;
LPDIRECT3DINDEXBUFFER8 pIB;
PrimitiveVersionRecord * aVersRecs;
int nVersions;
PrimitiveInstanceRecord * aInstRecs;
int nInstances;
D3DPRIMITIVETYPE d3dType;
LPDIRECT3DTEXTURE8 pNormalMap;
LPDIRECT3DCUBETEXTURE8 pCubeMap;
D3DVECTOR4 vAmbient;
D3DVECTOR4 vDiffuse;
D3DVECTOR4 vSpecular;
DWORD dwPShader;
DWORD dwVShader;
ShaderTypes shaderType;
PrimitiveTypes primitiveType;
bool bHiZ;
void createSphereVersion(const SphereVers *psphere,
BYTE *pbase,BYTE *pextra,
unsigned short *pi,
int idx,int ndet_bias );
void createCylinderVersion(const CylinderVers *pcyl,
BYTE *pbase,BYTE *pextra,
unsigned short *pi,
int idx,int ndet_bias );
void createConeVersion(const ConeVers * pcone,
BYTE *pbase,BYTE *pextra,
unsigned short *pi,
int idx, int ndet_bias );
void createBoxVersion(BYTE *pbase,BYTE *pextra,
unsigned short *pi,
int idx );
void createTorusVersion(const TorusVers * ptorus,
BYTE *pbase,BYTE *pextra,
unsigned short *pi,
int idx,int ndet_bias );
void createSurfOfRevVersion(const SurfOfRevVers *psurf,
BYTE *pbase,BYTE *pextra,
unsigned short *pi,
int idx,int ndet_bias);
void initSphereInstance( const SphereInst *psphere, int idx);
void initCylinderInstance( const CylinderInst *pcyl, int idx);
void initConeInstance(const ConeInst *pcone,int idx);
void initBoxInstance(const BoxInst *pbox,int idx);
void initTorusInstance(const TorusInst *ptorus,int idx);
void initSurfOfRevInstance(const SurfOfRevInst *psurf,int idx);
void initSphereVersion(const SphereVers *psphere,int idx,int ndet_bias);
void initCylinderVersion(const CylinderVers *pcyl,int idx,int ndet_bias);
void initConeVersion(const ConeVers *pcone,int idx,int ndet_bias);
void initBoxVersion(int idx);
void initTorusVersion(const TorusVers *ptorus,int idx,int ndet_bias);
void initSurfOfRevVersion(const SurfOfRevVers *psurf,int idx,int ndet_bias);
public:
void Init();
void UnInit();
void render(const D3DLIGHT8 &light,bool b_query_blob);
void renderZ();
void renderShadowMap(bool b_hi_z);
void create( const void * version_data,
int num_versions,
const void * instance_data,
int num_insts,
int ndet_bias,
ShaderTypes shader,
PrimitiveTypes primitive,
LPDIRECT3DTEXTURE8 pnormal_map,
LPDIRECT3DCUBETEXTURE8 pcubemap );
};
///////////////////////////////////////////////////////////////////////////////
class SceneRenderer
{
protected:
PrimitiveSet * pSetHiDet[pt_NoTypes];
PrimitiveSet * pSetLoDet[pt_NoTypes];
IDirect3DSurface8 * pSBufTarget;
IDirect3DSurface8 * pRenderTarget;
IDirect3DSurface8 * pZBuffer;
D3DSurface fakeTarget;
float fZOffset;
float fZSlopeScale;
bool bUseLoDetail;
D3DVECTOR4 * decompressQuats(short *p_quat_data, DWORD *p_sign_data,int nquats);
D3DVECTOR * decompressVecs(short *p_vec_data, int nvecs);
short * decompressIndices(char *p_index_data,int nindices);
void updateSBuffer(bool b_hi_z);
void createSceneGeometry(PrimitiveSet **pp_sets,int ndet_bias);
public:
D3DVECTOR4 *pQuats;
short *pQuatIdSeq[NUM_ROT_SEQ];
D3DVECTOR *pPos;
short *pPosIdSeq[NUM_POS_SEQ];
IDirect3DTexture8 *pSBufDepthHi;
IDirect3DTexture8 *pSBufDepthLo;
D3DMATRIX matWTSHi;
D3DMATRIX matWTSLo;
D3DMATRIX *pRotAnims;
int nRotAnims;
D3DVECTOR *pPosAnims;
int nPosAnims;
void create();
void destroy();
void render(bool b_with_shadows,bool b_use_blob_intensity);
void renderZ();
void advanceTime(float fElapsedTime, float fDt);
void updateShadows();
};
#endif // __SCENE_RENDERER_H__
+668
View File
@@ -0,0 +1,668 @@
const BYTE g_greenfog_xpu[] =
{
0x50, 0x53, 0x42, 0x30, 0x30, 0xDA, 0x30, 0xD9, 0x30, 0xDB,
0x30, 0xDD, 0x10, 0x10, 0xD1, 0xDD, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x30, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x20, 0xDA, 0x20, 0xD9, 0x20, 0xDB, 0x20, 0xCD, 0x00, 0x00,
0xC1, 0xCD, 0x00, 0x00, 0xCD, 0xC8, 0x20, 0xC1, 0x20, 0xCC,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D,
0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x01, 0x00,
0x21, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xF0, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x01, 0x00, 0x00,
};
const BYTE g_scene_bump_xpu[] =
{
0x50, 0x53, 0x42, 0x30, 0x5A, 0x58, 0x59, 0x58, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0B, 0x0C,
0x80, 0x11, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x4A, 0x48, 0x49, 0x48, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00,
0xCD, 0xCD, 0x00, 0x00, 0xCD, 0xCD, 0x00, 0x00, 0xCD, 0xCD,
0x0D, 0xC2, 0x0C, 0xC1, 0xC1, 0x20, 0x05, 0xC4, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0xFF,
0x00, 0x00, 0x00, 0x00, 0xCD, 0x30, 0x0C, 0x00, 0xD0, 0x00,
0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00,
0xD0, 0x00, 0x00, 0x00, 0xCD, 0x05, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x11, 0x01, 0x00,
0x21, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0x1F, 0xF0, 0xFF, 0xFF, 0x2F, 0xFF,
0xF4, 0x01, 0x00, 0x00,
};
const BYTE g_scene_phong_xpu[] =
{
0x50, 0x53, 0x42, 0x30, 0x5A, 0xD1, 0x59, 0xD1, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0B, 0x0C,
0x80, 0x11, 0x01, 0x0C, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x4A, 0xC1, 0x49, 0xC1, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00,
0xCD, 0xCD, 0x00, 0x00, 0xCD, 0xCD, 0x00, 0x00, 0xCD, 0xCD,
0x00, 0x00, 0xCD, 0xCD, 0x0D, 0xC2, 0x0C, 0xC1, 0xC1, 0x20,
0x05, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0xFF,
0x00, 0x00, 0x00, 0x00, 0xCD, 0x30, 0x0C, 0x00, 0xD0, 0x00,
0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00,
0xD0, 0x00, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0xCD, 0x05,
0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x08, 0x11, 0x01, 0x00,
0x20, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF3, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xF2,
0xF4, 0x01, 0x00, 0x00,
};
const BYTE g_scene_zr_xpu[] =
{
0x50, 0x53, 0x42, 0x30, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,
0x3D, 0x3D, 0x10, 0x10, 0xDD, 0xD4, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x48, 0x48, 0x00, 0x00, 0x2D, 0x2D, 0x00, 0x00,
0xCD, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xD0, 0x20, 0x08, 0x00, 0xD0, 0x00,
0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x11, 0x01, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x01, 0x00, 0x00,
};
const BYTE g_shield_xpu[] =
{
0x50, 0x53, 0x42, 0x30, 0x5B, 0x5A, 0x5B, 0x59, 0x1D, 0x1D,
0x1C, 0x1C, 0xDD, 0xDD, 0xDC, 0xDC, 0xDD, 0xDD, 0xDC, 0xDC,
0xDD, 0xDD, 0xDC, 0xDC, 0xDC, 0x30, 0xD1, 0xDC, 0x30, 0x1D,
0x30, 0x1C, 0x10, 0x10, 0x30, 0xD2, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x33, 0xFF, 0x66, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xCD, 0x04, 0x00, 0x00, 0xCD, 0x04, 0x00, 0x00,
0xCD, 0x04, 0x00, 0x00, 0xCD, 0x04, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
0x4B, 0x4A, 0x4B, 0x49, 0x0D, 0x0D, 0x0C, 0x0C, 0xCD, 0xCD,
0xCC, 0xCC, 0xCD, 0xCD, 0xCC, 0xCC, 0xCD, 0xCD, 0xCC, 0xCC,
0xCC, 0x20, 0xC1, 0xCC, 0x20, 0x0D, 0x20, 0x0C, 0xC8, 0x20,
0xC1, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xCD, 0x30, 0x0C, 0x00, 0xCD, 0x04,
0x00, 0x00, 0xCD, 0x04, 0x00, 0x00, 0xCD, 0x04, 0x00, 0x00,
0xCD, 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x08, 0x11, 0x01, 0x00,
0x21, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x2F, 0xFF, 0xFF, 0xFF, 0x0F,
0xFF, 0x01, 0x00, 0x00,
};
const BYTE g_shield_sh_xpu[] =
{
0x50, 0x53, 0x42, 0x30, 0x10, 0x10, 0x30, 0xD4, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
0x80, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x20, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x01, 0x00, 0x00,
};
const BYTE g_vblob_xpu[] =
{
0x50, 0x53, 0x42, 0x30, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,
0x30, 0x1C, 0x10, 0x10, 0x3D, 0x3D, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x30, 0xD1, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x49, 0x48, 0x00, 0x00, 0x20, 0x0C, 0x00, 0x00,
0x2D, 0x2D, 0x00, 0x00, 0xC1, 0x2C, 0x20, 0xC1, 0x20, 0xCC,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0x20, 0x08, 0x00, 0xD0, 0x00,
0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x01, 0x00,
0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x0F, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x01, 0x00, 0x00,
};
const BYTE g_vbloblet_xpu[] =
{
0x50, 0x53, 0x42, 0x30, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,
0x30, 0x1C, 0x10, 0x10, 0x3D, 0x3D, 0x10, 0x10, 0xD1, 0x3C,
0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0xD1, 0xDC, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x49, 0x48, 0x00, 0x00, 0x20, 0x0C, 0x00, 0x00,
0x2D, 0x2D, 0x00, 0x00, 0xC1, 0x2C, 0x20, 0xC1, 0x20, 0xCC,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0x20, 0x08, 0x00, 0xD0, 0x00,
0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x01, 0x00,
0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x0F, 0x21, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x01, 0x00, 0x00,
};
const BYTE g_greenfog_xvu[] =
{
0x78, 0x20, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00,
0x20, 0x00, 0x6C, 0x10, 0x36, 0x08, 0x00, 0xF8, 0x70, 0x20,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x02, 0x20, 0x00, 0x6C, 0x10,
0x36, 0x08, 0x48, 0xF8, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x24, 0x4C, 0x00, 0x6C, 0x18, 0x36, 0x08, 0xF8, 0x0F,
0x20, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x64, 0x4C, 0x00,
0x6C, 0x18, 0x36, 0x08, 0xF8, 0x0F, 0x30, 0x2F, 0x00, 0x00,
0x00, 0x00, 0x1B, 0xA4, 0x4C, 0x00, 0x6C, 0x18, 0x36, 0x08,
0xF8, 0x0F, 0x40, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00,
0x6C, 0x00, 0x6C, 0x10, 0x36, 0x24, 0x50, 0xF8, 0x70, 0x30,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x40, 0x6C, 0x00, 0x6C, 0x10,
0x36, 0x34, 0x58, 0xF8, 0x70, 0x30, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x80, 0x6C, 0x00, 0x6C, 0x10, 0x36, 0x44, 0x60, 0xF8,
0x70, 0x30, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x40, 0x47, 0x06,
0xFF, 0x1B, 0x36, 0xC4, 0x00, 0xE8, 0x78, 0x10, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x60, 0x87, 0x00, 0x6C, 0x28, 0x00, 0xC4,
0x01, 0xE8, 0x70, 0x30,
};
const BYTE g_scene_bump_xvu[] =
{
0x78, 0x20, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00,
0xEC, 0x00, 0x6C, 0x18, 0x36, 0x08, 0x00, 0x88, 0x70, 0x20,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x20, 0xEC, 0x00, 0x6C, 0x18,
0x36, 0x08, 0x00, 0x48, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x40, 0xEC, 0x00, 0x6C, 0x18, 0x36, 0x08, 0x00, 0x28,
0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x60, 0xEC, 0x00,
0x6C, 0x18, 0x36, 0x08, 0x00, 0x18, 0x70, 0x20, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x00, 0xED, 0x00, 0x6C, 0x18, 0x36, 0x08,
0x60, 0x88, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x20,
0xED, 0x00, 0x6C, 0x18, 0x36, 0x08, 0x60, 0x48, 0x70, 0x20,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x40, 0xED, 0x00, 0x6C, 0x18,
0x36, 0x08, 0x60, 0x28, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x60, 0xED, 0x00, 0x6C, 0x18, 0x36, 0x08, 0xF8, 0x0F,
0x20, 0x21, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x02, 0x6C, 0x03,
0x6C, 0x18, 0x36, 0x0C, 0x4C, 0xF8, 0x30, 0x21, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x00, 0x40, 0x01, 0x6C, 0x68, 0xFE, 0x25,
0x60, 0x18, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xC0,
0x4C, 0x00, 0x6C, 0x18, 0x36, 0x08, 0xF8, 0x0F, 0x40, 0x2E,
0x00, 0x00, 0x00, 0x00, 0x1A, 0x80, 0x6C, 0x00, 0x69, 0x14,
0x36, 0x0C, 0xF8, 0x0F, 0x50, 0x1E, 0x00, 0x00, 0x00, 0x00,
0x1A, 0xA0, 0x6C, 0x00, 0x69, 0x14, 0x36, 0x0C, 0xF8, 0x0F,
0xA0, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0xA0, 0x00,
0x6C, 0xA8, 0x34, 0x54, 0xF8, 0x0F, 0x60, 0x28, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x00, 0xA0, 0x08, 0x6D, 0x48, 0x37, 0xA4,
0xF8, 0x0F, 0xB1, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x09, 0x6E, 0x28, 0xFE, 0x65, 0xF8, 0x0F, 0x78, 0xDE,
0x00, 0x00, 0x00, 0x00, 0x1B, 0xE0, 0xAC, 0x00, 0x6C, 0x18,
0x36, 0x74, 0xF8, 0x0F, 0x80, 0x28, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x00, 0x6C, 0x48, 0x35, 0x14, 0xF8, 0x0F,
0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x40, 0x06,
0x6E, 0xA8, 0x36, 0x14, 0x1C, 0xE8, 0x90, 0x1E, 0x00, 0x00,
0x00, 0x00, 0x1A, 0x04, 0xA0, 0x00, 0x6C, 0x10, 0x36, 0x94,
0x50, 0x88, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x06,
0xA0, 0x00, 0x6C, 0x10, 0x36, 0x94, 0x50, 0x48, 0x70, 0x20,
0x00, 0x00, 0x00, 0x00, 0x1A, 0x08, 0xA0, 0x00, 0x6C, 0x10,
0x36, 0x94, 0x50, 0x28, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x60, 0x00, 0x6A, 0x10, 0x36, 0x04, 0xF8, 0x0F,
0x20, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x40, 0x47, 0x06,
0xFF, 0x1B, 0x36, 0xC4, 0x00, 0xE8, 0x78, 0x10, 0x00, 0x00,
0x00, 0x00, 0x1A, 0x04, 0xA0, 0x00, 0x6C, 0x10, 0x36, 0x24,
0x58, 0x88, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x06,
0xA0, 0x00, 0x6C, 0x10, 0x36, 0x24, 0x58, 0x48, 0x70, 0x20,
0x00, 0x00, 0x00, 0x00, 0x1A, 0x08, 0xA0, 0x00, 0x6C, 0x10,
0x36, 0x24, 0x58, 0x28, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x60, 0x87, 0x00, 0x6C, 0x28, 0x00, 0xC4, 0x01, 0xE8,
0x70, 0x30,
};
const BYTE g_scene_phong_xvu[] =
{
0x78, 0x20, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00,
0xEC, 0x00, 0x6C, 0x18, 0x36, 0x08, 0x00, 0x88, 0x70, 0x20,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x20, 0xEC, 0x00, 0x6C, 0x18,
0x36, 0x08, 0x00, 0x48, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x40, 0xEC, 0x00, 0x6C, 0x18, 0x36, 0x08, 0x00, 0x28,
0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x60, 0xEC, 0x00,
0x6C, 0x18, 0x36, 0x08, 0x00, 0x18, 0x70, 0x20, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x00, 0xED, 0x00, 0x6C, 0x18, 0x36, 0x08,
0x60, 0x88, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x20,
0xED, 0x00, 0x6C, 0x18, 0x36, 0x08, 0x60, 0x48, 0x70, 0x20,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x40, 0xED, 0x00, 0x6C, 0x18,
0x36, 0x08, 0x60, 0x28, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x60, 0xED, 0x00, 0x6C, 0x18, 0x36, 0x08, 0xF8, 0x0F,
0x20, 0x21, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x6C, 0x01,
0x6C, 0x18, 0x36, 0x0C, 0xF8, 0x0F, 0x30, 0x21, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x00, 0x40, 0x01, 0x6C, 0x68, 0xFE, 0x25,
0x60, 0x18, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xC0,
0x4C, 0x00, 0x6C, 0x18, 0x36, 0x08, 0xF8, 0x0F, 0x40, 0x2E,
0x00, 0x00, 0x00, 0x00, 0x1A, 0x80, 0x6C, 0x00, 0x69, 0x14,
0x36, 0x0C, 0xF8, 0x0F, 0x50, 0x1E, 0x00, 0x00, 0x00, 0x00,
0x1A, 0xA0, 0x6C, 0x00, 0x69, 0x14, 0x36, 0x0C, 0xF8, 0x0F,
0xA0, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0xA0, 0x00,
0x6C, 0xA8, 0x34, 0x54, 0xF8, 0x0F, 0x60, 0x28, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x00, 0xA0, 0x08, 0x6D, 0x48, 0x37, 0xA4,
0xF8, 0x0F, 0xB1, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x09, 0x6E, 0x28, 0xFE, 0x65, 0xF8, 0x0F, 0x78, 0xDE,
0x00, 0x00, 0x00, 0x00, 0x1B, 0xE0, 0xAC, 0x00, 0x6C, 0x18,
0x36, 0x74, 0xF8, 0x0F, 0x80, 0x28, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x00, 0x6C, 0x48, 0x35, 0x14, 0xF8, 0x0F,
0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x40, 0x06,
0x6E, 0xA8, 0x36, 0x14, 0x1C, 0xE8, 0x90, 0x1E, 0x00, 0x00,
0x00, 0x00, 0x1A, 0x02, 0xA0, 0x00, 0x6C, 0x10, 0x36, 0x94,
0x50, 0x88, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x04,
0xA0, 0x00, 0x6C, 0x10, 0x36, 0x94, 0x50, 0x48, 0x70, 0x20,
0x00, 0x00, 0x00, 0x00, 0x1A, 0x06, 0xA0, 0x00, 0x6C, 0x10,
0x36, 0x94, 0x50, 0x28, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x60, 0x00, 0x6A, 0x10, 0x36, 0x04, 0xF8, 0x0F,
0x20, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x40, 0x47, 0x06,
0xFF, 0x1B, 0x36, 0xC4, 0x00, 0xE8, 0x78, 0x10, 0x00, 0x00,
0x00, 0x00, 0x1A, 0x02, 0xA0, 0x00, 0x6C, 0x10, 0x36, 0x24,
0x58, 0x88, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x04,
0xA0, 0x00, 0x6C, 0x10, 0x36, 0x24, 0x58, 0x48, 0x70, 0x20,
0x00, 0x00, 0x00, 0x00, 0x1A, 0x06, 0xA0, 0x00, 0x6C, 0x10,
0x36, 0x24, 0x58, 0x28, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x60, 0x87, 0x00, 0x6C, 0x28, 0x00, 0xC4, 0x01, 0xE8,
0x70, 0x30,
};
const BYTE g_scene_zr_xvu[] =
{
0x78, 0x20, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00,
0xEC, 0x00, 0x6C, 0x18, 0x36, 0x08, 0xF8, 0x0F, 0x20, 0x28,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x20, 0xEC, 0x00, 0x6C, 0x18,
0x36, 0x08, 0xF8, 0x0F, 0x20, 0x24, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x40, 0xEC, 0x00, 0x6C, 0x18, 0x36, 0x08, 0xF8, 0x0F,
0x20, 0x22, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x60, 0xEC, 0x00,
0x6C, 0x18, 0x36, 0x08, 0xF8, 0x0F, 0x20, 0x21, 0x00, 0x00,
0x00, 0x00, 0xAA, 0x00, 0x20, 0x02, 0x6C, 0x10, 0x36, 0x24,
0x04, 0xF8, 0x30, 0x9F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
0x20, 0x00, 0x6C, 0x10, 0x36, 0x24, 0xF8, 0x0F, 0x40, 0x21,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x20, 0x6E, 0x00, 0x6C, 0x10,
0x36, 0x34, 0xF8, 0x0F, 0x50, 0x3E, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x00, 0x80, 0x05, 0xFD, 0x6B, 0x36, 0x34, 0xF8, 0x0F,
0x6F, 0x11, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x4E, 0x00,
0x6C, 0xA8, 0x36, 0x0C, 0xF8, 0x0F, 0x60, 0x2E, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x00, 0x60, 0x01, 0x6C, 0x68, 0x36, 0x34,
0xF8, 0x0F, 0x70, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00,
0x80, 0x01, 0x6C, 0x68, 0x36, 0x34, 0xF8, 0x0F, 0x70, 0x21,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x40, 0x01, 0x6C, 0xE8,
0x36, 0x64, 0x18, 0xF8, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x00, 0x40, 0x00, 0x6C, 0x28, 0x36, 0x24, 0xF8, 0x0F,
0x80, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x40, 0x4E, 0x00,
0x6C, 0x18, 0x36, 0x84, 0xF8, 0x0F, 0x90, 0x2E, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x60, 0x6E, 0x00, 0x6C, 0x10, 0x36, 0x94,
0x48, 0xE8, 0x70, 0x30, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00,
0x80, 0x01, 0x6C, 0x28, 0x36, 0x14, 0x48, 0x18, 0x70, 0x20,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x40, 0x47, 0x06, 0xFF, 0x1B,
0x36, 0xC4, 0x00, 0xE8, 0x78, 0x10, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x60, 0x87, 0x00, 0x6C, 0x28, 0x00, 0xC4, 0x01, 0xE8,
0x70, 0x30,
};
const BYTE g_shield_xvu[] =
{
0x78, 0x20, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00,
0xEC, 0x00, 0x6C, 0x18, 0x36, 0x08, 0xF8, 0x0F, 0x20, 0x28,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x20, 0xEC, 0x00, 0x6C, 0x18,
0x36, 0x08, 0xF8, 0x0F, 0x20, 0x24, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x40, 0xEC, 0x00, 0x6C, 0x18, 0x36, 0x08, 0xF8, 0x0F,
0x20, 0x22, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x60, 0xEC, 0x00,
0x6C, 0x18, 0x36, 0x08, 0xF8, 0x0F, 0x20, 0x21, 0x00, 0x00,
0x00, 0x00, 0x1A, 0x02, 0xAC, 0x00, 0x6C, 0x18, 0x34, 0x08,
0xF8, 0x0F, 0x30, 0x28, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x22,
0xAC, 0x00, 0x6C, 0x18, 0x34, 0x08, 0xF8, 0x0F, 0x30, 0x24,
0x00, 0x00, 0x00, 0x00, 0x1A, 0x42, 0xAC, 0x00, 0x6C, 0x18,
0x34, 0x08, 0xF8, 0x0F, 0x30, 0x22, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x20, 0x6D, 0x00, 0x6C, 0x14, 0x36, 0x24, 0xF8, 0x0F,
0x40, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x40, 0x6D, 0x00,
0x6C, 0x14, 0x36, 0x24, 0xF8, 0x0F, 0x70, 0x3E, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x00, 0xA0, 0x02, 0x6D, 0x6C, 0x36, 0x44,
0x64, 0xE8, 0x50, 0x18, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x00,
0xA0, 0x00, 0x6C, 0x68, 0x34, 0x74, 0xF8, 0x0F, 0x80, 0x28,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x6C, 0x18,
0x54, 0x57, 0xF8, 0x0F, 0x60, 0x24, 0x00, 0x00, 0x00, 0x00,
0x55, 0x00, 0x80, 0x00, 0x69, 0x68, 0x34, 0x64, 0x48, 0xE8,
0x30, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x00,
0x6C, 0x18, 0x54, 0x87, 0xF8, 0x0F, 0x90, 0x24, 0x00, 0x00,
0x00, 0x00, 0x55, 0x00, 0x80, 0x00, 0x69, 0x68, 0x34, 0x94,
0x50, 0xE8, 0x30, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x60,
0x6D, 0x00, 0x68, 0x14, 0x36, 0x24, 0xF8, 0x0F, 0xA0, 0x3E,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x80, 0xEC, 0x00, 0x6C, 0x18,
0x36, 0x24, 0x00, 0x88, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x1A, 0x00, 0xA0, 0x00, 0x6C, 0x68, 0x34, 0xA4, 0xF8, 0x0F,
0xB0, 0x28, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0xEC, 0x00,
0x6C, 0x18, 0x36, 0x24, 0x00, 0x48, 0x70, 0x20, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x6C, 0x18, 0x54, 0xB7,
0xF8, 0x0F, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00,
0x80, 0x00, 0x6A, 0x68, 0x34, 0x04, 0x58, 0xE8, 0x30, 0x90,
0x00, 0x00, 0x00, 0x00, 0x1B, 0xC0, 0xEC, 0x00, 0x6C, 0x18,
0x36, 0x24, 0x00, 0x28, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x1B, 0xE0, 0xEC, 0x00, 0x6C, 0x18, 0x36, 0x24, 0x00, 0x18,
0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x40, 0x47, 0x06,
0xFF, 0x1B, 0x36, 0xC4, 0x00, 0xE8, 0x78, 0x10, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x60, 0x87, 0x00, 0x6C, 0x28, 0x00, 0xC4,
0x01, 0xE8, 0x70, 0x30,
};
const BYTE g_shield_sh_xvu[] =
{
0x78, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00,
0x20, 0x00, 0x6C, 0x10, 0x36, 0x08, 0xF8, 0x0F, 0x20, 0x2F,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x80, 0x01, 0x6C, 0x48,
0x36, 0x24, 0xF8, 0x0F, 0x20, 0x21, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x00, 0xED, 0x00, 0x6C, 0x18, 0x36, 0x24, 0xF8, 0x0F,
0x30, 0x28, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x20, 0xED, 0x00,
0x6C, 0x18, 0x36, 0x24, 0xF8, 0x0F, 0x30, 0x24, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x40, 0xED, 0x00, 0x6C, 0x18, 0x36, 0x24,
0xF8, 0x0F, 0x30, 0x22, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x60,
0xED, 0x00, 0x6C, 0x18, 0x36, 0x24, 0xF8, 0x0F, 0x30, 0x21,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x80, 0x2D, 0x00, 0x6C, 0x10,
0x36, 0x0C, 0xF8, 0x0F, 0x20, 0x21, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x00, 0x6E, 0x00, 0x6C, 0x14, 0x36, 0x34, 0xF8, 0x0F,
0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0xA0, 0x00,
0x6C, 0x88, 0x36, 0x44, 0xF8, 0x0F, 0x50, 0x21, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x00, 0x00, 0x08, 0xFD, 0x13, 0x36, 0x08,
0xF8, 0x0F, 0x1F, 0x50, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00,
0x40, 0x00, 0x6C, 0x88, 0x36, 0x14, 0xF8, 0x0F, 0x60, 0x2F,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x80, 0x01, 0x6C, 0x28,
0x36, 0x14, 0xF8, 0x0F, 0x70, 0x2F, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x00, 0x60, 0x00, 0xFC, 0x17, 0x36, 0x74, 0xF8, 0x0F,
0x80, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xC0, 0x4C, 0x00,
0x6C, 0x18, 0x36, 0x84, 0xF8, 0x0F, 0x90, 0x2F, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x00, 0x80, 0x00, 0x6C, 0xC8, 0x36, 0x94,
0xF8, 0x0F, 0xA0, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00,
0xA0, 0x00, 0x6C, 0x48, 0x37, 0xA4, 0xF8, 0x0F, 0xB0, 0x21,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x20, 0xEC, 0x00, 0x6C, 0x18,
0x36, 0xA4, 0xF8, 0x0F, 0x70, 0x24, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x00, 0xEC, 0x08, 0xFE, 0x1B, 0x36, 0xA4, 0xF8, 0x0F,
0x7E, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x60, 0xEC, 0x00,
0x6C, 0x18, 0x36, 0xA4, 0xF8, 0x0F, 0x70, 0x21, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x00, 0x60, 0x01, 0x6C, 0x48, 0x37, 0xA4,
0x18, 0xE8, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00,
0x40, 0x02, 0x6D, 0x48, 0x37, 0x14, 0x04, 0xD8, 0x00, 0xDE,
0x00, 0x00, 0x00, 0x00, 0x1B, 0xE0, 0xAC, 0x00, 0x6C, 0x18,
0x36, 0x04, 0xF8, 0x0F, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00,
0xFF, 0x00, 0x20, 0x00, 0x6C, 0x10, 0x36, 0x74, 0xF8, 0x0F,
0x80, 0x22, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0x8D, 0x00,
0x6C, 0x48, 0x36, 0x04, 0xF8, 0x0F, 0x30, 0x31, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x00, 0x40, 0x00, 0x6C, 0x08, 0x36, 0x04,
0xF8, 0x0F, 0x40, 0x21, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xC0,
0x8D, 0x00, 0x6C, 0x18, 0x36, 0x44, 0xF8, 0x0F, 0x50, 0xD1,
0x00, 0x00, 0x00, 0x00, 0xAA, 0x80, 0x4C, 0x00, 0x6C, 0x08,
0x55, 0x0D, 0x00, 0x28, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x1B, 0xE0, 0x4D, 0x01, 0x6C, 0x18, 0x36, 0x54, 0xF8, 0x0F,
0x60, 0x21, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0x4C, 0x00,
0x6C, 0x18, 0x36, 0x64, 0xF8, 0x0F, 0x90, 0x21, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x00, 0x40, 0x00, 0x6C, 0x10, 0xFE, 0x95,
0x18, 0x18, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x40,
0x47, 0x06, 0xFF, 0x1B, 0x36, 0xC4, 0x00, 0xE8, 0x78, 0x10,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x60, 0x87, 0x00, 0x6C, 0x28,
0x00, 0xC4, 0x01, 0xE8, 0x70, 0x30,
};
const BYTE g_vblob_xvu[] =
{
0x78, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x60,
0x4D, 0x00, 0x6C, 0x18, 0x36, 0x08, 0xF8, 0x0F, 0xA0, 0x2E,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0xA0, 0x00, 0x6C, 0x48,
0x37, 0xA4, 0xF8, 0x0F, 0x20, 0x28, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x40, 0x4D, 0x00, 0x6C, 0x18, 0x36, 0x08, 0xF8, 0x0F,
0xB0, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x2D, 0x08,
0x6C, 0x10, 0x36, 0x0C, 0xF8, 0x0F, 0xA8, 0x91, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x80, 0x6D, 0x00, 0x6C, 0x10, 0x36, 0xB4,
0xF8, 0x0F, 0xB0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x6C, 0x48, 0x35, 0x14, 0xF8, 0x0F, 0xA0, 0x2E,
0x00, 0x00, 0x00, 0x00, 0xFF, 0x02, 0x20, 0x00, 0x6C, 0x10,
0x36, 0x08, 0xF8, 0x0F, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x2D, 0x00, 0x6C, 0x10, 0x36, 0x0C, 0xF8, 0x0F,
0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x80, 0x00,
0x6E, 0x08, 0x36, 0xA4, 0xF8, 0x0F, 0xB0, 0xDF, 0x00, 0x00,
0x00, 0x00, 0x1A, 0x20, 0x6D, 0x00, 0x6A, 0x14, 0x36, 0x0C,
0xF8, 0x0F, 0x00, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00,
0x2D, 0x00, 0x6C, 0x10, 0x36, 0x0C, 0xF8, 0x0F, 0x20, 0x21,
0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0xA0, 0x00, 0x6C, 0x08,
0x34, 0x04, 0xF8, 0x0F, 0x20, 0x28, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x80, 0xEC, 0x00, 0x6C, 0x18, 0x36, 0xB4, 0x00, 0x88,
0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x2D, 0x08,
0x6C, 0x10, 0x36, 0x0C, 0xF8, 0x0F, 0x98, 0x91, 0x00, 0x00,
0x00, 0x00, 0x1B, 0xA0, 0xEC, 0x00, 0x6C, 0x18, 0x36, 0xB4,
0x00, 0x48, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x6C, 0x08, 0x34, 0x14, 0xF8, 0x0F, 0x20, 0x2E,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x62, 0x4D, 0x02, 0x6C, 0x18,
0x36, 0x08, 0x54, 0xF8, 0x00, 0x9E, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x00, 0xA0, 0x00, 0x6C, 0x08, 0x36, 0x04, 0xF8, 0x0F,
0x20, 0x28, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xE0, 0xEC, 0x00,
0x6C, 0x18, 0x36, 0xB4, 0x00, 0x18, 0x70, 0x20, 0x00, 0x00,
0x00, 0x00, 0x1B, 0xC0, 0xEC, 0x08, 0x6C, 0x18, 0x36, 0xB4,
0x00, 0x28, 0x18, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x6C, 0x08, 0x36, 0x14, 0xF8, 0x0F, 0x90, 0x2E,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x20, 0x00, 0x6C, 0x10,
0x36, 0x94, 0x48, 0xF8, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x40, 0x47, 0x06, 0xFF, 0x1B, 0x36, 0xC4, 0x00, 0xE8,
0x78, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x60, 0x87, 0x00,
0x6C, 0x28, 0x00, 0xC4, 0x01, 0xE8, 0x70, 0x30,
};
const BYTE g_vbloblet_xvu[] =
{
0x78, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x60,
0xAD, 0x02, 0x6C, 0x18, 0x36, 0x08, 0x4C, 0xF8, 0x20, 0x2E,
0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x2D, 0x00, 0x6C, 0x10,
0x36, 0x0C, 0xF8, 0x0F, 0x50, 0x21, 0x00, 0x00, 0x00, 0x00,
0x1B, 0xA0, 0x4D, 0x00, 0x6C, 0x18, 0x36, 0x24, 0xF8, 0x0F,
0x30, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x80, 0x8D, 0x00,
0x6C, 0x10, 0x36, 0x0C, 0xF8, 0x0F, 0x40, 0xDE, 0x00, 0x00,
0x00, 0x00, 0x55, 0x00, 0x2D, 0x00, 0x6C, 0x10, 0x36, 0x0C,
0xF8, 0x0F, 0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x40,
0x6D, 0x00, 0x6C, 0x10, 0x36, 0x44, 0xF8, 0x0F, 0x50, 0x3E,
0x00, 0x00, 0x00, 0x00, 0x1A, 0x20, 0x6D, 0x00, 0x69, 0x14,
0x36, 0x0C, 0xF8, 0x0F, 0x60, 0x5E, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x80, 0xEC, 0x00, 0x6C, 0x18, 0x36, 0x54, 0x00, 0x88,
0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0xA0, 0x00,
0x6C, 0xC8, 0x34, 0x64, 0xF8, 0x0F, 0x70, 0x28, 0x00, 0x00,
0x00, 0x00, 0x1B, 0xC0, 0xEC, 0x00, 0x6C, 0x18, 0x36, 0x54,
0x00, 0x28, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0,
0xEC, 0x08, 0x6D, 0x18, 0x36, 0x54, 0x00, 0x48, 0x18, 0xD0,
0x00, 0x00, 0x00, 0x00, 0x1B, 0xE0, 0xEC, 0x00, 0x6C, 0x18,
0x36, 0x54, 0x00, 0x18, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x00, 0x6C, 0xC8, 0x34, 0x14, 0xF8, 0x0F,
0x80, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x20, 0x00,
0x6C, 0x10, 0x36, 0x84, 0x50, 0xF8, 0x70, 0x20, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x40, 0x47, 0x06, 0xFF, 0x1B, 0x36, 0xC4,
0x00, 0xE8, 0x78, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x60,
0x87, 0x00, 0x6C, 0x28, 0x00, 0xC4, 0x01, 0xE8, 0x70, 0x30,
};
const BYTE g_slash_interior_xpu[] =
{
0x50, 0x53, 0x42, 0x30, 0x10, 0x10, 0x30, 0xD4, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x20, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x01, 0x00, 0x00,
};
const BYTE g_slash_interior_xvu[] =
{
0x78, 0x20, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00,
0xEC, 0x00, 0x6C, 0x18, 0x36, 0x08, 0x00, 0x88, 0x70, 0x20,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x20, 0xEC, 0x00, 0x6C, 0x18,
0x36, 0x08, 0x00, 0x48, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x40, 0xEC, 0x00, 0x6C, 0x18, 0x36, 0x08, 0x00, 0x28,
0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x60, 0xEC, 0x00,
0x6C, 0x18, 0x36, 0x08, 0x00, 0x18, 0x70, 0x20, 0x00, 0x00,
0x00, 0x00, 0x1A, 0xA0, 0x2C, 0x00, 0x6C, 0x10, 0x36, 0x0C,
0xF8, 0x0F, 0x20, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x80,
0x6C, 0x00, 0x68, 0x14, 0x36, 0x0C, 0xF8, 0x0F, 0x30, 0x9E,
0x00, 0x00, 0x00, 0x00, 0x1A, 0xE0, 0x2C, 0x00, 0x6C, 0x10,
0x36, 0x0C, 0xF8, 0x0F, 0x50, 0x2E, 0x00, 0x00, 0x00, 0x00,
0x1A, 0xA2, 0x8C, 0x00, 0x68, 0x10, 0xAA, 0x34, 0xF8, 0x0F,
0x40, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xC0, 0x6C, 0x00,
0x69, 0x14, 0x36, 0x0C, 0xF8, 0x0F, 0x60, 0x5E, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x40, 0x47, 0x06, 0xFF, 0x1B, 0x36, 0xC4,
0x00, 0xE8, 0x78, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xE2,
0x8C, 0x00, 0x68, 0x10, 0xAA, 0x64, 0xF8, 0x0F, 0x70, 0x3E,
0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x8D, 0x00, 0x69, 0x18,
0x34, 0x44, 0xF8, 0x0F, 0x80, 0xDE, 0x00, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x4D, 0x00, 0x6C, 0x18, 0x34, 0x74, 0xF8, 0x0F,
0x90, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x60, 0x00,
0x6A, 0x14, 0x36, 0x84, 0x18, 0xE8, 0x70, 0x50, 0x00, 0x00,
0x00, 0x00, 0x1B, 0x60, 0x87, 0x00, 0x6C, 0x28, 0x00, 0xC4,
0x01, 0xE8, 0x70, 0x30,
};
+24
View File
@@ -0,0 +1,24 @@
xps.1.1
; Inputs:
; t0 = surface normal (renormalize and dot with light)
; c0 = light 1 direction
; c1 = light 2 direction
; c2 = base blob color
; c3 = ambient color
tex t0
dp3 r0, t0_bx2, c0_bx2
dp3 r1, t0_bx2, c1_bx2
add r0, r0_sat, r1_sat
mul r0.rgb, r0, c2.rgb
add r0.rgb, r0.rgb, c3.rgb
mov r0.a, v0.a
;xdd r1, r0, t0_bx2, v1, t0_bx2, -v1 ; r0 and r1 are the dots of the normal with the light dir and negative dir
;xmma discard, discard, r0, r0_sat, v0, r1_sat, v0 ; r0 is the blob color scaled by the non-negative dot
+68
View File
@@ -0,0 +1,68 @@
;------------------------------------------------------------------------------
; Vertex shader to do ripple/wave effect.
;------------------------------------------------------------------------------
xvs.1.1
;------------------------------------------------------------------------------
; Vertex streams expected by this shader
; struct BlobVertex
; {
; D3DXVECTOR3 pos; (v0)
; // D3DXVECTOR3 normal; (v1) // same as pos!
; // Diffuse color is set as a constant.
; };
;
; Expected vertex shaders constants
; c0-c3 = Transpose of world matrix
; c4-c7 = Transpose of view*projection matrix
; c8 = some constants, x=0, y=1, z=2, w=0.5
;
; Outputs:
; oT0 = surface normal (renormalize and dot with light)
; oD0 = base blob color
; oD1 = light direction
;------------------------------------------------------------------------------
#define WORLD_MAT_T_0 c0
#define WORLD_MAT_T_1 c1
#define WORLD_MAT_T_2 c2
#define WORLD_MAT_T_3 c3
#define VIEW_PROJ_T_0 c4
#define VIEW_PROJ_T_1 c5
#define VIEW_PROJ_T_2 c6
#define VIEW_PROJ_T_3 c7
#define ZERO c8.x
#define ONE c8.y
#define TWO c8.z
#define HALF c8.w
#define POSITION v0
#define NORMAL v0
#define LIGHT_AMB c9
#define BLOB_COLOR c10
mov oT0, NORMAL
; Transform position by world matrix (store in r2)
dp4 r2.x, POSITION, WORLD_MAT_T_0
dp4 r2.y, POSITION, WORLD_MAT_T_1
dp4 r2.z, POSITION, WORLD_MAT_T_2
dp4 r2.w, POSITION, WORLD_MAT_T_3
; Transform position by view*projection matrix.
dp4 oPos.x, r2, VIEW_PROJ_T_0
dp4 oPos.y, r2, VIEW_PROJ_T_1
dp4 oPos.z, r2, VIEW_PROJ_T_2
dp4 oPos.w, r2, VIEW_PROJ_T_3
+63
View File
@@ -0,0 +1,63 @@
xps.1.1
;------------------------------------------------------------------------------
#define CP_AMBIENT 0
#define CP_DIFFUSE 1
#define CP_SPECULAR 2
#define CP_NORMAL 3
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; t0 = light vector
; t1 = halfway vector
;------------------------------------------------------------------------------
def c[CP_NORMAL], 0.f,0.f,1.f,1.f
tex t0
tex t1
dp3 r0,t0_bx2,c[CP_NORMAL]
dp3 r1,t1_bx2,c[CP_NORMAL]
mad r0,r0_sat,c[CP_DIFFUSE],c[CP_AMBIENT]
mul r1,r1_sat,r1_sat
mul r1,r1,r1
mul r1,r1,c[CP_SPECULAR]
add r0,r1_sat,r0_sat
mov r0,r0_sat
+57
View File
@@ -0,0 +1,57 @@
xvs.1.1
#define CV_FINAL_MAT 0
#define CV_LIGHT_POS 4
#define CV_EYE_POS 5
; Transform point from object space to screen space
m4x4 oPos, v0, c[CV_FINAL_MAT]
;Normalize light vector
mov r1,c[CV_LIGHT_POS]
sub r0.xyz, r1.xyz, v0.xyz
dp3 r2.x, r0.xyz, r0.xyz
rsq r1.x, r2.x
mul r2.xyz, r1.x, r0.xyz
;Normalize eye vector
sub r3.xyz, c[CV_EYE_POS].xyz, v0.xyz
dp3 r4.x, r3.xyz, r3.xyz
rsq r1.x, r4.x
mul r3.xyz, r1.x, r3.xyz
;Normalize half-way vector = light vector + eye vector
add r4.xyz,r3.xyz,r2.xyz
dp3 r3.x, r4.xyz, r4.xyz
rsq r1.x, r3.x
mul r4.xyz, r1.x, r4.xyz
;Transform light vector into tangent space
m3x3 oT0,r2,v2
;Transform halfway vector into tangent space
m3x3 oT1, r4,v2
+34
View File
@@ -0,0 +1,34 @@
xps.1.1
; tex0 is the intensity texture
; tex1+ are the plasma textures
tex t0
tex t1
tex t2
tex t3
add r1, t1.a, t2.a ; add the plasmas together
add r1, r1, t3.a ; add the plasmas together
mul r1, r1, c0 ; multiple by blob intensity
; Render first plasma only, at full (x3) intensity
;add r1, t1, t1
;add r1, r1, t1
;mov r1, t1
mul r0.rgb, t0, r1 ; normal fog mode; multiply intensity by plasma
add r0.rgb, r0.rgb, c1.rgb ; add fade to yellow
;mov r0, t0 ; just render the intensity texture
mov r0.a, 1-zero ; set alpha to full
+17
View File
@@ -0,0 +1,17 @@
;------------------------------------------------------------------------------
; Vertex shader to render green fog
;------------------------------------------------------------------------------
xvs.1.1
mov oPos, v0
mov oT0, v1
mul r0, v2, c1
mul r1, v2, c3
mul r2, v2, c5
add oT1, r0, c0
add oT2, r1, c2
add oT3, r2, c4
+40
View File
@@ -0,0 +1,40 @@
xps.1.1
#define AMBIENT c0
#define DIFFUSE c1
#define SPECULAR c2
#define NORMAL_MAP t0
#define LIGHT_DIR t1
#define HALF_DIR t2
#define SHADOW_MAP t3
#define FALLOFF v0
def c4, 0.25f,0.25f,0.25f,1.f
tex t0 ; normal map
tex t1 ; light dir cubemap
tex t2 ; half dir cubemap
tex t3 ; shadow depth map
; Compute N dot L and N dot H
xdd r0,r1,t0_bx2,t1_bx2,t0_bx2,t2_bx2
; Raise N dot H to 16th power
mul r1.rgb,r1_sat.rgb,r1_sat.rgb
mul r1.rgb,r1.rgb,r1.rgb
mul r1.rgb,r1.rgb,r1.rgb
mul r1.rgb,r1.rgb,r1.rgb
; Scale diffuse and specular terms by coefficients, and sum the resulting terms.
xmma r0.rgb,r1.rgb,v1.rgb,DIFFUSE.rgb,r0_sat.rgb,SPECULAR.rgb,r1_sat.rgb
; Scale by falloff, and add in ambient term
mad r0.rgb,v0.rgb,v1_sat.rgb,AMBIENT.rgb
xfc r0,t3,zero,prod,r0,c4,c4.a
+88
View File
@@ -0,0 +1,88 @@
xvs.1.1
#define FINAL_MAT_COL0 c0
#define FINAL_MAT_COL1 c1
#define FINAL_MAT_COL2 c2
#define FINAL_MAT_COL3 c3
#define LIGHT_POS c4
#define EYE_POS c5
#define OBJECT_SCALE c6
#define LIGHT_ATTEN c7
#define OBJ_SHADOW_MAT c8
#define VERT_POS v0
#define VERT_UV v1
#define VERT_S v2
#define VERT_T v3
#define VERT_N v4
; Transform and project vertex.
dp4 oPos.x, VERT_POS, FINAL_MAT_COL0
dp4 oPos.y, VERT_POS, FINAL_MAT_COL1
dp4 oPos.z, VERT_POS, FINAL_MAT_COL2
dp4 oPos.w, VERT_POS, FINAL_MAT_COL3
; Transform and project vertex to shadow map space
dp4 oT3.x,VERT_POS,c8
dp4 oT3.y,VERT_POS,c9
dp4 oT3.z,VERT_POS,c10
dp4 r0.w,VERT_POS,c11
;clamp w (q) to 0
slt r1, c0, c0
max r0.w, r0.w, r1.w
mov oT3.w, r0.w
; Compute light vector.
mul r8.xyz, VERT_POS.xyz,OBJECT_SCALE
sub r0.xyz, LIGHT_POS.xyz,r8.xyz
dp3 r1.x, r0.xyz,r0.xyz
rsq r0.w, r1.x
; Compute per-vertex light attenuation.
dst r6, r1.xxxx, r0.wwww
dp3 r7.x, r6,LIGHT_ATTEN ; this gives us c0 + c1*d + c2*d*d
rcc oD0.xyz, r7.x
; Normalize light vector.
mul r1.xyz, r0.w,r0.xyz
; Transform light vector to tangent space.
dp3 oT1.x,r1.xyz,VERT_S
dp3 oT1.y,r1.xyz,VERT_T
dp3 oT1.z,r1.xyz,VERT_N
; Normalize eye vector
sub r3.xyz, EYE_POS.xyz,r8.xyz
dp3 r4.x, r3.xyz,r3.xyz
rsq r5.x, r4.x
mul r2.xyz, r5.x,r3.xyz
; Compute halfway vector and transform to tangent space
add r0.xyz,r2.xyz,r1.xyz
dp3 oT2.x,r0.xyz,VERT_S
dp3 oT2.y,r0.xyz,VERT_T
dp3 oT2.z,r0.xyz,VERT_N
; Texture coordinates for normal map.
mov oT0,VERT_UV
+39
View File
@@ -0,0 +1,39 @@
xps.1.1
#define AMBIENT c0
#define DIFFUSE c1
#define SPECULAR c2
#define NORMAL c3
#define LIGHT_DIR t1
#define HALF_DIR t2
#define SHADOW_MAP t3
#define FALLOFF v0
def NORMAL, 0.f,0.f,1.f,1.f
def c4, 0.25f,0.25f,0.25f,1.f
tex t1
tex t2
tex t3
; Compute N dot L and N dot H
xdd r0,r1,NORMAL,t1_bx2,NORMAL,t2_bx2
; Raise N dot H to 32nd power
mul r1.rgb,r1_sat.rgb,r1_sat.rgb
mul r1.rgb,r1.rgb,r1.rgb
mul r1.rgb,r1.rgb,r1.rgb
mul r1.rgb,r1.rgb,r1.rgb
mul r1.rgb,r1.rgb,r1.rgb
; Scale diffuse and specular terms by coefficients, and sum the resulting terms.
xmma r0.rgb,r1.rgb,v1.rgb,DIFFUSE.rgb,r0_sat.rgb,SPECULAR.rgb,r1_sat.rgb
; Scale by falloff, and add in ambient term
mad r0.rgb,v0.rgb,v1_sat.rgb,AMBIENT.rgb
; shadow map.
xfc r0,t3,zero,prod,r0,c4,c4.a
+86
View File
@@ -0,0 +1,86 @@
xvs.1.1
#define FINAL_MAT_COL0 c0
#define FINAL_MAT_COL1 c1
#define FINAL_MAT_COL2 c2
#define FINAL_MAT_COL3 c3
#define LIGHT_POS c4
#define EYE_POS c5
#define OBJECT_SCALE c6
#define LIGHT_ATTEN c7
#define OBJ_SHADOW_MAT c8
#define VERT_POS v0
#define VERT_S v1
#define VERT_T v2
#define VERT_N v3
; Transform and project vertex.
dp4 oPos.x, VERT_POS, FINAL_MAT_COL0
dp4 oPos.y, VERT_POS, FINAL_MAT_COL1
dp4 oPos.z, VERT_POS, FINAL_MAT_COL2
dp4 oPos.w, VERT_POS, FINAL_MAT_COL3
; Transform and project vertex to shadow map space
dp4 oT3.x,VERT_POS,c8
dp4 oT3.y,VERT_POS,c9
dp4 oT3.z,VERT_POS,c10
dp4 r0.w, VERT_POS,c11
;clamp w (q) to 0
slt r1, c0, c0
max r0.w, r0.w, r1.w
mov oT3.w, r0.w
; Compute light vector.
mul r8.xyz, VERT_POS.xyz,OBJECT_SCALE
sub r0.xyz, LIGHT_POS.xyz,r8.xyz
dp3 r1.x, r0.xyz,r0.xyz
rsq r0.w, r1.x
; Compute per-vertex light attenuation.
dst r6, r1.xxxx, r0.wwww
dp3 r7.x, r6,LIGHT_ATTEN ; this gives us c0 + c1*d + c2*d*d
rcc oD0.xyz, r7.x
; Normalize light vector.
mul r1.xyz, r0.w,r0.xyz
; Transform light vector to tangent space.
dp3 oT1.x,r1.xyz,VERT_S
dp3 oT1.y,r1.xyz,VERT_T
dp3 oT1.z,r1.xyz,VERT_N
; Normalize eye vector
sub r3.xyz, EYE_POS.xyz,r8.xyz
dp3 r4.x, r3.xyz,r3.xyz
rsq r5.x, r4.x
mul r2.xyz, r5.x,r3.xyz
; Compute halfway vector and transform to tangent space
add r0.xyz,r2.xyz,r1.xyz
dp3 oT2.x,r0.xyz,VERT_S
dp3 oT2.y,r0.xyz,VERT_T
dp3 oT2.z,r0.xyz,VERT_N
+15
View File
@@ -0,0 +1,15 @@
xps.1.1
texcoord t0
;mov r0, v0
;mov r0, t0
dp3 r1, t0_bx2, t0_bx2
mul r1, 1-r1, 1-r1
mul r0, v0, r1
xfc zero, zero, zero, r0, zero, zero, 1-zero
+47
View File
@@ -0,0 +1,47 @@
xvs.1.1
#define FINAL_MAT_COL0 c0
#define FINAL_MAT_COL1 c1
#define FINAL_MAT_COL2 c2
#define FINAL_MAT_COL3 c3
#define Z_MUL c16
#define Z_ADD c17
#define POS_MUL c18
#define POS_SHIFT c19
; POS_MUL is something like 0.5f, 0.5f, 0.0f, 1.0f
; POS_SHIFT is 0.5f, 0.5f, 0.5f, 0.0f
#define VERT_POS v0
; Transform and project vertex.
dp4 r4.x, VERT_POS, FINAL_MAT_COL0
dp4 r4.y, VERT_POS, FINAL_MAT_COL1
dp4 r4.z, VERT_POS, FINAL_MAT_COL2
dp4 r4.w, VERT_POS, FINAL_MAT_COL3
mov oPos, r4
mov r10, r4.zzzz
mov r11, r4.wwww
add r8, r10, Z_ADD
mul r0.xyz, Z_MUL, r8
sge r0.w, r10, r10 ; make the alpha component 1
; make sure oD0 is at least zero
slt r1, r10, r10
sge r1.w, r10, r10
max oD0, r0, r1
rcp r9, r11 ; r9 is 1/w
mul r0, r4, r9 ; divide screen coordinates by w
mul r3, r0, POS_MUL ; scaled by half (or so), so it goes from 0 to 1, z is nulled
add oT0, r3, POS_SHIFT
sge oT0.w, r9, r9
+44
View File
@@ -0,0 +1,44 @@
xps.1.1
; Inputs:
; t0 = reflection vector -- environment cubemap
; t1 = halfway vector for blob light -- normalization cubemap
; t2 = halfway vector for mood light -- normalization cubemap
; t3 = normal with -- normalization cubemap
; c0 = base color (should be black with medium alpha)
; c1 = blob intensity
; c2 = specular coefficient
def c3, 0.2f,0.5f,0.2f,1.f
tex t0
tex t1
tex t2
tex t3
; N dot H,
xdd r0,r1,t1_bx2,t3_bx2,t2_bx2,t3_bx2
; Raise to the 32nd power
xmma r0,r1,v0,r0_sat,r0_sat,r1_sat,r1_sat
xmma r0,r1,v0,r0,r0,r1,r1
xmma r0,r1,v0,r0,r0,r1,r1
xmma r0,r1,v0,r0,r0,r1,r1
; scale by const color for highlight with green fringe
mad r0,r0,c3,r0
; Add in specular highlight for other light
add r0,r0_sat,r1_sat
; scale specular highlights by spec coefficients, and add term to cubemap
mad r0.rgb, r0_sat,c2,t0
xfc r0, c1, zero, zero, zero, zero, c0.a
+99
View File
@@ -0,0 +1,99 @@
;------------------------------------------------------------------------------
; Vertex shader to render shields
;------------------------------------------------------------------------------
xvs.1.1
;------------------------------------------------------------------------------
; Vertex streams expected by this shader
; struct ShieldVertex
; {
; D3DVECTOR position;
; D3DVECTOR normal;
; };
;
; Expected vertex shaders constants
; c0-c3 = Transpose of object to world matrix
; c4-c7 = Transpose of view*projection matrix
; c8 = some constants, x=0, y=1, z=2, w=0.5
; c9 = eye location in world space
;
; Outputs:
; oPos = position of vertex
; oT0 = reflection vector (lookup into environment cubemap)
; oT1 = reflection vector for specular phong shading
; oT2 = vertex normal in world coordinates
;------------------------------------------------------------------------------
#define WORLD_T_0 c0
#define WORLD_T_1 c1
#define WORLD_T_2 c2
#define WORLD_T_3 c3
#define VIEW_PROJ_T_0 c4
#define VIEW_PROJ_T_1 c5
#define VIEW_PROJ_T_2 c6
#define VIEW_PROJ_T_3 c7
#define ZERO c8.x
#define ONE c8.y
#define TWO c8.z
#define HALF c8.w
#define POSITION v0
#define NORMAL v1
#define EYE_POS c9
#define BLOB_LIGHT_POS c10
#define MOOD_LIGHT_POS c11
; Destination temporary registers
#define WORLD_POS r11
#define WORLD_NORMAL r10
dp4 WORLD_POS.x, POSITION, WORLD_T_0
dp4 WORLD_POS.y, POSITION, WORLD_T_1
dp4 WORLD_POS.z, POSITION, WORLD_T_2
dp4 WORLD_POS.w, POSITION, WORLD_T_3
dp3 WORLD_NORMAL.x, NORMAL.xyz, WORLD_T_0.xyz
dp3 WORLD_NORMAL.y, NORMAL.xyz, WORLD_T_1.xyz
dp3 WORLD_NORMAL.z, NORMAL.xyz, WORLD_T_2.xyz
; Reflect eye vector off surface normal and store in T0.
sub r2, WORLD_POS, EYE_POS
;dp3 r2.x, r0.xyz, r0.xyz
;rsq r1.x, r2.x
;mul r2.xyz, r1.xxx, r0.xyz ; r2 now has normalized "vertex - eye" vector
dp3 r1.x, r2.xyz, WORLD_NORMAL.xyz
mul r1.y, r1.x, -TWO
mad r3.xyz, r1.yyy, WORLD_NORMAL.xyz, r2.xyz
mov oT0.xyz, r3.xyz ; store reflection vector for cubemap lookup
; compute reflection vector for blob light
sub r8,WORLD_POS,BLOB_LIGHT_POS
dp3 r1.x, r8.xyz, WORLD_NORMAL.xyz
mul r1.y, r1.x, -TWO
mad r3.xyz, r1.yyy, WORLD_NORMAL.xyz, r8.xyz
mov oT1.xyz, r3.xyz ;
; compute reflection vector for mood light
sub r8.xyz,WORLD_POS.xyz,MOOD_LIGHT_POS.xyz
dp3 r1.x, r8.xyz, WORLD_NORMAL.xyz
mul r1.y, r1.x, -TWO
mad r3.xyz, r1.yyy, WORLD_NORMAL.xyz, r8.xyz
mov oT2.xyz, r3.xyz ;
; pass vertex-to-eye
mov oT3.xyz,-r2.xyz
; Transform position by view*projection matrix.
dp4 oPos.x, WORLD_POS, VIEW_PROJ_T_0
dp4 oPos.y, WORLD_POS, VIEW_PROJ_T_1
dp4 oPos.z, WORLD_POS, VIEW_PROJ_T_2
dp4 oPos.w, WORLD_POS, VIEW_PROJ_T_3
+20
View File
@@ -0,0 +1,20 @@
xps.1.1
; Inputs:
; t0 = surface normal (renormalize and dot with eye)
; t1 = eye direction
; c0 = base blob color
; c1 = ambient color
tex t0
tex t1
dp3 r0, t0_bx2, t1_bx2
mov r1, r0_sat
mul r0, 1-r1, 1-r1
mul r0.rgb, 1-r0, c0.rgb
add r0.rgb, r0.rgb, c1.rgb
mov r0.a, c0.a
;mov r0.rgb, t0.rgb
+105
View File
@@ -0,0 +1,105 @@
;------------------------------------------------------------------------------
; Vertex shader to do ripple/wave effect.
;------------------------------------------------------------------------------
xvs.1.1
;------------------------------------------------------------------------------
; Vertex streams expected by this shader
; struct VBlobConstantVertex
; {
; D3DVECTOR unit_sphere_normal; // v0
; };
; struct VBlobChangingVertex
; {
; D3DVECTOR4 normal; // not normalized (do it in the GPU); w is the displacement due to bumps // v1
; };
;
; Expected vertex shaders constants
; c4-c7 = Transpose of view*projection matrix
; c8 = some constants, x=0, y=1, z=2, w=0.5
; c9 = eye location
; c10 = blob scaling
; c11 = 1/ blob scaling
; c12 = blob center
;
; Outputs:
; oPos = position of vertex
; oT0 = surface normal (renormalize and dot with light)
; oT1 = direction to eye (renormalize and dot with light)
;------------------------------------------------------------------------------
#define VIEW_PROJ_T_0 c4
#define VIEW_PROJ_T_1 c5
#define VIEW_PROJ_T_2 c6
#define VIEW_PROJ_T_3 c7
#define ZERO c8.x
#define ONE c8.y
#define TWO c8.z
#define HALF c8.w
#define US_POSITION v0
#define US_NORMAL v0
#define LNORMAL v1.xyz
#define DISPLACEMENT v1.w
#define EYE_POS c9
#define SCALING c10
#define OO_SCALING c11
#define CENTER c12
; Destination temporary registers
#define L_EL_NORM r9
#define ELLIPSE_NORMAL r10
#define WORLD_POS r11
; Adjust the unit-sphere normal for the scale factor
mul r10, US_NORMAL, OO_SCALING
dp3 r2.x, r10, r10
rsq r1.x, r2.x
mul ELLIPSE_NORMAL.xyz, r1.xxx, r10.xyz
mov ELLIPSE_NORMAL.w, ONE
mul r11, US_POSITION, SCALING
add r11, r11, CENTER ; r11 is now the position in world coordinates
; Add the displacement.
mov r0.xyz, v1.www
mov r0.w, ZERO
mad WORLD_POS, ELLIPSE_NORMAL, r0, r11 ; r11 now has the displacement applied
;Normalize eye position
sub r0.xyz, EYE_POS.xyz, WORLD_POS.xyz
dp3 r2.x, r0.xyz, r0.xyz
rsq r1.x, r2.x
mul r2.xyz, r1.x, r0.xyz
mov r2.w, ONE
mov r0.w, ONE
mov oT1, r2
;Normalize local surface normal
mul r0, LNORMAL, OO_SCALING
dp3 r2.x, r0, r0
rsq r1.x, r2.x
mul L_EL_NORM.xyz, r1.x, r0
mov L_EL_NORM.w, ONE
mov oT0, L_EL_NORM
; Transform position by view*projection matrix.
dp4 oPos.x, WORLD_POS, VIEW_PROJ_T_0
dp4 oPos.y, WORLD_POS, VIEW_PROJ_T_1
dp4 oPos.z, WORLD_POS, VIEW_PROJ_T_2
dp4 oPos.w, WORLD_POS, VIEW_PROJ_T_3
+19
View File
@@ -0,0 +1,19 @@
xps.1.1
; Inputs:
; t0 = surface normal (renormalize and dot with eye)
; t1 = eye direction
; c0 = base blob color
; c1 = ambient color
; c2 = alpha_scale
tex t0
tex t1 ; is probably normalized anyway, the eye position hardly changes wrt the small bloblets
dp3 r0, t0_bx2, t1_bx2
mov r1, r0_sat
mul r0, 1-r1, 1-r1
mul r0.rgba, 1-r0, c0.rgba
add r0.rgb, r0.rgb, c1.rgb
mul r0.a, r0.a, c2.a
+90
View File
@@ -0,0 +1,90 @@
;------------------------------------------------------------------------------
; Vertex shader to do ripple/wave effect.
;------------------------------------------------------------------------------
xvs.1.1
;------------------------------------------------------------------------------
; Vertex streams expected by this shader
; struct VBlobConstantVertex
; {
; D3DVECTOR unit_sphere_normal; // v0
; };
;
; Expected vertex shaders constants
; c4-c7 = Transpose of view*projection matrix
; c8 = some constants, x=0, y=1, z=2, w=0.5
; c9 = eye location
; c10 = blob center
; c11 = direction of scaling
; c12 = scaling perpendicular to direction
; c13 = parallel minus perpendicular scaling multiplied by scaling direction
;
; Outputs:
; oPos = position of vertex
; oT0 = surface normal (renormalize and dot with light)
; oT1 = direction to eye (renormalize and dot with light)
;------------------------------------------------------------------------------
#define VIEW_PROJ_T_0 c4
#define VIEW_PROJ_T_1 c5
#define VIEW_PROJ_T_2 c6
#define VIEW_PROJ_T_3 c7
#define ZERO c8.x
#define ONE c8.y
#define TWO c8.z
#define HALF c8.w
#define US_POSITION v0
#define US_NORMAL v0
#define LNORMAL v1.xyz
#define DISPLACEMENT v1.w
#define EYE_POS c9
#define CENTER c10
#define SCALE_DIR c11
#define SCALE_DIR_PERP c12
#define SCALE_DIR_PMP c13
; SCALE_DIR_PMP is parallel scale minus perpendicular scale multiplied by SCALE_DIR
; Destination temporary registers
#define L_EL_NORM r9
#define ELLIPSE_NORMAL r10
#define WORLD_POS r11
mov oT0, US_NORMAL
; Scale the point for wobble.
dp3 r0, US_POSITION, SCALE_DIR
mul r1, r0, SCALE_DIR_PMP
mad r2, SCALE_DIR_PERP, US_POSITION, r1
add WORLD_POS, r2, CENTER
mov WORLD_POS.w, ONE
; can combine the mul and add into another mad
;Normalize eye position
; (This stays in world coordinates, so it should probably just be normalized in the constant.
sub r0.xyz, EYE_POS.xyz, WORLD_POS.xyz
dp3 r2.x, r0.xyz, r0.xyz
rsq r1.x, r2.x
mul r2.xyz, r1.x, r0.xyz
mov r2.w, ONE
mov r0.w, ONE
mov oT1, r2
; Transform position by view*projection matrix.
dp4 oPos.x, WORLD_POS, VIEW_PROJ_T_0
dp4 oPos.y, WORLD_POS, VIEW_PROJ_T_1
dp4 oPos.z, WORLD_POS, VIEW_PROJ_T_2
dp4 oPos.w, WORLD_POS, VIEW_PROJ_T_3
+48
View File
@@ -0,0 +1,48 @@
#define GPXMEM 0xfe830000
#define GPYMEM 0xfe836000
#define GPPMEM 0xfe83a000
struct patch {
unsigned int start;
unsigned int end;
unsigned int loop;
unsigned char pitch;
unsigned char bank;
};
struct word {
unsigned int start;
unsigned int end;
unsigned char bank;
unsigned int volume;
};
struct two_pole_lpf {
unsigned short c0;
unsigned short c1;
unsigned short c2;
};
#define N_OSCS 11
#define OSC_SIZE 6
#define ST_VOLUME_R 66
#define ST_VOLUME_L 77
/*
* adpcm equates
*/
#define ADP_END 109
#define ADP_BANK 111
#define ADP_PRE_VOLUME_R 116
#define ADP_PRE_VOLUME_L 120
#define ADP_PRE_START 117
#define ADP_STATUS 115
#define ADP_VOLUME_R 110
#define ADP_VOLUME_L 112
#define OSC_0_MOD_INDEX 119
+31
View File
@@ -0,0 +1,31 @@
# C_DEFINES=$(C_DEFINES) -DPROFILE
# C_DEFINES=$(C_DEFINES) -DDETERMINISTIC
LINKER_FLAGS=$(LINKER_FLAGS) /MAP
SOURCES=\
CamControl.cpp \
camera.cpp \
GreenFog.cpp \
logo_renderer.cpp \
qrand.cpp \
renderer.cpp \
scene_renderer.cpp \
Shield.cpp \
tex_gen.cpp \
VBlob.cpp \
xbs_app.cpp \
fastmath.cpp \
placementdoodad.cpp \
bootsound.cpp \
mslogo.cpp \
dev.c \
cf.c \
evf.c \
globals.c \
sos.c \
proc.c \
stboot.c
+659
View File
@@ -0,0 +1,659 @@
#include <dsound.h>
#include "sos.h"
#include "macros.h"
#include "bootsnd.h"
#include "pitches.h"
#ifdef STARTUPANIMATION
#pragma data_seg("INIT_RW")
#pragma code_seg("INIT")
#pragma bss_seg("INIT_RW")
#pragma const_seg("INIT_RD")
// Tell linker to put bootsound code and data into INIT section
#pragma comment(linker, "/merge:DSOUND=INIT")
#pragma comment(linker, "/merge:INIT_RD=INIT")
#pragma comment(linker, "/merge:INIT_RW=INIT")
#endif //STARTUPANIMATION
DSENVELOPEDESC Env1a = {
DSEG_AMPLITUDE, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x5, // hold
0x20, // decay
0x0, // release
0x7f, // sustain
0x0, // pitch scale
0x0, // filter scale
};
DSENVELOPEDESC Env1m = {
DSEG_MULTI, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x0, // hold
0x10, // decay
0x0, // release
0x1f, // sustain
0x10, // pitch scale
0x7f, // filter scale
};
DSENVELOPEDESC Env2a = {
DSEG_AMPLITUDE, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x0, // hold
0x40, // decay
0x0, // release
0x3f, // sustain
0x7f, // pitch scale
0x0, // filter scale
};
DSENVELOPEDESC Env2m = {
DSEG_MULTI, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x100, // attack
0x0, // hold
0x10, // decay
0x0, // release
0x1f, // sustain
0x40, // pitch scale
0x4f, // filter scale
};
DSENVELOPEDESC Env3a = {
DSEG_AMPLITUDE, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x3, // hold
0x10, // decay
0x20, // release
0x10, // sustain
0x0, // pitch scale
0x0, // filter scale
};
DSENVELOPEDESC Env3m = {
DSEG_MULTI, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x0, // hold
0x10, // decay
0x0, // release
0x1f, // sustain
0x10, // pitch scale
0x1f, // filter scale
};
DSENVELOPEDESC OpenEnva = {
DSEG_AMPLITUDE, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x0, // attack
0x0, // hold
0x0, // decay
0x0, // release
0xff, // sustain
0x0, // pitch scale
0x0, // filter scale
};
DSENVELOPEDESC OpenEnvm = {
DSEG_MULTI, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0, // attack
0x0, // hold
0x00, // decay
0x00, // release
0xff, // sustain
0x0, // pitch scale
0x0, // filter scale
};
extern unsigned short Sin128[];
extern unsigned short Saw128[];
extern unsigned short Noise8192[];
extern unsigned short FM32768[];
extern unsigned short Glock[];
extern unsigned short Thun8k[];
extern unsigned short Cannon[];
extern unsigned short Bubble[];
extern unsigned short ThunEl16[];
extern unsigned short ReverseThunEl16[];
//
// patch is table, loop, env1, env2
// so, patches are defined by a waveform, a length, a loop address
// and the pair of envelopes.
//
const struct DSPpatch PatchSin = {
Sin128, // start addr
256, // length
0, // loop start
256, // loop end
1, // loop sound
&Env1a, // ampitude envelope
&Env1m // multi purpose envelope
};
///////////////////////////////////////////////////////////////////////
DSENVELOPEDESC SawEnv1a = {
DSEG_AMPLITUDE, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x2, // hold
0x10, // decay
0x0, // release
0x9f, // sustain
0x0, // pitch scale
0x0, // filter scale
};
DSENVELOPEDESC SawEnv1m = {
DSEG_MULTI, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x10, // attack
0x100, // hold
0x100, // decay
0x80, // release
0xff, // sustain
0x00, // pitch scale
-80, // filter scale
};
const struct DSPpatch PatchSaw1 = {
Saw128, // start addr
256, // length
0, // loop start
256, // loop end
1, // loop sound
&SawEnv1a, // ampitude envelope
&SawEnv1m // multi purpose envelope
};
///////////////////////////////////////////////////////////////////////
DSENVELOPEDESC SawEnv2a = {
DSEG_AMPLITUDE, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x0, // hold
0x40, // decay
0x0, // release
0x3f, // sustain
0x7f, // pitch scale
0x0, // filter scale
};
DSENVELOPEDESC SawEnv2m = {
DSEG_MULTI, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x100, // attack
0x0, // hold
0x10, // decay
0x0, // release
0x1f, // sustain
0x00, // pitch scale
0x0, // filter scale
};
const struct DSPpatch PatchSaw2 = {
Saw128, // start addr
256, // length
0, // loop start
256, // loop end
1, // loop sound
&SawEnv2a, // ampitude envelope
&SawEnv2m // multi purpose envelope
};
///////////////////////////////////////////////////////////////////////
const struct DSPpatch PatchSaw3 = {
Saw128, // start addr
256, // length
0, // loop start
256, // loop end
1, // loop sound
&Env3a, // ampitude envelope
&Env3m // multi purpose envelope
};
const struct DSPpatch PatchSquare = {
Saw128, // start addr
256, // length
0, // loop start
256, // loop end
1, // loop sound
&Env3a, // ampitude envelope
&Env3m // multi purpose envelope
};
/////////////////////////////////////////////////////////////////////
DSENVELOPEDESC NoiseEnv1a = {
DSEG_AMPLITUDE, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x3, // hold
0x10, // decay
0x20, // release
0xff, // sustain
0x0, // pitch scale
0x0, // filter scale
};
DSENVELOPEDESC NoiseEnv1m = {
DSEG_MULTI, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x100, // attack
0x0, // hold
0x30, // decay
0xc0, // release
0xff, // sustain
0x0, // pitch scale
0x0, // filter scale
};
/////////////////////////////////////////////////////////////////////
const struct DSPpatch PatchEnvNoise1 = {
Noise8192, // start addr
8192*2, // length
0, // loop start
8192*2, // loop end
1, // loop sound
&NoiseEnv1a, // ampitude envelope
&NoiseEnv1m // multi purpose envelope
};
//////////////////////////////
const struct DSPpatch PatchFM = {
FM32768, // start addr
32768, // length
0, // loop start
32768, // loop end
0, // loop sound
&OpenEnva, // ampitude envelope
&OpenEnvm // multi purpose envelope
};
///////////////////////////////////////////////////////////////
const struct DSPpatch PatchGlock = {
Glock, // start addr
3768*2, // length...from glock.equ
0, // loop start
3768*2, // loop end
0, // Don't loop this sound
&OpenEnva, // ampitude envelope
&OpenEnvm // multi purpose envelope
};
///////////////////////////////////////////////////////////////
const struct DSPpatch PatchThun8k = {
Thun8k, // start addr
10922*2, // length...from glock.equ
0, // loop start
10922*2, // loop end
0, // Don't loop this sound
&OpenEnva, // ampitude envelope
&OpenEnvm // multi purpose envelope
};
///////////////////////////////////////////////////////////////
const struct DSPpatch PatchThunEl16 = {
ThunEl16, // start addr
0x5540*2, // length...from glock.equ
0, // loop start
0x5540*2, // loop end
0, // Don't loop this sound
&OpenEnva, // ampitude envelope
&OpenEnvm // multi purpose envelope
};
///////////////////////////////////////////////////////////////
const struct DSPpatch PatchRevThun = {
ReverseThunEl16, // start addr
0x5540*2, // length...from glock.equ
0, // loop start
0x5540*2, // loop end
0, // Don't loop this sound
&OpenEnva, // ampitude envelope
&OpenEnvm // multi purpose envelope
};
///////////////////////////////////////////////////////////////
const struct DSPpatch PatchCannon = {
Cannon, // start addr
3086*2, // length...from glock.equ
0, // loop start
3086*2, // loop end
0, // Don't loop this sound
&OpenEnva, // ampitude envelope
&OpenEnvm // multi purpose envelope
};
const struct DSPpatch PatchBubble = {
Bubble, // start addr
6719*2, // length...from glock.equ
0, // loop start
6719*2, // loop end
1, // loop this sound
&OpenEnva, // ampitude envelope
&OpenEnvm // multi purpose envelope
};
#define PSIN1 0
#define PSAW1 1
#define PSQUARE 2
#define PSAW2 3
#define PSAW3 4
#define PNOISE1 5
#define PGLOCK 6
#define PTHUN 7
#define PCANNON 8
#define PBUBBLE 9
#define PFM 10
#define PTHUNEL16 11
#define PREVTHUN 12
struct DSPpatch const *Patches[] = {
&PatchSin, // patch 0
&PatchSaw1, // patch 1
&PatchSquare, // patch 2
&PatchSaw2, // patch 3
&PatchSaw3, // patch 4
&PatchEnvNoise1, // patch 5
&PatchGlock, // patch 6
&PatchThun8k, // patch 7
&PatchCannon, // 8
&PatchBubble, // 9
&PatchFM, // 10
&PatchThunEl16, //11
&PatchRevThun // 12
};
// throbbing bass
//
const unsigned short Boot0[] = {
rest(194),
fset(25000,26000),
patch(PSAW1),
volume(40),
loop(13),
note(dd1,57),
rest(3),
endloop,
note(dd1,28),
rest(2),
loop(6),
volume(15),
note(dd1,27),
rest(3),
endloop,
loop(255),
rest(2000),
endloop
};
//noise whoosh for opening
const unsigned short Boot1[] = {
fset(1000,26000),
patch(5),
volume(43),
note(cc2,1),
loop(10),
finc(3000,26000),
slur(cc2,13),
endloop,
ring(4),
volume(20),
loop(60),
volume(1),
finc(-1000,26000),
slur(cc2,15),
endloop,
loop(255),
rest(2000),
endloop
};
// bubbling sound
const unsigned short Boot2[] = {
patch(PBUBBLE),
volume(0),
fset(5000,26000),
rest(194),
note(dd2,412),
loop(20),
ring(20),
finc(1000,26000),
endloop,
loop(30),
ring(10),
volume(4),
endloop,
loop(255),
rest(2000),
endloop
};
// first and last flashes
const unsigned short Boot3[] = {
patch(PTHUN),
volume(20),
fset(32767,26000),
rest(134),
note(dd2,820),
note(dd2,200),
loop(20),
ring(20),
volume(2),
finc(-1000,26000),
endloop,
ring(10000),
loop(255),
rest(2000),
endloop
};
// fast noisy stuff...
//
const unsigned short Boot4[] = {
rest(194),
fset(32000,26000),
patch(PNOISE1),
volume(160),
loop(10),
volume(-3),
note(cc4,15),
rest(5),
note(ff4,15),
volume(-3),
rest(5),
note(gg5,15),
rest(5),
volume(-3),
note(ff4,15),
rest(5),
endloop,
note(ff4,18),
loop(255),
rest(2000),
endloop
};
// glocks....
const unsigned short Boot5[] = {
patch(PGLOCK),
volume(70),
rest(1194),
fset(32000,26000),
loop(40),
note(cc4,18),
rest(2),
volume(15),
endloop,
note(cc4,500),
loop(255),
rest(2000),
endloop
};
// glocks....
const unsigned short Boot6[] = {
patch(PGLOCK),
volume(70),
rest(1194),
fset(32000,26000),
loop(40),
note(cc3,18),
rest(2),
volume(15),
endloop,
note(cc3,500),
loop(255),
rest(2000),
endloop
};
/////
// glocks....
const unsigned short Boot8[] = {
patch(PGLOCK),
volume(70),
rest(1194),
fset(32000,26000),
loop(40),
note(gg3,18),
rest(2),
volume(15),
endloop,
note(cc3,500),
loop(255),
rest(2000),
endloop
};
// bass beg....
const unsigned short Boot7[] = {
patch(PSAW2),
volume(3),
fset(1000,26000),
note(dd2,1),
loop(19),
slur(dd2,10),
finc(1500,2600),
endloop,
loop(255),
rest(2000),
endloop
};
const unsigned short *Boot[] = {
Boot0,Boot1,Boot2,Boot3,Boot4,Boot5,Boot6,Boot7,Boot8
};
/////////////////////////////////////////////////////////////////////////
const unsigned short Tune0[] = {
patch(PREVTHUN),
note(cc3,800),
patch(PTHUNEL16),
note(cc3,800),
rest(200),
patch(PSIN1),
loop(5),
loop(120),
note(cc2,50),
xpose(200),
rest(0),
endloop,
loop(120),
note(cc0,50),
xpose(-200),
rest(0),
endloop,
endloop,
note(5,6),
rest(0x10),
// 0,1,2,3,4
};
const unsigned short Tune1[] = {
// fset(6000,26000),
patch(PSIN1),
note(cc3,200),
};
const unsigned short *Tune[] = {
Tune0
};
const struct sound sound_calls[] = {
0,0,0,NULL, //0
1,0,0x1ff,Boot, //1
1,0,0x001,Tune, //2
1,0,0x001,Tune, //2
};
struct sound sound_calls2[2];
int max_sound_call = 0x2;
int default_clock_value = 80;
+805
View File
@@ -0,0 +1,805 @@
#include <dsound.h>
#include "sos.h"
#include "macros.h"
#include "bootsnd.h"
#include "pitches.h"
#ifdef STARTUPANIMATION
#pragma data_seg("INIT_RW")
#pragma code_seg("INIT")
#pragma bss_seg("INIT_RW")
#pragma const_seg("INIT_RD")
// Tell linker to put bootsound code and data into INIT section
#pragma comment(linker, "/merge:DSOUND=INIT")
#pragma comment(linker, "/merge:INIT_RD=INIT")
#pragma comment(linker, "/merge:INIT_RW=INIT")
#endif //STARTUPANIMATION
DSENVELOPEDESC Env1a = {
DSEG_AMPLITUDE, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x5, // hold
0x20, // decay
0x0, // release
0x7f, // sustain
0x0, // pitch scale
0x0, // filter scale
};
DSENVELOPEDESC Env1m = {
DSEG_MULTI, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x0, // hold
0x10, // decay
0x0, // release
0x1f, // sustain
0x10, // pitch scale
0x7f, // filter scale
};
DSENVELOPEDESC Env2a = {
DSEG_AMPLITUDE, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x0, // hold
0x40, // decay
0x0, // release
0x3f, // sustain
0x7f, // pitch scale
0x0, // filter scale
};
DSENVELOPEDESC Env2m = {
DSEG_MULTI, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x100, // attack
0x0, // hold
0x10, // decay
0x0, // release
0x1f, // sustain
0x40, // pitch scale
0x4f, // filter scale
};
DSENVELOPEDESC Env3a = {
DSEG_AMPLITUDE, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x3, // hold
0x10, // decay
0x20, // release
0x10, // sustain
0x0, // pitch scale
0x0, // filter scale
};
DSENVELOPEDESC Env3m = {
DSEG_MULTI, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x0, // hold
0x10, // decay
0x0, // release
0x1f, // sustain
0x10, // pitch scale
0x1f, // filter scale
};
DSENVELOPEDESC OpenEnva = {
DSEG_AMPLITUDE, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x0, // attack
0x0, // hold
0x0, // decay
0x0, // release
0xff, // sustain
0x0, // pitch scale
0x0, // filter scale
};
DSENVELOPEDESC OpenEnvm = {
DSEG_MULTI, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0, // attack
0x0, // hold
0x00, // decay
0x00, // release
0xff, // sustain
0x0, // pitch scale
0x0, // filter scale
};
extern unsigned short Sin128[];
extern unsigned short Saw128[];
extern unsigned short Noise8192[];
extern unsigned short FM32768[];
extern unsigned short Glock[];
extern unsigned short Bubble[];
extern unsigned short ThunEl16[];
extern unsigned short ReverseThunEl16[];
//
// patch is table, loop, env1, env2
// so, patches are defined by a waveform, a length, a loop address
// and the pair of envelopes.
//
const struct DSPpatch PatchSin = {
Sin128, // start addr
256, // length
0, // loop start
256, // loop end
1, // loop sound
&Env1a, // ampitude envelope
&Env1m // multi purpose envelope
};
///////////////////////////////////////////////////////////////////////
DSENVELOPEDESC SawEnv1a = {
DSEG_AMPLITUDE, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x2, // hold
0x10, // decay
0x0, // release
0x9f, // sustain
0x0, // pitch scale
0x0, // filter scale
};
DSENVELOPEDESC SawEnv1m = {
DSEG_MULTI, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x10, // attack
0x100, // hold
0x100, // decay
0x80, // release
0xff, // sustain
0x00, // pitch scale
-80, // filter scale
};
const struct DSPpatch PatchSaw1 = {
Saw128, // start addr
256, // length
0, // loop start
256, // loop end
1, // loop sound
&SawEnv1a, // ampitude envelope
&SawEnv1m // multi purpose envelope
};
///////////////////////////////////////////////////////////////////////
DSENVELOPEDESC SawEnv2a = {
DSEG_AMPLITUDE, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x0, // hold
0x40, // decay
0x0, // release
0x3f, // sustain
0x7f, // pitch scale
0x0, // filter scale
};
DSENVELOPEDESC SawEnv2m = {
DSEG_MULTI, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x100, // attack
0x0, // hold
0x10, // decay
0x0, // release
0x1f, // sustain
0x00, // pitch scale
0x0, // filter scale
};
const struct DSPpatch PatchSaw2 = {
Saw128, // start addr
256, // length
0, // loop start
256, // loop end
1, // loop sound
&SawEnv2a, // ampitude envelope
&SawEnv2m // multi purpose envelope
};
///////////////////////////////////////////////////////////////////////
const struct DSPpatch PatchSaw3 = {
Saw128, // start addr
256, // length
0, // loop start
256, // loop end
1, // loop sound
&Env3a, // ampitude envelope
&Env3m // multi purpose envelope
};
const struct DSPpatch PatchSquare = {
Saw128, // start addr
256, // length
0, // loop start
256, // loop end
1, // loop sound
&Env3a, // ampitude envelope
&Env3m // multi purpose envelope
};
/////////////////////////////////////////////////////////////////////
DSENVELOPEDESC NoiseEnv1a = {
DSEG_AMPLITUDE, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x1, // attack
0x3, // hold
0x10, // decay
0x20, // release
0xff, // sustain
0x0, // pitch scale
0x0, // filter scale
};
DSENVELOPEDESC NoiseEnv1m = {
DSEG_MULTI, // EG
DSEG_MODE_DELAY, // mode
0, // delay
0x100, // attack
0x0, // hold
0x30, // decay
0xc0, // release
0xff, // sustain
0x0, // pitch scale
0x0, // filter scale
};
/////////////////////////////////////////////////////////////////////
const struct DSPpatch PatchEnvNoise1 = {
Noise8192, // start addr
8192*2, // length
0, // loop start
8192*2, // loop end
1, // loop sound
&NoiseEnv1a, // ampitude envelope
&NoiseEnv1m // multi purpose envelope
};
//////////////////////////////
const struct DSPpatch PatchFM = {
FM32768, // start addr
32768, // length
0, // loop start
32768, // loop end
0, // loop sound
&OpenEnva, // ampitude envelope
&OpenEnvm // multi purpose envelope
};
///////////////////////////////////////////////////////////////
const struct DSPpatch PatchGlock = {
Glock, // start addr
3768*2, // length...from glock.equ
0, // loop start
3768*2, // loop end
0, // Don't loop this sound
&OpenEnva, // ampitude envelope
&OpenEnvm // multi purpose envelope
};
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
const struct DSPpatch PatchThunEl16 = {
ThunEl16, // start addr
0x5540*2, // length...from glock.equ
0, // loop start
0x5540*2, // loop end
0, // Don't loop this sound
&OpenEnva, // ampitude envelope
&OpenEnvm // multi purpose envelope
};
///////////////////////////////////////////////////////////////
const struct DSPpatch PatchRevThun = {
ReverseThunEl16, // start addr
0x5540*2, // length...from glock.equ
0, // loop start
0x5540*2, // loop end
0, // Don't loop this sound
&OpenEnva, // ampitude envelope
&OpenEnvm // multi purpose envelope
};
///////////////////////////////////////////////////////////////
const struct DSPpatch PatchBubble = {
Bubble, // start addr
6719*2, // length...from glock.equ
0, // loop start
6719*2, // loop end
1, // loop this sound
&OpenEnva, // ampitude envelope
&OpenEnvm // multi purpose envelope
};
#define PSIN1 0
#define PSAW1 1
#define PSQUARE 2
#define PSAW2 3
#define PSAW3 4
#define PNOISE1 5
#define PGLOCK 6
#define PBUBBLE 7
#define PFM 8
#define PTHUNEL16 9
#define PREVTHUN 10
struct DSPpatch const *Patches[] = {
&PatchSin, // patch 0
&PatchSaw1, // patch 1
&PatchSquare, // patch 2
&PatchSaw2, // patch 3
&PatchSaw3, // patch 4
&PatchEnvNoise1, // patch 5
&PatchGlock, // patch 6
&PatchBubble, // 7
&PatchFM, // 8
&PatchThunEl16, //9
&PatchRevThun // 10
};
// throbbing bass
//
const unsigned short Boot0[] = {
fset(29000,26000),
patch(PSAW1),
volume(10),
rest(194-50),
note(dd1,130),
rest(2),
note(dd1,125),
rest(3),
note(dd1,70),
rest(2),
note(dd1,77),
rest(3),
note(dd1,97),
rest(3),
note(dd1,91),
rest(3),
note(dd1,47),
rest(3),
note(dd1,51),
rest(3),
note(dd1,57),
rest(3),
note(dd1,132),
rest(0),
// rest(194),
// fset(29000,26000),
// patch(PSAW1),
// volume(10),
// loop(13),
//
// note(dd1,57),
// rest(3),
// endloop,
// note(dd1,28),
// rest(2),
// loop(6),
// volume(15),
// note(dd1,27),
// rest(3),
// endloop,
//
loop(255),
rest(20000),
endloop
};
//noise whoosh for opening
const unsigned short Boot1[] = {
fset(1000,26000),
patch(5),
volume(43),
note(cc2,1),
loop(10),
finc(3000,26000),
slur(cc2,13),
endloop,
ring(4),
volume(20),
loop(60),
volume(1),
finc(-1000,26000),
slur(cc2,15),
endloop,
loop(255),
rest(2000),
endloop
};
// bubbling sound
const unsigned short Boot2[] = {
patch(PBUBBLE),
volume(12),
fset(6000,26000),
rest(134),
note(dd2,412+60),
loop(20),
ring(20),
finc(1000,26000),
endloop,
loop(30),
ring(10),
volume(4),
endloop,
loop(255),
rest(20000),
endloop
};
// first and last flashes
const unsigned short Boot3[] = {
patch(PTHUNEL16),
volume(40),
fset(32767,26000),
rest(134),
note(dd3,820),
volume(-25),
note(dd3,200),
loop(20),
ring(20),
volume(2),
finc(-1000,26000),
endloop,
ring(10000),
loop(255),
rest(2000),
endloop
};
// fast noisy stuff...
//
const unsigned short Boot4[] = {
rest(194),
fset(32000,26000),
patch(PNOISE1),
volume(160),
loop(8),
volume(-3),
note(cc4,15),
rest(5),
note(ff4,15),
volume(-3),
rest(5),
note(gg5,15),
rest(5),
volume(-3),
note(ff4,15),
rest(5),
endloop,
loop(3),
xpose(0x100),
volume(-3),
note(cc4,10),
rest(5),
note(ff4,10),
volume(-3),
rest(5),
note(gg5,10),
rest(5),
volume(-3),
note(ff4,10),
rest(5),
endloop,
note(ff4,10),
loop(255),
rest(20000),
endloop
};
// glocks....
const unsigned short Boot5[] = {
patch(PGLOCK),
volume(55),
rest(1114),
fset(32000,26000),
note(as2,20),
note(ff2,20),
note(as1,20),
volume(10),
loop(6),
note(as2,18),
rest(2),
volume(30),
note(as2,18),
rest(2),
volume(20),
note(as2,18),
rest(2),
volume(-35),
finc(-2500,26000),
endloop,
loop(255),
rest(20000),
endloop
};
// glocks....
const unsigned short Boot6[] = {
// patch(PGLOCK),
// volume(10),
// loop(100),
// note(cc3,55),
// rest(5),
// endloop,
// rest(1194),
// fset(32000,26000),
// note(cc3,40),
// rest(1),
// note(ff3,40),
// rest(1),
// note(cc3,40),
// rest(1),
// note(gg3,400),
// rest(1),
// loop(40),
// note(cc3,18),
// rest(2),
// volume(2),
// endloop,
// note(cc3,500),
loop(255),
rest(20000),
endloop
};
/////
// glocks....
const unsigned short Boot8[] = {
patch(PGLOCK),
volume(100),
rest(1194),
fset(32000,26000),
// note(cc2,40),
// rest(1),
// note(ff2,40),
// rest(1),
// note(cc2,40),
// rest(1),
// note(gg2,400),
// rest(1),
// loop(40),
// note(gg2,18),
// rest(2),
// volume(2),
// endloop,
// note(cc3,500),
loop(255),
rest(20000),
endloop
};
// bass beg....
const unsigned short Boot7[] = {
patch(PSAW2),
xpose(0x60),
volume(18),
fset(1000,26000),
note(dd2,1),
loop(19),
slur(dd2,10),
finc(1500,2600),
endloop,
rest(800),
note(dd2,1),
loop(30),
slur(dd2,10),
finc(-750,2600),
endloop,
loop(30),
slur(dd2,5),
volume(3),
endloop,
loop(255),
rest(2000),
endloop
};
////////////////////////////////////////////////////////
// Boot track 9: Pulses in sync with blob
const unsigned short Boot9[] = {
patch(PTHUNEL16),
volume(50),
rest(326-50),
note(aa2,280),
rest(0),
volume(-15),
note(aa2,244),
rest(0),
volume(-15),
note(aa2,500),
loop(255),
rest(2000),
endloop
};
////////////////////////////////////////////////////////
// Boot track A: Pulses in sync with blob
const unsigned short BootA[] = {
patch(PTHUNEL16),
volume(50),
rest(454-50),
note(aa2,252),
rest(0),
note(aa2,194),
rest(0),
volume(-20),
note(aa2,200),
loop(255),
rest(2000),
endloop
};
////////////////////////////////////////////////////////
// Boot track B: Pulses in sync with blob
const unsigned short BootB[] = {
patch(PTHUNEL16),
volume(50),
rest(526-50),
note(aa2,274),
rest(0),
note(aa2,154),
rest(0),
volume(-20),
note(aa2,200),
loop(255),
rest(2000),
endloop
};
const unsigned short *Boot[] = {
Boot0,Boot1,Boot2,Boot3,Boot4,Boot5,Boot6,Boot7,Boot8,Boot9,BootA,BootB
};
/////////////////////////////////////////////////////////////////////////
const unsigned short Tune0[] = {
patch(PREVTHUN),
note(cc3,800),
patch(PTHUNEL16),
note(cc3,800),
rest(200),
patch(PSIN1),
loop(5),
loop(120),
note(cc2,50),
xpose(200),
rest(0),
endloop,
loop(120),
note(cc0,50),
xpose(-200),
rest(0),
endloop,
endloop,
note(5,6),
rest(0x10),
// 0,1,2,3,4
};
const unsigned short Tune1[] = {
// fset(6000,26000),
patch(PSIN1),
note(cc3,200),
};
const unsigned short *Tune[] = {
Tune0
};
const struct sound sound_calls[] = {
0,0,0,NULL, //0
1,0,0xfff,Boot, //1
1,0,0x001,Tune, //2
1,0,0x001,Tune, //2
};
struct sound sound_calls2[2];
int max_sound_call = 0x2;
int default_clock_value = 80;
+932
View File
@@ -0,0 +1,932 @@
//
// tex_gen.cpp
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001, Pipeworks Software Inc.
// All rights reserved
#include "precomp.h"
#include "tex_gen.h"
#include "xbs_app.h"
#include "qrand.h"
#ifndef STARTUPANIMATION
#define ALLOC_TEX_MEM(nb) MemAlloc(nb)
#define FREE_TEX_MEM(pb) MemFree(pb)
#else
#define ALLOC_TEX_MEM(nb) MemAllocContiguous(nb,D3DTEXTURE_ALIGNMENT)
#define FREE_TEX_MEM(pb) MemFreeContiguous(pb)
#endif
inline DWORD GetMaxMipCountFromSize(DWORD size )
{
DWORD c = 0;
while(size >>= 1)
++c;
return c;
}
inline D3DCOLOR VectorToRGBA( const D3DVECTOR* v)
{
D3DCOLOR color;
FLOAT r = ( ( v->x + 1.0f ) * 127.5f );
FLOAT g = ( ( v->y + 1.0f ) * 127.5f );
FLOAT b = ( ( v->z + 1.0f ) * 127.5f );
FLOAT a = ( 255.0f);
__asm
{
cvttss2si edx, a
cvttss2si ecx, r
cvttss2si ebx, g
cvttss2si eax, b
shl ebx, 8
or eax, ebx
shl ecx, 16
or eax, ecx
shl edx, 24
or eax, edx
mov color, eax
}
return color;
}
LPDIRECT3DTEXTURE8 CreateHighlightTexture(int size,int power,bool b_falloff_alpha, float f_linear_w, float f_cos_w)
{
IDirect3DTexture8 *pTexture;
gpd3dDev->CreateTexture( size,size,1,0,D3DFMT_A8R8G8B8,NULL,&pTexture );
D3DSURFACE_DESC desc;
pTexture->GetLevelDesc(0,&desc);
D3DLOCKED_RECT rc;
pTexture->LockRect(0,&rc,NULL,0);
int tmp = 4096/size;
float ooRadius = 1.0f/(float)(size/2);
int cntrx = (size-1) / 2;
int cntry = (size-1) / 2;
unsigned int *pData;
pData = (unsigned int *)rc.pBits;
DWORD *pSourceBits = (DWORD *)ALLOC_TEX_MEM(sizeof(DWORD)*size*size);
unsigned char cosTable[257];
for (int i=0; i < 256; i++)
{
float Cos,Sin;
SinCos((float)i/256.f,&Sin,&Cos);
for (int k = power; k; --k)
Cos *=Cos;
float f_sum = 255.f * (Cos * f_cos_w + (float(256-i) / 256.f) * f_linear_w);
__asm
{
cvttss2si eax, f_sum
mov ebx,i
mov cosTable[ebx],al
}
}
for (int y=0; y < size; y++)
{
unsigned int *pPixel = (unsigned int *)pSourceBits + y*size;
for (int x=0; x < y; x++)
{
float f_dist = fast_sqrt((float)((x-cntrx)*(x-cntrx) + (y-cntry)*(y-cntry))) * ooRadius;
if (f_dist < 1.f)
{
unsigned int c;
float indexShift = f_dist * 256.f;
__asm
{
cvttss2si ebx, indexShift;
movzx eax, byte ptr cosTable[ebx]
mov c,eax
}
unsigned char a = b_falloff_alpha ? c : 255;
DWORD P = c | c<<8 | c<<16 | a<<24;
*pPixel++ = P;
}
else
{
unsigned char a = b_falloff_alpha ? 0 : 0xff000000;
*pPixel++ = a;
}
}
}
XGSwizzleRect(pSourceBits,
0,
NULL,
rc.pBits,
size,
size,
NULL,
sizeof(DWORD));
pTexture->UnlockRect(0);
FREE_TEX_MEM(pSourceBits);
return pTexture;
}
LPDIRECT3DTEXTURE8 CreateGlowTexture(int width,int height,int colorScale,int noise,int seed)
{
IDirect3DTexture8 *pTexture;
int mipLevels = max(GetMaxMipCountFromSize(width),GetMaxMipCountFromSize(height));
gpd3dDev->CreateTexture(
width,
height,
mipLevels,
0,
D3DFMT_A8R8G8B8,
D3DPOOL_MANAGED,
&pTexture);
for (int i=0; i < mipLevels; i++)
{
D3DSURFACE_DESC desc;
pTexture->GetLevelDesc(i,&desc);
D3DLOCKED_RECT rc;
pTexture->LockRect(i,&rc,NULL,0);
int sWidth = width >> i;
int tmp = 4096/sWidth;
int sHeight = height >> i;
int scale=1;
while (tmp!=1) {
scale++;
tmp=tmp>>1;
}
int cntrx = (sWidth-1) / 2;
int cntry = (sHeight-1) / 2;
unsigned int *pData;
pData = (unsigned int *)rc.pBits;
DWORD *pSourceBits = (DWORD *)ALLOC_TEX_MEM(sizeof(DWORD)*sWidth*sHeight);
unsigned int *pPixel = (unsigned int *)pSourceBits;
for (int y=0; y < sHeight; y++)
{
for (int x=0; x < sWidth; x++)
{
_asm
{
mov ecx,scale
mov eax,x
mov ebx,y
sub eax,cntrx
sub ebx,cntry
sal eax,cl
imul eax
sal ebx,cl
xchg eax,ebx
mov edi,pPixel
imul eax
mov edx,4096*4096
add ebx,eax
sub edx,ebx
jnc noOverflow1
xor edx,edx
noOverflow1: mov ebx,edx
mov eax,ebx
mul noise
mov ecx,seed
mov eax,edx
mov edx,ecx
rcl ecx,13
sub edx,11
sub ecx,edx
mov seed,ecx
mul ecx
shl edx,15
sub ebx,edx
jge bxOk1
xor ebx,ebx
bxOk1: and ebx,0x1ff0000
rcl ebx,8
sbb ebx,0
mov eax,ebx
shr eax,24
mul al
mul eax
shr eax,16
mul eax
shr eax,16
and eax,0xff00
mov ecx,eax
shr ecx,8
or ecx,eax
mov eax,ecx
shl ecx,16
or ecx,eax
mov [edi],ecx
add edi,4
mov pPixel,edi
}
}
}
XGSwizzleRect(pSourceBits,
0,
NULL,
rc.pBits,
sWidth,
sHeight,
NULL,
sizeof(DWORD));
pTexture->UnlockRect(i);
FREE_TEX_MEM(pSourceBits);
}
return pTexture;
}
LPDIRECT3DTEXTURE8 CreateGradientTexture( DWORD dwWidth, DWORD dwHeight,
DWORD dwClrStart, DWORD dwClrEnd)
{
LPDIRECT3DTEXTURE8 pTex = NULL;
gpd3dDev->CreateTexture( dwWidth, dwHeight, 1, 0, D3DFMT_A8R8G8B8, NULL, &pTex );
DWORD *pSourceBits = (DWORD *)ALLOC_TEX_MEM(sizeof(DWORD)*dwWidth*dwHeight);
D3DCOLORVALUE cv_start,cv_end;
cv_start.a = ((float)(dwClrStart>>24))/255.f;
cv_start.r = ((float)((dwClrStart>>16)&0xff))/255.f;
cv_start.g = ((float)((dwClrStart>>8)&0xff))/255.f;
cv_start.b = ((float)(dwClrStart&0xff))/255.f;
cv_end.a = ((float)(dwClrEnd>>24))/255.f;
cv_end.r = ((float)((dwClrEnd>>16)&0xff))/255.f;
cv_end.g = ((float)((dwClrEnd>>8)&0xff))/255.f;
cv_end.b = ((float)(dwClrEnd&0xff))/255.f;
float del = 1.f/((float)(dwHeight-1));
for(DWORD r = 0; r < dwHeight; r++)
{
float t = del * ((float)r);
D3DCOLOR color;
FLOAT _r = (cv_start.r * (1.f-t) + cv_end.r * t) * 255.f;
FLOAT _g = (cv_start.g * (1.f-t) + cv_end.g * t) * 255.f;
FLOAT _b = (cv_start.b * (1.f-t) + cv_end.b * t) * 255.f;
FLOAT _a = (cv_start.a * (1.f-t) + cv_end.a * t) * 255.f;
__asm
{
cvttss2si edx, _a
cvttss2si ecx, _r
cvttss2si ebx, _g
cvttss2si eax, _b
shl ebx, 8
or eax, ebx
shl ecx, 16
or eax, ecx
shl edx, 24
or eax, edx
mov color, eax
}
DWORD *ppix = pSourceBits + r * dwWidth;
for(DWORD x = 0; x < dwWidth; x++)
{
*ppix++ = color;
}
};
D3DLOCKED_RECT rc;
pTex->LockRect(0,&rc,NULL,0);
XGSwizzleRect(pSourceBits,
0,
NULL,
rc.pBits,
dwWidth,
dwHeight,
NULL,
sizeof(DWORD));
FREE_TEX_MEM(pSourceBits);
pTex->UnlockRect(0);
return pTex;
}
LPDIRECT3DTEXTURE8 CreateIntensityTexture(
int size,
bool b_convert_to_normal_map,
float f_height_scale,
int noise,
int seed,
int clr_mask,
int intensity_seed,
bool b_use_intensity_seed,
DWORD intensity_max,
int negative_prob
)
{
LPDIRECT3DTEXTURE8 pTex;
gpd3dDev->CreateTexture(size,size,1,0,D3DFMT_A8R8G8B8,D3DPOOL_MANAGED,&pTex);
D3DLOCKED_RECT rc;
pTex->LockRect(0,&rc,NULL,0);
DWORD *pSourceBits = (DWORD *)ALLOC_TEX_MEM(sizeof(DWORD)*size*size);
DWORD *pPixel = pSourceBits;
memset(pPixel,0,sizeof(DWORD)*size*size);
QRand rng;
rng.Init(seed);
DWORD i = (b_use_intensity_seed) ? intensity_seed : rng.Rand(intensity_max);
*pPixel = (i<<16)|(i<<8)|(i);
int curSize = size>>1;
int curX = curSize;
int curY = curSize;
int curNoise = noise>>1;
int curStep = size;
bool bSquare = true;
bool bSecondPass = false;
while(curSize > 0)
{
int lx = curX - curSize;
int rx = curX + curSize;
int ly = curY - curSize;
int uy = curY + curSize;
if(lx < 0) lx += size;
if(rx >= size) rx -= size;
if(ly < 0) ly += size;
if(uy >= size) uy -= size;
if(bSquare)
{
DWORD crnSW = *(pPixel + size*ly + lx);
DWORD crnSE = *(pPixel + size*ly + rx);
DWORD crnNW = *(pPixel + size*uy + lx);
DWORD crnNE = *(pPixel + size*uy + rx);
DWORD dwI = ((crnSW&0xff) + (crnSE&0xff) + (crnNW&0xff) + (crnNE&0xff) ) >> 2;
if(rng.Rand(100) > negative_prob)
{
dwI += rng.Rand(curNoise);
if(dwI > intensity_max)
dwI = intensity_max;
}
else
{
dwI -= rng.Rand(curNoise);
if(dwI > 255)
dwI = 0;
}
*(pPixel + size*curY + curX) = (dwI<<16)|(dwI<<8)|(dwI);
curX += curStep;
if(curX >= size)
{
curY += curStep;
if(curY >= size)
{
curX = curSize;
curY = 0;
bSquare = false;
continue;
}
curX = curSize;
}
}
else
{
DWORD crnN = *(pPixel + size*uy + curX);
DWORD crnS = *(pPixel + size*ly + curX);
DWORD crnW = *(pPixel + size*curY + lx);
DWORD crnE = *(pPixel + size*curY + rx);
DWORD dwI = ((crnN&0xff) + (crnS&0xff) + (crnE&0xff) + (crnW&0xff)) >> 2;
if(rng.Rand(100) > negative_prob)
{
dwI += rng.Rand(curNoise);
if(dwI > intensity_max)
dwI = intensity_max;
}
else
{
dwI -= rng.Rand(curNoise);
if(dwI > 255)
dwI = 0;
}
*(pPixel + size*curY + curX) = (dwI<<16)|(dwI<<8)|(dwI);
curX += curStep;
if(curX >= size)
{
curY += curStep;
if(curY >= size)
{
if(bSecondPass)
{
curStep = curSize;
curSize >>= 1;
curNoise >>= 1;
curX = curSize;
curY = curSize;
bSquare = true;
}
else
{
curX = 0;
curY = curSize;
}
bSecondPass = !bSecondPass;
continue;
}
curX = bSecondPass ? 0 : curSize;
}
}
}
DWORD *pTooFar = pPixel + size*size;
while(pPixel != pTooFar)
{
*pPixel = (((*pPixel)&0xff)<<24) | ((*pPixel)&clr_mask);
pPixel++;
}
if(b_convert_to_normal_map)
{
for( int y=0; y<size; y++ )
{
DWORD *prow0 = pSourceBits + size*y;
DWORD *prow1 = pSourceBits + size*(y+1);
if(prow1 >= pTooFar)
prow1 = pTooFar;
for( int x = 0; x < size; x++ )
{
DWORD* p00 = prow0 + x;
DWORD* p10 = prow0 + x + 1;
if(p10 >= pTooFar)
p10 = pTooFar;
DWORD* p01 = prow1 + x;
FLOAT fHeight00 = (FLOAT)(((*p00)&0x00ff0000)>>16) * f_height_scale;
FLOAT fHeight10 = (FLOAT)(((*p10)&0x00ff0000)>>16) * f_height_scale;
FLOAT fHeight01 = (FLOAT)(((*p01)&0x00ff0000)>>16) * f_height_scale;
D3DVECTOR vPoint00;
Set(&vPoint00, x+0.0f, y+0.0f, fHeight00 );
D3DVECTOR vPoint10;
Set(&vPoint10,x+0.1f, y+0.0f, fHeight10 );
D3DVECTOR vPoint01;
Set(&vPoint01, x+0.0f, y+0.1f, fHeight01 );
D3DVECTOR v10;
Sub(vPoint10,vPoint00,&v10);
D3DVECTOR v01;
Sub(vPoint01,vPoint00,&v01);
D3DVECTOR v;
Cross(v10, v01, &v);
Normalize(&v);
*p00 = VectorToRGBA( &v );
}
}
}
XGSwizzleRect(pSourceBits,
0,
NULL,
rc.pBits,
size,
size,
NULL,
sizeof(DWORD));
FREE_TEX_MEM(pSourceBits);
pTex->UnlockRect(0);
return pTex;
}
void CreateIntensityTexture_8Bit(
LPDIRECT3DTEXTURE8 ppTextures[],
int num,
int size,
int noise,
int seed,
int intensity_seed,
int intensity_max
)
{
#define MAX_TEXTURES (3)
if (num > MAX_TEXTURES) return;
D3DLOCKED_RECT rcs[MAX_TEXTURES];
int tex_size = size*size;
int i;
for (i=0; i<num; i++)
{
gpd3dDev->CreateTexture(size,size,1,0,D3DFMT_A8,D3DPOOL_MANAGED,&ppTextures[i]);
ppTextures[i]->LockRect(0,&rcs[i],NULL,0);
}
BYTE *pSourceBits = (BYTE *)ALLOC_TEX_MEM(sizeof(BYTE)*size*size * num);
// byte = pSourceBits[tex_num*tex_size + y*size + x];
BYTE *pPixel = pSourceBits;
memset(pPixel,0,sizeof(BYTE)*tex_size*num);
QRand rng;
rng.Init(seed);
*pPixel = (BYTE)intensity_seed;
int curSize = size>>1;
int curX = curSize;
int curY = curSize;
int curNoise = noise>>1;
int curStep = size;
bool bSquare = true;
bool bSecondPass = false;
while(curSize > 0)
{
int lx = curX - curSize;
int rx = curX + curSize;
int ly = curY - curSize;
int uy = curY + curSize;
if(lx < 0) lx += size;
if(rx >= size) rx -= size;
if(ly < 0) ly += size;
if(uy >= size) uy -= size;
if(bSquare)
{
for (i=0; i<num; i++)
{
int crnSW = *(pPixel + tex_size * i + size*ly + lx);
int crnSE = *(pPixel + tex_size * i + size*ly + rx);
int crnNW = *(pPixel + tex_size * i + size*uy + lx);
int crnNE = *(pPixel + tex_size * i + size*uy + rx);
int dwI = (crnSW + crnSE + crnNW + crnNE) >> 2;
dwI += rng.Rand(curNoise*2) - curNoise;
*(pPixel + tex_size * i + size*curY + curX) = (BYTE) (max(0, min(intensity_max, dwI)));
}
curX += curStep;
if(curX >= size)
{
curY += curStep;
if(curY >= size)
{
curX = curSize;
curY = 0;
bSquare = false;
continue;
}
curX = curSize;
}
}
else
{
for (i=0; i<num; i++)
{
int crnN = *(pPixel + tex_size * i + size*uy + curX);
int crnS = *(pPixel + tex_size * i + size*ly + curX);
int crnW = *(pPixel + tex_size * i + size*curY + lx);
int crnE = *(pPixel + tex_size * i + size*curY + rx);
int dwI = ((crnN&0xff) + (crnS&0xff) + (crnE&0xff) + (crnW&0xff)) >> 2;
dwI += rng.Rand(curNoise*2) - curNoise;
*(pPixel + tex_size * i + size*curY + curX) = (BYTE) (max(0, min(intensity_max, dwI)));
}
curX += curStep;
if(curX >= size)
{
curY += curStep;
if(curY >= size)
{
if(bSecondPass)
{
curStep = curSize;
curSize >>= 1;
curNoise >>= 1;
curX = curSize;
curY = curSize;
bSquare = true;
}
else
{
curX = 0;
curY = curSize;
}
bSecondPass = !bSecondPass;
continue;
}
curX = bSecondPass ? 0 : curSize;
}
}
}
for (i=0; i<num; i++)
{
XGSwizzleRect(pSourceBits,
0,
NULL,
rcs[i].pBits,
size,
size,
NULL,
sizeof(BYTE));
ppTextures[i]->UnlockRect(0);
}
FREE_TEX_MEM(pSourceBits);
}
LPDIRECT3DCUBETEXTURE8 CreateNormalizationCubeMap(DWORD dwSize)
{
LPDIRECT3DCUBETEXTURE8 pCubeMap;
gpd3dDev->CreateCubeTexture( dwSize, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pCubeMap );
DWORD * pSourceBits = (DWORD *)ALLOC_TEX_MEM(sizeof(DWORD)*dwSize*dwSize);
for( DWORD i=0; i<6; i++ )
{
LPDIRECT3DSURFACE8 pCubeMapFace;
pCubeMap->GetCubeMapSurface( (D3DCUBEMAP_FACES)i, 0, &pCubeMapFace );
DWORD* pPixel = pSourceBits;
D3DVECTOR n;
FLOAT w, h;
for( DWORD y = 0; y < dwSize; y++ )
{
h = (FLOAT)y / (FLOAT)(dwSize-1); // 0 to 1
h = ( h * 2.0f ) - 1.0f; // -1 to 1
for( DWORD x = 0; x < dwSize; x++ )
{
w = (FLOAT)x / (FLOAT)(dwSize-1); // 0 to 1
w = ( w * 2.0f ) - 1.0f; // -1 to 1
switch( i )
{
case D3DCUBEMAP_FACE_POSITIVE_X: // +x
n.x = +1.0;
n.y = -h;
n.z = -w;
break;
case D3DCUBEMAP_FACE_NEGATIVE_X: // -x
n.x = -1.0;
n.y = -h;
n.z = +w;
break;
case D3DCUBEMAP_FACE_POSITIVE_Y: // y
n.x = +w;
n.y = +1.0;
n.z = +h;
break;
case D3DCUBEMAP_FACE_NEGATIVE_Y: // -y
n.x = +w;
n.y = -1.0;
n.z = -h;
break;
case D3DCUBEMAP_FACE_POSITIVE_Z: // +z
n.x = +w;
n.y = -h;
n.z = +1.0;
break;
case D3DCUBEMAP_FACE_NEGATIVE_Z: // -z
n.x = -w;
n.y = -h;
n.z = -1.0;
break;
}
Normalize(&n);
*pPixel++ = VectorToRGBA( &n );
}
}
D3DLOCKED_RECT lock;
pCubeMapFace->LockRect( &lock, 0, 0L );
XGSwizzleRect( pSourceBits, 0, NULL, lock.pBits, dwSize, dwSize,
NULL, sizeof(DWORD) );
pCubeMapFace->UnlockRect();
pCubeMapFace->Release();
}
FREE_TEX_MEM(pSourceBits);
return pCubeMap;
}
LPDIRECT3DCUBETEXTURE8 CreateStaticReflectionCubeMap( DWORD dwSize )
{
Camera old_camera = gApp.theCamera;
LPDIRECT3DCUBETEXTURE8 pCubeMap;
gpd3dDev->CreateCubeTexture(dwSize,1,D3DUSAGE_RENDERTARGET,D3DFMT_A8R8G8B8,NULL,&pCubeMap);
LPDIRECT3DSURFACE8 pOldRT,pOldZ;
gpd3dDev->GetRenderTarget(&pOldRT);
gpd3dDev->GetDepthStencilSurface(&pOldZ);
LPDIRECT3DSURFACE8 pNewZ;
gpd3dDev->CreateDepthStencilSurface(dwSize,dwSize,D3DFMT_LIN_D24S8,
D3DMULTISAMPLE_2_SAMPLES_MULTISAMPLE_LINEAR,
&pNewZ);
D3DMATRIX oldProjMat = gApp.theCamera.matProj;
D3DMATRIX oldViewMat = gApp.theCamera.matWTC;
gApp.theCamera.setProjection(Pi/2.f,1.f,0.1f,400.f);
D3DVECTOR pos;
Set(&pos,0.f,0.f,0.f);
for(DWORD dwFace = 0; dwFace < 6; dwFace++)
{
LPDIRECT3DSURFACE8 pNewRT;
pCubeMap->GetCubeMapSurface( (D3DCUBEMAP_FACES)dwFace, 0, &pNewRT );
gpd3dDev->SetRenderTarget(pNewRT,pNewZ);
if( gpd3dDev->BeginScene() == D3D_OK )
{
gpd3dDev->Clear(0,NULL,
D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET,
0xff000000,
1.f,
0 );
D3DMATRIX viewMat;
SetCubeMapView( dwFace, pos, &viewMat );
gApp.theCamera.setWTC(viewMat);
gApp.sceneGeom.advanceTime(SCENE_ANIM_START_TIME + SCENE_ANIM_LEN,0.f);
gApp.sceneGeom.render(false,false);
pNewRT->Release();
gpd3dDev->EndScene();
}
}
gpd3dDev->SetRenderTarget(pOldRT,pOldZ);
pOldRT->Release();
pOldZ->Release();
pNewZ->Release();
gApp.theCamera = old_camera;
return pCubeMap;
}
int GetNumberOfIndicesForTristripMesh(int x_quads, int y_quads, bool b_d_tap_1, bool b_d_tap_2)
{
if (x_quads <= 14)
{
// Single stack is sufficient.
// Each mesh is composed of x_quads*2 + 1 priming vertices,
// and for each row there are (x_quads+1)*2 + 2 CR vertices, minus one on the last row.
return ((b_d_tap_1) ? 1 : 0) +
x_quads*2 + 1 +
y_quads*( 2*(x_quads+1) + 2) - 1 +
((b_d_tap_2) ? 1 : 0);
}
return
GetNumberOfIndicesForTristripMesh( 14, y_quads, b_d_tap_1, true) +
GetNumberOfIndicesForTristripMesh(x_quads-14, y_quads, true, b_d_tap_2);
}
// returns number of indices added
int CreateTristripForMesh( WORD* p_index_buffer,
int x_quads, // number of quad columns
int y_quads, // number of quad rows
bool b_double_tap_first,
bool b_double_tap_last,
int start_index, // starting index of lower-left corner
int vstride, // vertex difference between rows
int hstride // vertex difference between columns
)
{
if (!vstride) vstride = x_quads+1;
if (!hstride) hstride = 1;
if (x_quads > 14)
{
int num = 0;
num += CreateTristripForMesh(&p_index_buffer[num], 14, y_quads, b_double_tap_first, true, start_index , vstride, hstride);
num += CreateTristripForMesh(&p_index_buffer[num], x_quads-14, y_quads, true, b_double_tap_last, start_index+14*hstride, vstride, hstride);
return num;
}
int num = 0;
if (b_double_tap_first) p_index_buffer[num++] = (WORD) (start_index);
p_index_buffer[num++] = (WORD) (start_index);
int i;
for (i=1; i<=x_quads; i++)
{
p_index_buffer[num++] = (WORD) (start_index + i*hstride);
p_index_buffer[num++] = (WORD) (start_index + i*hstride);
}
for (int j=0; j<y_quads; j++)
{
p_index_buffer[num++] = (WORD) (start_index + j*vstride); // double tap beginning of line
for (int i=0; i<=x_quads; i++)
{
p_index_buffer[num++] = (WORD) (start_index + j*vstride + i*hstride);
p_index_buffer[num++] = (WORD) (start_index + (j+1)*vstride + i*hstride);
}
if (j<y_quads-1) p_index_buffer[num++] = (WORD) (start_index + (j+1)*vstride + x_quads*hstride); // double tap end of line
}
if (b_double_tap_last) p_index_buffer[num++] = (WORD) (start_index + y_quads*vstride + x_quads*hstride);
return num;
}
LPDIRECT3DINDEXBUFFER8 CreateTristripForMesh(int x_quads, int y_quads, int* p_num_indices)
{
LPDIRECT3DINDEXBUFFER8 p_ib;
int dummy;
if (!p_num_indices) p_num_indices = &dummy;
*p_num_indices = GetNumberOfIndicesForTristripMesh(x_quads, y_quads);
gpd3dDev->CreateIndexBuffer(
*p_num_indices * sizeof(WORD),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_DEFAULT,
&p_ib
);
WORD* p_indices;
p_ib->Lock(0, 0, (BYTE**)&p_indices, 0);
CreateTristripForMesh(p_indices, x_quads, y_quads);
p_ib->Unlock();
return p_ib;
}
+63
View File
@@ -0,0 +1,63 @@
//
// bs_texgen.h
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001, Pipeworks Software Inc.
// All rights reserved
#ifndef __TEX_GEN_H__
#define __TEX_GEN_H__
LPDIRECT3DTEXTURE8 CreateIntensityTexture(
int size,
bool b_convert_to_normal_map = false,
float f_height_scale = 1.f/512.f,
int noise = 1024,
int seed = 0,
int clr_mask = 0x00ffffff,
int intensity_seed = 255,
bool b_use_intensity_seed = false,
DWORD intensity_max = 255,
int negative_prob = 50
);
void CreateIntensityTexture_8Bit(
LPDIRECT3DTEXTURE8 ppTextures[],
int num,
int size,
int noise,
int seed,
int intensity_seed,
int intensity_max
);
LPDIRECT3DTEXTURE8 CreateGlowTexture(int width,int height,int colorScale,int noise,int seed);
LPDIRECT3DTEXTURE8 CreateGradientTexture(DWORD dwWidth,DWORD dwHeight,DWORD dwClrStart,DWORD dwClrEnd);
LPDIRECT3DCUBETEXTURE8 CreateNormalizationCubeMap(DWORD dwSize);
LPDIRECT3DCUBETEXTURE8 CreateStaticReflectionCubeMap(DWORD dwSize);
LPDIRECT3DTEXTURE8 CreateHighlightTexture(int size,int power,
bool b_falloff_alpha,
float f_linear_w, float f_cos_w);
int GetNumberOfIndicesForTristripMesh(
int x_quads,
int y_quads,
bool b_d_tap_1=false,
bool b_d_tap_2=false
);
int CreateTristripForMesh( WORD* p_index_buffer,
int x_quads, // number of quad columns
int y_quads, // number of quad rows
bool b_double_tap_first=false,
bool b_double_tap_last=false,
int start_index = 0, // starting index of lower-left corner
int vstride = 0, // vertex difference between rows
int hstride = 0 // vertex difference between columns
); // returns number of indices added
LPDIRECT3DINDEXBUFFER8 CreateTristripForMesh(int x_quads, int y_quads, int* p_num_indices);
#endif //__TEX_GEN_H__
+350
View File
@@ -0,0 +1,350 @@
/*
xbt.h
*/
#ifndef __xbt_h__
#define __xbt_h__
#include "d3d8types.h"
#define FVF_xbt D3DFVF_XYZ
struct xbt_vertex
{
float x,y,z;
};
const float xbt_OO_POS_SCALE = 0.002508f;
const float xbt_POS_DELTA = 41.065369f;
const float xbt_OO_TEX_SCALE = -61.068704f;
const float xbt_TEX_DELTA = -1000000.000000f;
///////////////////////////////////////////////////////////////////////////////
const int vertex_count_text_0 = 156;
short verts_text_0C[] =
{
-29368,-16381,-16375, // x,y,z
-32752,-19098,-16375, // x,y,z
-31303,-19096,-16375, // x,y,z
-28656,-16952,-16375, // x,y,z
-27947,-16381,-16375, // x,y,z
-24567,-13668,-16375, // x,y,z
-26012,-13668,-16375, // x,y,z
-28656,-15814,-16375, // x,y,z
-31323,-13667,-16375, // x,y,z
-32748,-13668,-16375, // x,y,z
-26011,-19099,-16375, // x,y,z
-24563,-19098,-16375, // x,y,z
-17241,-16195,-16375, // x,y,z
-16875,-15892,-16375, // x,y,z
-23197,-16837,-16375, // x,y,z
-17767,-16837,-16375, // x,y,z
-17241,-16592,-16375, // x,y,z
-17482,-13978,-16375, // x,y,z
-17631,-13777,-16375, // x,y,z
-18229,-14512,-16375, // x,y,z
-17341,-14216,-16375, // x,y,z
-18180,-14621,-16375, // x,y,z
-18115,-14760,-16375, // x,y,z
-17211,-14489,-16375, // x,y,z
-18042,-14928,-16375, // x,y,z
-17096,-14794,-16375, // x,y,z
-17965,-15125,-16375, // x,y,z
-16999,-15131,-16375, // x,y,z
-17890,-15350,-16375, // x,y,z
-17825,-15603,-16375, // x,y,z
-16925,-15498,-16375, // x,y,z
-17775,-15884,-16375, // x,y,z
-23189,-15884,-16375, // x,y,z
-24897,-15884,-16375, // x,y,z
-24897,-16837,-16375, // x,y,z
-24093,-16837,-16375, // x,y,z
-24089,-15884,-16375, // x,y,z
-17771,-13594,-16375, // x,y,z
-23188,-13593,-16375, // x,y,z
-22735,-14514,-16375, // x,y,z
-23341,-13768,-16375, // x,y,z
-23488,-13970,-16375, // x,y,z
-23627,-14208,-16375, // x,y,z
-22784,-14624,-16375, // x,y,z
-22849,-14762,-16375, // x,y,z
-23755,-14481,-16375, // x,y,z
-22922,-14930,-16375, // x,y,z
-23868,-14787,-16375, // x,y,z
-22999,-15127,-16375, // x,y,z
-23964,-15124,-16375, // x,y,z
-23073,-15352,-16375, // x,y,z
-24038,-15491,-16375, // x,y,z
-23139,-15605,-16375, // x,y,z
-24046,-17245,-16375, // x,y,z
-23154,-17120,-16375, // x,y,z
-23971,-17623,-16375, // x,y,z
-23099,-17366,-16375, // x,y,z
-23873,-17969,-16375, // x,y,z
-23035,-17579,-16375, // x,y,z
-22964,-17766,-16375, // x,y,z
-23755,-18281,-16375, // x,y,z
-22887,-17934,-16375, // x,y,z
-23622,-18558,-16375, // x,y,z
-22807,-18089,-16375, // x,y,z
-23477,-18796,-16375, // x,y,z
-22725,-18238,-16375, // x,y,z
-23325,-18994,-16375, // x,y,z
-23181,-19156,-16375, // x,y,z
-17783,-19156,-16375, // x,y,z
-18244,-18241,-16375, // x,y,z
-17607,-18874,-16375, // x,y,z
-17437,-18588,-16375, // x,y,z
-18221,-18195,-16375, // x,y,z
-18163,-18080,-16375, // x,y,z
-17279,-18291,-16375, // x,y,z
-18082,-17905,-16375, // x,y,z
-17138,-17978,-16375, // x,y,z
-17990,-17683,-16375, // x,y,z
-17899,-17424,-16375, // x,y,z
-17019,-17643,-16375, // x,y,z
-17821,-17138,-16375, // x,y,z
-16930,-17283,-16375, // x,y,z
-16875,-16890,-16375, // x,y,z
-14534,-14523,-16375, // x,y,z
-9555,-13605,-16375, // x,y,z
-15016,-13619,-16375, // x,y,z
-10027,-14518,-16375, // x,y,z
-9376,-13854,-16375, // x,y,z
-15135,-13768,-16375, // x,y,z
-9197,-14166,-16375, // x,y,z
-15307,-14007,-16375, // x,y,z
-9965,-14655,-16375, // x,y,z
-9028,-14534,-16375, // x,y,z
-9882,-14833,-16375, // x,y,z
-9789,-15055,-16375, // x,y,z
-8879,-14949,-16375, // x,y,z
-9697,-15320,-16375, // x,y,z
-8761,-15403,-16375, // x,y,z
-9618,-15631,-16375, // x,y,z
-8682,-15885,-16375, // x,y,z
-9562,-15987,-16375, // x,y,z
-8654,-16389,-16375, // x,y,z
-9541,-16389,-16375, // x,y,z
-8681,-16881,-16375, // x,y,z
-9563,-16789,-16375, // x,y,z
-8757,-17327,-16375, // x,y,z
-9620,-17140,-16375, // x,y,z
-8874,-17736,-16375, // x,y,z
-9701,-17445,-16375, // x,y,z
-9023,-18116,-16375, // x,y,z
-9794,-17704,-16375, // x,y,z
-15468,-14296,-16375, // x,y,z
-14598,-14659,-16375, // x,y,z
-14682,-14838,-16375, // x,y,z
-15611,-14633,-16375, // x,y,z
-14777,-15059,-16375, // x,y,z
-15733,-15013,-16375, // x,y,z
-14870,-15324,-16375, // x,y,z
-15826,-15435,-16375, // x,y,z
-14950,-15633,-16375, // x,y,z
-15886,-15894,-16375, // x,y,z
-15006,-15988,-16375, // x,y,z
-15907,-16389,-16375, // x,y,z
-15028,-16389,-16375, // x,y,z
-15880,-16881,-16375, // x,y,z
-15006,-16788,-16375, // x,y,z
-15805,-17327,-16375, // x,y,z
-14947,-17139,-16375, // x,y,z
-15688,-17736,-16375, // x,y,z
-14865,-17442,-16375, // x,y,z
-15540,-18116,-16375, // x,y,z
-14769,-17700,-16375, // x,y,z
-9888,-17920,-16375, // x,y,z
-9197,-18473,-16375, // x,y,z
-9973,-18094,-16375, // x,y,z
-9387,-18814,-16375, // x,y,z
-10035,-18227,-16375, // x,y,z
-14673,-17915,-16375, // x,y,z
-15367,-18473,-16375, // x,y,z
-14588,-18088,-16375, // x,y,z
-15177,-18814,-16375, // x,y,z
-14525,-18221,-16375, // x,y,z
-9585,-19149,-16375, // x,y,z
-14980,-19149,-16375, // x,y,z
-4808,-16381,-16375, // x,y,z
-8192,-19098,-16375, // x,y,z
-6744,-19098,-16375, // x,y,z
-4099,-16952,-16375, // x,y,z
-1453,-19099,-16375, // x,y,z
-2,-19098,-16375, // x,y,z
-3386,-16381,-16375, // x,y,z
-6764,-13662,-16375, // x,y,z
-8188,-13668,-16375, // x,y,z
-4099,-15814,-16375, // x,y,z
-6,-13714,-16375, // x,y,z
-1430,-13678,-16375, // x,y,z
};
const int index_count_text_0 = 462;
char indices_text_0C[] =
{
0,1,1,
-2,2,1,
1,1,1,
-2,2,1,
1,1,-9,
7,1,-8,
10,1,-7,
-1,7,-6,
3,-7,3,
4,-4,1,
8,1,1,
-2,2,1,
1,-4,3,
2,1,1,
1,-3,2,
1,-1,2,
-1,1,1,
1,-3,2,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
-1,1,1,
1,-3,2,
1,-1,2,
-18,17,1,
-17,-1,18,
-17,17,1,
1,1,1,
1,-3,2,
-16,-1,19,
-18,18,1,
1,-20,19,
1,-1,2,
-1,1,1,
-2,2,1,
1,-4,3,
2,-1,-1,
2,-2,3,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
-19,20,-1,
-19,19,-15,
-22,18,4,
-22,22,-1,
-21,21,18,
1,-40,39,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
2,-1,-1,
2,-2,3,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
-1,1,1,
-2,2,1,
1,-4,3,
1,-1,2,
-1,1,1,
1,-3,2,
2,-1,-1,
2,-2,3,
1,-2,1,
1,-1,2,
1,-2,1,
2,-1,-1,
2,-2,3,
1,-2,1,
1,-1,2,
-66,65,1,
-65,-1,66,
1,-66,65,
2,1,1,
-1,-1,3,
1,-3,2,
-3,2,3,
1,-2,-1,
-3,5,2,
-1,-3,5,
1,-3,2,
1,-1,2,
-1,1,1,
1,-3,2,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
-27,7,21,
1,-29,28,
2,-1,-1,
2,-2,3,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
1,-1,2,
1,-2,1,
-21,1,22,
1,-24,23,
1,-1,2,
1,-2,1,
1,-1,2,
1,-6,-1,
7,-7,8,
1,-2,1,
1,-1,2,
1,-2,1,
2,-7,1,
7,-1,-6,
7,-7,5,
2,-2,-1,
4,1,1,
-2,2,1,
1,1,1,
-3,1,2,
1,1,-8,
9,-2,-7,
6,4,1,
-5,5,-2,
-6,3,3,
-9,3,6,
};
D3DVECTOR pos_anim_text[2] =
{
{-0.229403f,-267.650421f,-103.040421f},
{-0.229403f,-141.053757f,-54.439625f}
};
#endif
+30
View File
@@ -0,0 +1,30 @@
///////////////////////////////////////////////////////////////////////////////
//
// tm.h
//
///////////////////////////////////////////////////////////////////////////////
#ifndef __tm_h__
#define __tm_h__
DWORD tm_pixels[256] =
{
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff152305,0xff1e3207,0xff1e3207,0xff1e3207,0xff1e3207,0xff1e3207,0x0,0xff152305,0xff1e3207,0x0,0x0,0x0,0xff0e1703,0xff1e3207,0xff070c02,0x0,
0xff518814,0xff6fbb1b,0xff6fbb1b,0xff6fbb1b,0xff6fbb1b,0xff6fbb1b,0x0,0xff6fbb1b,0xff6fbb1b,0xff152305,0x0,0x0,0xff4a7d12,0xff6fbb1b,0xff1e3207,0x0,
0x0,0x0,0xff33560c,0xff6fbb1b,0x0,0x0,0x0,0xff6fbb1b,0xff6fbb1b,0xff3c640f,0x0,0xff070c02,0xff6fbb1b,0xff6fbb1b,0xff1e3207,0x0,
0x0,0x0,0xff33560c,0xff6fbb1b,0x0,0x0,0x0,0xff6fbb1b,0xff5a9716,0xff61a318,0x0,0xff2c4a0b,0xff5a9716,0xff6fbb1b,0xff1e3207,0x0,
0x0,0x0,0xff33560c,0xff6fbb1b,0x0,0x0,0x0,0xff6fbb1b,0xff33560c,0xff68af19,0xff0e1703,0xff437010,0xff33560c,0xff6fbb1b,0xff1e3207,0x0,
0x0,0x0,0xff33560c,0xff6fbb1b,0x0,0x0,0x0,0xff6fbb1b,0xff33560c,0xff437010,0xff33560c,0xff68af19,0xff152305,0xff6fbb1b,0xff1e3207,0x0,
0x0,0x0,0xff33560c,0xff6fbb1b,0x0,0x0,0x0,0xff6fbb1b,0xff33560c,0xff2c4a0b,0xff6fbb1b,0xff61a318,0x0,0xff6fbb1b,0xff1e3207,0x0,
0x0,0x0,0xff33560c,0xff6fbb1b,0x0,0x0,0x0,0xff6fbb1b,0xff33560c,0xff070c02,0xff6fbb1b,0xff3c640f,0x0,0xff6fbb1b,0xff1e3207,0x0,
0x0,0x0,0xff0e1703,0xff152305,0x0,0x0,0x0,0xff152305,0xff0e1703,0x0,0xff152305,0xff070c02,0x0,0xff1e3207,0xff070c02,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
};
#endif // ___h__
+267
View File
@@ -0,0 +1,267 @@
//-----------------------------------------------------------------------------
// File: XBInput.cpp
//
// Desc: Input helper functions for the XBox samples
//
// Hist: 12.15.00 - Separated from XBUtil.cpp for December XDK release
// 01.03.00 - Made changes for real Xbox controller
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include "defines.h"
#ifdef INCLUDE_INPUT
#include <xtl.h>
#include "XBInput.h"
//-----------------------------------------------------------------------------
// Globals
//-----------------------------------------------------------------------------
// Deadzone for thumbsticks
#define XBINPUT_DEADZONE 0.25
// Threshold for analog buttons
#define XBINPUT_BUTTONTHRESHOLD 1
// Global instance of gamepad devices
XBGAMEPAD g_Gamepads[4];
//-----------------------------------------------------------------------------
// Name: XBInput_CreateGamepads()
// Desc: Creates the gamepad devices
//-----------------------------------------------------------------------------
HRESULT XBInput_CreateGamepads( XBGAMEPAD** ppGamepads )
{
// Get a mask of all currently available devices
DWORD dwDeviceMask = XGetDevices( XDEVICE_TYPE_GAMEPAD );
// Open the devices
for( DWORD i=0; i < XGetPortCount(); i++ )
{
ZeroMemory( &g_Gamepads[i], sizeof(XBGAMEPAD) );
if( dwDeviceMask & (1<<i) )
{
// Get a handle to the device
g_Gamepads[i].hDevice = XInputOpen( XDEVICE_TYPE_GAMEPAD, i,
XDEVICE_NO_SLOT, NULL );
// Store capabilites of the device
XInputGetCapabilities( g_Gamepads[i].hDevice, &g_Gamepads[i].caps );
}
}
// Created devices are kept global, but for those who prefer member
// variables, they can get a pointer to the gamepads returned.
if( ppGamepads )
(*ppGamepads) = g_Gamepads;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: XBInput_GetInput()
// Desc: Processes input from the gamepads
//-----------------------------------------------------------------------------
VOID XBInput_GetInput( XBGAMEPAD* pGamepads )
{
if( NULL == pGamepads )
pGamepads = g_Gamepads;
// Get status about gamepad insertions and removals. Note that, in order to
// not miss devices, we will check for removed device BEFORE checking for
// insertions
DWORD dwInsertions, dwRemovals;
XGetDeviceChanges( XDEVICE_TYPE_GAMEPAD, &dwInsertions, &dwRemovals );
// Loop through all gamepads
for( DWORD i=0; i < XGetPortCount(); i++ )
{
// Handle removed devices.
pGamepads[i].bRemoved = ( dwRemovals & (1<<i) ) ? TRUE : FALSE;
if( pGamepads[i].bRemoved )
{
XInputClose( pGamepads[i].hDevice );
pGamepads[i].hDevice = NULL;
}
// Handle inserted devices
pGamepads[i].bInserted = ( dwInsertions & (1<<i) ) ? TRUE : FALSE;
if( pGamepads[i].bInserted )
{
// TCR 1-14 Device Types
pGamepads[i].hDevice = XInputOpen( XDEVICE_TYPE_GAMEPAD, i,
XDEVICE_NO_SLOT, NULL );
XInputGetCapabilities( g_Gamepads[i].hDevice, &g_Gamepads[i].caps );
}
// If we have a valid device, poll it's state and track button changes
if( pGamepads[i].hDevice )
{
// Read the input state
XINPUT_STATE xiState;
XInputGetState( pGamepads[i].hDevice, &xiState );
// Copy gamepad to local structure
pGamepads[i].wButtons = xiState.Gamepad.wButtons;
pGamepads[i].bAnalogButtons[0] = xiState.Gamepad.bAnalogButtons[0];
pGamepads[i].bAnalogButtons[1] = xiState.Gamepad.bAnalogButtons[1];
pGamepads[i].bAnalogButtons[2] = xiState.Gamepad.bAnalogButtons[2];
pGamepads[i].bAnalogButtons[3] = xiState.Gamepad.bAnalogButtons[3];
pGamepads[i].bAnalogButtons[4] = xiState.Gamepad.bAnalogButtons[4];
pGamepads[i].bAnalogButtons[5] = xiState.Gamepad.bAnalogButtons[5];
pGamepads[i].bAnalogButtons[6] = xiState.Gamepad.bAnalogButtons[6];
pGamepads[i].bAnalogButtons[7] = xiState.Gamepad.bAnalogButtons[7];
pGamepads[i].sThumbLX = xiState.Gamepad.sThumbLX;
pGamepads[i].sThumbLY = xiState.Gamepad.sThumbLY;
pGamepads[i].sThumbRX = xiState.Gamepad.sThumbRX;
pGamepads[i].sThumbRY = xiState.Gamepad.sThumbRY;
// Put Xbox device input for the gamepad into our custom format
pGamepads[i].fX1 = (pGamepads[i].sThumbLX+0.5f)/32767.5f;
if( fabsf(pGamepads[i].fX1) < XBINPUT_DEADZONE )
pGamepads[i].fX1 = 0.0f;
pGamepads[i].fY1 = (pGamepads[i].sThumbLY+0.5f)/32767.5f;
if( fabsf(pGamepads[i].fY1) < XBINPUT_DEADZONE )
pGamepads[i].fY1 = 0.0f;
pGamepads[i].fX2 = (pGamepads[i].sThumbRX+0.5f)/32767.5f;
if( fabsf(pGamepads[i].fX2) < XBINPUT_DEADZONE )
pGamepads[i].fX2 = 0.0f;
pGamepads[i].fY2 = (pGamepads[i].sThumbRY+0.5f)/32767.5f;
if( fabsf(pGamepads[i].fY2) < XBINPUT_DEADZONE )
pGamepads[i].fY2 = 0.0f;
// Get the boolean buttons that have been pressed since the last
// call. Each button is represented by one bit.
pGamepads[i].wPressedButtons = ( pGamepads[i].wLastButtons ^ pGamepads[i].wButtons ) & pGamepads[i].wButtons;
pGamepads[i].wLastButtons = pGamepads[i].wButtons;
// Get the analog buttons that have been pressed since the last
// call. Here, we considered an analog button pressed (a boolean
// condition) if that value is >= the threshold.
for( DWORD b=0; b<8; b++ )
{
// Turn the 8-bit polled value into a boolean value
BOOL bPressed = ( pGamepads[i].bAnalogButtons[b] >= XBINPUT_BUTTONTHRESHOLD );
if( bPressed )
pGamepads[i].bPressedAnalogButtons[b] = !pGamepads[i].bLastAnalogButtons[b];
else
pGamepads[i].bPressedAnalogButtons[b] = FALSE;
// Store the current state for the next time
pGamepads[i].bLastAnalogButtons[b] = bPressed;
}
}
}
}
//-----------------------------------------------------------------------------
// Name: XBInput_GetPrimaryController()
// Desc: The primary controller is the first controller used by a player.
// If no controller has been used or the controller has been removed,
// the primary controller is the controller inserted at the lowest
// port number. Function returns NULL if no controller is inserted.
//-----------------------------------------------------------------------------
const XBGAMEPAD* XBInput_GetPrimaryController()
{
static INT nPrimaryController = -1;
// If primary controller has been set and hasn't been removed, use it
const XBGAMEPAD* pGamePad = NULL;
if( nPrimaryController != -1 )
{
pGamePad = &g_Gamepads[ nPrimaryController ];
if( pGamePad->hDevice != NULL )
return pGamePad;
}
// Primary controller hasn't been set or has been removed...
// Examine each inserted controller to see if any is being used
INT nFirst = -1;
for( DWORD i=0; i < XGetPortCount(); ++i )
{
pGamePad = &g_Gamepads[i];
if( pGamePad->hDevice != NULL )
{
// Remember the lowest inserted controller ID
if( nFirst == -1 )
nFirst = i;
// If any button is active, we found the primary controller
if( XBInput_IsAnyButtonActive( pGamePad ) )
{
nPrimaryController = i;
return pGamePad;
}
}
}
// No controllers are inserted
if( nFirst == -1 )
return NULL;
// The primary controller hasn't been set and no controller has been
// used yet, so return the controller on the lowest port number
pGamePad = &g_Gamepads[ nFirst ];
return pGamePad;
}
//-----------------------------------------------------------------------------
// Name: XBInput_IsAnyButtonActive()
// Desc: TRUE if any button depressed or any thumbstick offset on the given
// controller.
//-----------------------------------------------------------------------------
BOOL XBInput_IsAnyButtonActive( const XBGAMEPAD* pGamePad )
{
// Check digital buttons
if( pGamePad->wButtons )
return TRUE;
// Check analog buttons
for( DWORD i = 0; i < 8; ++i )
{
if( pGamePad->bAnalogButtons[ i ] )
return TRUE;
}
// Check thumbsticks
if( pGamePad->fX1 > XBINPUT_DEADZONE ||
pGamePad->fX1 < -XBINPUT_DEADZONE ||
pGamePad->fY1 > XBINPUT_DEADZONE ||
pGamePad->fY1 < -XBINPUT_DEADZONE )
{
return TRUE;
}
if( pGamePad->fX2 > XBINPUT_DEADZONE ||
pGamePad->fX2 < -XBINPUT_DEADZONE ||
pGamePad->fY2 > XBINPUT_DEADZONE ||
pGamePad->fY2 < -XBINPUT_DEADZONE )
{
return TRUE;
}
// Nothing active
return FALSE;
}
#endif // INCLUDE_INPUT
+105
View File
@@ -0,0 +1,105 @@
//-----------------------------------------------------------------------------
// File: XBInput.h
//
// Desc: Input helper functions for the XBox samples
//
// Hist: 12.15.00 - Separated from XBUtil.h for December XDK release
// 01.03.00 - Made changes for real Xbox controller
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef XBINPUT_H
#define XBINPUT_H
//-----------------------------------------------------------------------------
// Name: struct XBGAMEPAD
// Desc: structure for holding Gamepad data
//-----------------------------------------------------------------------------
struct XBGAMEPAD : public XINPUT_GAMEPAD
{
// Inherited members from XINPUT_GAMEPAD
//
// WORD wButtons;
// BYTE bAnalogButtons[8];
// SHORT sThumbLX;
// SHORT sThumbLY;
// SHORT sThumbRX;
// SHORT sThumbRY;
// Thumb stick values in range [-1,+1]
FLOAT fX1;
FLOAT fY1;
FLOAT fX2;
FLOAT fY2;
// Buttons pressed since last poll
WORD wLastButtons;
BOOL bLastAnalogButtons[8];
WORD wPressedButtons;
BOOL bPressedAnalogButtons[8];
// Rumble properties
XINPUT_RUMBLE Rumble;
XINPUT_FEEDBACK Feedback;
// Device properties
XINPUT_CAPABILITIES caps;
HANDLE hDevice;
// Flags for whether gamepad was just inserted or removed
BOOL bInserted;
BOOL bRemoved;
};
//-----------------------------------------------------------------------------
// Global access to gamepad devices
//-----------------------------------------------------------------------------
extern XBGAMEPAD g_Gamepads[4];
//-----------------------------------------------------------------------------
// Name: XBInput_CreateGamepads()
// Desc: Creates the gamepad devices
//-----------------------------------------------------------------------------
HRESULT XBInput_CreateGamepads( XBGAMEPAD** ppGamepads = NULL );
//-----------------------------------------------------------------------------
// Name: XBInput_GetInput()
// Desc: Processes input from the gamepads
//-----------------------------------------------------------------------------
VOID XBInput_GetInput( XBGAMEPAD* pGamepads = NULL );
//-----------------------------------------------------------------------------
// Name: XBInput_GetPrimaryController()
// Desc: The first controller used by the player or the controller on the
// lowest numbered slot. NULL if no controllers inserted.
//-----------------------------------------------------------------------------
const XBGAMEPAD* XBInput_GetPrimaryController();
//-----------------------------------------------------------------------------
// Name: XBInput_IsAnyButtonActive()
// Desc: TRUE if any button or thumbstick depressed on the given controller
//-----------------------------------------------------------------------------
BOOL XBInput_IsAnyButtonActive( const XBGAMEPAD* );
#endif // XBINPUT_H
File diff suppressed because it is too large Load Diff
+198
View File
@@ -0,0 +1,198 @@
//
// xbox_app.h
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001, Pipeworks Software Inc.
// All rights reserved
#ifndef __XBOX_APP_H__
#define __XBOX_APP_H__
#include "renderer.h"
#include "camera.h"
#include "scene_renderer.h"
#include "logo_renderer.h"
#include "VBlob.h"
#include "Shield.h"
#include "GreenFog.h"
#include "qrand.h"
#include "CamControl.h"
#include "PlacementDoodad.h"
#ifdef INCLUDE_INPUT
#include "XBInput.h"
#endif // INCLUDE_INPUT
#include "defines.h"
///////////////////////////////////////////////////////////////////////////////
class XBoxStartupApp
{
private:
int nWidth;
int nHeight;
bool bPaused;
bool bActive;
bool bLoop;
bool bCameraUnderControl;
bool bUserControlledIntensity;
bool bRenderGeom;
bool bRenderSlash;
float fTimeElapsed;
float fJogDeltaTime;
float fIIDT;
float fBaseBlobIntensity;
float fBlobIntensity;
float fSmoothedBlobIntensity;
DWORD dwLastTick;
DWORD dwLastFramecountTick;
#ifndef FINAL_BUILD
int numFrames, numFramesTooSlow;
float fFastestFrame, fSlowestFrame;
#endif
enum { NUM_PULSES = 12 };
D3DVECTOR vPulses[NUM_PULSES]; // x=center time, y=time radius of effect, z=intensity
void initIntensityPulses();
float sumIntensityPulses(float et);
void process();
void drawFrame();
// we still want to move around when paused.
void advanceTime(float dt, float cam_dt);
ShieldMgr shieldMgr;
LogoRenderer logoGeom;
QRand qrand;
#ifdef INCLUDE_INPUT
XDEVICE_PREALLOC_TYPE * inputDeviceTypes;
DWORD dwNumInputDeviceTypes;
XBGAMEPAD * pGamepad;
XBGAMEPAD defaultGamepad;
void processInput();
#endif // INCLUDE_INPUT
float fCamRad, fSavedCamRad;
float fCamTheta, fSavedCamTheta;
float fCamPhi, fSavedCamPhi;
float fCamRadBlob;
#ifdef INCLUDE_PLACEMENT_DOODAD
bool bPositionLookatMode;
D3DVECTOR ptLookatPosition;
PlacementDoodad placementDoodad;
public:
const D3DVECTOR& getLookatPoint() const { return ptLookatPosition; }
protected:
#endif
public:
#ifndef STARTUPANIMATION
float fInitTimes[64];
void startTimeRec(int i) { fInitTimes[i] = ((float)GetTickCount()) * 0.001f; }
void endTimeRec(int i) { fInitTimes[i] = (((float)GetTickCount()) * 0.001f) - fInitTimes[i]; }
#endif // STARTUPANIMATION
Renderer theRenderer;
Camera theCamera;
D3DLIGHT8 blobLight;
D3DLIGHT8 moodLight;
LPDIRECT3DCUBETEXTURE8 pNormalCubeMapLoRes;
LPDIRECT3DCUBETEXTURE8 pNormalCubeMapHiRes;
LPDIRECT3DCUBETEXTURE8 pStaticReflectionCubeMap;
LPDIRECT3DTEXTURE8 pRoughBumpMap;
LPDIRECT3DTEXTURE8 pGlowMap;
DWORD dwPShader[st_NoTypes];
DWORD dwVShader[st_NoTypes];
SceneRenderer sceneGeom;
VBlob vblob;
CameraController camController;
GreenFog greenFog;
int nBootCount;
int appSpeedId;
bool bSceneShadowsOn;
bool bFogOn;
bool bWideScreen;
void Construct();
void Destruct();
bool init(int width,int height);
void shutdown();
int run();
void pause();
void activate();
#ifndef BINARY_RESOURCE
DWORD loadVertexShader(const TCHAR *pName,const DWORD *pdwDecl);
DWORD loadPixelShader(const TCHAR *pName);
#else // BINARY_RESOURCE
DWORD loadVertexShader(const BYTE *pb,const DWORD *pdwDecl);
DWORD loadPixelShader(const BYTE *pb);
#endif // BINARY_RESOURCE
float getElapsedTime() const { return fTimeElapsed; }
float getBaseBlobIntensity() const { return fBaseBlobIntensity; }
float getBlobIntensity() const { return fBlobIntensity; }
float getPulseIntensity() const { return fBlobIntensity - fBaseBlobIntensity; }
float getSmoothedBlobIntensity() const { return fSmoothedBlobIntensity; }
float getIIDT() const { return fIIDT; } // IIDT is integration of (intensity * dt)
float getCameraRadiusFromBlob() const { return fCamRadBlob; }
float getCameraRadius() const { return fCamRad; }
float getCameraTheta() const { return fCamTheta; }
float getCameraPhi() const { return fCamPhi; }
ShieldMgr* getShieldMgr() { return &shieldMgr; }
inline float fRand01();
inline float fRand11();
inline int rand() { return qrand.Rand(); }
};
///////////////////////////////////////////////////////////////////////////////
#define XBSA_RAND_MAX 0x00010000
#define XBSA_RAND_MASK 0x0000FFFF
inline float XBoxStartupApp::fRand01()
{
static float mul = 1.0f / ((float)XBSA_RAND_MAX);
return ((float)(qrand.Rand()&XBSA_RAND_MASK)) * mul;
}
inline float XBoxStartupApp::fRand11()
{
static float mul = 2.0f / ((float)XBSA_RAND_MAX);
return (((float)(qrand.Rand()&XBSA_RAND_MASK)) * mul) - 1.0f;
}
///////////////////////////////////////////////////////////////////////////////
extern XBoxStartupApp gApp;
#endif // __XBOX_APP_H__
+80
View File
@@ -0,0 +1,80 @@
//
// xbs_math.h
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001, Pipeworks Software Inc.
// All rights reserved
#ifndef __XBS_MATH_H__
#define __XBS_MATH_H__
struct D3DVECTOR4 : public _D3DVECTOR
{
float w;
};
const float Pi = 3.1415926535897932384626433832795028841971693993751058209f;
const float DegreeToRad = 0.017453292519943295769236907684883f; // (Pi / 180)
const float RadToDegree = 57.295779513082320876798154814114f; // (180 / Pi)
inline void SetLookAt(const D3DVECTOR &cam, const D3DVECTOR &look, const D3DVECTOR &up, D3DMATRIX *pres);
inline void SetProjection(float fov,float aspect, float near_plane, float far_plane, D3DMATRIX *pres);
inline void SetInverse(const D3DMATRIX &mat, D3DMATRIX *pres);
inline void SetTranspose(const D3DMATRIX &mat, D3DMATRIX *pres);
inline void SetIdentity(D3DMATRIX *pres);
inline void SetXRotation(float r,D3DMATRIX *pres);
inline void SetYRotation(float r,D3DMATRIX *pres);
inline void SetZRotation(float r,D3DMATRIX *pres);
inline void SetXYZRotation(float x,float y,float z, D3DMATRIX *pres);
inline void SetRotationFromLHQuat(const D3DVECTOR4 &quat,D3DMATRIX *pres);
inline void SetRotationFromRHQuat(const D3DVECTOR4 &quat,D3DMATRIX *pres);
inline void SetScale(float x,float y,float z,D3DMATRIX *pres);
inline void SetCubeMapView(DWORD dwFace, const D3DVECTOR &pos,D3DMATRIX *pres);
inline void TransformPoint(const D3DVECTOR &pt,const D3DMATRIX &mat, D3DVECTOR *pres);
inline void TransformVector(const D3DVECTOR &v,const D3DMATRIX &mat, D3DVECTOR *pres);
inline void TransformPoint(const D3DVECTOR4 &pt,const D3DMATRIX &mat, D3DVECTOR4 *pres);
inline void MulMats(const D3DMATRIX &a, const D3DMATRIX &b,D3DMATRIX *pres);
inline void ConcatMats(const D3DMATRIX &a, const D3DMATRIX &b, D3DMATRIX *pres);
inline float Dot(const D3DVECTOR &a, const D3DVECTOR &b);
inline float Length2(const D3DVECTOR &v);
inline float Length(const D3DVECTOR &v);
inline float Distance2(const D3DVECTOR &lhs, const D3DVECTOR &rhs);
inline float Distance(const D3DVECTOR &lhs, const D3DVECTOR &rhs);
inline void Normalize(D3DVECTOR *pres);
inline void Cross(const D3DVECTOR &a, const D3DVECTOR &b, D3DVECTOR *pres);
inline void Scale(D3DVECTOR *pres,float s);
inline void Set(D3DVECTOR *pres,float x,float y,float z);
inline void Set(D3DVECTOR4 *pres,float x,float y,float z,float w);
inline void Sub(const D3DVECTOR &lhs, const D3DVECTOR &rhs, D3DVECTOR *pres);
inline void Add(const D3DVECTOR &a, const D3DVECTOR &b, D3DVECTOR *pres);
inline void SetQuatFromAxis(const D3DVECTOR &axis, float angle,D3DVECTOR4 *pres);
inline float DotQuats(const D3DVECTOR4 &q0,const D3DVECTOR4 &q1);
inline void SlerpQuats(const D3DVECTOR4 &q0,const D3DVECTOR4 &q1,float t,D3DVECTOR4 *pres);
inline void NormalizeQuat(D3DVECTOR4 *pres);
inline bool IsEq(float a,float b);
inline bool PtsEq(const D3DVECTOR &a,const D3DVECTOR &b);
inline void AddScaled(D3DVECTOR* ptarget, const D3DVECTOR& src, float scale);
inline float QuickLength(const D3DVECTOR& vec);
inline void QuickNormalize(D3DVECTOR* p_vec); // left unchanged if the length is already small
inline void SinCos(const float &a, float *ps, float *pc);
inline float AngleFromSinCos(const float &s, const float &c);
inline void bs_swap(float& a, float& b);
inline void bs_swap(int& a, int& b);
inline float Square(float a) { return a*a; }
#include "xbs_math_inl.h"
#endif // __XBS_MATH_H__
+630
View File
@@ -0,0 +1,630 @@
//
// xbs_math_inl.h
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001, Pipeworks Software Inc.
// All rights reserved
#ifndef __XBS_MATH_INL_H__
#define __XBS_MATH_INL_H__
#include "fastmath.h"
///////////////////////////////////////////////////////////////////////////////
inline void SetLookAt(const D3DVECTOR &cam, const D3DVECTOR &look, const D3DVECTOR &up, D3DMATRIX *pres)
{
D3DVECTOR zAxis = look;
zAxis.x -= cam.x;
zAxis.y -= cam.y;
zAxis.z -= cam.z;
Normalize(&zAxis);
D3DVECTOR xAxis;
Cross(zAxis,up,&xAxis);
Normalize(&xAxis);
D3DVECTOR yAxis;
Cross(xAxis,zAxis,&yAxis);
pres->_11 = xAxis.x;
pres->_12 = yAxis.x;
pres->_13 = zAxis.x;
pres->_14 = 0.f;
pres->_21 = xAxis.y;
pres->_22 = yAxis.y;
pres->_23 = zAxis.y;
pres->_24 = 0.f;
pres->_31 = xAxis.z;
pres->_32 = yAxis.z;
pres->_33 = zAxis.z;
pres->_34 = 0.f;
pres->_41 = pres->_42 = pres->_43 = 0.f;
pres->_44 = 1.f;
D3DVECTOR inv_cam;
inv_cam.x = -cam.x;
inv_cam.y = -cam.y;
inv_cam.z = -cam.z;
D3DVECTOR r_inv_cam;
TransformVector(inv_cam,*pres,&r_inv_cam);
pres->_41 = r_inv_cam.x;
pres->_42 = r_inv_cam.y;
pres->_43 = r_inv_cam.z;
}
///////////////////////////////////////////////////////////////////////////////
void SetProjection(float fov,float aspect,float near_plane,float far_plane,D3DMATRIX *pres)
{
float fov2 = fov * .5f;
float c,s,ct;
SinCos(fov2, &s, &c);
ct = c / s;
float w = aspect * ct;
float h = ct;
float Q = far_plane / (far_plane - near_plane);
pres->_11 = w;
pres->_12 = 0.f;
pres->_13 = 0.f;
pres->_14 = 0.f;
pres->_21 = 0.f;
pres->_22 = h;
pres->_23 = 0.f;
pres->_24 = 0.f;
pres->_31 = 0.f;
pres->_32 = 0.f;
pres->_33 = Q;
pres->_34 = 1.f;
pres->_41 = 0.f;
pres->_42 = 0.f;
pres->_43 = -Q * near_plane;
pres->_44 = 0.f;
}
///////////////////////////////////////////////////////////////////////////////
inline void SetInverse(const D3DMATRIX &mat, D3DMATRIX *pres)
{
pres->_11 = mat._11;
pres->_12 = mat._21;
pres->_13 = mat._31;
pres->_14 = 0.f;
pres->_21 = mat._12;
pres->_22 = mat._22;
pres->_23 = mat._32;
pres->_24 = 0.f;
pres->_31 = mat._13;
pres->_32 = mat._23;
pres->_33 = mat._33;
pres->_34 = 0.f;
D3DVECTOR inv_trans;
inv_trans.x = -mat._41;
inv_trans.y = -mat._42;
inv_trans.z = -mat._43;
D3DVECTOR r_inv_trans;
TransformVector(inv_trans,*pres,&r_inv_trans);
pres->_41 = r_inv_trans.x;
pres->_42 = r_inv_trans.y;
pres->_43 = r_inv_trans.z;
pres->_44 = 1.f;
}
///////////////////////////////////////////////////////////////////////////////
inline void SetTranspose(const D3DMATRIX &mat, D3DMATRIX *pres)
{
pres->_11 = mat._11;
pres->_12 = mat._21;
pres->_13 = mat._31;
pres->_14 = mat._41;
pres->_21 = mat._12;
pres->_22 = mat._22;
pres->_23 = mat._32;
pres->_24 = mat._42;
pres->_31 = mat._13;
pres->_32 = mat._23;
pres->_33 = mat._33;
pres->_34 = mat._43;
pres->_41 = mat._14;
pres->_42 = mat._24;
pres->_43 = mat._34;
pres->_44 = mat._44;
}
///////////////////////////////////////////////////////////////////////////////
inline void SetIdentity(D3DMATRIX *pres)
{
pres->_11 = pres->_22 = pres->_33 = pres->_44 = 1.f;
pres->_12 = pres->_13 = pres->_14 =
pres->_21 = pres->_23 = pres->_24 =
pres->_31 = pres->_32 = pres->_34 =
pres->_41 = pres->_42 = pres->_43 = 0.f;
}
///////////////////////////////////////////////////////////////////////////////
inline void SetXRotation(float r,D3DMATRIX *pres)
{
float s,c;
SinCos(r,&s,&c);
pres->_11 = 1.f;
pres->_12 = 0.f;
pres->_13 = 0.f;
pres->_14 = 0.f;
pres->_21 = 0.f;
pres->_22 = c;
pres->_23 = s;
pres->_24 = 0.f;
pres->_31 = 0.f;
pres->_32 = -s;
pres->_33 = c;
pres->_34 = 0.f;
pres->_41 = pres->_42 = pres->_43 = 0.f;
pres->_44 = 1.f;
}
///////////////////////////////////////////////////////////////////////////////
inline void SetYRotation(float r,D3DMATRIX *pres)
{
float s,c;
SinCos(r,&s,&c);
pres->_11 = c;
pres->_12 = 0.f;
pres->_13 = s;
pres->_14 = 0.f;
pres->_21 = 0.f;
pres->_22 = 1.f;
pres->_23 = 0.f;
pres->_24 = 0.f;
pres->_31 = -s;
pres->_32 = 0.f;
pres->_33 = c;
pres->_34 = 0.f;
pres->_41 = pres->_42 = pres->_43 = 0.f;
pres->_44 = 1.f;
}
///////////////////////////////////////////////////////////////////////////////
inline void SetZRotation(float r,D3DMATRIX *pres)
{
float s,c;
SinCos(r,&s,&c);
pres->_11 = c;
pres->_12 = s;
pres->_13 = 0.f;
pres->_14 = 0.f;
pres->_21 = -s;
pres->_22 = c;
pres->_23 = 0;
pres->_24 = 0.f;
pres->_31 = 0.f;
pres->_32 = 0.f;
pres->_33 = 1;
pres->_34 = 0.f;
pres->_41 = pres->_42 = pres->_43 = 0.f;
pres->_44 = 1.f;
}
///////////////////////////////////////////////////////////////////////////////
inline void SetXYZRotation(float x,float y,float z, D3DMATRIX *pres)
{
D3DMATRIX matx;
SetXRotation(x,&matx);
D3DMATRIX maty;
SetYRotation(y,&maty);
D3DMATRIX matxy;
MulMats(matx,maty,&matxy);
D3DMATRIX matz;
SetZRotation(z,&matz);
MulMats(matz,matxy,pres);
}
///////////////////////////////////////////////////////////////////////////////
inline void SetRotationFromRHQuat(const D3DVECTOR4 &q,D3DMATRIX *pres)
{
pres->_11 = q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z;
pres->_12 = 2.f*q.x*q.y + 2.f*q.w*q.z;
pres->_13 = 2.f*q.x*q.z - 2.f*q.w*q.y;
pres->_14 = 0.f;
pres->_21 = 2.f*q.x*q.y - 2.f*q.w*q.z;
pres->_22 = q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z;
pres->_23 = 2.f*q.y*q.z + 2.f*q.w*q.x;
pres->_24 = 0.f;
pres->_31 = 2.f*q.x*q.z + 2.f*q.w*q.y;
pres->_32 = 2.f*q.y*q.z - 2.f*q.w*q.x;
pres->_33 = q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z;
pres->_34 = 0.f;
pres->_41 = pres->_42 = pres->_43 = 0.f;
pres->_44 = 1.f;
}
///////////////////////////////////////////////////////////////////////////////
inline void SetRotationFromLHQuat(const D3DVECTOR4 &q,D3DMATRIX *pres)
{
pres->_11 = q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z;
pres->_21 = 2.f*q.x*q.y + 2.f*q.w*q.z;
pres->_31 = 2.f*q.x*q.z - 2.f*q.w*q.y;
pres->_41 = 0.f;
pres->_12 = 2.f*q.x*q.y - 2.f*q.w*q.z;
pres->_22 = q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z;
pres->_32 = 2.f*q.y*q.z + 2.f*q.w*q.x;
pres->_42 = 0.f;
pres->_13 = 2.f*q.x*q.z + 2.f*q.w*q.y;
pres->_23 = 2.f*q.y*q.z - 2.f*q.w*q.x;
pres->_33 = q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z;
pres->_43 = 0.f;
pres->_14 = pres->_24 = pres->_34 = 0.f;
pres->_44 = 1.f;
}
///////////////////////////////////////////////////////////////////////////////
inline void TransformPoint(const D3DVECTOR &pt,const D3DMATRIX &mat, D3DVECTOR *pres)
{
pres->x = pt.x * mat._11 + pt.y * mat._21 + pt.z * mat._31 + mat._41;
pres->y = pt.x * mat._12 + pt.y * mat._22 + pt.z * mat._32 + mat._42;
pres->z = pt.x * mat._13 + pt.y * mat._23 + pt.z * mat._33 + mat._43;
}
///////////////////////////////////////////////////////////////////////////////
inline void TransformVector(const D3DVECTOR &v,const D3DMATRIX &mat, D3DVECTOR *pres)
{
pres->x = v.x * mat._11 + v.y * mat._21 + v.z * mat._31;
pres->y = v.x * mat._12 + v.y * mat._22 + v.z * mat._32;
pres->z = v.x * mat._13 + v.y * mat._23 + v.z * mat._33;
}
///////////////////////////////////////////////////////////////////////////////
inline void TransformPoint(const D3DVECTOR4 &pt,const D3DMATRIX &mat, D3DVECTOR4 *pres)
{
pres->x = pt.x * mat._11 + pt.y * mat._21 + pt.z * mat._31 + pt.w * mat._41;
pres->y = pt.x * mat._12 + pt.y * mat._22 + pt.z * mat._32 + pt.w * mat._42;
pres->z = pt.x * mat._13 + pt.y * mat._23 + pt.z * mat._33 + pt.w * mat._43;
pres->w = pt.x * mat._14 + pt.y * mat._24 + pt.z * mat._34 + pt.w * mat._44;
}
///////////////////////////////////////////////////////////////////////////////
inline void MulMats(const D3DMATRIX &a, const D3DMATRIX &b,D3DMATRIX *pres)
{
pres->_11 = a._11*b._11 + a._12*b._21 + a._13*b._31 + a._14*b._41;
pres->_12 = a._11*b._12 + a._12*b._22 + a._13*b._32 + a._14*b._42;
pres->_13 = a._11*b._13 + a._12*b._23 + a._13*b._33 + a._14*b._43;
pres->_14 = a._11*b._14 + a._12*b._24 + a._13*b._34 + a._14*b._44;
pres->_21 = a._21*b._11 + a._22*b._21 + a._23*b._31 + a._24*b._41;
pres->_22 = a._21*b._12 + a._22*b._22 + a._23*b._32 + a._24*b._42;
pres->_23 = a._21*b._13 + a._22*b._23 + a._23*b._33 + a._24*b._43;
pres->_24 = a._21*b._14 + a._22*b._24 + a._23*b._34 + a._24*b._44;
pres->_31 = a._31*b._11 + a._32*b._21 + a._33*b._31 + a._34*b._41;
pres->_32 = a._31*b._12 + a._32*b._22 + a._33*b._32 + a._34*b._42;
pres->_33 = a._31*b._13 + a._32*b._23 + a._33*b._33 + a._34*b._43;
pres->_34 = a._31*b._14 + a._32*b._24 + a._33*b._34 + a._34*b._44;
pres->_41 = a._41*b._11 + a._42*b._21 + a._43*b._31 + a._44*b._41;
pres->_42 = a._41*b._12 + a._42*b._22 + a._43*b._32 + a._44*b._42;
pres->_43 = a._41*b._13 + a._42*b._23 + a._43*b._33 + a._44*b._43;
pres->_44 = a._41*b._14 + a._42*b._24 + a._43*b._34 + a._44*b._44;
}
///////////////////////////////////////////////////////////////////////////////
inline void SetScale(float x,float y,float z,D3DMATRIX *pres)
{
pres->_11 = x;
pres->_22 = y;
pres->_33 = z;
pres->_12 = pres->_13 = pres->_14 =
pres->_21 = pres->_23 = pres->_24 =
pres->_31 = pres->_32 = pres->_34 =
pres->_41 = pres->_42 = pres->_43 = 0.f;
pres->_44 = 1.f;
}
///////////////////////////////////////////////////////////////////////////////
inline void SetCubeMapView(DWORD dwFace, const D3DVECTOR &pos,D3DMATRIX *pres)
{
D3DVECTOR look,up;
switch( dwFace )
{
case D3DCUBEMAP_FACE_POSITIVE_X:
Set(&look,1.f,0.f,0.f);
Set(&up,0.f,1.f,0.f);
break;
case D3DCUBEMAP_FACE_NEGATIVE_X:
Set(&look,-1.f,0.f,0.f);
Set(&up,0.f,1.f,0.f);
break;
case D3DCUBEMAP_FACE_POSITIVE_Y:
Set(&look,0.f,1.f,0.f);
Set(&up,0.f,0.f,-1.f);
break;
case D3DCUBEMAP_FACE_NEGATIVE_Y:
Set(&look,0.f,-1.f,0.f);
Set(&up,0.f,0.f,1.f);
break;
case D3DCUBEMAP_FACE_POSITIVE_Z:
Set(&look,0.f,0.f,1.f);
Set(&up,0.f,1.f,0.f);
break;
case D3DCUBEMAP_FACE_NEGATIVE_Z:
Set(&look,0.f,0.f,-1.f);
Set(&up,0.f,1.f,0.f);
break;
}
D3DVECTOR lookat;
Add(pos,look,&lookat);
SetLookAt( pos, lookat, up, pres );
}
///////////////////////////////////////////////////////////////////////////////
inline void ConcatMats(const D3DMATRIX &a, const D3DMATRIX &b, D3DMATRIX *pres)
{
MulMats(a,b,pres);
TransformVector(*((const D3DVECTOR *)(&a._41)),b,(D3DVECTOR *)&pres->_41);
pres->_41 += b._41; pres->_42 += b._42; pres->_43 += b._43;
pres->_14 = pres->_24 = pres->_34 = 0.f;
pres->_44 = 1.f;
}
///////////////////////////////////////////////////////////////////////////////
inline float Dot(const D3DVECTOR &a, const D3DVECTOR &b)
{
return a.x*b.x + a.y*b.y + a.z*b.z;
}
///////////////////////////////////////////////////////////////////////////////
inline float Length2(const D3DVECTOR &v)
{
return v.x*v.x + v.y*v.y + v.z*v.z;
}
///////////////////////////////////////////////////////////////////////////////
inline float Length(const D3DVECTOR &v)
{
return fast_sqrt(Length2(v));
}
///////////////////////////////////////////////////////////////////////////////
inline float Distance2(const D3DVECTOR &lhs, const D3DVECTOR &rhs)
{
float dx = lhs.x - rhs.x;
float dy = lhs.y - rhs.y;
float dz = lhs.z - rhs.z;
return dx*dx + dy*dy + dz*dz;
}
///////////////////////////////////////////////////////////////////////////////
inline float Distance(const D3DVECTOR &lhs, const D3DVECTOR &rhs)
{
return fast_sqrt(Distance2(lhs, rhs));
}
///////////////////////////////////////////////////////////////////////////////
inline void Normalize(D3DVECTOR *pres)
{
float fooLen = 1.f/Length(*pres);
pres->x *= fooLen;
pres->y *= fooLen;
pres->z *= fooLen;
}
///////////////////////////////////////////////////////////////////////////////
inline void Cross(const D3DVECTOR &a, const D3DVECTOR &b, D3DVECTOR *pres)
{
pres->x = a.y*b.z - a.z*b.y;
pres->y = a.z*b.x - a.x*b.z;
pres->z = a.x*b.y - a.y*b.x;
}
///////////////////////////////////////////////////////////////////////////////
inline void Scale(D3DVECTOR *pres,float s)
{
pres->x *= s; pres->y *= s; pres->z *= s;
}
///////////////////////////////////////////////////////////////////////////////
inline void Set(D3DVECTOR *pres,float x,float y,float z)
{
pres->x = x; pres->y = y; pres->z = z;
}
///////////////////////////////////////////////////////////////////////////////
inline void Set(D3DVECTOR4 *pres,float x,float y,float z,float w)
{
pres->x = x; pres->y = y; pres->z = z; pres->w = w;
}
///////////////////////////////////////////////////////////////////////////////
inline void Sub(const D3DVECTOR &lhs, const D3DVECTOR &rhs, D3DVECTOR *pres)
{
pres->x = lhs.x - rhs.x;
pres->y = lhs.y - rhs.y;
pres->z = lhs.z - rhs.z;
}
///////////////////////////////////////////////////////////////////////////////
inline void SetQuatFromAxis(const D3DVECTOR &axis, float angle,D3DVECTOR4 *pres)
{
float s,c;
SinCos(angle*0.5f,&s,&c);
pres->x = axis.x * s;
pres->y = axis.y * s;
pres->z = axis.z * s;
pres->w = c;
}
///////////////////////////////////////////////////////////////////////////////
inline void NormalizeQuat(D3DVECTOR4 *pres)
{
float len2 = DotQuats(*pres,*pres);
if(len2 != 0.f)
{
float oo_len = 1.f/fast_sqrt(len2);
pres->x *= oo_len;
pres->y *= oo_len;
pres->z *= oo_len;
pres->w *= oo_len;
}
}
///////////////////////////////////////////////////////////////////////////////
inline float DotQuats(const D3DVECTOR4 &q0,const D3DVECTOR4 &q1)
{
return q0.x * q1.x + q0.y * q1.y + q0.z * q1.z + q0.w * q1.w;
}
///////////////////////////////////////////////////////////////////////////////
inline void SlerpQuats(const D3DVECTOR4 &q0,const D3DVECTOR4 &q1,float t,D3DVECTOR4 *pres)
{
float dp = DotQuats(q0,q1);
D3DVECTOR4 _q1 = q1;
if(dp < 0.f)
{
_q1.x = -q1.x;
_q1.y = -q1.y;
_q1.z = -q1.z;
_q1.w = -q1.w;
dp = -dp;
}
if(IsEq(dp,1.f))
{
pres->x = q0.x * (1.f - t) + _q1.x * t;
pres->y = q0.y * (1.f - t) + _q1.y * t;
pres->z = q0.z * (1.f - t) + _q1.z * t;
pres->w = q0.w * (1.f - t) + _q1.w * t;
}
else
{
float angle = fast_acos(dp);
float t0 = fast_sin(angle*(1.f-t));
float t1 = fast_sin(angle*t);
pres->x = q0.x * t0 + _q1.x * t1;
pres->y = q0.y * t0 + _q1.y * t1;
pres->z = q0.z * t0 + _q1.z * t1;
pres->w = q0.w * t0 + _q1.w * t1;
float oo_sin_theta = 1.f/fast_sin(angle);
pres->x *= oo_sin_theta;
pres->y *= oo_sin_theta;
pres->z *= oo_sin_theta;
pres->w *= oo_sin_theta;
}
}
///////////////////////////////////////////////////////////////////////////////
inline bool IsEq(float a,float b)
{
return fast_fabs(a-b) <= 0.00001f;
}
///////////////////////////////////////////////////////////////////////////////
inline bool PtsEq(const D3DVECTOR &a,const D3DVECTOR &b)
{
return IsEq(a.x,b.x) && IsEq(a.y,b.y) && IsEq(a.z,b.z);
}
///////////////////////////////////////////////////////////////////////////////
inline void AddScaled(D3DVECTOR* ptarget, const D3DVECTOR& src, float scale)
{
ptarget->x += src.x * scale;
ptarget->y += src.y * scale;
ptarget->z += src.z * scale;
}
///////////////////////////////////////////////////////////////////////////////
inline float QuickLength(const D3DVECTOR& vec)
{
float h = (float) fabs(vec.x);
float m = (float) fabs(vec.y);
float l = (float) fabs(vec.z);
float t;
if (m>h) { t = m; m = h; h = t; }
if (l>m) { t = l; l = m; m = t; }
if (m>h) { t = m; m = h; h = t; }
return (1.043388475f * (h + 0.34375f * m + 0.25f * l));
}
///////////////////////////////////////////////////////////////////////////////
inline void QuickNormalize(D3DVECTOR* p_vec)
{
float qlen = QuickLength(*p_vec);
if (qlen < 0.000001f) return;
float oo_qlen = 1.0f / qlen;
Scale(p_vec, oo_qlen);
}
///////////////////////////////////////////////////////////////////////////////
inline void Add(const D3DVECTOR &a, const D3DVECTOR &b, D3DVECTOR *pres)
{
pres->x = a.x + b.x;
pres->y = a.y + b.y;
pres->z = a.z + b.z;
}
///////////////////////////////////////////////////////////////////////////////
inline void SinCos(const float &a, float *ps, float *pc)
{
_asm
{
mov eax,[a]
fld dword ptr[eax]
fsincos
mov ebx,[pc]
mov ecx,[ps]
fstp dword ptr[ebx]
fstp dword ptr[ecx]
}
}
const float F_0 = 0.0f;
///////////////////////////////////////////////////////////////////////////////
inline float AngleFromSinCos(const float &s, const float &c)
{
// Calculates the angle that produces a given sin and cosine.
// This is a special case of atan2.
//
// Returns a value in (-Pi, Pi/2]
if (s <= -1) return -Pi / 2;
if (s >= 1) return Pi / 2;
if (c <= -1) return Pi;
if (c >= 1) return F_0;
// Use either asin or acos, depending on what we think will have the
// best numerical performance.
float a;
if (s < .1f && s > -.1f)
{
a = (float) fast_asin(s);
if (c < 0)
{
a = (float) Pi - a;
if (a > Pi) a -= 2 * Pi;
}
}
else
{
a = (float) fast_acos(c);
if (s < 0) a = (float) - a;
}
return a;
}
///////////////////////////////////////////////////////////////////////////////
inline void bs_swap(float& a, float& b)
{
float tmp = a;
a = b;
b = tmp;
}
///////////////////////////////////////////////////////////////////////////////
inline void bs_swap(int& a, int& b)
{
int tmp = a;
a = b;
b = tmp;
}
///////////////////////////////////////////////////////////////////////////////
#endif // __XBS_MATH_INL_H__