Site Stability Read more... ×
• entries
122
121
• views
69246

My not-so daily posts on my current console project

select()ing on stdin. O_o

Alright, so I've been working on a command line back-end to ExplorerMUD. It's in its own separate thread so I can get input from the person running the server at the same time as other stuff is going on. I can probably merge it into the same thread as the listener now, since I'm select()ing on stdin anyways, but that's beside the point.

The problem: I need to be able to retrieve input from stdin without blocking, and I have to do it without cin because cin just doesn't work like that. If you cin.getline() or cin>>, it waits until the next enter-press even if there's text waiting already, because it wasn't TECHNICALLY waitingblocking for input at the time. It does get the text, but only after you hit enter again, which leaves a newline in there or some other junk, which you'll retrieve next time you enter something... it throws everything off.

Then I found a link that described how to turn off canonical mode on the terminal. It worked, but ugh, no backspace or anything? In fact, the mere attempt at a backspace puts an ugly character in you really don't care about instead of backspacing? There has to be a better way.

Using fcntl to set stdin to O_NONBLOCK, then getting the input char by char with fgetc() worked. So simple, yet so beyond me at first. What a noob! :D

~Jonathan

Tough

Project 2 of the C++ workshop was unveiled.. I'm going to have to work hard to get that done. It really looks tough.. meaning, I've never done something as big as that before. Big being relative to what I have done before.

On other news, I've uploaded the [at the time] current versions of cConsole, my console-manipulation class (done but not polished, as the todo list states), and the source code and executable for "Consolian Arenamatic", my program for Project 1 of the C++ Workshop. Check the to-do list for details.

I've done away with the 'keys' string in cConsole I mentioned, and I'm working on the store. I've added two classes, armor and weapon, to hold the values for current armor and weapon ("*player.equip[0] = new armor", for example, though 'equip' isn't in player.h in the uploaded .zip), and now I just have to work on the store itself, and buying stuffs. Yay. Then I go on to the arena.

Hmm. Does anyone even read this, besides Programmer16? If you do, please comment... I feel all alone. [sad]

EDIT: I just realized the .zip had a VERY old version of the .exe! Oops! [tears]

User Input Hassles

I'm not actually sure how to proceed here. User input is easy enough on its own, but I need to continually Draw() at a certain framerate as well as watch for user input (and act on it wen it comes in). I created a Keyboard class, but I'm really not sure how to do this.

I want to draw, at the moment, once every 0.25 seconds. I also want to watch for user input constantly, and move the "camera" every time a key is pressed (but only allow them to move once every so often). And I don't want to continually loop, because I think that hogs CPU; I just want to do something if there's something to do, or it's time to draw.

The only thing I've managed to do, that works in some respect, checks the console input buffer every time through the loop and sets the appropriate element in an array of bools depending on what key event comes through. Then it draws, and Draw() checks the time elapsed between the last time we drew and now, and if we're good to go, it checks the arrow key booleans and moves accordingly. The problem here is that it only works if we held the key down when Draw() actually draws. If we hit an arrow key after 50ms since the last Draw(), and let go at 100ms since the last draw, it's like we never hit the key at all - Draw() doesn't recognize that we tried to move. And it keeps looping whether we have anything to do or not.

Obviously I'm new to handling keyboard input like this. I think WaitForMultipleObjects() could help (because it can wait on an input buffer handle), but I still have no idea how to proceed. A poke in the right direction would be hugely appreciated! =\
~Jonathan

Project Harbinger

Me and Programmer16 are working on a text adventure together (codename Project Harbinger), and it's very much like WinMUD, except P16 and I made a design doc for it, and we're using XML for the item, room, and monster files. Gotta get to figuring out TinyXML; I tried it once and got confused.

Timed stuffs!

First, a thanks to EasilyConfused for his much appreciated comment. :D

Today I coded in a timed delay thing into the game's main loop. This way things don't go lightning-fast on the player... it's limited to doing stuff once every 500 miliseconds now. I guess you could call each interval the game does stuff in a "frame", yes? I also added a keyboard input function, to check if there was a valid keypress, and return its virtual key identifier (for example, VK_ESCAPE)

Here's my main() function, to show you how the main loop looks so far. I think I just need to work on the actual gameplay now...

