Monday, April 23, 2007

Almost a game...

Today I merged the UI code with the Gamestate code. And lo and behold: Something that looks like a game.

Almost a game, almost.

I discovered there is something severely messed up(I nearly wrote fucked up) with my Post-Build step. It doesn't update the revision in the bottom of the screen properly. It probably has to do with TortoiseSVN and it not going a proper update after the commit. Because if I do an update after the commit and recreate the file, it works like a charm. Pretty weird.

Also, I'm thinking about how I am going to handle building of stuff. First of all, I need something that manages buildings. We shall call this the BuildingManager. The BuildingManager contains a list of all buildings in possession of the player. When a building is destroyed, it will remove it, etc. Also, I need something to uniquely ID the buildings across the network(Yes, I'm also thinking about). So, each building will have an unique identifier, which is nothing more but a sequential integer.

When a building is being constructed, the BuildingManager will receive it's application and store it. It will then return the unique identifier to the building and inform the network about a newly constructed building. When it is the first building of it's kind, it will also contact the ConstructionManager. The construction manager will look in TechTree and see if there are any changes needed. If for instance the building just placed is a construction yard, it will see that after a construction yard has been built, the slab and windtrap will be unlocked. It will then add these to the construction sidebar.

For a networked game, there will be a RemoteBuildingManager(RBM) and a RemoteConstructionManager(RCM). The RCM will not schedule any construction, it will only pass the order to the correct building. The LocalConstructionManager(LCM) however, will find an idle building and post the build order there to be completed. This has the added pro of the game being able to check if a player is using hacks(Because, it can see how long it takes before the next build order arrives. If the remote player has an instant build hack, it can see that the player still has to wait for the construction to be completed).

So, still a lot of work to do, and I'll start out with the techtree loader tomorrow.

Wednesday, April 18, 2007

Hello Arrakis!!

I added some more features to the Windowing system, and I think I'm done for now with the system. All that remains are the controls to be written, and I'll write those as soon as I need them.

Features I've added:
- Complete rendering of the borders and title bar
- Client rectangles(Client Rectangle = Window - borders)
- Dragging of windows
- Move event for when the window is being dragged around

The dragging of the window was quite some work, as I needed to change quite a lot of code. It wasn't very difficult, just required a lot of code changing, since I never wrote the code to be able to drag the windows around, nor intend to have borders around it them(Pretty stupid).

This initially ended up with the Control class drawing itself on the wrong position while being dragged, and the derived class draw on the correct position. Pretty weird, and I still have no idea why this happened. The image below shows this in action(I had to place my fingers in a really uncomfortable position to be able to get this pic. My left hand pink and ring finger held down the FN + ALT key, while my thumb help down the L-mouse on my touchpad, my index finger drew circles on the touchpad and my right hand was used to pressed Print Screen).

Dragging bug in action, nearly lost my fingers while obtaining this image

After I fixed the dragging bug, I'd figured I'd make a standard dialog window(Not yet written, but the code needed for it is ready, just need to be moved into another class). This is what it looks like:
Standard dialog with label and button

How does the dragging system work?
When the L mouse down event is catched, it checks if the mouse is over a window. If this is true, it will check if the mouse is within the ClientRectangle. If this isn't the case, it checks if the Y is within the bounds of the TitleBar. If this is true, it will record the state as Dragging for the LMouse button, and which control it is dragging.

On every mousemove, it checks if the LMouse is down, and when this is the case AND the state is dragging, it takes the Delta X and Y and substracts this from the position of the window. It then forces to update all the client rectangles and voila, done.

New control
I added a Label control. Not very special, it took like 2 minutes to create...

Todo for now:
- Create a MessageBox class.
- Add support for modal windows
- Incorporate UI into existing game class.
- Build CreditCounter control(Dune specific)
- Layout new todo list for building, techtree, etc.

Also, to answer a previously asked question about open-sourceness:
For now, I will keep the source closed. This is a personal project, and I don't take kindly to people changing my code while I'm still working on the game. However, after the game is completed, I might open-source it. However, I might, might release my UI system, in case people want to take a look at it, and perhaps improve it. It's not the best system out there, there are MUCH better UI systems out there, but it works for a small amount of controls.

Sunday, April 15, 2007

Image strips are in... And update on dialogs

Today I managed to add the images into the imagestrip. The image strip is the little strip that holds all the icons of the units/buildings you can make, and allows you to scroll through it.

It was rather simple to implement, except I ran into 2 little problems: The original images that were used in the original Dune for the imagestrip end up HUUUUGE when enlarged. So I scaled them up 2 and then reduced them to 66% of their size. That worked quite well(As you will see below).

After that it was a matter of painting the green bar between the 2 images and fit a few images in. Fitting the images in wasn't very difficult, except that was were the other problem was: The icons Stefan provided with his Dune 2 image set were too small. Increasing them in size turned out horrible. Really horrible. Loads of artifacts and they were pretty pixelated.

