Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


#ActualServant of the Lord

Posted 01 January 2013 - 11:32 AM

Flickering problem:

 

It has to do with 'system("cls")', yes. The command console isn't made for real-time graphics, so that flickering is kinda unavoidable. I'd just leave it as is.

 

I say 'kinda' unavoidable, because you *can* fix it, but it'd almost require redoing your entire game using some slightly more advanced features. It'd be better to use those "more advanced" features for your next game that you start from scratch, in my opinion.

 

But, here's how you do it:

std::cout is standard C++. The command console that std::cout happens to be printing to (in this situation; but it can print whereever you tell it to) is Microsoft Windows's command console. Other operating systems have their own consoles.

 

So standard C++ has std::cout. 'system("cls")' isn't standard C++ either. system() is standard, but 'cls' is actually starting a separate program that clears your command console. This is why it's so slow - it loads up an entirely new program, runs it, then closes it. Because it's slow, the delay between clearing the screen and your next draw is noticeable as an unwanted flickering.

 

So how can that be avoided? You can use non-standard Microsoft functions to interact with Microsoft's command console yourself, instead of calling another program to do so. These Microsoft functions let you: Set the color of individual characters (A huge selection of 16 colors! happy.png), use the mouse and find out what character the mouse is over or clicked on, and *manually place letters where you want on the console, instead of placing entire lines at a time*.

 

The downside is that the functions are a bit complicated and ugly. I haven't used them in over four years, but here's the old code I was using back then (I wrapped them in convenience functions):

 

Console.h

 

#include <windows.h> 
 
#ifndef TEXT_CONSOLE_H
#define TEXT_CONSOLE_H
 
#ifndef MOUSE_HWHEELED
#define MOUSE_HWHEELED 0x0008
#endif
#define MOUSE_CLICK 0
 
#define COLOR_WHITE (FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY)
#define COLOR_GREY (FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN)
#define COLOR_DARKGREY (0|FOREGROUND_INTENSITY)
#define COLOR_BLACK (0)
#define COLOR_CYAN (FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY)
#define COLOR_AQUA (FOREGROUND_BLUE|FOREGROUND_GREEN)
#define COLOR_YELLOW (FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY)
#define COLOR_GOLD (FOREGROUND_RED|FOREGROUND_GREEN)
#define COLOR_MAGENTA (FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY)
#define COLOR_PURPLE (FOREGROUND_RED|FOREGROUND_BLUE)
#define COLOR_DARKBLUE (FOREGROUND_BLUE)
#define COLOR_BLUE (FOREGROUND_BLUE|FOREGROUND_INTENSITY)
#define COLOR_DARKGREEN (FOREGROUND_GREEN)
#define COLOR_GREEN (FOREGROUND_GREEN|FOREGROUND_INTENSITY)
#define COLOR_DARKRED (FOREGROUND_RED)
#define COLOR_RED (FOREGROUND_RED|FOREGROUND_INTENSITY)
 
#define BG_COLOR_WHITE (BACKGROUND_RED|BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_INTENSITY)
#define BG_COLOR_GREY (BACKGROUND_RED|BACKGROUND_BLUE|BACKGROUND_GREEN)
#define BG_COLOR_DARKGREY (0|BACKGROUND_INTENSITY)
#define BG_COLOR_BLACK (0)
#define BG_COLOR_CYAN (BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_INTENSITY)
#define BG_COLOR_AQUA (BACKGROUND_BLUE|BACKGROUND_GREEN)
#define BG_COLOR_YELLOW (BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_INTENSITY)
#define BG_COLOR_GOLD (BACKGROUND_RED|BACKGROUND_GREEN)
#define BG_COLOR_MAGENTA (BACKGROUND_RED|BACKGROUND_BLUE|BACKGROUND_INTENSITY)
#define BG_COLOR_PURPLE (BACKGROUND_RED|BACKGROUND_BLUE)
#define BG_COLOR_DARKBLUE (BACKGROUND_BLUE)
#define BG_COLOR_BLUE (BACKGROUND_BLUE|BACKGROUND_INTENSITY)
#define BG_COLOR_DARKGREEN (BACKGROUND_GREEN)
#define BG_COLOR_GREEN (BACKGROUND_GREEN|BACKGROUND_INTENSITY)
#define BG_COLOR_DARKRED (BACKGROUND_RED)
#define BG_COLOR_RED (BACKGROUND_RED|BACKGROUND_INTENSITY)
 