int main()
{
Init(); // Sets up the HUD details and console title

bool quit = false;
int timestat = 0; // Because each frame is half a second, I need
// a way to know when to increment the HUD's time
// field - that is, once every two frames.

while (!quit)
{
unsigned long currtime = GetTickCount();
hud.Draw(0, 0); // The arguments specify the x,y coord of the
// top-left corner of the HUD.

GameInfo.score += 10;

if (timestat == 0) timestat = 1;
else if (timestat == 1) { timestat = 0; GameInfo.time += 1; }

// During the delay time, when nothing is being done, I watch for
// keypresses. I used to have it outside the while, but there was
// a visible delay between pressing and exiting when the key was
// pressed after the check and during the delay. Placing it in the
// loop lets me check as many times as the while iterates per frame,
// and because the game doesn't take long to process what I have so
// far, there's no visible delay in quitting.

while (currtime+500 > GetTickCount())
if (CheckForKeypress() == VK_ESCAPE)
{
quit = true;
break;
}
}
}

EDIT: If you're wondering, and I'm sure you are, the game looks no different now than a month ago. The only differences are internal, except that I'm actually displaying the game's data in the HUD, not just the "static" lines. Nothing new though, just zeroes! (Although I use a line of six zeroes as a static to the right of the Score line, so it looks like we've got a sort of zerofilled score going on when the score is drawn on top of it. I likey.)

EDIT: Abandoned. See next post for details.

As of today I'm working on an engine I call AdLib. It's really mostly just a hobby project... but I have plans for it. Unfortunately, it's on the same backburner as the Atom~View project (tentative name there). I have so many projects concurrently it's not even funny. *sigh*

I don't want to say much about AdLib, not because I'm worried about someone stealing it, but because I don't want to talk about something I'm unsure about. Suffice to say it's a parser.. that and the name should start the wheels turning, eh? Also, at first glance it's almost reinventing the wheel, and I'd rather not reveal too much until I can show why it isn't reinventing the wheel.

Well... I can't resist. Okay, three tidbits and that's all.

1) The engine's name is AdLib.
2) The engine is a parser.
3) (new!) I want to eventually write a module for Apache to interface with AdLib.

Eh, #3 is rather far off right now. Still, it's a goal I want to reach.

Anyone intrigued? Have any guesses? Drop me a comment! [wink]
~Jonathan

Pokemon: Mystery Dungeon

A lot of people will hate me for this, but I bought Pokemon Mystery Dungeon: Blue Rescue Team yesterday. It's actually pretty fun, but the menu controls take a while to get used to. Storyline's pretty good, music's okay but still enjoyable. The dungeons themselves STRONGLY remind me of Lufia: The Legend Returns for one of the older Game Boy systems, and Evolution Worlds for the GCN. The dungeons are designed VERY much like those two games, especially the traps from Evolution Worlds. Fun game, iffy controls.

Happy birthday to me!

I turned 17 today! I won't technically be 17 for maybe three more hours, but for all intents and purposes...

I've been working a lot on that Nucleus engine I mentioned previously. Right now I'm getting to know the Lua/C API so I can write a C module that Nucleus can load as a native extension to Java, as a Lua interop module. At the moment it's standalone for testing purposes, while I struggle to learn how to bind C++ classes/objects into Lua to my tastes. I'm happy with what I have so far, but right now it can only bind functions, not other kinds of values. It's probably worth writing down what I've learned so far though.

The goal: Access instance methods of a C++ object from Lua.
The problem: Lua can only easily bind static methods. There needs to be some way to tell a function what instance it should act on.
The solution (simple in hindsight): store the object instance as a full userdatum, and call its methods in Lua using the colon operator (object:method(params)). This is really just syntactic sugar for object.method(object, params). Given that object is the instance, object is really just 'this'.

The above is the keystone to the solution. Obviously it won't do much without some support. For example, we still have to bind a static function for Lua to call. Furthermore, userdata does nothing useful without a metatable. So we have to register a metatable to our new userdatum, with a (static) method registered as its __index at the very least. This function will handle lookups into the userdatum; if I do "object.foo", __index will recieve obj and "foo", and return an appropriate value, even if it's just nil. This is done with a static array of name/pointer pairs to allow lookups based on name.

We expect "object.method" to call __index and return that particular method. But remember, these methods are instance methods, and Lua can't call those directly. So instead of returning the method directly, we'll create a static 'thunk' function to resolve the access and call our instance method. We'll register this thunking function multiple times, once for each instance method, and registering a pointer to a data structure as an upvalue each time. The data structure just holds a pointer-to-member; even though pointers-to-member can't be casted to void*, a pointer to a vanilla struct instance sure can. This is basically just a Lua version of std::bind1st, creating a new object (closure) each time.