So I had to find a way to extract the images myself. This was rather problematic, as I had no idea which of the PAK files contained these images, and only 1 PAK file contained the palette files. I downloaded XCC Utilities and started messing around, but I was unable to load a palette after loading a new PAK file.

Eventually I extract the palette file, made copies of the MENTAT.PAK and FINALE.PAK. I then opened up XCC editor and placed the palette file into both these files and saved them. I then loaded up FINALE.PAK and MENTAT.PAK into XCC mixer and discovered that mentat had all the images, but that finale.pak also had a bunch. Duplicates that is, since all these images were also in mentat.pak. I have no idea why there were 15(!!) duplicates in the FINALE.PAK. These images(All just 1 frame) were the sardaukar, death hand, fremen, refinery, MCV, sand worm and a few others. When I looked in mentat.pak, I fould all the images, with their animations.

I extracted these files, and converted them into icons. The icons are 52x32 in size. If anyone wants these, for whatever reason, let me know, and I'll upload them. I also have to extract a few other files from the dune.pak file, since these are missing(I think I'm missing 1 missile impact animation and the burning/burned out tank).

Right now I need to update the image strip so that clicking is supported, it's possible to mask out all the images except 1(The building animation, not sure how I'm going to do that with multiple construction queues) and I need to fix the windows and their title-bar/border drawing.

The UI in action, showing the image strip(Scrolling works) and a window with title bar

I also need find a better way to render client areas of Windows. Right now they are textures. That's a a massive waste of VRAM, so I need to fix that. I'm probably going to use quads for the client area and just cram them into a VertexBuffer and render all the client areas at once. Not sure how that will work out, but I'll experiment with it. Alternatively, I could just create 1x1 textures with the correct background color, and rendered them stretched. Don't know which one is less work and/or cheaper to do in terms of performance.

Thursday, April 12, 2007

More gooey goodness...

Ok, f this. I just spent 30 minutes writing up an entry about my awesome progress with in-depth details of decisions, backgrouns and other information, and then Firefox decided to crash.

When I restarted it, it recovered the session, but the entire post was gone. And apparantly, clicking 'Recover post' does nothing, except show up a messagebox that it will replace the post with an older version. WHAT OLDER VERSION?

Here's an image of the UI in action: A button with the mouse over it and the left mouse button down. Hooray, BOOOOORING! And yes, I'm annoyed now. Really annoyed. Annoyed as in I want to break something. And yes, I have anger management issues. It's a miracle I never killed someone.

A really not very exciting image with a button responding to a mouse down event. Tee hee

Wednesday, April 11, 2007

It's my birthday...

So yeah, I turned 24 today. Nothing special, just a funny cat. Also, I have no time to code today.

Monday, April 09, 2007

Still working on the UI....

Yes, I am working on the UI stuff. I got the events sorted out, and I'm right now working on rendering the system controls and the window bar. Nothing special to see right now.

To keep you guys happy, here's a cat. DuneCat

Saturday, April 07, 2007

User Interfaces are GO!

So, yesterday I started working on the user interface code. I thought it over a bit, and came to the conclusion I would go with the "Everything is a window" approach. The reason for this was so that I could make the WindowManager class a Task, shove it into my engine, and forget about it.

However, it made me think later on: What if you're playing an FPS, and everything is a window? Then there might be a chance that you have your comm. window open while laying an ambush. You suddenly see an enemy walk around the corner. He hasn't seen you yet, so you jump up, aim at his head and hit left mouse. But instead of shooting him the head, you'll order a pizza from the comm. window, and end up dead yourself. Oops, comm. window stole the cursor focus.

So, before I managed to mess everything up, I changed it all to be "not-everything-is-a-window", and non-task. Basically, I have to keep track of the WindowManager now, and during each update cycle check if the mouse is over a window, and then ignore the input in the regular game handler. When it's not over a window, I do my normal mouse logic. In the case of the FPS, it would mean I have to press a special button before I'm able to interact with the UI.

Right now, basics are in, that is: I have the WindowManager, basic flat-style windows and response from the windows from the mouse. As seen in this exciting image(I merged to images together, because having 2 huge black images with 4 colored squares is boring).

Basically, I clicked on the blue window, and it came Top-Most. Exciting huh? Indeed, it's not...