int ConsoleStartup();
void ConsoleShutdown();
 
int ConsolePollMessages(INPUT_RECORD *eventBuffer, int bufferSize);
 
int CreateBuffer(int width, int height);
void DestroyBuffer();
 
int ResizeConsole(int width, int height);
void ConsoleSize(int *width, int *height);
int ShowCursor(bool show);
 
void Color(int x, int y, WORD color);
void FillColor(int x, int y, int w, int h, WORD color);
void Write(int x, int y, char *character, WORD color);
void WriteTextCentered(int x, int y, char *text, WORD color);
void WriteText(int x, int y, char *text, WORD color);
void Fill(int x, int y, int w, int h, char *character, WORD color);
void UpdateScreen();
 
int ErrorBox(char *message, char *title);
 
#endif /* TEXT_CONSOLE_H */
 
Console.cpp
#include "Console.h"
#include "main.h"
 
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
WORD OldConsoleColors;
DWORD OldConsoleMode;
HANDLE hStdout, hStdin;
 
CHAR_INFO *Buffer = NULL;
 
DWORD ConsoleMode;
 
int ConsoleStartup()
{
hStdin = GetStdHandle(STD_INPUT_HANDLE);
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
 
    if(hStdin == INVALID_HANDLE_VALUE || hStdout == INVALID_HANDLE_VALUE) 
        return ErrorBox("Startup: GetStdHandle", "Console Error");
 
if(!GetConsoleScreenBufferInfo(hStdout, &consoleInfo))
return ErrorBox("Startup: GetConsoleScreenBufferInfo", "Console Error");
 
if(!GetConsoleMode(hStdin, &OldConsoleMode)) 
       return ErrorBox("Startup: GetConsoleMode", "Console Error");
 
    ConsoleMode = OldConsoleMode & ~(ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT); //|ENABLE_MOUSE_INPUT|ENABLE_WINDOW_INPUT
    if(!SetConsoleMode(hStdin, ConsoleMode)) 
       return ErrorBox("Startup: SetConsoleMode", "Console Error");
 
if(!SetConsoleMode(hStdin, ConsoleMode)) 
       return ErrorBox("Startup: SetConsoleMode", "Console Error");
 
CreateBuffer(consoleInfo.dwSize.X, consoleInfo.dwSize.Y);
 
OldConsoleColors = consoleInfo.wAttributes;
 
ShowCursor(false);
SetConsoleTitle("Text ORPG");
}
 
void ConsoleShutdown()
{
    SetConsoleMode(hStdin, OldConsoleMode);
    SetConsoleTextAttribute(hStdout, OldConsoleColors);
ShowCursor(true);
DestroyBuffer();
}
 
int ConsolePollMessages(INPUT_RECORD *eventBuffer, int bufferSize)
{
DWORD numEvents = 0;
 
if(!ReadConsoleInput(hStdin, eventBuffer, bufferSize, &numEvents))
ErrorBox("ConsolePollMessages: ReadConsoleInput", "Console Error");
 
return numEvents;
}
 
int CreateBuffer(int width, int height)
{
if(Buffer)
DestroyBuffer();
 
Buffer = new CHAR_INFO[width*height];
}
 
void DestroyBuffer()
{
delete[] Buffer;
Buffer = NULL;
}
 