Now, "object.method" will call into __index and get back our simple thunking method, with a unique upvalue representing the method to call. So, calling this method with parameters (and using the colon syntax to pass a hidden 'this') should successfully resolve to a call to an object's instance method: "object:method(1,2,3)".

The code is... a bit ugly right now. I want to try to clean it up a bit before I make it public, and hopefully add support for __index returning things other than a function. This is a hobby project, so while I know I could just go the C route and go with static functions in separate .c files, I like working with objects, and it's fun to figure out how this is all supposed to work. [smile]

~Jonathan

EDIT: May as well post what my goal code is on the Lua end. This is what I want to be able to do when the interop module is finished:

local server = atom.request("server/telnet")

server.handlers["connect"] = function(self, client)
local db = atom.request("database/mysql")
db:use("blacklist")

local result = db:query("SELECT * FROM tbl WHERE IP='" .. client.IP .. "'")
if #result > 0 then
self:disconnect(client, result[1].reason)
end
end

Ideally, the server.handlers table/udata would use a __newindex metamethod to tell when something's being assigned, and register the hooks appropriately. I think it's pretty intuitive, and I'm almost positive I can do everything in this snippet. Give me some time, people... [grin]

OpenGL and Windows

So, I finally got around to downloading the PSDK, and I grabbed my OpenGL Superbible and did some example stuff, read a bit, etc. Unfortunately, their collision-detection on the square-bouncing-off-window-walls example was off (strangely), and the square bounces windowHeight+squareSize too high, and bounced squareSize up off the bottom (like some kind of invisible floor). Well, poo. (Yes, I tried fixing it. No luck.)

I'm trying some Win32 (you heard me) programming with Windows instead, just to get a grasp on windows and event-driven stuffs, using a tutorial at this site.

OpenGL is definitely not a beginner's API. =|

EDIT: Scratch that. I'm done with Win32. Just going to try to dig through some OpenGL code...

Cripes 2.0: Maze Generation DONE!

I'm practically dancing in my seat right now! :D I just finished the maze generation. I basically have a MapLoader class with a pure virtual function called Generate(), which takes a width and a height, and returns a vector of Entities (presumably the walls). I derived a MazeGen class from it, which implements a maze-building algorithm and then creates and positions wall and corner entities based on the algorithm results. I haven't added in any code to randomly remove walls, so it's a basic maze right now. Still, I just had to take a screenshot!

Wooooooooooooooooooooo. :D

It takes over a full second to load each maze, unfortunately, because I have so many corner entities. I'm hoping that my random-wall-removal will help mitigate that, but we'll see.

EDIT: Matched the cell sizes to the original Snipes. Each is 8 chars wide, 6 chars high. I wasn't expecting the discrepancy... Also, made my walls blue. So so so much better. It looks almost real! Now for collision detection... well, tomorrow. *yawn*

Lua 5.1.1

Well, Scavenger (on IRC) may/may not be joining Project Harbinger part-time, sinec Programmer16 wants to devote a little more time to Ascension. Meanwhile, I've found a new hobby, which might (read: WILL) make people think I'm crazy, or a loon. Check it out, though, it does make some sense.

On the subject of loons, I'm trying to get into Lua 5.1.1. I'm having MASSIVE trouble getting the luaopen_ functions to work, since they have to be pushed onto the Lua stack, then their arguments, then called from the stack. And apparently, when I call, I'm trying to call a nil value. Here's my code, from memory (since I'm on another computer):

lua_State *L = lua_open();

lua_getfield(L, /**/, "luaopen_io");
lua_pcall(L, 0, 0, 0);

When I check for errors (using a handy function I found on the net), I get a "calling a nil value" or whatever error, so apparently I'm not pushing luaopen_io properly, or using lua_pcall right (but I've tried it every which way). Help would be VERY appreciated... [sad]

The Cow jumped over the Moon

About the title: My math teacher was discussing the origins of the name Lua (Portuguese for Moon), and since Lua is Luna minus the N, he said "Well, Moon minus the N is Moo."

