0

I'm looking for a way to show a "DOS" output in a Roguelike fashion, ie. it loks like you have a DOS window filled with characters (the level) which can change or move when the user pushes buttons, clicks with the mouse etc.

In a normal DOS window (say the output from a classic c++ program or .bat) you can only 'write more text' and you have to redraw the whole level if anything changes which is cumbersome and causes artefacts (the updated level slowly scrolls in).

I know I can use say Qt or SDL and draw 2D tiles with characters to overcome this problem but it seems complicated for what I want to do, is there an easy way (say a C++ library) that will let me draw characters anywhere in the/a 'DOS' window?

Thanks!

[EDIT] Thanks, I'll check out all your suggestions, +1 for all!

[EDIT]PDCurses won, a tutorial on how to use it can be found here (it says NCurses but it works perfectly well for a simple Hello world example): http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/

Valmond
  • 2,897
  • 8
  • 29
  • 49

5 Answers5

4

When Rogue was written, it used the curses screen control library.

You can get various implementations of it for Windows. Some translate the curses calls into ordinary Windows console calls:

PDCurses for Windows

Others make a true GUI window, and then draw the enhanced features like bold and underline in a "faked" terminal (like your idea of using Qt or SDL to draw the tiles):

PDCurses for "real" Windows

If you want to tie yourself directly to Microsoft's rarely-used console API functions, you can do that. But if nostalgia is your goal with pursuing such a UI in this day and age, then learning curses would make you cross-platform and let you understand things like the Rogue source code better.

And if kicking into actual DOS emulation is your goal (as per DOSBox), there was another popular option: directly accessing the screen memory. You could peek and poke around...write a 65 at the right place and an "A" shows up.

Then there was ANSI.SYS, which was used on many a bulletin board system back in the day...but is similarly obsolete.

1

Here is an MSDN link with a series of functions that might help you out: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682073%28v=vs.85%29.aspx

Most likely you could

SetConsoleCursorPosition
WriteConsole

Over and over again to do what you want.

Connor Hollis
  • 1,115
  • 1
  • 7
  • 13
1

If it's really DOS, then ansi.sys will enable color codes and positioning cursor: At server fault there's a thread about enabling ansi codes in windows COMMAND.COM. Haven't tested, HTH.

You might also want to check ncurses, which is a library ported to many systems.

Community
  • 1
  • 1
Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57
1

One more alternative:

Create text area widget, such as Qt's QPlainTextEdit, QTextEdit or QTextBrowser, make it read-only, set font to fixed width, and fill it up with text of desired color, fixed number of characters on fixed number of rows.

hyde
  • 60,639
  • 21
  • 115
  • 176
  • I actually considered it but it wouldn't have that good old DOS feeling (IMHO), +1 anyway – Valmond Nov 21 '12 at 10:52
  • For that good old DOS feeling, I think you want full screen text mode... And I think this would be best emulated by making a custom full screen widget (possibly using something like these suggestions as the "renderer", or doing your own painting) with right font. Also, for added realism, you may have to experiment with creating just the right blokyness/softness/scan-lined CRT look to match the original, in which case custom painting is probably way to go :) – hyde Nov 21 '12 at 11:05
  • @Valmond for best feeling, you may have to use OpenGL shaders, that's what others have done: http://filthypants.blogspot.fi/2010/12/crt-pixel-shader-filter-for-snes.html – hyde Nov 21 '12 at 11:10
  • I just didn't want it to be a big project where it won't work in integrated videocards and so on (been there!), just something simple and pdcurse does it perfectly well :-) Thanks though! – Valmond Nov 21 '12 at 16:17
1

Try this:

#include <iostream>
#include <windows.h> 
using namespace std;


void gotoxy(int x, int y)
{
  static HANDLE hStdout = NULL;
  COORD coord;

  coord.X = x;
  coord.Y = y;

  if(!hStdout)
  {
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
  }

  SetConsoleCursorPosition(hStdout,coord);
}




int main(void)
{

  gotoxy(30 , 12);
  cout<<" Writing anywhere \n";

  gotoxy(1 , 22);
  cout<<" \nPress any key to continue\n";
  cin.ignore();
  cin.get();

   return 0;
}
Software_Designer
  • 8,490
  • 3
  • 24
  • 28