int ResizeConsole(int width, int height)
{
SMALL_RECT consoleWindow = {0, 0, 0, 0};
COORD consoleBuffer = {0, 0};
COORD tempBuffer = {0, 0};
COORD maxWindowSize = GetLargestConsoleWindowSize(hStdout);
 
if(width >= maxWindowSize.X)
width = maxWindowSize.X;
if(height >= maxWindowSize.Y)
height = maxWindowSize.Y;
 
consoleWindow.Right = width-1;
consoleWindow.Bottom = height-1;
consoleBuffer.X = width;
consoleBuffer.Y = height;
 
tempBuffer.X = consoleInfo.dwSize.X;
if(tempBuffer.X < consoleWindow.Right)
tempBuffer.X = consoleWindow.Right;
 
tempBuffer.Y = consoleInfo.dwSize.Y;
if(tempBuffer.Y < consoleWindow.Bottom)
tempBuffer.Y = consoleWindow.Bottom;
 
if(!SetConsoleScreenBufferSize(hStdout, tempBuffer))
return ErrorBox("ResizeConsole: SetConsoleScreenBufferSize (tempBuffer)", "Console Error");
 
if(!SetConsoleWindowInfo(hStdout, true, &consoleWindow))
return ErrorBox("ResizeConsole: SetConsoleWindowInfo", "Console Error");
 
if(!SetConsoleScreenBufferSize(hStdout, consoleBuffer))
return ErrorBox("ResizeConsole: SetConsoleScreenBufferSize (consoleBuffer)", "Console Error");
 
if(!GetConsoleScreenBufferInfo(hStdout, &consoleInfo))
return ErrorBox("ResizeConsole: GetConsoleScreenBufferInfo", "Console Error");
 
//Secondary buffer, for double buffering.
CreateBuffer(consoleBuffer.X, consoleBuffer.Y);
}
 
void ConsoleSize(int *width, int *height)
{
if(width)
*width = consoleInfo.dwSize.X;
if(height)
*height = consoleInfo.dwSize.Y;
}
 
int ShowCursor(bool show)
{
CONSOLE_CURSOR_INFO cursorInfo;
if(!GetConsoleCursorInfo(hStdout, &cursorInfo))
return ErrorBox("Startup: GetConsoleCursorInfo", "Console Error");
 
//Hide the cursor
cursorInfo.bVisible = show;
if(!SetConsoleCursorInfo(hStdout, &cursorInfo))
return ErrorBox("Startup: GetConsoleCursorInfo", "Console Error");
}
 
void Color(int x, int y, WORD color)
{
COORD pos;
pos.X = x; pos.Y = y;
if(x > consoleInfo.dwSize.X)
return;
if(y > consoleInfo.dwSize.Y)
return;
 
Buffer[y * consoleInfo.dwSize.X + x].Attributes = color;
}
 
void FillColor(int x, int y, int w, int h, WORD color)
{
const int SCREEN_WIDTH = consoleInfo.dwSize.X;
const int SCREEN_HEIGHT = consoleInfo.dwSize.Y;
 
int height = SCREEN_HEIGHT - y;
if(height < 1)
return;
if(height > h)
height = h;
 
int width = SCREEN_WIDTH - x;
if(width < 1)
return;
if(width > w)
width = w;
 
for(int Y = y; Y < (y+height); Y++)
{
for(int X = x; X < (x+width); X++)
{
Buffer[Y * consoleInfo.dwSize.X + X].Attributes = color;
}
}
}
 
void Write(int x, int y, char *character, WORD color)
{
COORD pos;
pos.X = x; pos.Y = y;
if(x > consoleInfo.dwSize.X)
return;
if(y > consoleInfo.dwSize.Y)
return;
 
Buffer[y * consoleInfo.dwSize.X + x].Char.AsciiChar = *character;
Buffer[y * consoleInfo.dwSize.X + x].Attributes = color;
}
 
void WriteTextCentered(int x, int y, char *text, WORD color)
{
WriteText(x - (strlen(text)/2), y, text, color);
}
 
void WriteText(int x, int y, char *text, WORD color)
{
COORD pos;
pos.X = x; pos.Y = y;
 
int textLength = strlen(text);
int length = consoleInfo.dwSize.X - pos.X;
if(length < 1)
return;
if(length > textLength)
length = textLength;
 
for(int i = 0; i < length; i++)
{
Buffer[y * consoleInfo.dwSize.X + (x+i)].Char.AsciiChar = text[i];
Buffer[y * consoleInfo.dwSize.X + (x+i)].Attributes = color;
}
}
 