Before I started to work on the gooey system, I also updated my mouse input code a bit. It no longer uses DirectInput but regular Mouse Events. This has the added advantage of that I have the mouse acceleration that Windows provides for me(Before, the Windows mouse would move faster than the in-game mouse. That's now fixed.). Also, the Windows mouse cursor is now hidden. I have no idea what kept me from doing Cursor.Hide() in the first place...

Tomorrow and monday it is easter(Yes, we have 2 easter days), so I doubt I'll manage to do any work on the gooey system. But, I'm currently writing the mouse-event cascading system. Meaning: When the mouse is over a certain window, this window will check for any updates(movement, etc.) and trigger the events, and then see if any of it's children need to know about the mouse update. I started out with this code to be in the WindowManager, but that ended up being a horrible mess. So I now leave this to the base Control class.

Thursday, April 05, 2007


I finished coding up the windtraps.

The technique behind this is pretty easy. What I do is create a static texture for all windtraps in white. During rendering, I first render the white texture with an overlay color, and on top of that, I render the normal windtrap texture. And in the Update() function of the windtrap, I have a timer to increase/decrease the color every 1/10th of a second. Simple, and effective.

I will probably add this texture to the SpriteSheet, as it would reduce texture swapping. And texture swapping is bad, m'kay?

I also added a link to the development blog of an online friend of mine. He's developing a 3D engine and a bunch of games with it. Except it takes him a decade to produce it all. Yes, I'm serious. A decade.

Tuesday, April 03, 2007

Building basics are done

I got the basics of the buildings in! And by basics I mean the image files, the classes(Each building has it's own class, as oppossed to units which mostly consists of 1 class and a few derived for special units).

Buildings in action

The reasons are simple: Most buildings have a bunch of animations which are non-standard(starport, refinery, radar), buildings also add 'things' to the game. For instance, building a light factory, enables you to construct new units. By spawning the building, it 'registers' itself with the game, exposing the features to the rest.

All the buildings also play their 'pre-deployment' sequence. This is a different sprite(See below), which is displayed when the building is deployed. It then 'blinks' between the normal and the deploy image a few times with decreasing interval and finally shows up normally. Nothing fancy, nothing difficult to make. However, I must say, I'm getting a quite a lot of timers... Thank god timers don't have a 68MB memory footprint(A la the clock in Vista).

Buildings before being fully deployement

I'm not sure how I'm going to proceed from now on. Probably the next thing to do is to get the powerplant operational, showing it's animation. EDIT: In before someone comments about it: Yes, the 3x3 and 3x2 buildings are off half a tile. This is because they render using their position, not by tile. since I used 64 as X position, it renders from 64 - (32 * 1.5) = 16. Would I use X - 80, they'd render normally.

However, this probably does bring up the problem I had before: Images are alphablended into 1 fugly soup of weird colors. I really should spend some time testing out with the various D3DXSprite render modes to figure out how to only replace specific colors. If the power plant works, I'm going to make buildings selectable, including a selection marker.

After that, I will probably start working on the UI parts. I'm not really looking forward to that, but after that, it will start piecing together.

Stefan: On a sidenote to what you said about rotating the turret and moving: Good point. I'll fix that aswell.

In other random news: I got a new archwire for my braces. I went for 012 to an 016. I know it means the thickness of the wire, but not really sure how. I'd assume it's 0.12cm, but not sure. Anyway, my teeth are sore now. But I know what I'm doing it for: sexy teef!

And, changed the layout of the blog a bit. I upgraded to the new layouts, which allow me to expand the layout myself. I'm probably going to add a ToDo list to the left navigation bar. Should be hot.

Monday, April 02, 2007

Little weapon update!

I fixed a few things in the weapons. I made rockets leave smoke trails. It does look good, when you fire a single rocket. With 2 rockets, it looks a whole lot less pretty. Probably has to do with the fire rate of 0.5 and the trail spawning with the same rate. Here's how it looks:

Looking good. I did have a few bugs with it, which was good in the end, since I had a nasty little parse bug with the rules.ini. Apparantly, float.Parse() looks at the Locale settings for numbers, and on my Dutch settings, it excepts to see a ',' as decimal point, instead of a '.'. Therefor, it parsed my 0.5 to 5. I fixed that with with a NumberFormatInfo instance, setting the correct char and passing it to every float.Parse() call. Nothing serious.

Oh, this was a little timing info bug. I had the smoke trails randomly pick a number between 0.0 and 0.5 for releasing their puffs, but forgot to set it back to 0.5 after the initial puff(I wanted a gap of 0.5 between puffs, and a random first puff, so they're not all on the same spot).

This is the final result, including a demonstration of the enemy quad being on firing(Including debug output. I should remove these, otherwise I end up with a cluttered debug log, which I don't really want.

Now I'm going to add Buildings to the game, and after that, the User Interface :D.

Speaking of which... I have basically a week off... Not something I'm very happy with, because I'm missing 5 exams now. But my stupid college requires that I sign in for every course I follow(I'm automatically enrolled to the course, but I have to enroll for the exams). Since I forgot to enroll myself for the exams, I'm not allowed to make them. Kinda weird. You're enrolled for the course, but not for the exam by default. I'm pretty pissed off...