Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion code/rle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ int RLEEngine::Compress(void const * source, void * dest, int length) const
** Count the number of transparent pixels in this run.
*/
int runcount = 0;
while (sptr[runcount] == '\0' && runcount <= length) {
while (runcount < length && sptr[runcount] == '\0') {
runcount++;
}

Expand Down
9 changes: 7 additions & 2 deletions code/stbuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "rle.h"
#include "surface.h"
#include "voxdrsys.h"

#include <cstring>

Expand Down Expand Up @@ -44,8 +45,12 @@ StaticBufferClass::~StaticBufferClass(void)
}
}

static char CompressionBuffer[256];

/*
* A 256-pixel voxel row can expand when RLE encodes isolated transparent pixels:
* each such pixel takes two bytes, plus the row's length prefix. Reserve twice
* the voxel-buffer width so every cached voxel row fits.
*/
static char CompressionBuffer[2 * VOXEL_BITMAP_WIDTH];

/// <summary>
/// Adds a compressed copy of a surface region to the buffer.
Expand Down
98 changes: 8 additions & 90 deletions code/voxdrsys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#include "voxlib.h"
#include "wwfile.h"

#include <algorithm>
#include <iterator>

BOOL VoxelDrawSystem::EnableLighting;
BOOL VoxelDrawSystem::EnableZBuffer;