void Fill(int x, int y, int w, int h, char *character, WORD color)
{
const int SCREEN_WIDTH = consoleInfo.dwSize.X;
const int SCREEN_HEIGHT = consoleInfo.dwSize.Y;
 
int height = SCREEN_HEIGHT - y;
if(height < 1)
return;
if(height > h)
height = h;
 
int width = SCREEN_WIDTH - x;
if(width < 1)
return;
if(width > w)
width = w;
 
for(int Y = y; Y < (y+height); Y++)
{
for(int X = x; X < (x+width); X++)
{
Buffer[Y * consoleInfo.dwSize.X + X].Char.AsciiChar = *character;
Buffer[Y * consoleInfo.dwSize.X + X].Attributes = color;
}
}
}
 
void UpdateScreen()
{
COORD dwBufferSize = {consoleInfo.dwSize.X, consoleInfo.dwSize.Y}; 
COORD dwBufferCoord = {0, 0}; 
SMALL_RECT rcRegion = {0, 0, consoleInfo.dwSize.X-1, consoleInfo.dwSize.Y-1}; 
 
WriteConsoleOutput(hStdout, (CHAR_INFO*)Buffer, dwBufferSize, dwBufferCoord, &rcRegion);
}
 
int ErrorBox(char *message, char *title)
{
MessageBox(NULL, TEXT(message), TEXT(title), MB_OK);
return -1;
}

 

Warning: The code is poorly written - that was while I was a newbie programmer. Now I've leveled up twice to a novice programmer. laugh.png

 

Here's a screenshot from the project I was working on at the time: (February 25th, 2008)

screenshotfeb25.png

 

Here's a screenshot another GameDev.net user gave me (JTippets or JBourne I think?) of what the colors look like:

consolecolors.png

 

Here's a chart of the different characters for the console:

asciichart.gif

 

Enjoy!


#1Servant of the Lord

Posted 01 January 2013 - 11:29 AM

Flickering problem:

 

It has to do with 'system("cls")', yes. The command console isn't made for real-time graphics, so that flickering is kinda unavoidable. I'd just leave it as is.

 

I say 'kinda' unavoidable, because you *can* fix it, but it'd almost require redoing your entire game using some slightly more advanced features. It'd be better to use those "more advanced" features for your next game that you start from scratch, in my opinion.

 

But, here's how you do it:

std::cout is standard C++. The command console that std::cout happens to be printing to (in this situation; but it can print whereever you tell it to) is Microsoft Windows's command console. Other operating systems have their own consoles.

 

So standard C++ has std::cout. 'system("cls")' isn't standard C++ either. system() is standard, but 'cls' is actually starting a separate program that clears your command console. This is why it's so slow - it loads up an entirely new program, runs it, then closes it. Because it's slow, the delay between clearing the screen and your next draw is noticeable as an unwanted flickering.

 

So how can that be avoided? You can use non-standard Microsoft functions to interact with Microsoft's command console yourself, instead of calling another program to do so. These Microsoft functions let you: Set the color of individual characters (A huge selection of 16 colors! happy.png), use the mouse and find out what character the mouse is over or clicked on, and *manually place letters where you want on the console, instead of placing entire lines at a time*.

 

The downside is that the functions are a bit complicated and ugly. I haven't used them in over four years, but here's the old code I was using back then (I wrapped them in convenience functions):

 

Console.h