Anyways, with Programmer16's help, I found a tutorial that's up to date with Lua 5.1, so YAY, I've got Lua working. Now I've got to experiment with calls between Lua and C++ (making a calculator as a test project), and then I'll try integrating into Harbinger (that's not for a bit though).

To Programmer16: I was away today, wasn't home at 5 EST, sorry.

cConsole

This is a blast from the past... Apparently, Programmer16 studied my cConsole code to research how to "interface with the console", and wrote his own Console class (without the input capabilities, from what I can tell) for use in his recent Quickies games. That's pretty neat, and quite an ego boost for the amateur 'grammer to have his code used in someone else's program.

I'm definitely considering going back and improving it, since it's apparently a useful resource for Windows console programming. I'll get on it after I'm done with my Card classes. Hey, cConsole (renamed to Console when I do it) will definitely be handy at the very least for the C++ Workshop projects.

Uh.. that's actually why I originally wrote it. Talk about getting sidetracked.

Speaking of the Card classes, I haven't worked on them much lately, but CardDeck needs some reworking, since it's got some very strange bugs, like iterator invalidations which I had thought I'd fixed, and on Draw() getting an invalid card when I know there's cards in there.

Finally... it'd be nice to get a comment or two here? My last few entries garnered zilch.

WinMUD, SVN, and XP, oh my!

Technically WinMUD is not a MUD, but its the name I gave it when I started, so I'm sticking with it.

Anyways, I've decided to change my to-do list to reflect changed to WinMUD instead of Arenamatic, since the only part of Arenamatic I was really looking forward to (and pleased with) was cConsole. Take a look. [grin]

I've finished, for the most part, the Roomset component. It's fairly well-known, or at least I thought it was, that a MUD or similar game is made of three parts: rooms, connections, and entities. And, duh, functionality, but I'm talking about actual parts. So far I have the rooms and connections finished, and I'm working on entities. Now, that doesn't mean I'm almost done; no, I still have the command parser after that, and then I'll have to figure some way of linking (not the compile-and-link sort) them together.

In other news, I got an SVN up. Sooner or later I'll get a link up to it; make it easy for you to look at my progress. I'll be committing my changes every time I get something right, which might be a couple times a day, so when I get the SVN up, watch it. [wink]

Also, I set up a new WinXP account exclusively for my programming stuff. I've named it ProGamer RM, kudos to anyone who can figure out why. (if no-one guesses, or comments, I'll say what it is in the next entry)

Gonna work a bit more tonight then head to bed.

My current project, among other things

Currently I'm working on a set of header functions to be used for creating an "arena battle" game (text-based). My curent focus is on the store (where you spend money you get from winning arena battles), and it's been a bit tough. I managed to get the LoadStore and SaveStore functions working, though. When the user of these headers (specifically, cStore.h - don't ask about the c, please) creates an object of type store (the name I gave to my store class), the user passes a string argument with the name of the file they want to use to load shop data from. The constructor then calls LoadStore(), which parses every line of the file given and separates the lines at certain points. Hmm, maybe I should give an example.

// ...
#include "cStore.h"

store shop("shop.txt"); //Calls the constructor (you're probably thinking, "DUH!")

// ... skipping to cStore.h (EDIT: Everything from here down is in "class store")

private:
map shopMap;
string file;
ifstream shopIn;
ofstream shopOut;

/*
*Please pretend there's a public: here... I don't want to have
*to re-indent my code 8 spaces. >_ */
store(string userfile)
{
shopIn.open(userfile.c_str()); //This opens an ifstream with the user-specified file
cout "Loading Store\n"; //Just for testing purposes; I want to make sure I don't break my code somehow.
}

~store()
{
if (shopIn.is_open()) shopIn.close();
if (shopOut.is_open()) shopOut.close();
SaveStore(); //Saves the store to a file
}

{
string line, key;
string item[2];
do
{
shopIn >> line; //Gets a line from shopIn every iteration of the do-while
if ((line != (item[0] + '%' + item[1])) && (line != "")) //If the line is not the same as the line before...
{
item[0] = PairSplit(line); //...then parse the line and save the first half here...
item[1] = PairSplit(line, 1); //..and save the second half here.
shopMap.insert(pair(item[0], item[1])); //Insert the key-value pair into the shopMap.
cout 0]] //Debugging cout statement.
}
} while (!shopIn.eof());
}

