• entries
72
38
• views
22419

Here is what you weren't looking for.

## I love the morning!

Yeah, mornings rock when I don't have to work.

Wednesday night we had a few tornados in the area, I lost power at about 7pm that night. Nothing big really, a few trees down and the usual. The damage from this was nothing compared to what is currently going on in the gulf. This is really about how I lost my last mornings of joy.

Thursday came around, and I get a call at 7am from my boss, he told me they do not have power yet and I should wait by my phone. I kindly informed him that I have today off, but thanked him for the information. I had to bring my girlfriend into work because bla bla bla early in the morning, at this time there were about 110,000 people in my area w/o power. So 1 out of 3 people are unshowered and looking for coffee, the local gas station was closed and all the ones I drove by were packed full. I was one of the unshowered in need of a pack of smokes and a cup of joe. Not that interisting, I know. Just getting to the point, I left home a little after 7am and arrived home around 10am, it took like 3 hours to get coffee and smokes. I tried to call my family to see if anyone needed help with some cleaning up, didn't get a hold of any of them. I decide to move my computer desk now that it's off, and I can't turn it on. It was fun, and I am happy that I have it where it is now, but I ended up sitting at home with no power until about 5pm. Then I had a serious game session, yay.

Saturday we had a generator and air compressor rented, the power company said since we have partial power and other places have none, we were on the bottom of the list. They said it would be 3-5 days (from Thursday) before power would be restored fully. Saturday was actually nothing to complain about really, we had a lot of extra people. I usualy get stuck on CS calls all the time and have to clear thoes before it will send in the TS queue. With all the extra people, it was really slow and I was able to poke around online when I was not on a call. Plus we only stayed 1 hour later than normal, insted of 3. The call volume was not as high as they had anticipated. My friends are having a baby, and I went to my first baby shower after work. It was boring.

Sunday, this is soo much better. In my favorite spot, I have a nice playlist put together, just started drinking my 2nd pot, just finished putting summaries on two classes I made for my GTR File project, I couldn't be happier. I added support for multiple input files when importing to archive, and also a new file button. Infact I just found out about how to add summaries to my code. For all of you who don't know already, if you type three slashes "///" above a function or variable like you are going to comment it, it will fill in the "" tags for you. Makes it nice so you can comment for intellisense.

I doubt many people are interested in this, but here are the two C# classes I made. They are not really finished, I am working on getting the DataBlock to be a MemoryStream insted of a byte array, so keep that in mind if you actually read the code.

GTRFile.cs

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;

using ICSharpCode.SharpZipLib;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;

