Monday, December 8, 2008
QuickTime Player in Internet Explorer
Question 1: Why don't my DOM events work in Internet Explorer?
Answer: They work, but they don't work properly, that's for sure. The Apple documentation provides an example the just doesn't work. QuickTime DOM events won't get sent unless you add a [relatively simple] hack, the essence of which requires you to reload the clip you're playing. Pseudocode looks like this (in javascript):
load clip in QuickTime
wait until plugin status is loaded (or complete )
// begin hack
quicktimeMovie.SetResetPropertiesOnReload(false);
quicktimeMovie.setURL(movieURL);
registerDOMEvents(quicktimeMovie);
// end hack
So essentially, you have to generate your object/embed code, load the quicktime player once (by setting innerHTML somewhere), and then do a setURL with the same clip before registering for DOM Events. If you don't do the setURL, you won't get DOM events.
Note that for other browsers you don't have to do this. So I suggest you wrap this code up in an if(IE) block.
Question 2: With the hack above (in IE), why does my app hang when loading long (15 minutes plus) clips?
Answer: Your app is hanging because the QuickTime plugin didn't get time to stabilize before you called setURL. I didn't find a way around this, but a solid solution is to use a dummy clip (1 or 2 seconds of black) that you load up before loading your real clip. Once you've got DOM events registered, you can use setURL to switch to other clips. Pseudocode looks something like this:
function initQuickTime()
{
[code from answer 1 loading a dummy clip]
}
function loadClip(clip)
{
if(firstLoad)
{
initQuickTime();
}
quicktimeMovie.setURL(clip);
}
And you're good to go. setURL can be used from here on in if you need to switch clips.
Other Notes:
1. You can't resize the QuickTime window without reloading the clip. I really want to be wrong about this, but if you need to change the size of the video window, you have to redo your object/embed code. Kind of a pain, but resizing has to be done almost never, so it's workable.
2. If you're writing debug code, make sure all your test clips are on your http server. I made this mistake and wasted a couple hours. If, for example, you're working my pseudocode in question 2 and your dummy clip is on your PC, but your app accesses clips on an http server somewhere, it just won't work. QuickTime player has some initialization in it that defaults to either local files or http files (I don't really know the details).
That's about it. Overall I really like QuickTime player. Compared to the directshow work I've done, it's a lot easier to use. There are a lot less corner cases you have to deal with (if you're trying to get frame accuracy, for example). The compatibility issues in diffferent browsers come with the turf, and they're realtively easy to deal with elegantly if you know what you're up against.
Monday, October 20, 2008
Adobe XFDF
Saturday, October 4, 2008
XML schemas, Excel, and getting what you want
Saturday, September 20, 2008
Character Generator update
I made a fix for the healing surges not showing up, and I fixed a bug that was keeping humans from getting their bonus skill, feat, and power.
Friday, September 19, 2008
bugs in Generator
Wednesday, September 17, 2008
D&D Character Generator
UPDATE 2009.04.01 - You will need Flash 10 to run this now. I've updated the "view as PDF" functionality so it uses the new Flash 10 feature to create files on the fly. It doesn't have to ask my server to create the file anymore. Hooray! I've also changed the size a bit. See the change log in the about box for more info.
Ok. I've FINALLY finished a project I've been working on for the last couple months. I've been giving it about two 4 hour sessions a week, and [AT LAST!] I'm satisfied enough with it to post it.
It's a character generator for Dungeons and Dragons 4th edition. I got the books in July when they released the set, and I thought it would be fun to put together a character generator that made it a bit easier to parse the whole thing.
This bad boy is written in Flex, so you can run it from any web browser with Flash 9. The general idea is that you build your character through the flex interface, and when you're done, click the "View as PDF" button and out pops a nice PDF for you to print out. It DOES NOT replace the Player's Handbook in any way. It's more of an easing function on the whole ordeal.
Use the app here. You'll need Flash 9. Don't forget that you can drag and drop your stat numbers in the Standard Array and Roll entry types. I haven't yet figured out a good way to indicate that they're draggable, as the Flex "useHandCursor" flag doesn't see to work.
Here's a list of caveats / known flaws / things that aren't implemented:
- THIS DOES NOT REPLACE THE PLAYERS HANDBOOK.
- choosing of equipment is not implemented. You'll need to use the PHB after you print your PDF.
- Half-Elf: after creating the PDF, be sure to choose an at-will power from another class for the dilettante race feature.
- Ranger: After creating the PDF, choose Dungeoneering or Nature as a skill. This will affect your modifier for the skill by 5 points, so don't forget!
- There appears to be an error in the class listings in the Player's Handbook. When a skill is automatically given (listed as "free" in my UI), it is also listed as a choice. In my code, I automatically remove the free skills from the choice list.
- I have not implemented languages. choose them on the PDF.
- Human: you get +2 to an ability of your choice. Do this on the PDF.
- The PDF has some fields that automatically fill as Zero. If there are certain ones you think should not be filled at all, let me know and I'll fix them.
- certain class and race features require you to choose between two things. In cases where this is not implemented, it is listed on the character sheet as a "choose x or y" listing under the class/race features sections.
UI bugs:
- there's a minor glitch in the positioning of the strength stat when you drag a number on top of it (only seen in the Roll entry type).
- Powers have no descriptions. They're intended to not have power descriptions, but they're supposed to say "See Player's Handbook".
Note that I got the character sheet pdf I'm currently using from here.
This was a very fun little project. I enjoy writing apps in Flex. In working on this, I learned about XML schemas, XFDF (a pdf format), and some Perl tricks I'm currently using on my server. I'll make some posts soon about all that stuff. I wrote some helper Flex apps that I'll post as well.
Friday, May 16, 2008
On Other Projects
Thursday, May 1, 2008
A Custom MFC Control to Display Guitar Chords
1. Create a class for your control, and inherit from a control similar to what you want to make. If nothing is similar, inherit from CStatic.
2. Override the OnPaint function to do your custom drawing.
Everything else is just MFC, although you have to be careful about redrawing. If you're constantly redrawing, you could get a bit of flicker.
To show your control in a dialog, you have do the following:
1. Add a Custom Control to the dialog.
2. Set the "Class" property of the custom control to the name of your custom class.
3. Make sure you register your custom class using the AfxRegisterClass() function. An example of this is in ChordDisplay.cpp.
In making this control, I learned something very important. If you can draw something with the CDC drawing functions, then do it that way. Bitmaps are easy enough to blit onto the Device Context, but if you need transparency or any fancy stuff, you're gonna be spending a good bit of time figuring it out (or searching for code that does what you want). I used 100% CDC drawing functions for my guitar control.
Here's a screenshot:
And, as always, my source code is here. The control can be told to draw a chord by filling a struct with some data. See ChordDatabase.cpp for more how to do that. An expansion of this would be to get a full database of chords that could be loaded from an xml file. I've only got a few chords here because it's just a sample to show the control.
Saturday, April 26, 2008
Farseer Physics
The only gripe i have is that it has basically zero documentation. And since this code has been around since 2006, I'm gonna guess no documentation is coming any time soon. The good news is they provide quite a bit of sample code, and the guy who wrote it seems to reply to just about every question people can think of on the codeplex boards.
Either way, i'm having some fun. I'll post some code when I get there.
Tuesday, April 8, 2008
Playing with OpenGL - Mouse Interaction
Anyways, I remember in the class I never ended up with an OpenGL app that would allow for proper mouse rotation of a 3d object. Mouse interaction was never really assigned in that class, and I remember spending a lot of my time trying to figure out the math the teacher was having us do instead.
So I thought now that I'm jumping back into OpenGL related stuff, my first project should be revisiting that very simple, yet often overlooked bit of code that handles mouse interaction. I reviewed some of the code I had written in the class, and it had the basic idea right, but not enough thought put into it.
So I started fresh. I've learned some interesting things:
ROTATION
If you rotate the camera about your scene, then you won't be able to spin a translated object in place (what you get is a big swing around the object, rather than watching the object spin). So it seems one wants to rotate the the whole scene before drawing it. This is, of course, to mimic what is seen in 3ds Max.
TRANSLATION
This is probably the easiest part of the math involved. Since translation from this projects point of view is moving about the screen plane, then we only have to move in two dimensions (The third dimension is zoom). All that needs be done is move our eyeball AND the point we're looking at in parallel.
ZOOM
This one is a bit tricky. The effect we want is to move our eye closer to the point we're looking at. This point is not necessarily the object. Imagine you have an eye location E and a focus point F. Moving our eye towards F involves a little bit of vector math. If we create a vector from E to F, we are half way there. To do that, subtract F from E in each dimension:
Vx = Fx - Ex;
Vy = Fy - Ey;
Vz = Fz - Ez;
Now we simple move our Eye point along this vector. Multiple the vector by some scaling factor and add
newEye = E + V*scale;
or
newEyex = Ex + Vx*scale;
newEyey = Ey + Vy*scale;
newEyez = Ez + Vz*scale;
When you think about the math, it makes sense. When you look at the math, it's easy to get confused.
At any rate, here's my program. I've tried to put it together so you don't need to modify your paths to get it to build (the glut library is included).
Saturday, April 5, 2008
Finished with Conway's game of life
Thursday, April 3, 2008
My First 3ds Max
1. 3ds max is a power tool for graphics.
2. There is a TON of functionality in 3ds Max.
3. The 3ds Max developers have made a custom UI so they can fit all the functionality in. For example, scroll bars are about 4 pixels wide.
4. Even with all the functionality, 3ds Max is actually pretty easy to use (so far).
The Quick start has you create a Greek structure with some columns and stairs. You then animate a camera along a line, and render a video. My camera skills need a lot of work, so I won't post the video I created. But here are a couple renderings of the structure itself to give you an idea.
and holy cow. I just closed 3ds Max, and instead of saying "Yes, I'd like to save", I clicked the no button on accident :(. Oh well, if I need to make that temple again later, I'll probably know way more and be able to make it even better.
Saturday, March 29, 2008
New Menu Code
Okay, It's been busy at home lately. I've been moving it. But I've been trying to find a little time every day to work on my XNA stuff, and I've got a much more complete menu system now.
I've made some changes:
- The menu now shows a default "Return" choice at the bottom of each list. This can be turned off by setting the "showBackChoice" boolean.
- The menu now has two types of choices, Normal and LeftRight. Normal choice will show their child choices as a separate menu when they are executed. LeftRight choices will show their child choices as a list to the left of the parent choice when they are SELECTED.
I've also made the sample code show a bit more info in the console as you are viewing the menu. The sample code initializes the menu as follows:
mainMenu.AddChoice("Choice 1");
MenuChoice choice = mainMenu.AddChoice("LR Choice");
choice.AddLeftRightChoices(new string[] { "one", "two", "three" });
choice = mainMenu.AddChoice("Sub Menu");
choice.AddChoice("Sub choice 1");
choice.AddChoice("Sub choice 2");
mainMenu.ChoiceExecuted += new Menu.ChoiceExecutedHandler(ChoiceExecuted);
mainMenu.ChoiceSelected += new Menu.ChoiceSelectedHandler(ChoiceSelected);
mainMenu.ChoiceDeselected += new Menu.ChoiceDeselectedHandler(ChoiceDeselected);
So there you go. Pretty simple. If I make any more changes, I'll be sure to post them. Possible changes could be:
- using a proper spriteFont to display the text (so we could use something besides Times new Roman).
- making background images actually work.
- something I overlooked....
I've realized as I've been working on this that is might have been easier to just implement it using a full on tree, rather than a bunch of sneaky lists.
Sunday, March 16, 2008
Basic Menu
Menu mainMenu;
Then, in LoadContent(), initialize the menu, it's choices, and any handlers you want to catch.
mainMenu = new GameMenu.Menu(this);
mainMenu.AddChoice("Show Sprite");
mainMenu.AddChoice("Return");
mainMenu.ChoiceExecuted += new Menu.ChoiceExecutedHandler(ChoiceExecuted);
Of course, ChoiceExecuted should be defined somewhere. I'll get to that at the end. In your Update() method, call the game menu's update function:
mainMenu.Update(gameTime);
And in the Draw() method, call the menu's draw function:
mainMenu.Draw(gameTime);
If the menu isn't visible, those functions will do nothing. To show the menu, you set the visible property to true. I do this in the Update method when the user pressed escape:
if (keyboardState.IsKeyDown(Keys.Escape) && !prevKeyBoardState.IsKeyDown(Keys.Escape))
{
mainMenu.visible = !mainMenu.visible;
}
And finally, when a menu choice is executed, you handle it as follows:
public void ChoiceExecuted(object source, Menu.MenuEvent e)
{
if (e.choiceString == "Show Sprite")
{
mainMenu.visible = false;
}
else if (e.choiceString == "Return")
{
mainMenu.visible = false;
}
}
All I'm doing in the sample code is hiding the menu, but you can do anything in there. There are also choiceSelected and choiceDeselected events, and they get fired in the current code.
My next update to this code should have the ability to navigate through menu pages, and the ability to give the user some left/right choices as far as options go (a "Sound On Off" menu choice, for example).
Tuesday, March 11, 2008
Quick Update
I was looking at some other XNA code yesterday, and I think I need to look into spriteFonts. I might be able to use those instead of the bitmap font class I'm using now. spriteFonts are built in to XNA, so they might be faster. I'll have an easier time modifying the font type, that's for sure. More later this week...
Thursday, March 6, 2008
Menu System, Continued
The only change to the below code is that you have to pass the Game class when you create the menu (I've created the menu system as a DrawableGameComponent):
menu = new Menu(this);
I'm using a bitmap font class that I got here to do the work of displaying the text. The only problem I can see with using this class is that it will force me into a certain font... It's pretty well designed though, so it has made it a lot easier to get going. I'll have to visit different fonts later. Right now, Times New Roman is my best friend.
Wednesday, March 5, 2008
Designing a Menu System
Menu menu = new Menu();
menu.AddChoice("New Game");
menu.AddChoice("Load Game");
MenuChoice OptionsMenu = menu.AddChoice("Options");
OptionsMenu.AddChoice("Resolution");
OptionsMenu.AddChoice("Volume");
menu.NodeSelectedEvent += new Menu.ChoiceExecutedHandler(ChoiceExecuted);
We'll see what I end up with. Hopefully it won't get too cluttered with code related to drawing the darn thing.
Monday, March 3, 2008
Some Changes and Updates
XNA - How to Disable Bitmap Magnification Blending (Blur)
Removing that doggone blending is actually quite simple. You have to modify your spriteBatch.begin() call, and modify the graphics device settings immediately after, like so:
spriteBatch.Begin(SpriteBlendMode.AlphaBlend,
SpriteSortMode.Immediate, SaveStateMode.None);
graphics.GraphicsDevice.SamplerStates[0].MagFilter = TextureFilter.None;
The key in the spriteBatch.Begin() call is the SpriteSortMode. Setting this value to immediate causes any changes to the graphics device to be applied immediately. And we want to make a change, as you can see in the next line of code. I'm changing the magnification filter to TextureFilter.None because I don't want it to blue anything. After this, you draw and scale your sprites like normal. The result looks like this:
ahh... much better!
Sunday, March 2, 2008
Displaying a Mouse Pointer in XNA
Texture2D m_mouseTexture;
Vector2 m_mousePos;
Be sure to initialize it to zero. For simplicity, I also generate a simple red square texture to use as the mouse pointer. I'm doing all of this in the Initialize() function. In my (very short) experience with XNA, you'd want to initialize textures in the LoadContent() function, but this is not loading from a file, so it's safe to do it all in the Initialize() function like this:
m_mousePos = Vector2.Zero;
m_mouseTexture = new Texture2D(graphics.GraphicsDevice, (int)POINTSIZE, (int)POINTSIZE, 1, TextureUsage.None, SurfaceFormat.Color);
Color[] texture = new Color[POINTSIZE * POINTSIZE];
for (int i = 0; i < texture.Length; ++i)
{
texture[i] = Color.Red;
}
m_mouseTexture.SetData(texture);
Now, in the Update() function, update your mouse position:
MouseState mouseState = Mouse.GetState();
m_mousePos.X = mouseState.X;
m_mousePos.Y = mouseState.Y;
And finally, in the Draw() function, draw your sprite in a spritebatch:
spriteBatch.Begin();
spriteBatch.Draw(m_mouseTexture, m_mousePos, null, Color.White, 0f,
Vector2.Zero, 1.0f, SpriteEffects.None, 0f);
spriteBatch.End();
Grab the sample project for this here.
Saturday, March 1, 2008
Conway's Game of Life
I thought I should talk a little about the project I'm focusing on right now. I'm still spinning up on XNA, and I was reading an article somewhere recently that mentioned Conway's Game of Life. I was never taught about this in school for some reason. What a wonderful little thing!
Anyways, I thought it would be fun to implement Conway's Game of Life in XNA to give myself something tangible (in the software sense... what does that really mean, anyways?) to work on. I've already got a basic architecture done, but I want to write down some of the guidelines I'm trying to stick to. Just basic stuff, like:
What am I trying to learn?
- I want to learn about what it will take to implement a menu system in XNA.
- I want to learn about mouse interaction with an object (the game board) on the screen.
Which Game of Life algorithm should I use?
- a few are mentioned on the wiki page, notably hashlife. Since I'm not trying to learn about Game of Life specifics, I'm going to start with brute force with two 2d arrays (one for the current interation, and one for the next). It will give me a good quick start on my goal, and also give me a good baseline if I decide to optimize the algorithm.
What operations should I allow?
- a mouse click should turn a cell on or off. Hold and drag to fill or unfill cells under the mouse pointer
- spacebar should step to the next iteration.
- enter should run through iterations at the chosen speed (we'll need a menu for that).
What should the menu contain?
- Options
- run speed
- window size
- colors?
- I'll leave any other nifty stuff for later.
Things that would be very interesting to implement:
- the ability to move and zoom the camera around the grid with the mouse or keyboard
- some logic to move and zoom the camera automatically, and follow the most activity in the grid. One nasty corner case for this is any gliders that come off of the high activity areas. how do i know when to ignore them?
More to come later when I have more of this implemented.
Friday, February 29, 2008
Yet Another Book
As time goes on, I'm going to force myself to learn how to use this darned blogger. I've always just trusted it as text entry and nothing more, but I'm sure it can do more. Thus, the nice photo of the book I just bought.
OpenGL SuperBible: Chapter 1
Thursday, February 28, 2008
New Books
Dreamweaver and my new webpage
I actually went to this page while I was building this page. I just couldn't figure out how to add the divider! But it's not my fault I couldn't find the command, it the fault of the UI designer :D. And by the way, I'd like to mention that my new apartment has a stove that looks like this. I'm very proud of this fact.
Wednesday, February 27, 2008
Updating the Wizard
//The various states the Wizard can be in
protected enum WizardState
{
Standing,
Walking,
Magicking,
Ducking,
Jumping
}//End enum WizardState
I've replace them with
//The various states the Wizard can be in
protected enum WizardState
{
Normal,
Ducking,
Jumping
}//End enum WizardState
In the original project, the code only allows for one state at a time, so you end up not being able to walk when jumping, or magick while walking or jumping. So i took the actions i wanted to be able to do during all times, specifically walking and magicking, and moved those out of the state enum. They shouldn't be treated as states. They're just actions the wizard can take. Then I realized there needed to be some sort of base state, so I added the Normal state, which is just the default.
The other big change is in the UpdateKeyboard function. Instead of an if..else if...else if chain of code, I changed it to a series of if statements so the UpdateKeyboard function will respond to all keys being pressed at once, rather than responding to one and returning.
One final minor change I made was to pull out the crouch animation when the wizard lands. I didn't like it. I've avoided posting code in here until I know how to get it formatted correctly... another action item, I suppose.
The end result, if you build my version of the project, is a wizard that can move and magick while jumping. It feels much more responsive, and makes me feel like I have a lot more control over the wizard.
There. I feel better now.
Tuesday, February 26, 2008
Catching Up
I recently went through a tutorial called The Wizard. I think i can safely say that I didn't like it. The design of the project starts out nicely. You've got your game, which has a wizard, which extends the Sprite class. Got it. They even go into spritesheets, of which the implementation details are new and useful to me. They talk about game states, and they are required for game design.
The code after that is... poor. What you end up with is a sprite you can move around on the screen, but which can only respond to a single command at a time. It's like those old games, like Dragon Warrior, where you'd press a button and the character would move, during which you couldn't do anything else. I don't think any new code should result in something like that. Even the most basic tutorials on the XNA site don't result in something like that. Then again, i bet this type of implementation would work well for a board game.