void SaveStore()
{
shopOut.open(file.c_str()); //opens an ofstream to the user-specified file
if (!shopMap.empty()) //if the shopMap is not empty
{
map::iterator forIter = shopMap.begin(); //iterator starting at the beginning of the map
map::iterator endIter = shopMap.end(); //iterator that stays at the end of the map
string line;
do
{
if (forIter->first != "" && forIter->second != "") //If forIter does not contain null values...
{
line = forIter->first + '%' + forIter->second; //...concatenate them using the %...
cout shopOut //...and print them to the file.
forIter++; //Increment forIter.
}
} while (forIter != endIter);
shopOut.close();
}
}

Uh... that wasn't as explanatory as I wanted it to be. [sad] Well... basically, when LoadStore is called, it parses the file and splits it into two variables at the '%' character. If the line "lp%Life_Potion$30" was in the file, we'd now have "lp" and "Life_Potion$30", paired and placed into the map. When the shop is saved, the process is reversed (concatenating the key and value with the '%').

Call me a newb, I think I posted this too early in the day. My mind needs to load up on gas. >_> I'm just too excited about getting a journal. :P As a question for anyone reading this, is it acceptable to post twice a day?

EDIT: Forgot to end the source tag. >_

Graphics

This is mostly just a response to comments in my last entry.

