Jump to content
  • Advertisement
Sign in to follow this  
SwindIer

Text placement problem for ASCII RPG (simple question)

This topic is 4862 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm looking to make a very very simple top view ASCII text RPG. It's a console game but I can't figure out how to place the text where I want to. I need a command similar to the Qbasic LOCATION command. Ex: I need to place the player on the screen and be able to manipulate that without having to redraw the whole screen.(I know I can use a simple "blank" mask to do so during movement). I know how to do this in SDL but I want this program simple and not include any outside graphics. Any help would be great! Thanks.

Share this post


Link to post
Share on other sites
Advertisement
SwindIer,

I'm not sure of your compiler/ environment, so this maybe completely useless to you (hopefully not). Anyway you might want to look into the library curses.

I'd google for it, but to get you started try:

http://pdcurses.sourceforge.net/
http://heather.cs.ucdavis.edu/~matloff/UnixAndC/CLanguage/Curses.pdf
http://www.unet.univie.ac.at/aix/aixprggd/genprogc/curses.htm

Cheers,

Tom

Share this post


Link to post
Share on other sites
Ok, I tried using Cursers. I'm currently running Slackware Linux 10.0. I downloaded the packages for cursers from sourceforge but I'm having some problems with the install. After running the configuration shell script I get this error:

"checking for location of X headers... configure: error: Cannot find required header file Intrinsic.h; XCursers cannot be configured."

I know you can specify the headers path by using the --x-include=/directoryOfHeaders but I've tried a bunch of directories and still no luck.

:-
Any help?

Share this post


Link to post
Share on other sites
Try looking up C or C++ I/O on CPPReference.com... I'm not sure if they have the functions you are looking for though.

Share this post


Link to post
Share on other sites
Its a bit ugly, but it works. On Dos/windows this requires conio2.h and lib, (google it), on Linux it just works.



#ifndef __LCONSOLE_H
#define __LCONSOLE_H


#include <string.h>
#include <stdio.h>

#ifdef LINUX

#include <termios.h>
#include <unistd.h>
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#endif

#endif

#ifdef DOS
#include <conio2.h>
#endif


// triggers a code in Linux
#define ESC 27

// triggers a code in DOS.
#define DOSARROW 224
#define DOSZERO 0

#define ENTER 10


// These mimic
// /usr/include/X11/keysymdef.h
// but I dont want to require that .h
#define LC_KEY_UP 0xFF97
#define LC_KEY_DOWN 0xFF99
#define LC_KEY_LEFT 0xFF96
#define LC_KEY_RIGHT 0xFF98
#define LC_KEY_HOME 0xFF95
#define LC_KEY_END 0xFF9C
#define LC_KEY_INSERT 0xFF9E
#define LC_KEY_DELETE 0xFF9F
#define LC_KEY_PAGEUP 0xFF9A
#define LC_KEY_PAGEDOWN 0xFF9B


#define CODE_LEN 5


typedef struct {
unsigned int one_code;
unsigned char long_codes[CODE_LEN];
} key_code;

#ifdef LINUX
#define POS_CODES 11
const key_code KEY_CODES[POS_CODES] =
{ {ESC, { ESC, 0, 0, 0, 0 } },
{LC_KEY_UP, { ESC, 91, 65, 0, 0 } },
{LC_KEY_DOWN, { ESC, 91, 66, 0, 0 } },
{LC_KEY_LEFT, { ESC, 91, 68, 0, 0 } },
{LC_KEY_RIGHT, { ESC, 91, 67, 0, 0 } },
{LC_KEY_HOME, { ESC, 91, 49, 126, 0 } },
{LC_KEY_INSERT, { ESC, 91, 50, 126, 0 } },
{LC_KEY_DELETE, { ESC, 91, 51, 126, 0 } },
{LC_KEY_END, { ESC, 91, 52, 126, 0 } },
{LC_KEY_PAGEUP, { ESC, 91, 53, 126, 0 } },
{LC_KEY_PAGEDOWN, { ESC, 91, 54, 126, 0 } }};

#endif

