drawkcaB | Backward Compatible logo

rants and tips about software

How to load data from QHI.DAT file

If you have an old Quicken Home Inventory or Quicken Home Inventory Manager installation and want to save your inventory database, you probably have problems using this data on a new computer system. This is because of various incompatibilities between multiple versions of Intuit inventory programs.

However, there's a simple way out. Download a program called Attic Manager. It's a home inventory program, just like QHIM, with one specific feature: it is able to import databases of all Quicken Home Inventory programs. At the time I write this, it supports the oldest IDB files, then the newer .QHI files and also the latest MDF files which come with most recent versions of Quicken.

Now, how does this help you, when you have a DAT file? Well, QHI.DAT is not really a database with your items. If you have QHI.DAT file, this means you have the oldest version of QHI, and there should be a file called QHI.IDB around as well. Attic Manager is able to load all items, locations, categories and other data from QHI.IDB file, so use that one.

As far as I know, Attic Manager is the only product on the market that is able to do this. Once you load the database into Attic Manager, you can export it into CSV format and then load into any Inventory program that supports loading from CSV or Excel (most of them do). Or, you can simply use Attic Manager itself. It is simple, clean, and fast. It works on newer versions of Windows, like Windows 7 and Windows 8 and also on 64bit systems as well. And knowing your data can be exported at any time sets you free from vendor lock-in.

Feedback & Share Milan Babuškov, 2013-05-15

Easel.js docs need improvement

A few days ago, Sebastian DeRossi asked me on Twitter how to improve Easel.js docs. As this is too large for Twitter's 140 characters, here's a short blog post of some issues I found:

1. I was looking for a way to Flip an image and docs don't mention that you can use negative values to scaleX and scaleY. I was really planning to work around this by creating all the required mirror images using ImageMagic and load 2 sets of sprites, when I accidentally found the example using negative values on some blog while searching for something completely different.

2. Say you are a complete beginner like me, and you wish to add a mouse click event handler to Bitmap. You would go into docs, click Bitmap, go to list of events, where it says Click and there are links to DisplayObject and MouseEvent there, but none of those lead to example how to actually use it. Failing this, I first found onClick only to find out that it is deprecated and I should use addEventListener(), without any example how to use it. BTW, I did manage to get onClick to work, but I did not want to use a deprecated function. In the end, I asked on StackOverflow and got a real example how to use addEventListener for mouse events.

3. The thing I'm still confused about, is what is the standard application structure. I.e. how to do the main game loop? In docs, the Getting Started section ends with this:

//Update stage will render next frame
createjs.Ticker.addEventListener("tick", handleTick);

function handleTick() {
    //Circle will move 10 units to the right.
    circle.x += 10;

    //Will cause the circle to wrap back
    if (circle.x > stage.canvas.width) { circle.x = 0; }
    stage.update();
}

Am I supposed to update all my logic in handleTick()? I would create my own functions of course, and call it from there. Should the structure of my program look like this:

createjs.Ticker.addEventListener("tick", handleTick);

function handleTick() {
    updateWorldLogic();
    stage.update();
}

Somewhere else, I found an example like this:

var canvas = document.getElementById("canvas_id");

startGame();
function startGame() {
    stage = new createjs.Stage(canvas);

    // NOTE the following comment, I have NO idea what it means???
    // We want to do some work before we update the canvas,
    // otherwise we could use Ticker.addListener(stage);

    createjs.Ticker.addListener(window);
    createjs.Ticker.useRAF = true;
    createjs.Ticker.setFPS(60);
}

function tick()
{
    // update the stage:
    stage.update();
}

This code works, but I don't understand the difference between:

  • createjs.Ticker.addListener(window);
  • createjs.Ticker.addListener(stage);
  • createjs.Ticker.addEventListener("tick", handleTick);

...and I'm having a hard time getting this clear from the docs.

Feedback & Share Milan Babuškov, 2013-05-13

How to flip an image horizontaly or vertically using easel.js

Looking at Easel.js docs, you might think that Flip() function is missing. However, flipping is done using scale with negative values. To flip image horizontally, use:

image.scaleX = -1;

To flip vertically, use:

image.scaleY = -1;

Before flipping, make sure you set the regX and/or regY to the center of image. Full example with image sized 120x50:

var myimg = new createjs.Bitmap("sword.png");
myimg.regX = 60;
myimg.regY = 25;
myimg.scaleX = -1;  // flip horizontally
myimg.scaleY = -1;  // flip vertically
Feedback & Share Milan Babuškov, 2013-05-08

Creating a mouse hover effect for button/image with HTML5 Canvas and easel.js

After ditching many other HTML5 Canvas libs, I was left with Easel.js. Documentation is sparse, without many examples. I had to google a lot to find this information, so I'm getting it up here hoping it might help someone else as well.

If you need a simple graphic (or text) button with hover support, then Easel's ButtonHelper class is what you need. You can create a simple image containing 3 buttons states (normal, hover, pressed) and set up ButtonHelper to do all the work.

Here's how I did it. First create an image with all 3 states. I used this PNG:

As you can see my image is 300x45 with each state being 100x45 pixels. Now the code:

// setup
stage.enableMouseOver();
var data = {
     images: ["3buttons.png"],
     frames: {width:100, height:45},
     animations: {normal:[0], hover:[1], clicked:[2]}
};
var spriteSheet = new createjs.SpriteSheet(data);
var button = new createjs.BitmapAnimation(spriteSheet);
var helper = new createjs.ButtonHelper(button, "normal", "hover", "clicked");

// set the button coordinates and display it on the screen
button.x = 100;
button.y = 100;
button.gotoAndStop("normal");
        

Yes, that's all. If you're looking for example with Text, take a look at this jsFiddle.

Note that each of the button states can be animated, just add more frames to the image file and configure the data.animations properly.

Feedback & Share Milan Babuškov, 2013-05-08

Selecting a HTML5 Canvas library for a turn-based strategy game

In the past couple of days I had determined to select a HTML5 Canvas library to use for my next game project. Some of the features I require:

  • Scaling and rotating support with Tweening
  • Availability or ready-made resource (images, audio) loader or able to easily make your own
  • Ability to click on a random image or text element (sprite) and handle the event easily, like jQuery 'click' handler
  • Ability to easily make hover effect over images/text
  • Some other stuff like Flip is desired by not absolutely required

After investigating a lot of frameworks, I narrowed the list down to: Crafty, MelonJS, Quintus, LimeJS, CanvasEngine, Cocos2d-hmtl5, CreateJS/EaselJS. Crafty does not have rotating support, MelonJS and Cocos2d require that you manually, traverse all the child nodes, find which ones are visible and hittest the mouse coordinates to get the hover effect. I could not find this information of Lime.js, but inability to preload audio turned me off. Quintus apparently does not support hover at all. So, I was left with CanvasEngine and EaselJS. RPG.js is moving to CanvasEngine, so I thought there must be some reason for that and tried CE first. However, elements.events.mouseover is buggy - the event fires only when mouse stops moving. So, I was left with EaselJS, and managed to get it to work, even easier than I thought by using ButtonHelper class. More in my next post...

Feedback & Share Milan Babuškov, 2013-05-08

Capturing mouse movement with Cocos2d-html5 and replacing default cursor

I decided to try to use Cocos2d instead of jQuery and DOM for my next browser game. I find Cocos2d documentation confusing, and googling around you are more likely to get Cocos2d-iPhone documentation that simply does not apply for some stuff.

I spent a couple of hours trying to understand how to handle mouse or if it is even possible. I found examples using Cocos2d-javascript that worked fine, but using the same code with Cocos2d-html5 did not. At one point I was close to conclude that mouse is not supported as everything tries to emulate touch. However, this is not the case, mouse handling works fine.

Currently (Cocos2d-html5 version 2.1.3), the best documentation is to read the file CCMouseDispatcher.js in cocos2d/touch_dispatcher directory. In your code, in layer object you can use onMouseMoved and other methods found in this file. You might need to figure out the parameters yourself. For example, onMouseMoved returns an event object which has getLocation() function, which returns another object with x and y properties. So, the code to draw a custom cursor would be something like creating the sprite and then updating its position like this:

onMouseMoved:function (event) {
    cursorSprite.setPosition(cc.p(
        event.getLocation().x,
        event.getLocation().y)
    );
}

Now, this would give you two cursors. I tried setting the cursor for the canvas element to none via CSS, but it did not work. Another workaround would be to set a transparent 1x1 pixel cursor using CSS like:

canvas { cursor: url('transparent-image.png') }

I'm yet to try if this works, but somehow I feel it won't. This is all using Firefox 16 on Linux.

Feedback & Share Milan Babuškov, 2013-05-07

Optimizing MySQL backups

In the past I've always used mysqldump without any additional parameters to back up MySQL databases. Today I started thinking if it could be faster, and I found some really useful switches:

--disable-keys - build non-unique indexes after all inserts are complete

--extended-insert - smaller sql file and faster inserts

--add-locks - lock tables while inserting

--quick - dump rows directly from database one-by-one instead of reading into RAM buffer first

Feedback & Share Milan Babuškov, 2013-04-18

Facebook uses Google Analytics for developers' site

I was reading the Facebook developers page looking for information about the Like button. Seeing a red flag from RequestPolicy Firefox extension, I got curious which 3rd party domain is used. To my surprise, it's Google Analytics:

That's really strange. Facebook is giving Google all the information about developers using their platform, which Google can then tie that will other information they already have on the users and target those developers in the future for any need they might have.

I'm pretty sure Facebook engineers are capable of creating a simple web analytics tool for their own website, so I'm really confused now.

Feedback & Share Milan Babuškov, 2013-03-14

Twitter Bootstrap 3.0 is coming

I'm browsing new Twitter Bootstrap v3, and it looks nice, except for flat buttons that might not be such a good idea IMHO. I like the grid system and cool ways to manage HTML tables. And I also found some bugs. Clicking the Action shows the menu in wrong place:

And something seems to be wrong with layout here:

This is using latest stable Firefox on Linux

Feedback & Share Milan Babuškov, 2013-03-10

Past posts

Copyright © Milan Babuškov 2006-2013