Expand All @@ -29,8 +32,6 @@ BSurface VoxelZSurface(VOXEL_BITMAP_WIDTH, VOXEL_BITMAP_HEIGHT, VOXEL_BITMAP_BPP
Vector3 MinVoxelBounds;
Vector3 MaxVoxelBounds;

Rect LastRenderRect(0,0,VOXEL_BITMAP_WIDTH-1, VOXEL_BITMAP_HEIGHT-1);

VoxelRenderStruct VoxelRenderData[64];
VoxelShadowRenderStruct VoxelShadowRenderData[64];

Expand Down Expand Up @@ -176,31 +177,13 @@ void VoxelDrawSystem::Precalculate_Light(VoxelLibrary * voxlib, int layer, int i
/// <remarks>Forget this routine and the previous object is still sitting in the buffer.</remarks>
void VoxelDrawSystem::Reset(void)
{
static int _need_buffer_init = true;

VoxelRenderDataCount = 0;
VoxelShadowRenderDataCount = 0;

if (_need_buffer_init) {
Clear_Buffer();
/* Cached images must never retain a pixel outside a previous render's bounds. */
Clear_Buffer();
if (VoxelDrawSystem::EnableZBuffer) {
Clear_Z_Buffer();
_need_buffer_init = false;
} else {
//Clear_Buffer(VoxelRect.X, VoxelRect.Y, VoxelRect.Width, VoxelRect.Height);
if (LastRenderRect.X >= 0 && LastRenderRect.Y >= 0 && LastRenderRect.X + LastRenderRect.Width <= VOXEL_BITMAP_WIDTH-1 && LastRenderRect.Y + LastRenderRect.Height <= VOXEL_BITMAP_HEIGHT-1) {
for (int i = LastRenderRect.Y; i <= LastRenderRect.Y + LastRenderRect.Height; i++) {
memset(&VoxelDrawBuffer[VOXEL_BITMAP_HEIGHT * i + LastRenderRect.X], 0, LastRenderRect.Width + 1);
}
} else {
memset(VoxelDrawBuffer, 0, sizeof(VoxelDrawBuffer));
}
if (VoxelDrawSystem::EnableZBuffer) {
if (LastRenderRect.Y <= LastRenderRect.Height + LastRenderRect.Y) {
for (int i = LastRenderRect.Y; i <= LastRenderRect.Y + LastRenderRect.Height; i++) {
memset(&VoxelDrawZBuffer[VOXEL_BITMAP_HEIGHT * i + LastRenderRect.X], 0, LastRenderRect.Width + 1);
}
}
}
}

MinVoxelBounds = Vector3(10000, 10000, 10000);
Expand Down Expand Up @@ -378,7 +361,6 @@ void VoxelDrawSystem::Render(Rect & rect, int & x, int & y)

rect.X -= 4;
rect.Y -= 4;
LastRenderRect = rect;

x = (int)center.X - rect.Width / 2;
y = (int)center.Y - rect.Height / 2;
Expand Down Expand Up @@ -434,8 +416,6 @@ SurfaceRegion VoxelDrawSystem::Render(void)
int width = MaxVoxelBounds.X - MinVoxelBounds.X;
int height = MaxVoxelBounds.Y - MinVoxelBounds.Y;

LastRenderRect = Rect(VOXEL_BITMAP_WIDTH / 2 - width / 2 - 4, VOXEL_BITMAP_HEIGHT / 2 - height / 2 - 4, width + 8, height + 8);

SurfaceRegion region;
region.Point.X = (int)center.X - (width + 8) / 2;
region.Point.Y = (int)center.Y - (height + 8) / 2;
Expand All @@ -453,43 +433,7 @@ SurfaceRegion VoxelDrawSystem::Render(void)
/// </summary>
void VoxelDrawSystem::Clear_Buffer(void)
{
memset(VoxelDrawBuffer, 0, sizeof(VoxelDrawBuffer));
}


/// <summary>
/// Clears a rectangle of the voxel drawing buffer.
/// This routine is used to wipe only the part of the buffer that a drawn object occupied.
/// A rectangle that would stray outside the voxel bitmap is treated as a request to clear
/// the whole buffer.
/// </summary>
void VoxelDrawSystem::Clear_Buffer(int x, int y, int width, int height)
{
if (x >= 0 && y >= 0 && x + width <= VOXEL_BITMAP_WIDTH-1 && y + height <= VOXEL_BITMAP_HEIGHT-1) {
for (int i = y; i <= y + height; i++) {
memset(&VoxelDrawBuffer[VOXEL_BITMAP_HEIGHT * i + x], 0, width);
}
} else {
memset(VoxelDrawBuffer, 0, sizeof(VoxelDrawBuffer));
}
}


/// <summary>
/// Clears a region of the voxel drawing buffer.
/// This routine is used to wipe only the part of the buffer that a drawn object occupied.
/// A region that would stray outside the voxel bitmap is treated as a request to clear
/// the whole buffer.
/// </summary>
void VoxelDrawSystem::Clear_Buffer(SurfaceRegion & region)
{
if (region.Point.X >= 0 && region.Point.Y >= 0 && region.Point.X + region.Bounds.X <= VOXEL_BITMAP_WIDTH-1 && region.Point.Y + region.Bounds.Y <= VOXEL_BITMAP_HEIGHT-1) {
for (int i = region.Point.Y; i <= region.Point.Y + region.Bounds.Y; i++) {
memset(&VoxelDrawBuffer[VOXEL_BITMAP_HEIGHT * i + region.Point.X], 0, region.Bounds.X+1);
}
} else {
memset(VoxelDrawBuffer, 0, sizeof(VoxelDrawBuffer));
}
std::fill(std::begin(VoxelDrawBuffer), std::end(VoxelDrawBuffer), 0);
}


Expand All @@ -498,31 +442,5 @@ void VoxelDrawSystem::Clear_Buffer(SurfaceRegion & region)
/// </summary>
void VoxelDrawSystem::Clear_Z_Buffer(void)
{
memset(VoxelDrawZBuffer, 0, sizeof(VoxelDrawZBuffer));
}


/// <summary>
/// Clears a rectangle of the voxel depth buffer.
/// This routine is used to wipe only the part of the depth buffer that a drawn object
/// occupied, which is cheaper than erasing the whole thing between objects.
/// </summary>
void VoxelDrawSystem::Clear_Z_Buffer(int x, int y, int width, int height)
{
for (int i = y; i <= y + height; i++) {
memset(&VoxelDrawZBuffer[VOXEL_BITMAP_HEIGHT * i + x], 0, width);
}
}


/// <summary>
/// Clears a region of the voxel depth buffer.
/// This routine is used to wipe only the part of the depth buffer that a drawn object
/// occupied, which is cheaper than erasing the whole thing between objects.
/// </summary>
void VoxelDrawSystem::Clear_Z_Buffer(SurfaceRegion & region)
{
for (int i = region.Point.Y; i <= region.Point.Y + region.Bounds.Y; i++) {
memset(&VoxelDrawZBuffer[VOXEL_BITMAP_HEIGHT * i + region.Point.X], 0, region.Bounds.X+1);
}
std::fill(std::begin(VoxelDrawZBuffer), std::end(VoxelDrawZBuffer), 0);
}
4 changes: 0 additions & 4 deletions code/voxdrsys.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,8 @@ namespace VoxelDrawSystem
SurfaceRegion Render(void);

void Clear_Buffer(void);
void Clear_Buffer(int x, int y, int width, int height);
void Clear_Buffer(SurfaceRegion & region);

void Clear_Z_Buffer(void);
void Clear_Z_Buffer(int x, int y, int width, int height);
void Clear_Z_Buffer(SurfaceRegion & region);
};


Expand Down
48 changes: 24 additions & 24 deletions code/voxlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
#include "wwfile.h"

#include <algorithm>
#include <climits>


short VoxelPixelDeltaTable[VOXEL_BITMAP_WIDTH][2];
unsigned char VoxelNormalTranslateTable[VOXEL_PALETTE_SIZE];
Expand Down Expand Up @@ -820,22 +818,22 @@ void VoxelLibrary::Render_Object(VoxelRenderStruct & voxel, Vector3 & center)

/// The drawer sums these deltas down the length of the model, so an error of
/// one unit here becomes one unit per voxel by the far end.
arg.TransformMatrix[0].I = short(float((double)corner_0.X + 128 - (double)center.X) * 256);
arg.TransformMatrix[0].J = short(float((double)corner_0.Y + 128 - (double)center.Y) * 256);
arg.TransformMatrix[0].K = short(float((double)corner_0.Z + 128 - (double)center.Z) * 256);
arg.TransformMatrix[0].I = static_cast<unsigned short>(static_cast<int>(((double)corner_0.X + 128 - (double)center.X) * 256.0));
arg.TransformMatrix[0].J = static_cast<unsigned short>(static_cast<int>(((double)corner_0.Y + 128 - (double)center.Y) * 256.0));
arg.TransformMatrix[0].K = static_cast<unsigned short>(static_cast<int>(((double)corner_0.Z + 128 - (double)center.Z) * 256.0));

arg.TransformMatrix[1].I = short(float(corner_x.X - corner_0.X) / (double)x_size * 256);
arg.TransformMatrix[2].I = short(float(corner_y.X - corner_0.X) / (double)y_size * 256);
arg.TransformMatrix[3].I = short(float(corner_z.X - corner_0.X) / (double)z_size * 256);
arg.TransformMatrix[1].I = static_cast<unsigned short>(static_cast<int>((corner_x.X - corner_0.X) / (double)x_size * 256.0));
arg.TransformMatrix[2].I = static_cast<unsigned short>(static_cast<int>((corner_y.X - corner_0.X) / (double)y_size * 256.0));
arg.TransformMatrix[3].I = static_cast<unsigned short>(static_cast<int>((corner_z.X - corner_0.X) / (double)z_size * 256.0));

arg.TransformMatrix[1].J = short(float(corner_x.Y - corner_0.Y) / (double)x_size * 256);
arg.TransformMatrix[2].J = short(float(corner_y.Y - corner_0.Y) / (double)y_size * 256);
arg.TransformMatrix[3].J = short(float(corner_z.Y - corner_0.Y) / (double)z_size * 256);
arg.TransformMatrix[1].J = static_cast<unsigned short>(static_cast<int>((corner_x.Y - corner_0.Y) / (double)x_size * 256.0));
arg.TransformMatrix[2].J = static_cast<unsigned short>(static_cast<int>((corner_y.Y - corner_0.Y) / (double)y_size * 256.0));
arg.TransformMatrix[3].J = static_cast<unsigned short>(static_cast<int>((corner_z.Y - corner_0.Y) / (double)z_size * 256.0));

if (VoxelDrawSystem::EnableZBuffer) {
arg.TransformMatrix[1].K = short(float(corner_x.Z - corner_0.Z) / (double)x_size * 256);
arg.TransformMatrix[2].K = short(float(corner_y.Z - corner_0.Z) / (double)y_size * 256);
arg.TransformMatrix[3].K = short(float(corner_z.Z - corner_0.Z) / (double)z_size * 256);
arg.TransformMatrix[1].K = static_cast<unsigned short>(static_cast<int>((corner_x.Z - corner_0.Z) / (double)x_size * 256.0));
arg.TransformMatrix[2].K = static_cast<unsigned short>(static_cast<int>((corner_y.Z - corner_0.Z) / (double)y_size * 256.0));
arg.TransformMatrix[3].K = static_cast<unsigned short>(static_cast<int>((corner_z.Z - corner_0.Z) / (double)z_size * 256.0));
}

int funcnum = VoxelRenderOrientations[orientation].Reversed;
Expand Down Expand Up @@ -936,14 +934,14 @@ void VoxelLibrary::Render_Shadow(VoxelShadowRenderStruct & voxel, Vector3 & cent
arg.StrideY = x_size;
arg.StartIndex = 0;

arg.TransformMatrix[0].I = short(float(corner_0.X + 128 - center.X) * 256);
arg.TransformMatrix[0].J = short(float(corner_0.Y + 128 - center.Y) * 256);
arg.TransformMatrix[0].I = static_cast<unsigned short>(static_cast<int>((corner_0.X + 128 - center.X) * 256.0));
arg.TransformMatrix[0].J = static_cast<unsigned short>(static_cast<int>((corner_0.Y + 128 - center.Y) * 256.0));

arg.TransformMatrix[1].I = short(float(corner_x.X - corner_0.X) / x_size * 256);
arg.TransformMatrix[2].I = short(float(corner_y.X - corner_0.X) / y_size * 256);
arg.TransformMatrix[1].I = static_cast<unsigned short>(static_cast<int>((corner_x.X - corner_0.X) / x_size * 256.0));
arg.TransformMatrix[2].I = static_cast<unsigned short>(static_cast<int>((corner_y.X - corner_0.X) / y_size * 256.0));

arg.TransformMatrix[1].J = short(float(corner_x.Y - corner_0.Y) / x_size * 256);
arg.TransformMatrix[2].J = short(float(corner_y.Y - corner_0.Y) / y_size * 256);
arg.TransformMatrix[1].J = static_cast<unsigned short>(static_cast<int>((corner_x.Y - corner_0.Y) / x_size * 256.0));
arg.TransformMatrix[2].J = static_cast<unsigned short>(static_cast<int>((corner_y.Y - corner_0.Y) / y_size * 256.0));

_voxel_draw_shadow(&arg);
}
Expand Down Expand Up @@ -1989,8 +1987,9 @@ void __cdecl Draw_Voxel_Regular(VoxelFuncArgumentStruct * state)
ptr++;

/// Compute buffer index and write color
VoxelDrawBuffer[(pixel_x >> 8) | (pixel_y & 0xFF00)] = color_index;
VoxelDrawBuffer[(pixel_x >> 8) | (pixel_y & 0xFF00) + 1] = color_index;
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
VoxelDrawBuffer[buffer_index] = color_index;
VoxelDrawBuffer[buffer_index + 1] = color_index;

pixel_x += state->TransformMatrix[3].I;
pixel_y += state->TransformMatrix[3].J;
Expand Down Expand Up @@ -2069,8 +2068,9 @@ void __cdecl Draw_Voxel_Reverse(VoxelFuncArgumentStruct * state)
ptr--;

/// Compute buffer index and write color
VoxelDrawBuffer[(pixel_x >> 8) | (pixel_y & 0xFF00)] = color_index;
VoxelDrawBuffer[(pixel_x >> 8) | (pixel_y & 0xFF00) + 1] = color_index;
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
VoxelDrawBuffer[buffer_index] = color_index;
VoxelDrawBuffer[buffer_index + 1] = color_index;

pixel_x += state->TransformMatrix[3].I;
pixel_y += state->TransformMatrix[3].J;
Expand Down
Loading