#ifdef DOS
#define POS_CODES 21
const key_code KEY_CODES[POS_CODES] =
{ {ESC, { ESC, 0, 0, 0, 0 } },
{LC_KEY_UP, { DOSARROW, 72, 0, 0, 0 } }, // between keys
{LC_KEY_DOWN, { DOSARROW, 80, 0, 0, 0 } },
{LC_KEY_LEFT, { DOSARROW, 75, 0, 0, 0 } },
{LC_KEY_RIGHT, { DOSARROW, 77, 0, 0, 0 } },
{LC_KEY_HOME, { DOSARROW, 71, 0, 0, 0 } },
{LC_KEY_INSERT, { DOSARROW, 82, 0, 0, 0 } },
{LC_KEY_DELETE, { DOSARROW, 83, 0, 0, 0 } },
{LC_KEY_END, { DOSARROW, 79, 0, 0, 0 } },
{LC_KEY_PAGEUP, { DOSARROW, 73, 0, 0, 0 } },
{LC_KEY_PAGEDOWN, { DOSARROW, 81, 0, 0, 0 } },
{LC_KEY_UP, { DOSZERO, 72, 0, 0, 0 } }, // The keypad keys
{LC_KEY_DOWN, { DOSZERO, 80, 0, 0, 0 } },
{LC_KEY_LEFT, { DOSZERO, 75, 0, 0, 0 } },
{LC_KEY_RIGHT, { DOSZERO, 77, 0, 0, 0 } },
{LC_KEY_HOME, { DOSZERO, 71, 0, 0, 0 } },
{LC_KEY_INSERT, { DOSZERO, 82, 0, 0, 0 } },
{LC_KEY_DELETE, { DOSZERO, 83, 0, 0, 0 } },
{LC_KEY_END, { DOSZERO, 79, 0, 0, 0 } },
{LC_KEY_PAGEUP, { DOSZERO, 73, 0, 0, 0 } },
{LC_KEY_PAGEDOWN, { DOSZERO, 81, 0, 0, 0 } } };
#endif

// Some buttons result in multiple buttons.
// To get them all you have to do another kbhit(), readch() pair.
// UP ARROW = 27, 91, 65
// DOWN ARROW = 27, 91, 66
// RIGHT ARROW = 27, 91, 67
// LEFT ARROW = 27, 91, 68
// ESC = 27
// INSERT = 27, 91, 50, 126
// DELETE = 27, 91, 51, 126





const char CURSOR_COLORS_TEXT[][5] =
{"0;30", "0;34", "0;32", "0;36", "0;31", "0;35", "0;33", "0;37",
"1;30", "1;34", "1;32", "1;36", "1;31", "1;35", "1;33", "1;37",
"40", "44", "42", "46", "41", "45", "43", "47"};

enum CURSOR_style_TYPE {
LC_RESET = 0,
LC_NORMAL = 0,
LC_BRIGHT = 1,
LC_DIM = 2, // dont work
LC_UNDERLINE = 3, // wont
LC_FOUR = 4, // real Underline??
LC_BLINK = 5, // Brights background also
LC_SIX = 6, // Bright Background?
LC_REVERSE = 7,
LC_HIDDEN = 8,
LC_NINE = 9,
LC_TEN = 10
};

const int CURSOR_COLOR_LINUX_CODES[] =
{ 30, 34, 32, 36, 31, 35, 33, 37,
30, 34, 32, 36, 31, 35, 33, 37};

enum CURSOR_COLOR_TYPE {
LC_BLACK,
LC_BLUE,
LC_GREEN,
LC_CYAN,
LC_RED,
LC_PURPLE,
LC_BROWN,
LC_LIGHT_GRAY,

// named that have the same value, but make more sense when in Bright mode
LC_DARK_GRAY,
LC_LIGHT_BLUE,
LC_LIGHT_GREEN,
LC_LIGHT_CYAN,
LC_LIGHT_RED,
LC_LIGHT_PURPLE,
LC_YELLOW,
LC_WHITE
};




// These need to exist under both. But under DOS they will
// define to empty.
// Starts Keyboard nonblocking mode.
void SetTTYRaw(bool HideEcho);
// ends Keyboard nonblocking mode
void RestoreTTY();

// returns 1 on true 0 on false.
int IsKBHit();
// returns the button hit.
int ReadKeyboard();


void SetCursorPos(size_t X, size_t Y);
void ClearScreen();
void ResetColor();
void SetColors(CURSOR_style_TYPE style, CURSOR_COLOR_TYPE Fg, CURSOR_COLOR_TYPE Bg);

#endif // end entire header






#include "LConsole.h"


#ifdef LINUX
// Stores keyboard settings
static struct termios new_settings, initial_settings;
static int peek_character = -1;
#endif

void SetTTYRaw(bool HideEcho)
{
#ifdef LINUX
tcgetattr(0,&initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ICANON;

if(HideEcho)
new_settings.c_lflag &= ~ECHO;

new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new_settings);
#endif
}

void RestoreTTY()
{
#ifdef LINUX
tcsetattr (STDIN_FILENO, TCSAFLUSH, &initial_settings);
#endif
}




int search_key_codes(unsigned char start_ch)
{
int PosLoop, FullCodeIndex;

unsigned char FullCodeStr[CODE_LEN+2] = "\0\0\0\0\0\0";
//printf(" searching ");
// read in the entire code str
FullCodeStr[0] = start_ch;
FullCodeIndex = 1;
// printf("@%d ", FullCodeStr[0]);
while(IsKBHit()) {
FullCodeStr[FullCodeIndex] = ReadKeyboard();
// printf("%u ", FullCodeStr[FullCodeIndex]);
FullCodeIndex++;
if(FullCodeIndex >= CODE_LEN) {
printf((char*)FullCodeStr);
return 0;
}
}
FullCodeStr[FullCodeIndex] = '\0';
// FullCodeIndex is the length of the str, including the NULL.
// printf(" *%u ", FullCodeIndex);


for(PosLoop = 0; PosLoop < POS_CODES; PosLoop++) {

if( strcmp((char*)KEY_CODES[PosLoop].long_codes, (char*)FullCodeStr) == 0)
return KEY_CODES[PosLoop].one_code;

} // end possible codes loop

return 0;
}


