Sign in to follow this  
  • entries
    122
  • comments
    121
  • views
    68497

Wrapping world display

Sign in to follow this  

215 views

I just finished adding a wrap-around functionality to World::Draw(), with a boolean parameter to enable it. It was actually a lot simpler than I thought it would be. In the previous version, without wrapping support, I had to clip the SMALL_RECT parameter entirely down to [0, width) and [0, height). In this version, I put the clipping code in an if-statement, only to be run if the wrap flag is false. Within the loops that map each World buffer index to a temporary buffer, I calculate the indexes with modulo, and if it's a negative result, I subtract it from width/height (because it's already floored down to that range). Here's the final code:


BOOL World::Draw(SMALL_RECT& clip, COORD drawloc, bool wrap) const
{
if (clip.Left > clip.Right || clip.Top > clip.Bottom)
throw std::exception("Bottom/Right cannot be greater than Top/Left!");

if (!wrap)
{
if (clip.Left < 0) clip.Left = 0;
if (clip.Top < 0) clip.Top = 0;
if (clip.Right >= width) clip.Right = width - 1;
if (clip.Bottom >= height) clip.Bottom = height - 1;
}

int view_width = (clip.Right - clip.Left + 1), view_height = (clip.Bottom - clip.Top + 1);

if (view_width == 0 || view_height == 0)
throw std::exception("Viewing dimensions too small.");

CHAR_INFO* buf = new CHAR_INFO[view_width*view_height];

for (int y = 0; y < view_height; ++y)
{
for (int x = 0; x < view_width; ++x)
{
int world_x = (x + clip.Left) % width,
world_y = (y + clip.Top) % height;

if (world_x < 0) world_x += width;
if (world_y < 0) world_y += height;

buf[x+(y*view_width)].Attributes = buffer[world_x+(world_y*width)].Attributes;
buf[x+(y*view_width)].Char = buffer[world_x+(world_y*width)].Char;
}
}

SMALL_RECT writeloc = {drawloc.X, drawloc.Y, view_width+drawloc.X-1, view_height+drawloc.Y-1};
COORD bufsize = {view_width, view_height};
COORD origin = {0, 0};

BOOL retval = WriteConsoleOutput(screen, buf, bufsize, origin, &writeloc);
delete buf;
return retval;
}






I also noticed this time around that I had a memory leak on the last line. Originally I was just returning the return value of WriteConsoleOutput(), but I had completely forgotten to delete[] the temporary buffer I passed to it. The last three lines here solved that.

So it wasn't nearly as hard as I thought it would be. Awesome!

~Jonathan
Sign in to follow this  


3 Comments


Recommended Comments

Dunno if the above is a copy-paste from your actual code, but you're calling


delete buf;

// instead of

delete [] buf;


I guess since you correctly mentioned delete[] in your post that this is just in the journal code.

Good to see text adventures alive and well. Always been a passion of mine.

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now