namespace GTR_File
{

/*
* Class: GTRFile
* Class for accessing elements stored withing the
* .GTR files
*/
///

public class GTRFile
{
System.Int64 SIG_HIGH = 0x414d524f544f4d47;
System.Int64 SIG_LOW = 0x0000000000303153;

///
/// Number of items in file.
///
public int items;
///
/// Length of stored file in bytes.
///
public int FileLength;
///
/// The full path of file.
///
public string sourceFileName;
///
/// true if file has been Parsed, false if not.
///
public bool parsed;

///
/// The index in file of first DataBlock byte.
///
private long DataOffset;
///
/// The ArrayList holding our GTRFileItem collection.
///
private System.Collections.ArrayList ItemArray;
private System.Int64 SigHigh;
private System.Int64 SigLow;

///
/// Constructor.
///
/// Name of file.
/// bool, parse file after open.
///
public GTRFile(string filename, bool parse)
{
ItemArray = new ArrayList();
parsed = false;
sourceFileName = filename;
if(parse)
this.Parse();
}

///
/// Create a new GTRFileItem.
///
/// The new item.
public GTRFileItem NewItem()
{
int item_n;
++items;
return (GTRFileItem)ItemArray[item_n];
}

///
/// Get GTRFileItem for index number.
///
/// Zero based index of item.
/// The GTRFileItem for index.
public GTRFileItem GetFileItem(int n)
{
if(n >= items)
return (GTRFileItem)null;
return (GTRFileItem)ItemArray[n];
}

///
///
///
/// The success of the operation.
{
try
{
return false;

}
catch (Exception e)
{
}

return true;
}

///
///
/// seeked to the begining of the file.
/// true if the signature matches, false if not.
{
try
{

if(SigHigh == SIG_HIGH && SigLow == SIG_LOW)
return true;

MessageBox.Show("Signature Mismatch!", "GTRFile::CheckSignature()");
return false;
}
catch (Exception e)
{
string strMsg = e.Message;
MessageBox.Show(strMsg,"GTRFile::CheckSignature()");
return false;
}
}

///
/// Parses the GTR file, reads the file index and loads the items into ItemArray.
///
/// The success of the operation.
public bool Parse()
{
System.IO.FileStream infs;

try
{
infs = new System.IO.FileStream(sourceFileName, System.IO.FileMode.Open );

for(int i=0;i {
GTRFileItem titem;
titem = (GTRFileItem)ItemArray[n];
}
for(int i=0;i {
GTRFileItem titem = (GTRFileItem)ItemArray;
long seek_pos = titem.Offset + DataOffset;
byte[] buff = new byte[titem.Length];
titem.StoreDataBlock(buff,titem.Length,true);
//titem.CompressedBlock = true;
titem.CompressionLevel = 1;
}

parsed = true;
return true;
}
catch (Exception e)
{
string strMsg = e.Message;
MessageBox.Show(strMsg, "GTRFile::Parse()");
return false;
}
//return false;
}

///
/// Get a BinaryReader seeked to selected indexed file.
///
/// Zero based index of item.
/// BinaryReader seeked to position of data in the .GTR file.
{
System.IO.FileStream infs = new System.IO.FileStream(sourceFileName, System.IO.FileMode.Open);

GTRFileItem fitem = (GTRFileItem)ItemArray[n];

{
}
}

///
/// Write a header for current in-memory file.
///
/// An open BinaryWriter to write to.
{
bwriter.Write(SIG_HIGH);
bwriter.Write(SIG_LOW);
bwriter.Write(items);

int dblocks_sz = 0;
for(int i=0;i dblocks_sz += ((GTRFileItem)ItemArray).Length;

int total_len = 16 + (items * 256) + dblocks_sz;
bwriter.Write(total_len);
}

///
/// Calculates offsets for all items in array.
///
/// Number of offsets calculated.
public int CalculateItemOffsets()
{
int ret = 0;
int run = 0;
for(int i=0;i {
GTRFileItem item = (GTRFileItem)ItemArray;
item.Offset = run;
run += item.Length;

++ret;
}
return ret;
}

///
/// Write index data for GTR file.
///
/// An open BinaryWriter seeked past header.
public void WriteIndex(System.IO.BinaryWriter bwriter)
{
try
{
for(int i=0;i {
GTRFileItem item = (GTRFileItem)ItemArray;
bwriter.Write(item.Type);
bwriter.Write(item.Offset);
bwriter.Write(item.USize);
bwriter.Write(item.Length);
byte[] fn240 = new byte[240];
// no string to byte[] conversion?!
// we have to copy the string into a char[]
// and then convert to byte[].
char[] grr = item.FileName.ToCharArray();
for(int j=0;j fn240[j] = Convert.ToByte(grr[j]);

// fill in remaining with 0x00
// item.FileName.Length will point us to 1+ the last
// byte in the filename in fn240 because it is zero indexed
for(int j = item.FileName.Length;j240;++j)
fn240[ j ] = (byte)'\0';

bwriter.Write(fn240);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message,"GTRFile::WriteIndex()");
}
}

///
/// Write DataBlocks from items to file.
///
/// An open BinaryWriter seeked past index.
public void WriteDataBlocks(System.IO.BinaryWriter bwriter)
{
try
{
for(int i=0;i {
GTRFileItem item = (GTRFileItem)ItemArray;
bwriter.Write(item.DataBlock,0,item.Length);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message,"GTRFile::WriteDataBlocks()");
}
}

///
/// Remove item at index from ItemArray
///
/// Zero based index of item to remove.
public void RemoveItem(int index)
{
if(index >= 0 && index this.ItemArray.Count)
{
this.ItemArray.RemoveAt(index);
this.items--;
}
}
};

}

GTRFileItem.cs

/*==========================================================
* Class: GTRFileItem
* Stores local information about each item archived in
* the .GTR file.
==========================================================*/

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;

using ICSharpCode.SharpZipLib;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;

namespace GTR_File
{
public class GTRFileItem
{
public static Int32 GMT = 0x00000011;
public static Int32 BMP = 0x00000012;
public static Int32 TGA = 0x00000014;
public static Int32 DDS = 0x00000237;

///
/// Type code for stored file.
///
public int Type;
///
/// Data-start offset past end-of-index.
///
public int Offset;
///
/// Uncompressed size of item.
///
public int USize;
///
/// Compressed length of item.
///
public int Length;
///
/// Local filename.
///
public string FileName;
///
/// byte array holding item data.
///
public byte[] DataBlock;
///
/// MemoryStream holding item data.
///
public System.IO.MemoryStream mstrm;

///
/// true if data is currently compressed, false if not.
///
public bool CompressedBlock;
///
/// Compression level used when compressing file.
///
public int CompressionLevel;

///
/// Empty, default constructor.
///
public GTRFileItem()
{
}

///
/// Discover the type code for the given file.
///
/// The filename to process.
/// 32-bit integer file type, 0 for unknown.
public Int32 FindItemType(string filename)
{
int flen = filename.Length;
int dotpos = 1 + filename.LastIndexOf(".");
if( (flen - dotpos) 3)
{
return 0;
}
char[] buf = new char[3];
filename.CopyTo(dotpos, buf, 0, 3);
string fileext = new string(buf);

if(fileext == "TGA")
return TGA;

else if(fileext == "BMP")
return BMP;

else if(fileext == "DDS")
return DDS;

else if(fileext == "GMT")
return GMT;

else
return 0;
}

///
///
/// The success of the operation.
{
try
{
string stmp = new string(ctmp);
int firstz = stmp.IndexOf('\0');
stmp = stmp.Remove(firstz, (stmp.Length - firstz));
FileName = stmp;
return true;
}
catch (Exception e)
{
return false;
}
}

///
/// Store data into items DataBlock and mstrm.
///
/// byte array to read from.
/// number of bytes to read
/// true if data passed is compressed, false if not
public void StoreDataBlock(byte[] indata, int length, bool compressed)
{
this.DataBlock = new byte[length];
this.DataBlock = indata;
this.CompressedBlock = compressed;
this.mstrm = new System.IO.MemoryStream(length);
this.mstrm.Write(indata,0,length);
}

///
/// Decompress DataBlock and mstrm.
///
public void DecompressBlock()
{
if(this.CompressedBlock == false)
return;
try
{
ICSharpCode.SharpZipLib.Zip.Compression.Inflater inflater = new
ICSharpCode.SharpZipLib.Zip.Compression.Inflater(false);

this.mstrm.Seek(0,System.IO.SeekOrigin.Begin);
InflaterInputStream ifStream = new InflaterInputStream(this.mstrm,inflater);

System.IO.MemoryStream iblock = new System.IO.MemoryStream();

byte[] dbuf = new byte[this.USize];

int len = 0;
while(true)
{
int sz = ifStream.Read( dbuf, 0, 4096);
if(sz 0)
break;
iblock.Write(dbuf,0,sz);
len += sz;
}

this.mstrm.SetLength(len);
this.mstrm.Write(iblock.ToArray(),0,len);
this.DataBlock = iblock.ToArray();
this.CompressedBlock = false;
this.USize = len;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message,"GTRFileItem::DecompressBlock");
}
}

///
/// Compress DataBlock with given compression level.
///
/// Level of compression (1-9)
public void CompressBlock(int level)
{
if(this.CompressedBlock == true)
return;
try
{
// record the uncompressed size
this.USize = (int)this.DataBlock.Length;

// Ms is the destination for the deflated stream
System.IO.MemoryStream Ms = new System.IO.MemoryStream();
// deflater initilized with compression level and header flag
ICSharpCode.SharpZipLib.Zip.Compression.Deflater deflater = new Deflater(level,false);
ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream Ds = new
DeflaterOutputStream(Ms,deflater);

// write the uncompressed data to the deflater stream
Ds.Write(this.DataBlock,0,(int)this.DataBlock.Length);
Ds.Flush();
Ds.Finish();

// copy compressed data to the block
this.DataBlock = Ms.ToArray();
// resize our objects memory stream
this.mstrm.SetLength(Ms.Length);
// update stream
this.mstrm = Ms;
this.CompressedBlock = true;
this.CompressionLevel = level;
this.Length = (int)Ms.Length;

Ds.Close();
Ms.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message,"GTRFileItem::CompressBlock");
}
}
};
}

Secrest, out!

Ok, that was too easy... I love the mornings!! Coffee is my best friend until about noon, when my stomach starts to boil and I have to switch over to something like water, pop, or juice. But for the two hours I have left before that happens, I will work on removing an item from the file, and inserting at a point in the index other than the end.

It just seems like that was way too easy. I just moved the decompression function into item class, because it has the DataBlock stored in itself now. After that it just became a matter of looping throught the array a few times to get the data I needed, in the order I need it. I'm thinking that removing an item from the "file" will just be a removal from the ArrayList, and overwrite the existing file, or save as new. Pretty much same thing with the insertion-at-index, I should be able to easily do that to the ArrayList, and again just overwrite or save as new from the updated list.

Maybe I will make it to adding recompression with different level today, who knows. I guess I will upload source and exe files later tonight when I feel I'm done for the day.

I still have to determine type code from file extention too, but here is a screenie for you.
C5RICON.TGA is the file I imported into the original archive.

Uploaded with release, and debug builds, with source code, and required DLL files.

## Its a little better.

Looking back, it makes sence that the data blocks are compressed. I was able to get SharpZipLib to do exactly what I wanted, and in minimal code. Really just a function call to the inflater and deflater, check the return code for errors and all was good.

Extracting a file out of the archive is working great. I decided to move the decompression function into the class that reads and parses the file. I also added a place to store the datablock in the FileItem class. I think this will help when I finish the import routine, because I will need to rewrite the file, I will have to recalculate the offsets. Ok, so that does not really explain why.. but I will have the output routine in the class that has the ArrayList of FileItems, so it can write out the file index, and because the file uses an offset that starts at the end of the index I don't need to calculate it. It should go something like this, item.offset = sum_of_all_previous_items_lengths. The first index always has an offset of 0, this is handy.

Anyways, I'm not much of a writer so I'll just get on to coding today. I hope I can finish the importing this morning.

I came up with a funny question...
When dealing with compressed files that are being read off of a hard disk, is it faster (with modern processors) to read in 9,000 bytes and decompress it in to memory, or read in the uncompressed 900,000 bytes stright in to memory? I know that the HDD is the slowest deice in the system, but 900,000 bytes isn't alot. I do think it is faster to decompress the chunk in memory, but I want to write a feature for this program that will rearchive the file with lower compression, to see if I am wrong. To see if the game actually loads faster because of the reduced compression. Too bad I probally will not be able to actually measure the difference. I can't think of anything other than my wrist watch that will be able to time the length of the loading screens for the game.

Until next time.

## Zoned out.

And not long after that I bought GTR, and then a Logitech MOMO Racing wheel. I can't really say enough about how great a nice wheel is for racing game fans. So I won't.

I will tell you that it finally got me up to coding again though. I have not really done alot of programming lately, so I decided to do a little 3rd-party app for my new favorite game.

The challenge, extract files from a game data file. All was well, I found the signature, then the number of items, and the total file length. Followed by 256 bytes for each item, four for (what I think is) a type identifier, 4 bytes start offset, 4 bytes unknown (at this time) use, 4 bytes data block length, and finally two hundred and forty bytes for file name.

Read all the items into an ArrayList for storage (in a class), and display the list in a ListBox. Simple enough. Read the data start offset and add that to the items offset, Read the length into a file.

Well, the data I get isn't what I expected. I have an idea on what the unknown data field is, I think it is the uncompressed length of the file stored. I think that because the unknown field is always larger than the length field. I extracted a BMP file, and it was not correct, header was completly wrong. Ho-hum, compression seems like it would be pretty normal.

Now I just hope its RLE, because everything else is a little complicated to just impliment on the fly into the tool. Looking at how 'simple' the data is stored in the file, I think it will be RLE but I have alot of research to do to find out what kind of compression this uses just by looking at the files data. RLE also seems likely because it would be easy to read and decompress at the same time. The data block always starts with 78 9C (hex) and the following two bytes seem to always fall on hex combinations of D and E, but have been observed to be different at times. If you know alot about RLE detection, or compression in general, and would like to help out email or PM me please!

If you have GTR, you can download my little tool if you want to see what is inside the .GTR data files. GTR File (C#, requires .NET).

## more

The chapter on transactions seemed short. I guess that they just sound complicated. More likely they will get back to it later, and this is juat an introduction to them. Other sites have given the book some bad reviews, but I don't really care. Most of them were just talking about code errors. Newflash people, technical books have errors! Thats why they have errata on some website, the good ones do. Take it for what it is and learn from it. It's not intended to make you a master at everything ever in ADO.NET. I'm sure it would have to be 3 times thicker and would make actually just learning about it much much harder. If I like what I find in ADO.NET with this book, I might pick up the hard cover MS-Press book on the subject, named just "ADO.NET". Can't trust reviews on most places that only give the reviewer one paragraph to describe it.

I'm also excited about my plan to finally take my MS certs this winter.

Yay!

## Slow down champ.

Working through the first few chapters of a book can be interesting. What happened to me, was not really paying attention to what the book was trying to teach me at that time. It was just going over opening and closing connections. The sample code did some other things, where we had to write some code. I decided to test myself, by commenting the source, to prove to myself I know what I learned. Well I was wrong. I thought it was doing something completly different than what it was really doing. So I got side tracked by trying to learn what I was doing in these places that were not the real focus. After this happened, I thought to myself "they should warn you, 'its ok to not understand this and that'". Well, the next chapter had a section that said just that.

Yay.

## I'll be back

After my drive crashed, and summer time hit in.. I had no time. I took 2 vacations, one in June and one in July for the 4th. In June my and the GF went to Lakeside, Ohio. Drove there, and back. Well I rode in the back of a Suburban, in total we spent 3 full days driving. Lakeside is cool, but its a sober community. I guess that is the only way to keep it nice like it was, very peaceful.

So yeah, summertime crept up on me and stole all my time. Not to mention all the money that you put into your car in the summer. Now I am poor again, and will be spending much more time in VS.

Oh yeah, and other forums are boring.

## Something programming related.

I finally bought an ADO.NET book, found this one at Barnes & Nobel and decided to pick it up. I have no way to rate, or review it because It's my first book on ADO.NET. With that being true, I want to say that I do like how it gets you into the creation of objects quickly. Minimal setup time for the MSDE (if you know what you are doing) is required. It gives C# and VB samples which is nice.

I think I am like most people, who have a general idea of what a database system does, and take a wild guess about how it works. I really do like expanding my knowledge on different computer related subjects.

Until next time...

## Busy.

Yeah, I have been busy playing games. I feel a bit distant from game programming right now. I think I should widen my skill set. I have done most of my programming with from-scratch source, I really need to get more comfortable working with different API styles. I am working with .NET stuff right now, just basic controlls stuff like reading values from textBoxes and such.

I have been also working on a keylogger for use at work. We work with an AS/400 database, and the terminal client does not have a history. So I figure I'll see what I can do with a keylogger. They seem easy enough in form, but mine crashes the application that is in focus when the input is read. Fun stuff. A little hard to debug though. I dont have a system debugger like SoftIce, maybe I dont need one, but I set a breakpoint in the code that is within the KeyboardProc function that I wrote, and it does not break. I have set the breakpoint to several positions and none of them cause it to stop before the crash.

I also want to learn about multi-threaded applications. I think I better learn that now, with multi core being the new standard in CPU development from now on.

## oh teh noes!!

my C: drive is gone. virus? maybe. booohoooooo hooOOO!!!!! :(

## Untitled

User input has been added. I might have found why I was having upload problems. Still at work, so I will make this one short.

## im writing in here

I have alot of the little bugs worked out of the game logic code. Some new stuff was added for a computer player AI with Basic Stratigy plus a High-Low count. I was going to add input so the player wasnt always a computer player, but I didnt really try too hard. I was busy cleaning up the rules logic, it was some times paying out on player busts. I still have a some-how-broken bool that is getting a true reading, when the last function set it to false. But oh well, here is a run that went better than any have with the current build.

Most runs only go 400-900 rounds, and have a high funds of about the same range.

I tried to upload it, but I get this:

I try again, and I get a different error. So Ill just post the new stuff in source.

#ifndef _TABLE_H_
#define _TABLE_H_

#include "Player.h"
#include "Deck.h"
#include "Hand.h"
#include "Card.h"

typedef struct TableRulesT
{
float minBet;
float maxBet;
unsigned int numDecks;
float Saturation;
} TableRules;

class Table
{
public:
Deck* TheCards;
Deck* TheBoot;

Player * Dealer;
vector Players;

TableRules Rules;

Table()
{
Dealer = new Player();
Dealer->name = "Dealer";
TheCards = new Deck();// (52);
TheBoot = new Deck();
SetRules();
TheCards->Generate(Rules.numDecks);
}
~Table()
{
delete Dealer;
delete TheCards;
delete TheBoot;
vector::iterator b = Players.begin();
vector::iterator e = Players.end();
for(;b != e; ++b)
delete *b;
}
{
Player * p;
Players.push_back((p = new Player()));
string pnum;
string pname = "Player";
p->name = pname ;
p->funds = 300;
return p;
}
Player* GetPlayer(unsigned int i)
{
return Players[i - 1];
}
TableRules SetRules(float minBet = 5, float maxBet = 200,
unsigned int numDecks = 4, float sat = 0.35f)
{
Rules.minBet = minBet;
Rules.maxBet = maxBet;
Rules.numDecks = numDecks;
Rules.Saturation = sat;
return Rules;
}

bool BetsDown();
void Deal();
void ShowTable();
void PlayersTurn();
void ScoreRound();
void CollectHands();
void AIBasicPlayer(Player * player);
};

#endif

#include "Table.h"

bool Table::BetsDown()
{
bool AllDown = true;
Player * p;
vector::iterator b = Players.begin();
vector::iterator e = Players.end();
for(;b != e; ++b)
{
p = *b;
if(p->active)
{
p->busted = false;
if(p->computer)
{
// setup computers Count based bet
if(TheCards->Count > 1)
{
cout "Count is: " Count float bet = (Rules.minBet * TheCards->Count);
if(bet > p->funds)
bet = p->funds;
p->bet = bet;
}
else
{
p->bet = Rules.minBet;
}
}
else
{
// input bet
}
if( (p->bet >= Rules.minBet) && (p->bet {
if(p->bet > p->funds)
p->bet = p->funds;
if(!p->bet)
{
AllDown = false;
}
else
{
p->funds -= p->bet;
}
}
else
{
p->bet = 0;
p->active = false;
}
cout name.c_str() " bets $" bet } } return AllDown; } void Table::Deal() { if(TheCards->Cards.size() 12) { *TheCards = *TheCards + *TheBoot; TheBoot->numCards = 0; TheBoot->Cards.clear(); TheCards->Shuffle(); cout "** Shuffled Deck **" } Dealer->hand.Hit(TheCards->Draw()); for(unsigned int i = 0;i { Players->hand.Hit(TheCards->Draw()); Players->active = true; Players->busted = false; } Dealer->hand.Hit(TheCards->Draw()); for(unsigned int i = 0;i { Players->hand.Hit(TheCards->Draw()); } } void Table::ShowTable() { cout "Dealer: "; Dealer->RevealCards(); for(unsigned int i=0;i { cout ->name.c_str() ": "; Players->RevealCards(); } } void Table::DealerTurn() { while(Dealer->Points() 17) { cout "Dealer takes a card.." Dealer->hand.Hit(TheCards->Draw()); Dealer->RevealCards(); } } void Table::PlayersTurn() { vector::iterator b = Players.begin(); vector::iterator e = Players.end(); Player * p; while(b != e) { p = *b; if(p->active) { if(p->computer) { AIBasicPlayer(p); } else { // input player } if(p->busted == true) { *TheBoot = *TheBoot + p->hand.GiveBack(); } } ++b; } } void Table::ScoreRound() { unsigned int pnts; unsigned int dpnt = Dealer->Points(); float income; vector::iterator b = Players.begin(); vector::iterator e = Players.end(); Player * p; for(;b != e; ++b) { p = *b; pnts = p->Points(); if( p->busted ) { cout name.c_str() " lost$" bet }
else if( (pnts 22 && pnts > dpnt) || dpnt > 21)
{
cout name.c_str() " wins $"; if(pnts == 21 && p->hand.Cards.size() == 2) { income = p->bet + (p->bet * 1.5f); p->funds += income; } else { income = (p->bet * 2); p->funds += income; } cout bet) } else if( pnts == dpnt ) { cout name.c_str() " pushed." income = p->bet; p->funds += income; } else { cout name.c_str() " lost$" bet }
p->bet = 0;
cout name.c_str() " Funds: \$" funds
}
}

void Table::CollectHands()
{
Deck in;
in = in + Dealer->hand.GiveBack();
vector::iterator b = Players.begin();
vector::iterator e = Players.end();
Player * p;
for(;b != e; ++b)
{
p = *b;
if(p->active && (p->busted == false) )
in = in + p->hand.GiveBack();
}
*TheBoot = *TheBoot + in;
}

void Table::AIBasicPlayer(Player * player)
{
Card dupc = Dealer->hand.Cards[1];
bool thinking = true;
player->busted = false;
while(thinking)
{
/*
if(TheCards->Count > 4)
{
thinking = false;
cout name.c_str() break;
}
*/
if(player->Points() == 21 && player->hand.numCards == 2)
{
cout name.c_str() " blackjack!" thinking = false;
break;
}
switch(dupc.Point())
{
case 0x03:
case 0x04:
case 0x05:
case 0x06:
{
if(player->Points() 11)
{
Card C = player->hand.Hit(TheCards->Draw());
cout name.c_str() " takes a card: ";
DisplaySV(C.value); cout "Points: " Points() // hit card
}
else
{
thinking = false;
cout name.c_str() " stands." // stand
}
break;
}
case 0x07:
case 0x08:
case 0x09:
case 0x0A:
//case 0x0B:
//case 0x0C:
//case 0x0D:
case 0x01:
{
if( player->Points() 16 )
{
Card C = player->hand.Hit(TheCards->Draw());
cout name.c_str() " takes a card: ";
DisplaySV(C.value); cout "Points: " Points() // hit
}
else
{
thinking = false;
cout name.c_str() " stands." // stand
}
break;
}
default:
thinking = false;
cout name.c_str() " stands." // stand
break;
}
//****
// check for busted
//****
if(player->Points() > 21)
{
cout name.c_str() " busted." thinking = false;
player->busted = true;
}
}
}

It's in progress still in places.

## a journal entry

Hmm, perhaps I was influenced by outside sources without their disgression. Whatever it was it made me take my shuffle method, and redesign it to work with operator* along side of the operator/. So now I can split the deck another time easily and clearly in the code.

void Deck::Shuffle()
{
unsigned int sz = numCards;
vector D;
vector E;
vector F;

srand((unsigned)time(NULL));
unsigned int ra = 5 + (rand() % 3);

for(unsigned int h = 0;h {
*this = *this 1 + (rand() % (sz/4)));
D = *this / 2;
E = D[0] / 2;
F = D[1] / 2;
D[1] = F[0] * F[1];
D[0] = E[0] * E[1];
*this = D[0] * D[1];
}
}

I think it looks better, maybe it works better. I read on some other website about Blackjack Gold, they had this long list of features that made it more 'realistic gameplay'. So I guess I wanted to make my shuffle just a little more flexable than it was. That game also had a nice system where you could design your own stratagy method for playing, and let the computer run the hands. It would give you the obviously desired information of weither or not your stratagy paid off. I would like to do something like that if I keep this going, but I really dont know how to let that stuff be configured realtime. Either way, I am having fun.

## More on twenty-one

Building this deck of cards is pretty fun. I have what I consider to be a pretty good foundation thus far. I spent some time today playing with what I wanted to do to my code. I do not have a compiler with me at work, so I always have errors when I get home and try to build. I always rely on the compiler to remember the syntax of things I am new to. What that means is I spent most of the evening fixing my code to work, and now it works. The thing I like the most, is the Deck::operator/ that I added. It takes the current deck and returns a vector(n). I had to fix alot of the crap I had in my other operators, I wasn't using them so they didn't get tested. Until tonight, and they didn't work correctly. I know you dont like it when I talk alot, so here are the goodies.

deck.h
#ifndef _DECK_H_
#define _DECK_H_

#include "card.h"

using namespace std;

class Deck
{
public:
unsigned int numCards;
vector Cards;

Deck() { numCards = 0; }
Deck(int ds)
{
numCards = ds;
Cards.resize(numCards);
}
Deck(const Deck & d)
{
Cards = d.Cards;
numCards = d.numCards;
}

~Deck() {};

bool Generate(unsigned int n);
void Display();
void Shuffle();
Card TakeBottom();
Card TakeTop();

{
++numCards;
vector::iterator e = Cards.end();
Cards.insert(e,c);
}
{
++numCards;
vector::iterator b = Cards.begin();
Cards.insert(b,c);
}
void ShiftUp()
{
Card C = TakeBottom();
}
void ShiftDown()
{
Card C = TakeTop();
}
const Deck operatorunsigned int n )
{
for(unsigned int i = 0;i ShiftUp();
return *this;
}
const Deck operator>> ( unsigned int n )
{
for(unsigned int i = 0;i ShiftDown();
return *this;
}

/*==============================
equality operator, copy
==============================*/
const Deck operator= ( const Deck & a)
{
Cards = a.Cards;
numCards = a.numCards;
return *this;
}
/*==============================
adds deck 'a' to the end of 'this' deck
==============================*/
const Deck operator+ ( const Deck & a)
{
vector::const_iterator b = a.Cards.begin();
vector::const_iterator e = a.Cards.end();
for(;b != e; ++b)
{
}
return *this;
}
const Deck operator+= ( const Deck & a)
{
vector::const_iterator b = a.Cards.begin();
vector::const_iterator e = a.Cards.end();
for(;b != e; ++b)
{
}
return *this;
}
const Deck operator+ ( const Card & a )
{
return *this;
}
vectoroperator/ ( unsigned int n )
{
vector d (n);

if( n % 2 )
return d;
if( n > Cards.size() )
return d;

unsigned int i=0,j=0,s=(unsigned int)(Cards.size() / n);

for(; i {
}

return d;
}
};

// Display Suit and Value
void DisplaySV(unsigned char sample);

#endif

deck.cpp
#include "stdafx.h"

#include "deck.h"

using namespace std;

void DisplaySV(unsigned char sample)
{
unsigned char sh = sample & 0xF0;
unsigned char sl = sample & 0x0F;
switch(sh)
{
cout "S";
break;
case S_DIMON:
cout "D";
break;
case S_CLUBS:
cout "C";
break;
case S_HEART:
cout "H";
break;
default:
break;
}
switch(sl)
{
case 0x01:
cout "A";
break;
case 0x0B:
cout "J";
break;
case 0x0C:
cout "Q";
break;
case 0x0D:
cout "K";
break;
default:
cout int)sl;
break;
}
cout " ";
}

bool Deck::Generate(unsigned int n)
{
if( (n > 1) && (n % 2) )
return false;

Cards.resize( n * 52 );

vector::iterator b = Cards.begin();
unsigned char suitn = 0x10;

for(unsigned int a=0;a 4);++a)
{
for(unsigned char i=1;i {
b->value = (unsigned char)(suitn + i);
++b;
}
suitn = suitn 1;
if(!(suitn & 0xF0))
suitn = 0x10;
}

numCards = 52 * n;
return true;
}

void Deck::Display()
{
vector::iterator B = Cards.begin();
vector::iterator E = Cards.end();
for(;B != E; ++B)
DisplaySV(B->value);
}

void Deck::Shuffle()
{
unsigned int sz = numCards;
vector D;

srand((unsigned)time(NULL));
unsigned int ra = 5 + (rand() % 3);
unsigned int rn;

Display(); cout for(unsigned int h = 0;h {
*this = *this 1 + (rand() % (sz/4)));
D = *this / 2;
D[0].Display(); cout D[1].Display(); cout for(unsigned int i = 0; i {
rn = 1 + (rand() % 3);
for(unsigned int j=0;(j {
unsigned int tmpD = D[0].numCards;
if(tmpD > 0)
{
Card C = D[0].TakeBottom();
++i;
}
}
rn = 1 + (rand() % 3);
for(unsigned int k=0;(k {
unsigned int tmpD = D[1].numCards;
if(tmpD > 0)
{
Card C = D[1].TakeBottom();
++i;
}
}
}
}
Display(); cout }

Card Deck::TakeBottom()
{
Card c;
vector::iterator i = Cards.begin();
c = *i;
Cards.erase(i,i + 1);
--numCards;
return c;
}

Card Deck::TakeTop()
{
Card c;
vector::iterator i = Cards.end() - 1;
c = *i;
Cards.erase(i,i + 1);
--numCards;
return c;
}

Even poof I can use it!

I broke the player name somehow, and I still have not looked into it.

## teaser

The boss wont let me give out details, but here is a sneak preview of the latest project!

## Untitled

My ISP has been flakey, the name server will just start timing out, but it is still online because it can be pinged. I want to find a nameserver I can set to avoid having to use my ISPs. Oh well, every time I get pissed and decide to call, it starts working again. That means I have had time to play around with some code. I have been really far from anything game related, until I read the story of Mel in some jargon file site. And Mel wrote a blackjack program for some old computer. I worked at a casino doing security for a while, and that really made me want to write slot machine type code to reproduce the game. I never did make anything at the time, but now I decided to make a Deck class. The operator+ and operator= dont really work yet. But the rest of it is working.

deck.h

using namespace std;

class Card
{
public:
unsigned char value;
Card () {}
~Card () {}
unsigned char Suit()
{
return (value & 0xF0);
}
unsigned char Point()
{
switch( (value & 0x0F) )
{
case 0x0A:
case 0x0B:
case 0x0C:
case 0x0D:
return 0x0A;
break;
case 0x01:
return 0x01;
break;
default:
return (value & 0x0F);
break;
}
}
};

class Hand
{
public:
unsigned int numCards;
vector cards;
Hand()
{
numCards = 0;
}
~Hand() {}

void Hit(Card &c)
{
++numCards;
cards.push_back(c);
};
vector GiveBack()
{
vector c (cards);
cards.clear();
numCards = 0;
return c;
};
};

class Player
{
public:
Hand hand;
Player() {}
~Player() {}

unsigned int Points()
{
unsigned int p = 0;
for(unsigned int i = 0;i {
p += hand.cards.Point();
}
return p;
}
};

class Deck
{
public:
int numCards;
vectorunsigned char> cards;
vector Cards;

Deck() { numCards = 0; }
Deck(int ds)
{
numCards = ds;
Cards.resize(numCards);
}
Deck(Deck & d)
{
Cards = d.Cards;
numCards = d.numCards;
}

~Deck() {};

/*==============================
Generates the deck of cards, if the deck
is greater or less than 52 cards
it will return false;
==============================*/
bool Generate();
void Display();
void Shuffle();

Card TakeBottom();
Card TakeTop();

{
++numCards;
Cards.push_back(c); // *
}
{
++numCards;
vector::iterator bb = Cards.begin(); // *
Cards.insert(bb,c); // *
}
void ShiftUp()
{
}
void ShiftDown()
{
}
const Deck operatorunsigned int n )
{
for(unsigned int i = 0;i ShiftUp();
return *this;
}
const Deck operator>> ( unsigned int n )
{
for(unsigned int i = 0;i ShiftDown();
return *this;
}

/*==============================
equality operator, copy
==============================*/
Deck operator= ( Deck & a)
{
Deck D;
vectorunsigned char>::iterator b = a.cards.begin();
vectorunsigned char>::iterator e = a.cards.end();
for(;b != e; ++b)
{
D.cards.push_back(*b);
}
return D;
}
/*==============================
adds deck 'a' to the end of 'this' deck
==============================*/
Deck operator+ ( Deck & a)
{
Deck D(*this);
vectorunsigned char>::iterator b = a.cards.begin();
vectorunsigned char>::iterator e = a.cards.end();
for(;b != e; ++b)
{
D.cards.push_back(*b);
}
D.numCards = (D.numCards + a.numCards);
return D;
}
Deck operator+ ( unsigned char a )
{
Deck D(*this);
vectorunsigned char>::iterator p = D.cards.begin();
D.cards.insert(p, a);
++numCards;
return D;
}
};

// Display Suit and Value
void DisplaySV(unsigned char sample);

deck.cpp
#include "stdafx.h"

#include "stdafx.h"

#include "deck.h"

using namespace std;

void DisplaySV(unsigned char sample)
{
unsigned char sh = sample & 0xF0;
unsigned char sl = sample & 0x0F;
switch(sh)
{
case 0x80:
cout "S";
break;
case 0x40:
cout "D";
break;
case 0x20:
cout "C";
break;
case 0x10:
cout "H";
break;
default:
break;
}
switch(sl)
{
case 0x01:
cout "A";
break;
case 0x0B:
cout "J";
break;
case 0x0C:
cout "Q";
break;
case 0x0D:
cout "K";
break;
default:
cout int)sl;
break;
}
cout }

bool Deck::Generate()
{
vector::iterator b = Cards.begin();
vector::iterator e = Cards.end();// + 1;
unsigned char suitn = 0x10;

if( e - b != 52 )
return false;

while(b != e)
{
for(unsigned char i=1;i {
b->value = (unsigned char)(suitn + i);
++b;
}
suitn = suitn 1;
if(!suitn)
break;
}
numCards = 52;
return true;
}

void Deck::Display()
{
vector::iterator B = Cards.begin();
vector::iterator E = Cards.end();
for(;B != E; ++B)
DisplaySV(B->value);
}

void Deck::Shuffle()
{
unsigned int sz = numCards;
Deck A;
Deck B;

srand((unsigned)time(NULL));
int ra = 11 + (rand() % 5);
for(int i = 0;i {
*this for(unsigned int i=0;i {
if(i 2))
else
}

for(unsigned int i = 0; i 2 ); ++i)
{
}
}
}

Card Deck::TakeBottom()
{
Card c;
vector::iterator i = Cards.begin();
c = *i;
Cards.erase(i);
--numCards;
return c;
}

Card Deck::TakeTop()
{
Card c;
vector::iterator i = Cards.end() - 1;
c = *i;
Cards.erase(i);
--numCards;
return c;
}

main.cpp

#include "stdafx.h"
#include "deck.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
Deck TheCards(52);
Deck TheBoot;

TheCards.Generate();
cout "the cards:" TheCards.Display();

cout "the boot:" TheBoot.Display();

cout "Shuffle..." TheCards.Shuffle();

cout "the cards:" TheCards.Display();

cout "Shuffle..." TheCards.Shuffle();

cout "the cards:" TheCards.Display();

Player * player = new Player();
player->hand.Hit(TheCards.TakeTop());
player->hand.Hit(TheCards.TakeTop());
cout Points()
system("pause");
return 0;
}

There you have it. I think I might use it to make a simple black-jack game, but I'm sure it will be a little while unitl I get it in a graphic interface.

edit: Added some more support classes, Player, Hand, and Card. Almost all vector's have been removed, with exception to the operator+/= becuase they still dont work. Because I still dont use/need them.

## hi

Templates give me this feeling, like you can do anything with them. But I feel like I dont know what to do with them. So I have been just writing generic algorithms, the first few I picked up off of DADS 'M' section, and the rest have been just off the top of my head ones. Nothing really special, and I think I have already overwritten/deleted a few, but I still wanted to share them for anyone who needs some examples. So here is my little bit of template functions.

using namespace std;

template class T>
class Stupid
{
public:
T data;
int cnt;
Stupid()
{
data = T();
cnt = 0;
}
};

template class T>
class Trouble
{
T data;
public:
Trouble(T d) { data=d; }
T get() { return data; }
};

template
class Trouble int>
{
int data;
public:
Trouble(int d) { data=d; }
Trouble() { data = 1; }
int get();
};

int Troubleint>::get()
{
return data + 12;
}

template
T Mean( FwItr b, FwItr e )
{
T sum = T();
T cnt = T();

for(; b != e; ++b, ++cnt) sum += *b;
return cnt ? sum/cnt : T();
}

template
T Midrange( FwItr b, FwItr e )
{
typedef typename std::iterator_traits::value_type value_type;
value_type min(*b), max(*b);

for(; b != e; ++b)
{
if( *b > max )
max = *b;
if( *b min = *b;
}
return T( min + max ) / 2;
}

template
vector Mode( FwItr b, FwItr e )
{
vector modeList;
bool moding = true;

vector > StupidList ( e - b );
vector >::iterator itera;

cout
for(;b != e;++b)
{
//find(StupidList.begin(), StupidList.begin(), *b);

}
return modeList;
}

template class T>
vector RandVect( T min, T max, int num )
{
vector store (num);
vector::iterator b = store.begin();
vector::iterator e = store.end();
srand((unsigned)time(NULL));
for(;b!=e;++b)
*b = rand() % (max - min) + min;
return store;
}
template class T, typename FwItr>
T Arcane(FwItr b, FwItr e)
{
T t = T();
for(;b != e; ++b)
{
t += (T)(0.5 * *b);
}
return t;
}

Not much there really, and nothing special (Mode() does not actually preform said function). RandVect is the most recent, and I guess its the one I actually use. I wanted to pump vectors of random numbers through the math functions, so I decided that would be a great use of templates.

## contains spelling error(s)

Easter weekend, I guess it was a vacation because I had 4 days off from work. And I spend all of them out of town. So I also decided that I won't really post another big long explination of my world view. But I did want to get the jist of it out.

We shouldnt have a section of news each week that details the movie box office results, and ranks them for the weekend. I think there should be weekly sections detailing the money that big companies have donated to colleges and NSF type foundations. I am sick of this worthless product that any company can make, and just market the sh** out of it until they sell something. I think we need to move into a more productave state as a world. Back to the money that get donated to colleges, I talking millions. We have enough buisnesses in the country to fund college for everyone, if they would donate. So free school for anyone for as much as they can take. Any money that was donated that does not pay for college things that tuition would have, should go to developing new technologies. Any new technology that comes out of a funded-college should be free for any one within the country to use however they see fit. A patent would be held in the name of the United States. Only fees should be paid if it is used by a company in another country. So that would being better and newer technology to our businesses to use. And it would only cost them the cost of production + parts & shipping. I think that could help bring the country to a stronger state in the future. Heck, I don't think its really all that bad of an idea no matter where you live.

games should be about fun and adventure, not killing or getting killed only. im off to play cs:s now.

## The future of man-kind..

Does not look good at this point.

Nothing I am going to say here is all that original, not im my opinion. However I feel that alot of it is mostly unheard.

First off, I think we are currently a bacteria on this planet, but at a much higher level then we think of when we hear bacteria. I think it still hold true due to the ammount of time we have been on this planet, and how much we have changed it. We collect, consume, and destroy everything we can. Really we even told ourselves that its the correct thing to do, after all "god put that there for us to use" is what some of us are told when we are young. Ill back that up a little by saying that I have surrounded myself with exotic items, that I know are destined for a landfil. These 'exotic' things include my computer monitor, which is composed of glass, wire, plastic, and some toxic stuff I dont know about. These materials would never have collected in this space in front of me if they were not taken from various other locations that I could not travel to myself. You can do this for everything on your desk, well I was able to anyways. We really are comsuming our environment unconsiously moat of the time, consious the rest. No other species on this planet (that I know of) does this to its environment, and they have all been here longer than us.

Now thats just the 'environmental-issue', assuming that we never created the current global warming situation, and that everything is 'normal' as far as the plant's health, we would still have another problem. That problem (IMO) is genetic deterioration. What I mean by that, is I think we are making every generation weaker. We have come to learn, that using the same pestiside will over time, become ineffectave. The insects become immune to the poision, or whatever was used to make them dislike the plants. I feel it could also be said that every time we use a product to eleviate ourselves of some undesireable sympton, we will become more vournable to said sympton, or whatever is causing it. I feel this way because our body (IMHO) is not required to do as much as it would have to normally. It will come to be dependant on that product to take care of the problem in the future. It is understood that some species that live in many different parts of the world, can have different enviromental challenges. For example, a squirel that lives in Maine, will have to save food for a longer ammount of time then one from california. This type of habbit in the species comes in information passed down from parent to child, in the genetics. The building blocks work the same, it is crazy for us to think that there will not be negitave side effects from the use of these products over a long period of time.

People at one time, died alot more often, maybe. It is hard to tell if they really did die more often, but I think we are letting too many people live. I feel that this issue is related to the last one a little. When Cougars started attacking people in California, they said "the city is expanding.. bla bla, people in the cats environment.. bla bla, hungry cat eats person". Nothing hard to understand there. What is hard for me to understand is why people are suprised about getting attacked, you are in a mountian, its a mountian-cat. However many hundreds (or thousands) of years ago, if someone was going to be in that mountian, they would be prepared for a mountian-cat, bring a gun, big stick, or more people to keep safe. We no loger worry about this. People would get eaten by animals, poisioned, fall into a coma, get cancer, get infected, and the list goes on but you should see the point. We can now live on from things that would have normally killed someone, thus allowing them the chance to procreate. I feel that we are letting natural selection to fail in its purpose. Survival of the fittest indeed. I know this has the potential to piss people off, but I think that natures solution to this is homosexuality, and HIV/AIDS. Maybe AIDS is something that has been for all of time, and we are just new to it. But I feel homosexuality is created by the population size. It seems that it is more common in areas of higher populations. When humans were 'younger' (I'm talking about hundres of thousands, or even millions of years ago), there were no mass societies for people to live in, thus there was always a need for offspring. Take away the actual need for sex, when standing in a large city like New York you may feel very little need to contribute to the whole. Maybe even more so when times are bad. I don't think I should continue to speculate on the source of homosexuality in our society. What I wanted to point out, is that we are over-populated, and most homosexuals are not going to have offspring by nature. Thus making the homosexual person a contributor to the over-population solution. As unfortuniate as it may be, AIDS is known to kill people. And it even can be passed down to children. This effectivly cuts off a branch of a family tree. Best case senerio, an infected parent, does not infect the offspring and that child is allowed to reproduce freely. Worst case secerio, the virus prevents the infected person from reproducing by attacking the immune system of the infected person and everyone that person attempts to procreate with. This is currently what is happening in Africa (IIRC) with HIV/AIDS.

I cant write any more tonight. I still have one more thing to say about "The future of man-kind..", Next post.

If you find a spelling, or grammar error, please ignore it.

## ... no that wasnt it.

Yeah, so.. I didnt get anywhere with that tutorial. I think it was more of an exercise in how to install dependencys for Ogre. Its pretty simple at first, I just need CEGUI. However that little tool has 3 dependencys, boost, something, and something else. Lets say I only made it thru boost. Downloaded, and compiled it, took dang long enough. I dont have the correct Java installed I guess, because the .jam files didnt work for me. So I had to download some more stuff and compile that, just to compile boost. Not what I wanted to do. But I guess it bring me to something that I have come to, dependencys are OK. Maybe they are even good to have. I have been thinking, that when I start making progress with Ogre, I will start using Newton for phy/col. And FMOD for sound, something for this, and another for that. Seems like there will be either one big bloated exe, or a super small exe, with 4-5 dll files required to be present. Back to what I wanted to say, this is all fine. As long as using these tools makes programming the game easier, I don't care if I need to spend 2 days of downloading and compiling... as long as the user does not need to do anything. I mean, once you build the app you may need to include some support files, but that is something that we would be required to know. So we would either bundle the files w/ the install (simple), or instruct the user to go get the files from the vendor (angry customers).

edit: removed finished-the-wrong-thought ending.

## ahhh....

My girlfriend record American Idol with the DVR so she can watch it with her friends. It is on TV at 7pm here, for one hour. I get home at 6:40pm and usualy turn on the TV for some background noise as I putz around on the computer. But I cannot have the TV on when that show is being aired, at least not when I can help it. So I turn the TV off because I cannot change channels when it is recording, I could watch a movie or something, but I'm not watching I'm listening it to only. I listen to alot of reruns. Yeah, I just dont like watching that show. So I will take this dark silence and do the next Ogre Wiki Tutorial : "RaySceneQueries and Basic Mouse Usage (Part 1 of 2)". Ohh, I can't wait.

I finished the last tutorial : "Animation, Walking Between Points, and Basic Quaternions", and I even finished the exercises up to and including the "Difficult Questions". I am too eger to learn more right now, then to play redesign-your-code. But I say to you, if you are ready to try an open source engine; Ogre is my first venture away from just using DirectX, and I am finding it to be capable of doing everything I want it to. And I'm sure more too, very sure.

PS: Try Psycho Boy 3D (beta), fun.

## ...

I wrote some stuff in here, but I must have closed the window because its not here.

## the ogre is here

Being new to trying out the game development thing, I had to take notice to johnhatten here. I think of stuff I want to add to my game, but I find myself thinking of all the things I have to impliment to make it work. So I have decided to read the signs, OGRE 1.0 was just released, john told me to, and I know that it would take me way too long to make the engine that I want to use right now. So I downloaded and compiled it, I am going through the wiki tutorials now. Time to take a break I think.

I think once I get a grasp of the Ogre GUI, I will try to make my breakout clone in it. I'm sure I can find a col/phy library that works with ogre out there somewhere, or maybe it has that in it, I dont know yet. :)

## QPC Timer Class

I had a wild hair this morning, and decided to write a quick timer class. Works off of QueryPerformanceCounter/Timer functions. This was basiclly a test to learn how to use the two functions. Seems to be working ok.

You can use, comment, criticize, or flame my design at will.

class MTimer
{
public:
__int64 Resolution;
__int64 StartedT;
__int64 SampledT;
__int64 LastT;

MTimer()
{
StartedT = 0;
SampledT = 0;
LastT = 0;
}
~MTimer()
{
}
bool Init()
{
LARGE_INTEGER freq;
if(QueryPerformanceFrequency((LARGE_INTEGER*)&freq))
{
return true;
}
return false;
}
bool Start()
{
if(!Resolution) // first check for Init() success
return false;

LARGE_INTEGER samp;
if(QueryPerformanceCounter((LARGE_INTEGER*)&samp))
{
LastT = StartedT;
return true;
}
return false;
}
double Sample()
{
if(!Resolution)
return -1.0;

LARGE_INTEGER samp;
if(QueryPerformanceCounter((LARGE_INTEGER*)&samp))
{
double t = (double)(SampledT - LastT) / (double)Resolution;
LastT = SampledT;
return t;
}
return 0.0;
}
double Elapsed()
{
if(!Resolution)
return -1.0;

LARGE_INTEGER samp;
if(QueryPerformanceCounter((LARGE_INTEGER*)&samp))
{
double t = (double)(SampledT - StartedT) / (double)Resolution;
return t;
}
return 0.0;
}
};

this is kinda what my test app looks like, just wanted to keep it a short example of use.

int main()
{
double Timed, Elapsed;

MTimer MozTime;
MozTimer.Init();
MozTimer.Start();

for(int i=0;i100;++i)
{
Sleep(100 - i);
Timed = MozTimer.Sample();
// output or evaluate, whatever you need
}
Elapsed = MozTimer.Elapsed();
}

Hey, why not download the newest version? It has mouse support now. work_dbg.exe is windowed mode, debug build. Mouse does not always reacquire properly if you Alt+Tab. work.exe is fullscreen, release build. Alt+F4 to exit still.

Happy keys:
S - Stats, framerate and resolution.
W - Wireframe display.
E - Reset ball to paddle.
L - Camera roll.
Up Arrow - Move camera up.
Down Arrow - Move camera down.
Left / Right - Paddle movement.

Have fun. Source is out of date, so dont bother with it if you are looking for some code for any new features.