#include <windows.h> 
</p><div> </div>
<div>#ifndef TEXT_CONSOLE_H</div>
<div>#define TEXT_CONSOLE_H</div>
<div> </div>
<div>#ifndef MOUSE_HWHEELED</div>
<div>#define MOUSE_HWHEELED 0x0008</div>
<div>#endif</div>
<div>#define MOUSE_CLICK 0</div>
<div> </div>
<div>#define COLOR_WHITE (FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY)</div>
<div>#define COLOR_GREY (FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN)</div>
<div>#define COLOR_DARKGREY (0|FOREGROUND_INTENSITY)</div>
<div>#define COLOR_BLACK (0)</div>
<div>#define COLOR_CYAN (FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY)</div>
<div>#define COLOR_AQUA (FOREGROUND_BLUE|FOREGROUND_GREEN)</div>
<div>#define COLOR_YELLOW (FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY)</div>
<div>#define COLOR_GOLD (FOREGROUND_RED|FOREGROUND_GREEN)</div>
<div>#define COLOR_MAGENTA (FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY)</div>
<div>#define COLOR_PURPLE (FOREGROUND_RED|FOREGROUND_BLUE)</div>
<div>#define COLOR_DARKBLUE (FOREGROUND_BLUE)</div>
<div>#define COLOR_BLUE (FOREGROUND_BLUE|FOREGROUND_INTENSITY)</div>
<div>#define COLOR_DARKGREEN (FOREGROUND_GREEN)</div>
<div>#define COLOR_GREEN (FOREGROUND_GREEN|FOREGROUND_INTENSITY)</div>
<div>#define COLOR_DARKRED (FOREGROUND_RED)</div>
<div>#define COLOR_RED (FOREGROUND_RED|FOREGROUND_INTENSITY)</div>
<div> </div>
<div>#define BG_COLOR_WHITE (BACKGROUND_RED|BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_INTENSITY)</div>
<div>#define BG_COLOR_GREY (BACKGROUND_RED|BACKGROUND_BLUE|BACKGROUND_GREEN)</div>
<div>#define BG_COLOR_DARKGREY (0|BACKGROUND_INTENSITY)</div>
<div>#define BG_COLOR_BLACK (0)</div>
<div>#define BG_COLOR_CYAN (BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_INTENSITY)</div>
<div>#define BG_COLOR_AQUA (BACKGROUND_BLUE|BACKGROUND_GREEN)</div>
<div>#define BG_COLOR_YELLOW (BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_INTENSITY)</div>
<div>#define BG_COLOR_GOLD (BACKGROUND_RED|BACKGROUND_GREEN)</div>
<div>#define BG_COLOR_MAGENTA (BACKGROUND_RED|BACKGROUND_BLUE|BACKGROUND_INTENSITY)</div>
<div>#define BG_COLOR_PURPLE (BACKGROUND_RED|BACKGROUND_BLUE)</div>
<div>#define BG_COLOR_DARKBLUE (BACKGROUND_BLUE)</div>
<div>#define BG_COLOR_BLUE (BACKGROUND_BLUE|BACKGROUND_INTENSITY)</div>
<div>#define BG_COLOR_DARKGREEN (BACKGROUND_GREEN)</div>
<div>#define BG_COLOR_GREEN (BACKGROUND_GREEN|BACKGROUND_INTENSITY)</div>
<div>#define BG_COLOR_DARKRED (BACKGROUND_RED)</div>
<div>#define BG_COLOR_RED (BACKGROUND_RED|BACKGROUND_INTENSITY)</div>
<div> </div>
<div>int ConsoleStartup();</div>
<div>void ConsoleShutdown();</div>
<div> </div>
<div>int ConsolePollMessages(INPUT_RECORD *eventBuffer, int bufferSize);</div>
<div> </div>
<div>int CreateBuffer(int width, int height);</div>
<div>void DestroyBuffer();</div>
<div> </div>
<div>int ResizeConsole(int width, int height);</div>
<div>void ConsoleSize(int *width, int *height);</div>
<div>int ShowCursor(bool show);</div>
<div> </div>
<div>void Color(int x, int y, WORD color);</div>
<div>void FillColor(int x, int y, int w, int h, WORD color);</div>
<div>void Write(int x, int y, char *character, WORD color);</div>
<div>void WriteTextCentered(int x, int y, char *text, WORD color);</div>
<div>void WriteText(int x, int y, char *text, WORD color);</div>
<div>void Fill(int x, int y, int w, int h, char *character, WORD color);</div>
<div>void UpdateScreen();</div>
<div> </div>
<div>int ErrorBox(char *message, char *title);</div>
<div> </div>
<div>#endif /* TEXT_CONSOLE_H */
 
