From b691c43c44ff180d10e7d4a9afc83b98551ff586 Mon Sep 17 00:00:00 2001
From: daoge_cmd <3523206925@qq.com>
Date: Sun, 1 Mar 2026 12:16:08 +0800
Subject: Initial commit
---
.../CompressedTile/CompressedTile.spu.vcxproj | 160 ++++++
.../CompressedTile.spu.vcxproj.filters | 32 ++
.../CompressedTile.spu.vcxproj.vspscc | 10 +
.../CompressedTile/CompressedTileStorage_SPU.cpp | 544 +++++++++++++++++++++
.../CompressedTile/CompressedTileStorage_SPU.h | 156 ++++++
.../CompressedTile/CompressedTile_main.cpp | 63 +++
.../CompressedTile/SparseDataStorage_SPU.cpp | 5 +
.../CompressedTile/SparseDataStorage_SPU.h | 75 +++
.../CompressedTile/SparseLightStorage_SPU.cpp | 6 +
.../CompressedTile/SparseLightStorage_SPU.h | 83 ++++
.../PS3/SPU_Tasks/CompressedTile/stdafx.h | 0
11 files changed, 1134 insertions(+)
create mode 100644 Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile.spu.vcxproj
create mode 100644 Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile.spu.vcxproj.filters
create mode 100644 Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile.spu.vcxproj.vspscc
create mode 100644 Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTileStorage_SPU.cpp
create mode 100644 Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTileStorage_SPU.h
create mode 100644 Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile_main.cpp
create mode 100644 Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseDataStorage_SPU.cpp
create mode 100644 Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseDataStorage_SPU.h
create mode 100644 Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseLightStorage_SPU.cpp
create mode 100644 Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseLightStorage_SPU.h
create mode 100644 Minecraft.Client/PS3/SPU_Tasks/CompressedTile/stdafx.h
(limited to 'Minecraft.Client/PS3/SPU_Tasks/CompressedTile')
diff --git a/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile.spu.vcxproj b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile.spu.vcxproj
new file mode 100644
index 00000000..6cb491b0
--- /dev/null
+++ b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile.spu.vcxproj
@@ -0,0 +1,160 @@
+
+
+
+
+ ContentPackage
+ PS3
+
+
+ Debug
+ PS3
+
+
+ Release
+ PS3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {4B436D43-D35B-4E56-988A-A3543B70C8E5}
+ CompressedTile
+ %24/StoriesPark/Minecraft/MinecraftConsoles-dev/Minecraft.Client/PS3/SPU_Tasks/CompressedTile
+ https://tfs4jstudios.visualstudio.com/defaultcollection
+ .
+ {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
+
+
+
+ Application
+ SPU
+
+
+ Application
+ SPU
+
+
+ Application
+ SPU
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ PS3_Debug\
+ PS3_Debug\
+ *.obj;*.d;*.map;*.lst;*.pch;$(TargetPath);undefined;$(ExtensionsToDeleteOnClean)
+
+ false
+ PS3_Release\
+ PS3_ContentPackage\
+ PS3_Release\
+ PS3_ContentPackage\
+ *.obj;*.d;*.map;*.lst;*.pch;$(TargetPath);undefined;$(ExtensionsToDeleteOnClean)
+ *.obj;*.d;*.map;*.lst;*.pch;$(TargetPath);undefined;$(ExtensionsToDeleteOnClean)
+
+
+ false
+ false
+ $(ProjectName)
+ SpursInit
+ $(ProjectName)
+ $(ProjectName)
+
+
+
+ -ffunction-sections -fdata-sections -fstack-check %(AdditionalOptions)
+ $(SN_PS3_PATH)\spu\include\sn;$(SCE_PS3_ROOT)\target\spu\include;$(SCE_PS3_ROOT)\target\common\include;%(AdditionalIncludeDirectories)
+ true
+ SN_TARGET_PS3_SPU;_DEBUG;__GCC__;SPU;%(PreprocessorDefinitions)
+
+
+ true
+
+
+ -Wl,--gc-sections -g %(AdditionalOptions)
+ -ldma;-lspurs_jq;%(AdditionalDependencies)
+ false
+
+
+
+
+ JobBin2
+ ..\ObjFiles\Debug\$(TargetName).ppu$(ObjectExt)
+
+
+
+
+ -ffunction-sections -fdata-sections -fstack-check %(AdditionalOptions)
+ $(SN_PS3_PATH)\spu\include\sn;$(SCE_PS3_ROOT)\target\spu\include;$(SCE_PS3_ROOT)\target\common\include;%(AdditionalIncludeDirectories)
+ true
+ Level3
+ SN_TARGET_PS3_SPU;NDEBUG;__GCC__;SPU;%(PreprocessorDefinitions)
+
+
+ true
+
+
+ -Wl,--gc-sections -g %(AdditionalOptions)
+ -ldma;-lspurs_jq;%(AdditionalDependencies)
+ false
+
+
+
+
+ JobBin2
+ ..\ObjFiles\Release\$(TargetName).ppu$(ObjectExt)
+
+
+
+
+ -ffunction-sections -fdata-sections -fstack-check %(AdditionalOptions)
+ $(SN_PS3_PATH)\spu\include\sn;$(SCE_PS3_ROOT)\target\spu\include;$(SCE_PS3_ROOT)\target\common\include;%(AdditionalIncludeDirectories)
+ false
+ Level3
+ SN_TARGET_PS3_SPU;NDEBUG;__GCC__;SPU;_CONTENT_PACKAGE;%(PreprocessorDefinitions)
+
+
+ true
+
+
+ -Wl,--gc-sections -g %(AdditionalOptions)
+ -ldma;-lspurs_jq;%(AdditionalDependencies)
+ false
+
+
+
+
+ JobBin2
+ ..\ObjFiles\ContentPackage\$(TargetName).ppu$(ObjectExt)
+ Hard
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile.spu.vcxproj.filters b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile.spu.vcxproj.filters
new file mode 100644
index 00000000..61e540ec
--- /dev/null
+++ b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile.spu.vcxproj.filters
@@ -0,0 +1,32 @@
+
+
+
+
+ {881f28ee-ca74-4afc-94a6-2346cb88f86d}
+ cpp;c;cxx;cc;s;asm
+
+
+
+
+
+
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile.spu.vcxproj.vspscc b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile.spu.vcxproj.vspscc
new file mode 100644
index 00000000..b6d32892
--- /dev/null
+++ b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile.spu.vcxproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTileStorage_SPU.cpp b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTileStorage_SPU.cpp
new file mode 100644
index 00000000..dc134eca
--- /dev/null
+++ b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTileStorage_SPU.cpp
@@ -0,0 +1,544 @@
+#include "stdafx.h"
+#include "CompressedTileStorage_SPU.h"
+#ifdef SN_TARGET_PS3_SPU
+#include "..\Common\DmaData.h"
+#else
+#include "..\..\..\..\Minecraft.World\Tile.h"
+#include "..\..\..\..\Minecraft.World\TilePos.h"
+#include "..\..\..\..\Minecraft.World\LevelChunk.h"
+#endif
+
+#include
+
+#ifdef SN_TARGET_PS3_SPU
+TileCompressData_SPU::OutputData TileCompressData_SPU::m_OutputData;
+CompressedTileStorage_SPU* TileCompressData_SPU::m_pTileStorage;
+SparseLightStorage_SPU* TileCompressData_SPU::m_pLightStorage;
+SparseDataStorage_SPU* TileCompressData_SPU::m_pDataStorage;
+#endif
+
+// Note: See header for an overview of this class
+
+// int CompressedTileStorage::deleteQueueIndex;
+// XLockFreeStack CompressedTileStorage::deleteQueue[3];
+//
+// CRITICAL_SECTION CompressedTileStorage::cs_write;
+
+CompressedTileStorage_SPU::CompressedTileStorage_SPU(unsigned char* data)
+{
+ indicesAndData = data;
+ allocatedSize = 0;
+}
+
+
+CompressedTileStorage_SPU::~CompressedTileStorage_SPU()
+{
+}
+
+// Get an index into the normal ordering of tiles for the java game, given a block index (0 to 511) and a tile index (0 to 63)
+inline int CompressedTileStorage_SPU::getIndex(int block, int tile)
+{
+ // bits for index into data is: xxxxzzzzyyyyyyy
+ // we want block(b) & tile(t) spread out as:
+ // from: ______bbbbbbbbb
+ // to: bb__bb__bbbbb__
+ //
+ // from: _________tttttt
+ // to: __tt__tt_____tt
+
+ int index = ( ( block & 0x180) << 6 ) | ( ( block & 0x060 ) << 4 ) | ( ( block & 0x01f ) << 2 );
+ index |= ( ( tile & 0x30 ) << 7) | ( ( tile & 0x0c ) << 5 ) | ( tile & 0x03 );
+
+ return index;
+}
+
+// Get the block and tile (reversing getIndex above) for a given x, y, z coordinate
+//
+// bits for index into data is: xxxxzzzzyyyyyyy
+// bbttbbttbbbbbtt
+//
+// so x is: ___________xxxx
+// and maps to this bit of b ______bb_______
+// and this bit of t _________tt____
+//
+// y is: ________yyyyyyy
+// and maps to this bit of b __________bbbbb
+// and this bit of t _____________tt
+//
+// and z is: ___________zzzz
+// and maps to this bit of b ________bb_____
+// and this bit of t ___________tt__
+//
+
+inline void CompressedTileStorage_SPU::getBlockAndTile(int *block, int *tile, int x, int y, int z)
+{
+ *block = ( ( x & 0x0c ) << 5 ) | ( ( z & 0x0c ) << 3 ) | ( y >> 2 );
+ *tile = ( ( x & 0x03 ) << 4 ) | ( ( z & 0x03 ) << 2 ) | ( y & 0x03 );
+}
+
+
+// Get an individual tile value
+int CompressedTileStorage_SPU::get(int x, int y, int z)
+{
+ if(y<0)
+ return 0;
+ if(!indicesAndData) return 0;
+
+ unsigned short *blockIndices = (unsigned short *)indicesAndData;
+ unsigned char *data = indicesAndData + 1024;
+
+ int block, tile;
+ getBlockAndTile( &block, &tile, x, y, z );
+ int indexType = blockIndices[block] & INDEX_TYPE_MASK;
+
+ if( indexType == INDEX_TYPE_0_OR_8_BIT )
+ {
+ if( blockIndices[block] & INDEX_TYPE_0_BIT_FLAG )
+ {
+ // 0 bit reads are easy - the value is packed in the index
+ return ( blockIndices[block] >> INDEX_TILE_SHIFT ) & INDEX_TILE_MASK;
+ }
+ else
+ {
+ // 8-bit reads are just directly read from the 64 long array of values stored for the block
+ unsigned char *packed = data + ( ( blockIndices[block] >> INDEX_OFFSET_SHIFT ) & INDEX_OFFSET_MASK );
+ return packed[tile];
+ }
+ }
+ else
+ {
+ int bitspertile = 1 << indexType; // will be 1, 2 or 4 (from index values of 0, 1, 2)
+ int tiletypecount = 1 << bitspertile; // will be 2, 4 or 16 (from index values of 0, 1, 2)
+ int tiletypemask = tiletypecount - 1; // will be 1, 3 or 15 (from index values of 0, 1, 2)
+ int indexshift = 3 - indexType; // will be 3, 2 or 1 (from index values of 0, 1, 2)
+ int indexmask_bits = 7 >> indexType; // will be 7, 3 or 1 (from index values of 0, 1, 2)
+ int indexmask_bytes = 62 >> indexshift; // will be 7, 15 or 31 (from index values of 0, 1, 2)
+
+ unsigned char *tile_types = data + ( ( blockIndices[block] >> INDEX_OFFSET_SHIFT ) & INDEX_OFFSET_MASK );
+ unsigned char *packed = tile_types + tiletypecount;
+ int idx = ( tile >> indexshift ) & indexmask_bytes;
+ int bit = ( tile & indexmask_bits ) * bitspertile;
+ return tile_types[( packed[idx] >> bit ) & tiletypemask];
+ }
+ return 0;
+}
+
+#ifdef SN_TARGET_PS3_SPU
+
+
+
+
+void TileCompressData_SPU::uncompressTiles(int x0, int z0, int x1, int z1, bool upper)
+{
+ int y0 = -2;
+ int y1 = 18;
+ for(int iY=y0;iY255)
+ {
+ m_OutputData.m_tileIds[index] = 0;
+ }
+ else
+ {
+ m_OutputData.m_tileIds[index] = m_pTileStorage->get(sectionX, sectionY, sectionZ);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void TileCompressData_SPU::clearTiles(int x0, int z0, int x1, int z1, bool upper)
+{
+ int y0 = -2;
+ int y1 = 18;
+ for(int iY=y0;iY255)
+ {
+ m_OutputData.m_brightness[index] = 0;
+ }
+ else if(skyLight)
+ {
+ m_OutputData.m_brightness[index] = m_pLightStorage->get(sectionX, sectionY, sectionZ);
+ }
+ else
+ {
+ m_OutputData.m_brightness[index] |= m_pLightStorage->get(sectionX, sectionY, sectionZ) << 4;
+ }
+ }
+ }
+ }
+ }
+}
+
+void TileCompressData_SPU::clearLights(int x0, int z0, int x1, int z1, bool upper, bool skyLight)
+{
+ int y0 = -2;
+ int y1 = 18;
+ for(int iY=y0;iY255)
+ {
+ m_OutputData.m_data_flags[index] = 0;
+ }
+ else
+ {
+ m_OutputData.m_data_flags[index] = m_pDataStorage->get(sectionX, sectionY, sectionZ);
+ }
+ }
+ }
+ }
+ }
+}
+
+void TileCompressData_SPU::clearData(int x0, int z0, int x1, int z1, bool upper)
+{
+ int y0 = -2;
+ int y1 = 18;
+ for(int iY=y0;iY> 48)*128)+128;
+ DmaData_SPU::getAndWait(pDest, loadFrom, loadSize);
+}
+
+int padTo16(int size)
+{
+ if(size & 0x0f)
+ {
+ size &= ~0x0f;
+ size += 0x10;
+ }
+ return size;
+}
+void TileCompressData_SPU::loadAndUncompressLowerSection(int block, int x0, int z0, int x1, int z1)
+{
+
+ // tile IDs first
+ // ---------------------------
+ if(m_lowerBlocks[block] != NULL)
+ {
+ int dmaSize = padTo16(m_lowerBlocksSize[block]);
+ DmaData_SPU::getAndWait(m_pTileStorage->getDataPtr(), (uint32_t)m_lowerBlocks[block], dmaSize);
+// spu_print("Grabbed %d of data\n", m_lowerBlocksSize[block]);
+ uncompressTiles(x0, z0, x1, z1, false);
+ }
+ else
+ {
+ clearTiles(x0, z0, x1, z1, false);
+ }
+
+ // Sky Lights
+ // ---------------------------
+ if(m_lowerSkyLight[block] != 0)
+ {
+ dmaSparseStorage(m_lowerSkyLight[block], m_pLightStorage->getDataPtr());
+ uncompressLights(x0, z0, x1, z1, false, true);
+ }
+ else
+ {
+ clearLights(x0, z0, x1, z1, false, true);
+ }
+
+ // Block Lights
+ // ---------------------------
+ if(m_lowerBlockLight[block] != 0)
+ {
+ dmaSparseStorage(m_lowerBlockLight[block], m_pLightStorage->getDataPtr());
+ uncompressLights(x0, z0, x1, z1, false, false);
+ }
+ else
+ {
+ clearLights(x0, z0, x1, z1, false, false);
+ }
+
+ // Data
+ // ---------------------------
+ if(m_lowerData[block] != 0)
+ {
+ dmaSparseStorage(m_lowerData[block], m_pDataStorage->getDataPtr());
+ uncompressData(x0, z0, x1, z1, false);
+ }
+ else
+ {
+ clearData(x0, z0, x1, z1, false);
+ }
+}
+
+void TileCompressData_SPU::loadAndUncompressUpperSection(int block, int x0, int z0, int x1, int z1)
+{
+ if(m_upperBlocks[block] != NULL)
+ {
+ int dmaSize = padTo16(m_upperBlocksSize[block]);
+ DmaData_SPU::getAndWait(m_pTileStorage->getDataPtr(), (uint32_t)m_upperBlocks[block], dmaSize);
+ uncompressTiles(x0, z0, x1, z1, true);
+ }
+ else
+ {
+ clearTiles(x0, z0, x1, z1, true);
+ }
+
+ // Sky Lights
+ // ---------------------------
+ if(m_upperSkyLight[block] != 0)
+ {
+ dmaSparseStorage(m_upperSkyLight[block], m_pLightStorage->getDataPtr());
+ uncompressLights(x0, z0, x1, z1, true, true);
+ }
+ else
+ {
+ clearLights(x0, z0, x1, z1, true, true);
+ }
+
+ // Block Lights
+ // ---------------------------
+ if(m_upperBlockLight[block] != 0)
+ {
+ dmaSparseStorage(m_upperBlockLight[block], m_pLightStorage->getDataPtr());
+ uncompressLights(x0, z0, x1, z1, true, false);
+ }
+ else
+ {
+ clearLights(x0, z0, x1, z1, true, false);
+ }
+
+ // Data
+ // ---------------------------
+ if(m_upperData[block] != 0)
+ {
+ dmaSparseStorage(m_upperData[block], m_pDataStorage->getDataPtr());
+ uncompressData(x0, z0, x1, z1, true);
+ }
+ else
+ {
+ clearData(x0, z0, x1, z1, true);
+ }
+}
+
+
+void TileCompressData_SPU::uncompress( uint32_t eaDataOut )
+{
+ unsigned char pScratchArea[33*1024];
+ int outDataSize = sc_size*sc_size*sc_size*3;
+ CompressedTileStorage_SPU ts(pScratchArea);
+ SparseLightStorage_SPU ls(pScratchArea);
+ SparseDataStorage_SPU ds(pScratchArea);
+
+
+ for(int i=0;i= 128-16)
+ {
+ loadAndUncompressUpperSection(0, -2,-2, 0,0);
+ loadAndUncompressUpperSection(1, -2,0, 0,16);
+ loadAndUncompressUpperSection(2, -2,16, 0,18);
+
+ loadAndUncompressUpperSection(3, 0,-2, 16,0);
+ loadAndUncompressUpperSection(4, 0,0, 16,16);
+ loadAndUncompressUpperSection(5, 0,16, 16,18);
+
+ loadAndUncompressUpperSection(6, 16,-2, 18,0);
+ loadAndUncompressUpperSection(7, 16,0, 18,16);
+ loadAndUncompressUpperSection(8, 16,16, 18,18);
+ }
+
+// for(int i=0;i<20*20*20; i++)
+// {
+// m_OutputData.m_data_flags[i] = 0xEE;
+// m_OutputData.m_data_flags[i] = 0xEE;
+// m_OutputData.m_data_flags[i] = 0xEE;
+//
+// if(m_OutputData.m_data_flags[i] == 32)
+// {
+// spu_print("Help! 32 in flags\n");
+// }
+// }
+ DmaData_SPU::putAndWait(m_OutputData.m_tileIds, eaDataOut, outDataSize);
+}
+
+#else
+
+
+void TileCompressData_SPU::setForChunk( Region* region, int x0, int y0, int z0 )
+{
+ m_x0 = x0;
+ m_y0 = y0;
+ m_z0 = z0;
+
+ // we have to grab a 20x20x20 section, so we need 9 chunks in total, the centre chunk and all neighbours in x and z
+ int offsets[3] = {-2, 0, 18};
+ for(int i=0;i<3;i++)
+ {
+ for(int j=0; j<3;j++)
+ {
+ if(y0 <= 127+16)
+ {
+ LevelChunk* pLevelChunk = region->getLevelChunk(m_x0+offsets[i], 0, m_z0+offsets[j]);
+ if(pLevelChunk && !pLevelChunk->isEmpty())
+ {
+ m_lowerBlocks[i*3+j] = pLevelChunk->lowerBlocks->indicesAndData;
+ m_lowerBlocksSize[i*3+j] = pLevelChunk->lowerBlocks->allocatedSize;
+ m_lowerSkyLight[i*3+j] = pLevelChunk->lowerSkyLight->dataAndCount;
+ m_lowerBlockLight[i*3+j] = pLevelChunk->lowerBlockLight->dataAndCount;
+ m_lowerData[i*3+j] = pLevelChunk->lowerData->dataAndCount;
+ }
+ else
+ {
+ m_lowerBlocks[i*3+j] = NULL;
+ m_lowerBlocksSize[i*3+j] = 0;
+ m_lowerSkyLight[i*3+j] = 0;
+ m_lowerBlockLight[i*3+j] = 0;
+ m_lowerData[i*3+j] = 0;
+ }
+ }
+ if(y0 >= 128-16)
+ {
+ LevelChunk* pLevelChunk = region->getLevelChunk(m_x0+offsets[i], 128, m_z0+offsets[j]);
+ if(pLevelChunk && !pLevelChunk->isEmpty())
+ {
+ m_upperBlocks[i*3+j] = pLevelChunk->upperBlocks->indicesAndData;
+ m_upperBlocksSize[i*3+j] = pLevelChunk->upperBlocks->allocatedSize;
+ m_upperSkyLight[i*3+j] = pLevelChunk->upperSkyLight->dataAndCount;
+ m_upperBlockLight[i*3+j] = pLevelChunk->upperBlockLight->dataAndCount;
+ m_upperData[i*3+j] = pLevelChunk->upperData->dataAndCount;
+ }
+ else
+ {
+ m_upperBlocks[i*3+j] = NULL;
+ m_upperBlocksSize[i*3+j] = 0;
+ m_upperSkyLight[i*3+j] = 0;
+ m_upperBlockLight[i*3+j] = 0;
+ m_upperData[i*3+j] = 0;
+ }
+ }
+
+ }
+ }
+}
+
+
+
+#endif
\ No newline at end of file
diff --git a/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTileStorage_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTileStorage_SPU.h
new file mode 100644
index 00000000..51937a87
--- /dev/null
+++ b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTileStorage_SPU.h
@@ -0,0 +1,156 @@
+#pragma once
+
+#include
+
+#include "SparseLightStorage_SPU.h"
+#include "SparseDataStorage_SPU.h"
+
+#ifndef SN_TARGET_PS3_SPU
+#include "..\..\..\stdafx.h"
+#include "..\..\..\..\Minecraft.World\Region.h"
+#endif // SN_TARGET_PS3_SPU
+
+//#include "xmcore.h"
+
+// This class is used for the compressed storage of tile data. Unlike the SparseLightingStorage class, data is split into 512 blocks of 4x4x4 tiles. Then within each block, the
+// data is compressed as described below, with a selection of bits per tile available, in a method similar to a palettised image.
+
+// There are two elements to the storage... an index array (fixed size), and the actual storage required...
+
+// The index:
+// (1) Each index takes up 2 bytes, one for each 4x4x4 block ie 512 X 2 = 1024 bytes in total
+// (2) The type of index is determined by the least significant 2 bits, the other 14 bits represent an offset for the data, stored divided by 2
+// 0 - the data for this block is represented at 1 bit per tile. Data pointed to is 2 bytes describing the 2 possible tiles stored in this block, followed by 32 bytes of data (total 34 bytes)
+// 1 - the data for this block is represented at 2 bit per tile. Data pointed to is 4 bytes describing the 4 possible tiles stored in this block, followed by 64 bytes of data (total 68 bytes)
+// 2 - the data for this block is represented at 4 bit per tile. Data pointed to is 16 bytes describing the 16 possible tiles stored in this block, followed by 128 bytes of data (total 144 bytes)
+// 3 - if bit 2 is 0, then this block is represented at 8 bits per tile. Data pointed to is 64 bytes, offset must be a multiple of 4 (since bit 2 can also be thought of as being
+// the low bit of the offset (divided by 2 as in the other cases), and is zero)
+// - if bit 2 is 1, then this block is represented at 0 bits per tile. The upper 8 bits of the index store the tile value that is used by the entire block.
+// So:
+// oooooooooooooo00 - 1 bit per tile, offset oooooooooooooo0
+// oooooooooooooo01 - 2 bits per tile, offset oooooooooooooo0
+// oooooooooooooo10 - 4 bits per tile, offset oooooooooooooo0
+// ooooooooooooo011 - 8 bits per tile, offset ooooooooooooo00
+// tttttttt-----111 - 0 bits per tile - tile is tttttttt
+
+// Some notes on the logic of all of this...
+// (1) Large numbers of blocks in the world really don't need to be stored at a full 8 bits per tile.
+// In a worst-case scenario, all planes would be 256 bytes and we'd have to store offsets of up to 32704 ( 64 x 511). This would require 15 bits per offset to store, but since in all cases
+// the data can be stored with a 2 byte alignment, we can store offsets divided by 2, freeing up 2 bits to store the type of index for each plane. This allows us to encode 4 types, but we really have
+// 5 types (0, 1, 2, 4 or 8 bits per tile). Since the 8-bit per tile planes are likely to be very rare, we can free up an extra bit in those by making their offset 4-byte aligned, and
+// then use the extra bit to determine whether its a 0 or 8-bit per tile index. In the 0 bit case, we can use the bits used for the offset to store the actual tile value represented throughout the plane.
+// (2) The compression is done per 4x4x4 block rather than planes like the lighting, as that gives many more regions that have a small number of tile types than per plane, and can therefore
+// be compressed using less bits per tile. This is at the expense of a larger index, and more overhead from storing the tile types in each block (since there are more blocks than planes). However
+// on balance this still was found to give much better compression - around 12.5% vs 19% by doing things per plane.
+// (3) Another compromise is being made on how the memory is allocated. This is all currently done with physical allocations to bypass the general heap manager, in particular to allow the freeing
+// of memory to actually free whole memory pages cleanly rather than leaving them as managed by the heap manager. The downside to this is that all storage is done in whole 4K pages. Annoyingly,
+// a lot of our compressed chunks are just on the edge of fitting in 4K, so an awful lot of them end up being 8K when they are just a small amount over. However, in testing absolutely no chunks
+// were seen that got close to going over 8K compressed, so doing things this way then we at least know that we are reliably getting 25% compression, and freeing things up cleanly.
+// Note: see the comments on the getIndex and getBlockAndTile for an explanation of how the blocks themselves are organised in terms of mapping a chunk-wide x/y/z into a block and tile index.
+
+//#define BLOCK_COMPRESSION_STATS
+class CompressedTileStorage_SPU
+{
+private:
+ unsigned char *indicesAndData;
+public:
+ int allocatedSize;
+private:
+
+ static const int INDEX_OFFSET_MASK = 0x7ffe;
+ static const int INDEX_OFFSET_SHIFT = 1;
+ static const int INDEX_TILE_MASK = 0x00ff;
+ static const int INDEX_TILE_SHIFT = 8;
+ static const int INDEX_TYPE_MASK = 0x0003;
+ static const int INDEX_TYPE_1_BIT = 0x0000;
+ static const int INDEX_TYPE_2_BIT = 0x0001;
+ static const int INDEX_TYPE_4_BIT = 0x0002;
+ static const int INDEX_TYPE_0_OR_8_BIT = 0x0003;
+ static const int INDEX_TYPE_0_BIT_FLAG = 0x0004;
+
+ static const unsigned int MM_PHYSICAL_4KB_BASE = 0xE0000000; // Start of where 4KB page sized physical allocations are made
+public:
+ CompressedTileStorage_SPU(unsigned char* data);
+ ~CompressedTileStorage_SPU();
+private:
+ inline static int getIndex(int block, int tile);
+ inline static void getBlockAndTile(int *block, int *tile, int x, int y, int z);
+public:
+ unsigned char* getDataPtr() { return indicesAndData; }
+ int get(int x, int y, int z); // Get an individual tile value
+};
+
+class TileCompressData_SPU
+{
+ static const int sc_size = 20;
+
+public:
+ int m_x0;
+ int m_y0;
+ int m_z0;
+ void* m_lowerBlocks[9];
+ int m_lowerBlocksSize[9];
+ void* m_upperBlocks[9];
+ int m_upperBlocksSize[9];
+
+ int64_t m_lowerSkyLight[9]; // Contains packed-together data pointer (lower 32-bits), and count of lines used (upper 32-bits)
+ int64_t m_lowerBlockLight[9]; // Contains packed-together data pointer (lower 32-bits), and count of lines used (upper 32-bits)
+ int64_t m_upperSkyLight[9]; // Contains packed-together data pointer (lower 32-bits), and count of lines used (upper 32-bits)
+ int64_t m_upperBlockLight[9]; // Contains packed-together data pointer (lower 32-bits), and count of lines used (upper 32-bits)
+
+ int64_t m_lowerData[9]; // Contains packed-together data pointer (lower 32-bits), and count of lines used (upper 32-bits)
+ int64_t m_upperData[9]; // Contains packed-together data pointer (lower 32-bits), and count of lines used (upper 32-bits)
+
+#ifdef SN_TARGET_PS3_SPU
+ void* m_pRegion;
+
+ void uncompress(uint32_t eaOutData);
+
+ void uncompressTiles(int x0, int z0, int x1, int z1, bool upper);
+ void clearTiles(int x0, int z0, int x1, int z1, bool upper);
+
+ void uncompressLights(int x0, int z0, int x1, int z1, bool upper, bool skyLight);
+ void clearLights(int x0, int z0, int x1, int z1, bool upper, bool skyLight);
+
+ void uncompressData(int x0, int z0, int x1, int z1, bool upper);
+ void clearData(int x0, int z0, int x1, int z1, bool upper);
+
+ void dmaSparseStorage(int64_t dataAndSize, unsigned char* pDest);
+
+ void loadAndUncompressLowerSection(int block, int x0, int z0, int x1, int z1);
+ void loadAndUncompressUpperSection(int block, int x0, int z0, int x1, int z1);
+
+ bool validY(int yVal, bool upper)
+ {
+ if(upper)
+ {
+ if(yVal >= 128) return true;
+ }
+ else
+ {
+ if(yVal <= 127) return true;
+ }
+ return false;
+ }
+
+ class OutputData
+ {
+ public:
+ unsigned char m_tileIds[sc_size*sc_size*sc_size]; // byte
+ unsigned char m_brightness[sc_size*sc_size*sc_size]; // 2x 4bit
+ unsigned char m_data_flags[sc_size*sc_size*sc_size]; // 2x 4bit
+ };
+
+ static OutputData m_OutputData;
+ static CompressedTileStorage_SPU* m_pTileStorage;
+ static SparseLightStorage_SPU* m_pLightStorage;
+ static SparseDataStorage_SPU* m_pDataStorage;
+#else
+ Region* m_pRegion;
+
+ void setForChunk( Region* region, int x0, int y0, int z0 );
+#endif // SN_TARGET_PS3_SPU
+
+ int padding[3];
+
+};
diff --git a/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile_main.cpp b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile_main.cpp
new file mode 100644
index 00000000..b25e04e0
--- /dev/null
+++ b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/CompressedTile_main.cpp
@@ -0,0 +1,63 @@
+/* SCE CONFIDENTIAL
+PlayStation(R)3 Programmer Tool Runtime Library 430.001
+* Copyright (C) 2007 Sony Computer Entertainment Inc.
+* All Rights Reserved.
+*/
+
+/* common headers */
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "CompressedTileStorage_SPU.h"
+#include "..\Common\DmaData.h"
+
+// #define SPU_HEAPSIZE (128*1024)
+// #define SPU_STACKSIZE (16*1024)
+//
+// CELL_SPU_LS_PARAM(128*1024, 16*1024); // can't use #defines here as it seems to create an asm instruction
+
+
+static const bool sc_verbose = false;
+
+CellSpursJobContext2* g_pSpursJobContext;
+
+void cellSpursJobQueueMain(CellSpursJobContext2 *pContext, CellSpursJob256 *pJob)
+{
+// CellSpursTaskId idTask = cellSpursGetTaskId();
+ unsigned int idSpu = cellSpursGetCurrentSpuId();
+
+ if(sc_verbose)
+ spu_print("CompressedTile [SPU#%u] start\n", idSpu);
+
+ g_pSpursJobContext = pContext;
+// void* pVolatileMem = NULL;
+// uint32_t volatileSize = 0;
+// ret = cellSpursGetTaskVolatileArea(&pVolatileMem, &volatileSize);
+// spu_print( "----------------- CompressedTile SPU Memory ------------------\n"
+// "Stack : %dKb\n"
+// "Heap : %dKb\n"
+// "Prog : %dKb\n"
+// "Free : %dKb\n"
+// "-------------------------------------------------------------\n",
+// SPU_STACKSIZE/1024,
+// SPU_HEAPSIZE/1024,
+// 256 - ((SPU_HEAPSIZE+SPU_STACKSIZE+volatileSize)/1024),
+// volatileSize/1024);
+
+
+// uint32_t eaEventFlag = spu_extract((vec_uint4)argTask, 0);
+ uint32_t eaDataIn = pJob->workArea.userData[0];
+ uint32_t eaDataOut =pJob->workArea.userData[1];
+
+ TileCompressData_SPU compressedData;// = new TileCompressData_SPU;
+ DmaData_SPU::getAndWait(&compressedData, eaDataIn, sizeof(TileCompressData_SPU));
+ compressedData.uncompress(eaDataOut);
+
+ if(sc_verbose)
+ spu_print("CompressedTile [SPU#%u] exit\n", idSpu);
+}
+
diff --git a/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseDataStorage_SPU.cpp b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseDataStorage_SPU.cpp
new file mode 100644
index 00000000..3b2f8e17
--- /dev/null
+++ b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseDataStorage_SPU.cpp
@@ -0,0 +1,5 @@
+#include "stdafx.h"
+#include "SparseDataStorage_SPU.h"
+
+
+
diff --git a/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseDataStorage_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseDataStorage_SPU.h
new file mode 100644
index 00000000..30266d7f
--- /dev/null
+++ b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseDataStorage_SPU.h
@@ -0,0 +1,75 @@
+#pragma once
+
+// 4J added - Storage for data (ie the extra per tile storage). Data is normally stored as 4-bits per tile, in a DataLayer class of 16384 bytes ( 128 x 16 x 16 x 0.5 )
+// This class provides more economical storage for such data by taking into consideration that it is quite common for large parts of the data to be very compressible (ie zero).
+// We are aiming here to balance performance (this data is accessed very frequently) against size.
+
+// Details of storage method:
+
+// 1. Data is split into horizontal planes, of which there are 128, and each taking up 128 bytes (16 x 16 x 0.5)
+// 2. Each of these layers has a permanently allocated index in this class (planeIndices).
+// 3. Data for allocatedPlaneCount planes worth of data is allocated in the data array ( allocatedPlaneCount * 128 bytes )
+// 4. If a plane index for a layer is < 128, then the data for that layer is at data[ index * 128 ]
+// 5. If a plane index for a layer is 128, then all values for that plane are 0
+
+// This class needs to be thread safe as there are times where chunk data is shared between server & main threads. Data values are queried
+// very regularly so this needs to be as light-weight as possible.
+
+// To meet these requirements, this class is now implemented using a lock-free system, implemented using a read-copy-update (RCU) type algorithm. Some details...
+
+// (1) The storage details for the class are now packed into a single __int64, which contains both a pointer to the data that is required and a count of how many planes worth
+// of storage are allocated. This allows the full storage to be updated atomically using compare and exchange operations (implemented with InterlockedCompareExchangeRelease64).
+// (2) The data pointer referenced in this __int64 points to an area of memory which is 128 + 128 * plane_count bytes long, where the first 128 bytes stoere the plane indices, and
+// the rest of the data is variable in size to accomodate however many planes are required to be stored
+// (3) The RCU bit of the algorithm means that any read operations don't need to do any checks or locks at all. When the data needs to be updated, a copy of it is made and updated,
+// then an attempt is made to swap the new data in - if this succeeds then the old data pointer is deleted later at some point where we know nothing will be reading from it anymore.
+// This is achieved by putting the delete request in a queue which means it won't actually get deleted until 2 game ticks after the last time its reference existed, which should give
+// us a large margin of safety. If the attempt to swap the new data in fails, then the whole write operation has to be attempted again - this is the only time there is really a
+// high cost for this algorithm and such write collisions should be rare.
+
+//#define DATA_COMPRESSION_STATS
+
+class SparseDataStorage_SPU
+{
+private:
+// unsigned char planeIndices[128];
+ unsigned char* m_pData;
+
+// unsigned char *data;
+// unsigned int allocatedPlaneCount;
+
+ static const int ALL_0_INDEX = 128;
+
+public:
+ SparseDataStorage_SPU(unsigned char* data) : m_pData(data) {}
+
+ unsigned char* getDataPtr() { return m_pData; }
+
+ int get(int x, int y, int z) // Get an individual data value
+ {
+ unsigned char *planeIndices, *data;
+ getPlaneIndicesAndData(&planeIndices, &data);
+
+ if( planeIndices[y] == ALL_0_INDEX )
+ {
+ return 0;
+ }
+ else
+ {
+ int planeIndex = x * 16 + z; // Index within this xz plane
+ int byteIndex = planeIndex / 2; // Byte index within the plane (2 tiles stored per byte)
+ int shift = ( planeIndex & 1 ) * 4; // Bit shift within the byte
+ int retval = ( data[ planeIndices[y] * 128 + byteIndex ] >> shift ) & 15;
+
+ return retval;
+ }
+ }
+
+ void getPlaneIndicesAndData(unsigned char **planeIndices, unsigned char **data)
+ {
+ *planeIndices = m_pData;
+ *data = m_pData + 128;
+ }
+
+};
+
diff --git a/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseLightStorage_SPU.cpp b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseLightStorage_SPU.cpp
new file mode 100644
index 00000000..9221eb1b
--- /dev/null
+++ b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseLightStorage_SPU.cpp
@@ -0,0 +1,6 @@
+#include "stdafx.h"
+#include "SparseLightStorage_SPU.h"
+
+
+
+
diff --git a/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseLightStorage_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseLightStorage_SPU.h
new file mode 100644
index 00000000..01b2aa6e
--- /dev/null
+++ b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/SparseLightStorage_SPU.h
@@ -0,0 +1,83 @@
+#pragma once
+#include
+
+// 4J added - Storage for block & sky light data. Lighting data is normally stored as 4-bits per tile, in a DataLayer class of 16384 bytes ( 128 x 16 x 16 x 0.5 )
+// This class provides more economical storage for such data by taking into consideration that it is quite common for large parts of the lighting data in a level to
+// be very compressible (large amounts of 0 for block lights, 0 and 15 for sky lights).
+// We are aiming here to balance performance (lighting data is accessed very frequently) against size.
+
+// Details of storage method:
+
+// 1. Lighting is split into horizontal planes, of which there are 128, and each taking up 128 bytes (16 x 16 x 0.5)
+// 2. Each of these layers has a permanently allocated index in this class (planeIndices).
+// 3. Data for allocatedPlaneCount planes worth of data is allocated in the data array ( allocatedPlaneCount * 128 bytes )
+// 4. If a plane index for a layer is < 128, then the data for that layer is at data[ index * 128 ]
+// 5. If a plane index for a layer is 128, then all values for that plane are 0
+// 6. If a plane index for a layer is 129, then all values for that plane are 15
+
+// This class needs to be thread safe as there are times where chunk (and light) data are shared between server & main threads. Light values are queried
+// very regularly so this needs to be as light-weight as possible.
+
+// To meet these requirements, this class is now implemented using a lock-free system, implemented using a read-copy-update (RCU) type algorithm. Some details...
+
+// (1) The storage details for the class are now packed into a single __int64, which contains both a pointer to the data that is required and a count of how many planes worth
+// of storage are allocated. This allows the full storage to be updated atomically using compare and exchange operations (implemented with InterlockedCompareExchangeRelease64).
+// (2) The data pointer referenced in this __int64 points to an area of memory which is 128 + 128 * plane_count bytes long, where the first 128 bytes stoere the plane indices, and
+// the rest of the data is variable in size to accomodate however many planes are required to be stored
+// (3) The RCU bit of the algorithm means that any read operations don't need to do any checks or locks at all. When the data needs to be updated, a copy of it is made and updated,
+// then an attempt is made to swap the new data in - if this succeeds then the old data pointer is deleted later at some point where we know nothing will be reading from it anymore.
+// This is achieved by putting the delete request in a queue which means it won't actually get deleted until 2 game ticks after the last time its reference existed, which should give
+// us a large margin of safety. If the attempt to swap the new data in fails, then the whole write operation has to be attempted again - this is the only time there is really a
+// high cost for this algorithm and such write collisions should be rare.
+
+//#define LIGHT_COMPRESSION_STATS
+
+class SparseLightStorage_SPU
+{
+private:
+// unsigned char planeIndices[128];
+ unsigned char* m_pData;
+
+// unsigned char *data;
+// unsigned int allocatedPlaneCount;
+
+ static const int ALL_0_INDEX = 128;
+ static const int ALL_15_INDEX = 129;
+public:
+ SparseLightStorage_SPU(unsigned char* data) : m_pData(data) {}
+
+ unsigned char* getDataPtr() { return m_pData; }
+
+ inline int get(int x, int y, int z) // Get an individual lighting value
+ {
+ unsigned char *planeIndices, *data;
+ getPlaneIndicesAndData(&planeIndices, &data);
+
+ if( planeIndices[y] == ALL_0_INDEX )
+ {
+ return 0;
+ }
+ else if ( planeIndices[y] == ALL_15_INDEX )
+ {
+ return 15;
+ }
+ else
+ {
+ int planeIndex = x * 16 + z; // Index within this xz plane
+ int byteIndex = planeIndex / 2; // Byte index within the plane (2 tiles stored per byte)
+ int shift = ( planeIndex & 1 ) * 4; // Bit shift within the byte
+ int retval = ( data[ planeIndices[y] * 128 + byteIndex ] >> shift ) & 15;
+
+ return retval;
+ }
+ }
+
+
+ inline void getPlaneIndicesAndData(unsigned char **planeIndices, unsigned char **data)
+ {
+ *planeIndices = m_pData;
+ *data = m_pData + 128;
+ }
+
+};
+
diff --git a/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/stdafx.h b/Minecraft.Client/PS3/SPU_Tasks/CompressedTile/stdafx.h
new file mode 100644
index 00000000..e69de29b
--
cgit v1.2.3