I know graphics is an advanced subject, but I've been doing text for 1-2 years now... I've already made enough text RPGs to make me sick. >_
In other news, I reinstalled World of Warcraft on my new computer; glad to say it works with Vista, unlike Guild Wars (:'(). I'm planning on getting the expansion ASAP.

Did I ever tell anyone I beta tested WoW: Burning Crusade last winter?

*cackles*

Update soon, not like anyone cares, but I thought I'd post this...

Brand new journal!

int main()
{
cout loser--;
}

Hehe. [grin]

I actually have no idea what to use my journal for, except for piling my almost hourly troubles with my current learning hobby/project into... and it's text-based, so I know you people will bug me about it being a waste to get GDNet+ when I'm still text-gramming. I just figured now would be a good time to get my parents to get it for me; my father was in a good mood today and I thought I'd ask. (Not that he's always in a bad mood; just that today he seemed a bit more allowing towards computer things.

You know, all this is making me think I should start out with an "about me". That's a good idea. Thanks, "all this". [grin]

Well, to start, my name is Jonathan and I am 13 years old. I have a little sister who bugs me to no end, and two parents who are awesome (my father is one of THE top players on Doom 3 free-for-all multiplayer, and my mother, while often stressing out, is very loving. [grin]). I am a Nintendo semi-freak (I refuse to be tugged over to PSP, although the new name for the Revolution (Wii) is a bit odd, and moreover I am a Legend of Zelda fan[atic]. I started learning to program when I was around 10 (althugh only sparsely, and forgot about programming after a short class in it), then got back into it last year when I was on vacation in Hawaii. Since then I've been learning C++, struggling slightly at pointers and trying my hand at a text-based RPG (which turned out pretty nice, even without prior designing, although the actual gameplay was never done). Currently, I'm working on what I call an "arena battle" program, creating my own headers that you could use to create your own arena game.

That should end the about me section... Tomorrow I'll try to post some stuff about my arena project.

World::View

Today (and partially last night) I wrote up a View class to wrap the clipped view of the World returned by World::DrawView(). It's constructible only by World (excepting the copy-ctor, which is public), taking width and height parameters to create a dynamically-allocated CHAR_INFO buffer. It overloads the [] operator and a conversion operator (because it was easy and it makes sense), and handles the buffer's memory itself.

class View
{
private:
CHAR_INFO* view;
int width, height;

View(int width, int height);
friend const View World::DrawView(int, int, int, int) const;
public:
View(const View& v);
~View();

View& operator=(const View& v);
CHAR_INFO* const operator[] (int idx);
operator const CHAR_INFO* const() const;

int Width() const;
int Height() const;
};

This is all I need to do to draw my world view to the screen:

void Game::Draw()
{
World::View worldview = world.DrawView(0, 0, world.Width(), world.Height());
SMALL_RECT drawRect = {0, 3, worldview.Width()-1, worldview.Height()+2};
COORD origin = {0, 0};
COORD worldsize = {worldview.Width(), worldview.Height()};

WriteConsoleOutput(hOut, worldview, worldsize, origin, &drawRect);
}

Notice that I can pass worldview to WriteConsoleOutput? That's the conversion operator (converts to const CHAR_INFO* const). I think it looks really clean. DrawView() takes the xy coordinates of the upper-left and lower-right rectangle to view. Technically, passing the world's Width and Height puts the rect one over the edge on the right and bottom sides, but DrawView clips it down, so it's a small shortcut rather than subtracting one from each. Then again, I have to do it in the drawRect anyways...

Wrapping world display

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 {
for (int x = 0; 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

Vacation

I'm going on vacation for two weeks in Florida! I'll be staying right by the east coast, and there's a cute girl living right across the street. [gasp] If I'm lucky, I might be able to work on some Lua while I'm there, but C++ is probably not going to happen. I tried to get a USB flash drive (2GB) today, but we didn't have time, so I'll have to grab one tomorrow if possible, but that's when we're leaving. I guess I'll just download lua and luac when I get there.

As for the airplane trip, I bought a magazine, four Dragonlance novels, and a book on applying mathematical concepts to game programming. I'm going to go through it all by the time we arrive in Florida...

Oh, does anyone know if it's possible to get your GDnet username changed?

Code::Blocks

I got U3 working, and I love it, but I'm working out the kinks on the rest of my thumb drive programs, like Code::Blocks; see next paragraph.

I've installed Code::Blocks on my Cruzer - it's easier to call it by its model name than "USB drive" or "thumb drive", and it sounds cooler - but I can't get it to see the MinGW compiler I installed there too. That means, I can't compile any programs! I tried getting MinGW to work with SciTE - a text editor I only picked up because it has decent Lua highlighting, and it's easy to point it to a lua compiler - but even when I point its C++ compiler setting to the compiler executable, it tosses a gazillion errors at me - all sprouting from me including . -_-

So, now I'm on the GameDev IRC channel, scrounging around for help getting this to work. (Code::Blocks, not SciTE, please) I guess I'll be able to get back to real programming when I come back from vacation... that's in 8 days.

Hmm

I've been trying to post 1-2 times here, once early and once late, so here's my late post. [grin]

Today I took to the task of splitting my .h files, which had class declarations AND definitions, into .h's with declarations and .cpp's with definitions. Took me a LONG while to actually figure out how to do it properly, with thanks going to P16.. wow, "P16" looks a lot like PIG.

Uhm.. I'm not sure if I want him to read that...

EDIT: Ooh, I'm going to have to start watching for when my journal viewcount hits 1337. [wow]

O_O

I've, like, neglected this thing. Not to mention GDNet+ expired on me. I've moved on from my Arena Battle project.. in retrospect, it was getting kind of convoluted. I'm now working on something totally new for me... Project 1 in the C++ Workshop!

No, seriously, it's new! You have to color the output, so I Googled around and found this. Encapsulating it in a class (cConsole), and setting a few functions for easy manipulation, I've created an easy interface with the console screen. I can color output with output(), and check specific keypresses with getKey().

Oh, getKey().. I just love it. I'll code-tag it here, and explain it, although all you C++ gurus out there should be able to understand it just fine. I just like explaining. :D

char cConsole::getKey()
{
while (true)
{
GetNumberOfConsoleInputEvents(rHnd, &numEvents);
if (numEvents == 0) continue;

INPUT_RECORD *eventBuffer = new INPUT_RECORD[numEvents];

int i = 0;
for (; i {
if (eventBuffer.EventType == KEY_EVENT)
{
int j = 0;
while (j {
if (eventBuffer.Event.KeyEvent.wVirtualKeyCode == keys[j])
{
delete eventBuffer;
break;
}
j++;
}
if (j == keys.length() + 1)
{
i++;
continue;
}
else return keys[j];
}
else
{
i++;
continue;
}
}
}
}

To start with, I have a public string variable in cConsole (don't yell!) that the user can set to, say, "123". This function cycles through any events that occur until a key event occurs. Then it cycles through the 'keys' string I mentioned, checking the key event against each character in 'keys', until it finds a match or cycles the whole string. If the iteration variable 'j' is 1 more than the string length, then it didn't find a match, and it continues. Otherwise, it returns the char that was matched, so the calling function can deal with it.

I love it. :D

The moon

I guess the Portuguese actually don't see the same moon as the rest of us. Seems they just see a big ball of code in the sky.

Ahem.
And for those people who actually comment here, I might just try SDL after I get a handle on the Lua basics. I kind of want to work on a simple text game before I go into graphics.