int IsKBHit()
{
#ifdef LINUX
unsigned char ch;
int nread;

if (peek_character != -1) return 1;
new_settings.c_cc[VMIN]=0;
tcsetattr(0, TCSANOW, &new_settings);
nread = read(0,&ch,1);
new_settings.c_cc[VMIN]=1;
tcsetattr(0, TCSANOW, &new_settings);
if(nread == 1)
{ //printf("!%d!", ch);
if(ch == ESC)
peek_character = search_key_codes(ch);
else
peek_character = ch;

return 1;
}
return 0;
#endif

#ifdef DOS
return kbhit();
#endif
}

int ReadKeyboard()
{
#ifdef LINUX
int ch;

if(peek_character != -1)
{
ch = peek_character;
peek_character = -1;
return ch;
}
read(0,&ch,1);
return ch;
#endif

#ifdef DOS

int ch;

ch = getch();

if(ch == DOSARROW || ch == DOSZERO)
return search_key_codes(ch);
else
return ch;
#endif
}



// http://www.linux.com/howtos/Bash-Prompt-HOWTO/x329.shtml

// 0,0 is at Top Left.
void SetCursorPos(size_t X, size_t Y)
{
#ifdef LINUX
printf("\033[%d;%df", Y+1, X+1); // yes, that command wants Y,X
// and +1 because this system actually counts from 1
// unlike everything else in all of computer-dom
#endif

#ifdef DOS
gotoxy(X,Y); // dos conio function
#endif

}

void ClearScreen()
{
#ifdef LINUX
printf("\033[2J");
#endif

#ifdef DOS
clrscr();
#endif
}



// Resets it to whatever the system wants it to be.
void ResetColor()
{
#ifdef LINUX
printf("\033[0m");
#endif

#ifdef DOS
normvideo();
#endif

}


void SetColors(CURSOR_STYLE_TYPE Style, CURSOR_COLOR_TYPE Fg, CURSOR_COLOR_TYPE Bg)
{
#ifdef LINUX
printf("\033[%d;%d;%dm", Style, CURSOR_COLOR_LINUX_CODES[Fg],
CURSOR_COLOR_LINUX_CODES[Bg]+10);
#endif

#ifdef DOS

if(Style == CT_NORMAL)
lowvideo();
else if(Style == CT_BRIGHT)
highvideo();

textbackground(Bg);
textcolor(Fg);
#endif
}



Share this post


Link to post
Share on other sites
Ok, I tried using your code and add it to my project. When I went to compile I got these errors


--------------------Configuration: rpg - Linux Debug--------------------
Compiling source file(s)...
LConsole.cpp
LConsole.cpp: In function `int search_key_codes(unsigned char)':
LConsole.cpp:61: error: `POS_CODES' undeclared (first use this function)
LConsole.cpp:61: error: (Each undeclared identifier is reported only once for
each function it appears in.)
LConsole.cpp:63: error: `KEY_CODES' undeclared (first use this function)
LConsole.cpp: At global scope:
LConsole.cpp:175: error: `CURSOR_style_TYPE' was not declared in this scope
LConsole.cpp:175: error: parse error before `,' token
LConsole.cpp:192:2: warning: no newline at end of file

rpg - 5 error(s), 1 warning(s)


I put the top code into it's header file "LConsole.h" and the bottom code into it's "brother" source file, "LConsole.cpp". Should I just redeclare the gobal constants again in LConsole.cpp?

Share this post


Link to post
Share on other sites
Before you include LConsole.h, or commandline as part of the g++ line, throw in a "#define LINUX" or "#define DOS"

Share this post


Link to post
Share on other sites
it's likely that you alread have "ncurses" installed, especially if you did a full install. at least i know a full install of slack 10.1 has it. i've been told it's very easy to learn and use.

Share this post


Link to post
Share on other sites
Quote:

Before you include LConsole.h, or commandline as part of the g++ line, throw in a "#define LINUX" or "#define DOS"


I tried that, but I'm still getting errors saying that it can't see the global variables in the source file from the header file.

Any other ideas?

About the ncursers thing, I tried that too, it didn't really give me any errors when I included cursers.h but I ran into problems the second I tried using any of the commands found on that reference site listed in an earlier message.

Well, so much for this being the easy question I thought it would be. :P

Share this post


Link to post
Share on other sites
-DLINUX (or -DDOS) in the g++ line that makes LConsole.cpp. That .cpp needs to seeyour define as well as your codes .cpp

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!