Mismatched texture on bottom of wall in start dungeon
In Arena it appears to use *BOXCAP 8 in START.INF which is WALLF.SET for the texture on the bottom of walls.
Not sure how to replicate this as my loading code only knows about one texture ID for all faces of the wall (ignore the different water shading, that is intentional in this engine). This problem also extends to the roof of buildings, it's hard to know what it should be because Arena locks the camera below the top of the Y=1 block.
https://github.com/afritz1/OpenTESArena/blob/b320aa80e90ce2bb36c6af09d36a717c173db993/OpenTESArena/src/World/MapGeneration.cpp#L487
void writeVoxelInfoForMAP1(ArenaTypes::VoxelID map1Voxel, uint8_t mostSigNibble, MapType mapType, const INFFile &inf,
const ExeData &exeData, ArenaTypes::VoxelType *outVoxelType, ArenaMeshUtils::ShapeInitCache *outShapeInitCache,
TextureAsset *outTextureAsset0, TextureAsset *outTextureAsset1, TextureAsset *outTextureAsset2, bool *outIsCollider,
VoxelFacing2D *outFacing)
{
DebugAssert(map1Voxel != 0);
DebugAssert(mostSigNibble != 0x8);
if ((map1Voxel & 0x8000) == 0)
{
const uint8_t mostSigByte = ArenaLevelUtils::getVoxelMostSigByte(map1Voxel);
const uint8_t leastSigByte = ArenaLevelUtils::getVoxelLeastSigByte(map1Voxel);
const bool voxelIsSolid = mostSigByte == leastSigByte;
if (voxelIsSolid)
{
// Regular solid wall.
*outVoxelType = ArenaTypes::VoxelType::Wall;
outShapeInitCache->initDefaultBoxValues();
ArenaMeshUtils::WriteWallRendererGeometryBuffers(outShapeInitCache->verticesView, outShapeInitCache->normalsView, outShapeInitCache->texCoordsView);
ArenaMeshUtils::WriteWallRendererIndexBuffers(outShapeInitCache->opaqueIndices0View, outShapeInitCache->opaqueIndices1View, outShapeInitCache->opaqueIndices2View);
const int textureIndex = mostSigByte - 1;
const int clampedTextureID = ArenaVoxelUtils::clampVoxelTextureID(textureIndex);
std::string voxelTextureFilename = ArenaVoxelUtils::getVoxelTextureFilename(clampedTextureID, inf);
const std::optional<int> voxelTextureSetIndex = ArenaVoxelUtils::getVoxelTextureSetIndex(clampedTextureID, inf);
*outTextureAsset0 = TextureAsset(std::move(voxelTextureFilename), voxelTextureSetIndex);
*outTextureAsset1 = *outTextureAsset0;
*outTextureAsset2 = *outTextureAsset0;
The original game had quite a few bugs, and you are surely going to fix some of them by accident in a modern reimplimentation. Any chance that is happening here? The second screenshot looks more correct.
This problem also affects the tops of buildings which currently copy the side texture, allowing things like a window on the roof which doesn't look right. It's tough because Arena clamps the camera from being able to see which texture is on a rooftop. I don't think the original logic has been added to the wiki by anyone yet.
I wonder if you could just create another object very thin with the proper ceiling/roof texture below/above the existing one. It's a bit of a hacky solution, but if it's possible to basically make a textured plane, that could maintain work?
The geometry is fine as-is, it's just the texture filename logic that's not matching Arena.
I wasn't able to find out so far what texture is used for the bottoms of walls. I will try to investigate it soon.
I'd love to see anything you can find. I tried out ghidra for the first time last night and was bewildered for a few hours, that kind of work is not for me!
It's possible the game is reading uninitialized memory, and whatever DOS or DOSBox have there is being interpreted as the above texture.
It seems it uses the texture in slot 46, don't know why yet.