Console.cpp
#include "Console.h"</div>
<div>#include "main.h"</div>
<div> </div>
<div>CONSOLE_SCREEN_BUFFER_INFO consoleInfo;</div>
<div>WORD OldConsoleColors;</div>
<div>DWORD OldConsoleMode;</div>
<div>HANDLE hStdout, hStdin;</div>
<div> </div>
<div>CHAR_INFO *Buffer = NULL;</div>
<div> </div>
<div>DWORD ConsoleMode;</div>
<div> </div>
<div>int ConsoleStartup()</div>
<div>{</div>
<div>hStdin = GetStdHandle(STD_INPUT_HANDLE);</div>
<div>    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);</div>
<div> </div>
<div>    if(hStdin == INVALID_HANDLE_VALUE || hStdout == INVALID_HANDLE_VALUE) </div>
<div>        return ErrorBox("Startup: GetStdHandle", "Console Error");</div>
<div> </div>
<div>if(!GetConsoleScreenBufferInfo(hStdout, &consoleInfo))</div>
<div>return ErrorBox("Startup: GetConsoleScreenBufferInfo", "Console Error");</div>
<div> </div>
<div>if(!GetConsoleMode(hStdin, &OldConsoleMode)) </div>
<div>       return ErrorBox("Startup: GetConsoleMode", "Console Error");</div>
<div> </div>
<div>    ConsoleMode = OldConsoleMode & ~(ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT); //|ENABLE_MOUSE_INPUT|ENABLE_WINDOW_INPUT</div>
<div>    if(!SetConsoleMode(hStdin, ConsoleMode)) </div>
<div>       return ErrorBox("Startup: SetConsoleMode", "Console Error");</div>
<div> </div>
<div>if(!SetConsoleMode(hStdin, ConsoleMode)) </div>
<div>       return ErrorBox("Startup: SetConsoleMode", "Console Error");</div>
<div> </div>
<div>CreateBuffer(consoleInfo.dwSize.X, consoleInfo.dwSize.Y);</div>
<div> </div>
<div>OldConsoleColors = consoleInfo.wAttributes;</div>
<div> </div>
<div>ShowCursor(false);</div>
<div>SetConsoleTitle("Text ORPG");</div>
<div>}</div>
<div> </div>
<div>void ConsoleShutdown()</div>
<div>{</div>
<div>    SetConsoleMode(hStdin, OldConsoleMode);</div>
<div>    SetConsoleTextAttribute(hStdout, OldConsoleColors);</div>
<div>ShowCursor(true);</div>
<div>DestroyBuffer();</div>
<div>}</div>
<div> </div>
<div>int ConsolePollMessages(INPUT_RECORD *eventBuffer, int bufferSize)</div>
<div>{</div>
<div>DWORD numEvents = 0;</div>
<div> </div>
<div>if(!ReadConsoleInput(hStdin, eventBuffer, bufferSize, &numEvents))</div>
<div>ErrorBox("ConsolePollMessages: ReadConsoleInput", "Console Error");</div>
<div> </div>
<div>return numEvents;</div>
<div>}</div>
<div> </div>
<div>int CreateBuffer(int width, int height)</div>
<div>{</div>
<div>if(Buffer)</div>
<div>DestroyBuffer();</div>
<div> </div>
<div>Buffer = new CHAR_INFO[width*height];</div>
<div>}</div>
<div> </div>
<div>void DestroyBuffer()</div>
<div>{</div>
<div>delete[] Buffer;</div>
<div>Buffer = NULL;</div>
<div>}</div>
<div> </div>
<div>int ResizeConsole(int width, int height)</div>
<div>{</div>
<div>SMALL_RECT consoleWindow = {0, 0, 0, 0};</div>
<div>COORD consoleBuffer = {0, 0};</div>
<div>COORD tempBuffer = {0, 0};</div>
<div>COORD maxWindowSize = GetLargestConsoleWindowSize(hStdout);</div>
<div> </div>
<div>if(width >= maxWindowSize.X)</div>
<div>width = maxWindowSize.X;</div>
<div>if(height >= maxWindowSize.Y)</div>
<div>height = maxWindowSize.Y;</div>
<div> </div>
<div>consoleWindow.Right = width-1;</div>
<div>consoleWindow.Bottom = height-1;</div>
<div>consoleBuffer.X = width;</div>
<div>consoleBuffer.Y = height;</div>
<div> </div>
<div>tempBuffer.X = consoleInfo.dwSize.X;</div>
<div>if(tempBuffer.X < consoleWindow.Right)</div>
<div>tempBuffer.X = consoleWindow.Right;</div>
<div> </div>
<div>tempBuffer.Y = consoleInfo.dwSize.Y;</div>
<div>if(tempBuffer.Y < consoleWindow.Bottom)</div>
<div>tempBuffer.Y = consoleWindow.Bottom;</div>
<div> </div>
<div>if(!SetConsoleScreenBufferSize(hStdout, tempBuffer))</div>
<div>return ErrorBox("ResizeConsole: SetConsoleScreenBufferSize (tempBuffer)", "Console Error");</div>
<div> </div>
<div>if(!SetConsoleWindowInfo(hStdout, true, &consoleWindow))</div>
<div>return ErrorBox("ResizeConsole: SetConsoleWindowInfo", "Console Error");</div>
<div> </div>
<div>if(!SetConsoleScreenBufferSize(hStdout, consoleBuffer))</div>
<div>return ErrorBox("ResizeConsole: SetConsoleScreenBufferSize (consoleBuffer)", "Console Error");</div>
<div> </div>
<div>if(!GetConsoleScreenBufferInfo(hStdout, &consoleInfo))</div>
<div>return ErrorBox("ResizeConsole: GetConsoleScreenBufferInfo", "Console Error");</div>
<div> </div>
<div>//Secondary buffer, for double buffering.</div>
<div>CreateBuffer(consoleBuffer.X, consoleBuffer.Y);</div>
<div>}</div>
<div> </div>
<div>void ConsoleSize(int *width, int *height)</div>
<div>{</div>
<div>if(width)</div>
<div>*width = consoleInfo.dwSize.X;</div>
<div>if(height)</div>
<div>*height = consoleInfo.dwSize.Y;</div>
<div>}</div>
<div> </div>
<div>int ShowCursor(bool show)</div>
<div>{</div>
<div>CONSOLE_CURSOR_INFO cursorInfo;</div>
<div>if(!GetConsoleCursorInfo(hStdout, &cursorInfo))</div>
<div>return ErrorBox("Startup: GetConsoleCursorInfo", "Console Error");</div>
<div> </div>
<div>//Hide the cursor</div>
<div>cursorInfo.bVisible = show;</div>
<div>if(!SetConsoleCursorInfo(hStdout, &cursorInfo))</div>
<div>return ErrorBox("Startup: GetConsoleCursorInfo", "Console Error");</div>
<div>}</div>
<div> </div>
<div>void Color(int x, int y, WORD color)</div>
<div>{</div>
<div>COORD pos;</div>
<div>pos.X = x; pos.Y = y;</div>
<div>if(x > consoleInfo.dwSize.X)</div>
<div>return;</div>
<div>if(y > consoleInfo.dwSize.Y)</div>
<div>return;</div>
<div> </div>
<div>Buffer[y * consoleInfo.dwSize.X + x].Attributes = color;</div>
<div>}</div>
<div> </div>
<div>void FillColor(int x, int y, int w, int h, WORD color)</div>
<div>{</div>
<div>const int SCREEN_WIDTH = consoleInfo.dwSize.X;</div>
<div>const int SCREEN_HEIGHT = consoleInfo.dwSize.Y;</div>
<div> </div>
<div>int height = SCREEN_HEIGHT - y;</div>
<div>if(height < 1)</div>
<div>return;</div>
<div>if(height > h)</div>
<div>height = h;</div>
<div> </div>
<div>int width = SCREEN_WIDTH - x;</div>
<div>if(width < 1)</div>
<div>return;</div>
<div>if(width > w)</div>
<div>width = w;</div>
<div> </div>
<div>for(int Y = y; Y < (y+height); Y++)</div>
<div>{</div>
<div>for(int X = x; X < (x+width); X++)</div>
<div>{</div>
<div>Buffer[Y * consoleInfo.dwSize.X + X].Attributes = color;</div>
<div>}</div>
<div>}</div>
<div>}</div>
<div> </div>
<div>void Write(int x, int y, char *character, WORD color)</div>
<div>{</div>
<div>COORD pos;</div>
<div>pos.X = x; pos.Y = y;</div>
<div>if(x > consoleInfo.dwSize.X)</div>
<div>return;</div>
<div>if(y > consoleInfo.dwSize.Y)</div>
<div>return;</div>
<div> </div>
<div>Buffer[y * consoleInfo.dwSize.X + x].Char.AsciiChar = *character;</div>
<div>Buffer[y * consoleInfo.dwSize.X + x].Attributes = color;</div>
<div>}</div>
<div> </div>
<div>void WriteTextCentered(int x, int y, char *text, WORD color)</div>
<div>{</div>
<div>WriteText(x - (strlen(text)/2), y, text, color);</div>
<div>}</div>
<div> </div>
<div>void WriteText(int x, int y, char *text, WORD color)</div>
<div>{</div>
<div>COORD pos;</div>
<div>pos.X = x; pos.Y = y;</div>
<div> </div>
<div>int textLength = strlen(text);</div>
<div>int length = consoleInfo.dwSize.X - pos.X;</div>
<div>if(length < 1)</div>
<div>return;</div>
<div>if(length > textLength)</div>
<div>length = textLength;</div>
<div> </div>
<div>for(int i = 0; i < length; i++)</div>
<div>{</div>
<div>Buffer[y * consoleInfo.dwSize.X + (x+i)].Char.AsciiChar = text[i];</div>
<div>Buffer[y * consoleInfo.dwSize.X + (x+i)].Attributes = color;</div>
<div>}</div>
<div>}</div>
<div> </div>
<div>void Fill(int x, int y, int w, int h, char *character, WORD color)</div>
<div>{</div>
<div>const int SCREEN_WIDTH = consoleInfo.dwSize.X;</div>
<div>const int SCREEN_HEIGHT = consoleInfo.dwSize.Y;</div>
<div> </div>
<div>int height = SCREEN_HEIGHT - y;</div>
<div>if(height < 1)</div>
<div>return;</div>
<div>if(height > h)</div>
<div>height = h;</div>
<div> </div>
<div>int width = SCREEN_WIDTH - x;</div>
<div>if(width < 1)</div>
<div>return;</div>
<div>if(width > w)</div>
<div>width = w;</div>
<div> </div>
<div>for(int Y = y; Y < (y+height); Y++)</div>
<div>{</div>
<div>for(int X = x; X < (x+width); X++)</div>
<div>{</div>
<div>Buffer[Y * consoleInfo.dwSize.X + X].Char.AsciiChar = *character;</div>
<div>Buffer[Y * consoleInfo.dwSize.X + X].Attributes = color;</div>
<div>}</div>
<div>}</div>
<div>}</div>
<div> </div>
<div>void UpdateScreen()</div>
<div>{</div>
<div>COORD dwBufferSize = {consoleInfo.dwSize.X, consoleInfo.dwSize.Y}; </div>
<div>COORD dwBufferCoord = {0, 0}; </div>
<div>SMALL_RECT rcRegion = {0, 0, consoleInfo.dwSize.X-1, consoleInfo.dwSize.Y-1}; </div>
<div> </div>
<div>WriteConsoleOutput(hStdout, (CHAR_INFO*)Buffer, dwBufferSize, dwBufferCoord, &rcRegion);</div>
<div>}</div>
<div> </div>
<div>int ErrorBox(char *message, char *title)</div>
<div>{</div>
<div>MessageBox(NULL, TEXT(message), TEXT(title), MB_OK);</div>
<div>return -1;</div>
<div>}

 

Warning: The code is poorly written - that was while I was a newbie programmer. Now I've leveled up twice to a novice programmer. laugh.png

 

Here's a screenshot from the project I was working on at the time:

 

 

Here's a screenshot another GameDev.net user gave me (JTippets or JBourne I think?) of what the colors look like:

 

 

Here's a chart of the different characters for the console:

asciichart.gif

 

Enjoy!


PARTNERS