2009-03-30

Walkthrough: Johnny Rocketfingers 2

Johnny Rocketfingers 2 is a point-and-click adventure game created by Ryan Katham. It can be found e.g. on here on Kongregate.
You should make sure to have played the first part as well, even though the second one has much more plot and animations. Also, the user interface is more advanced and includes a permanent inventory and different options.

Pick up ashes from ashtray.
Pick up empty bottle.
Use empty bottle on countertop.
Use ashes on thug.
Pick up card.
Pick up stuff under couch (use hand on "under couch").
Pick up knife from left wall (above the couch).
Pick up chain.
Use key on window.
Pick up gum on wall (under the windowsill).
Use gum with chain.
Use hand on ladder.
Walk left and use hand on trash can.
Walk right and talk to shady looking character.
Ask about information and where to find Thug Inc. Agree to get him what he wants.
Use hand on shop door.
Pick up Forty (the liquor bottle in the foreground).
Use Forty on the crack in the wall, beside the arcade game.
Leave shop. Use hand on the crack in the wall.
Walk to the bum and give him the bottle.
Pick up his money.
Go back into the shop.
Pick up Seltzer from the counter.
Talk to clerk.
Use hand on ladder.
(There are apparently dozens of different cool animations for the next sequence)
Use Seltzer with bread.
Use bread on the pigeon.
Use hand on nest.
Climb down.
Use hairpin on parking meter.
Walk to the right and use knife on drain.
Use hand on open drain.
Climb back up and go to alley.
Use knife on trash bag.
Leave alley and go back down to sewer.
Use wrench on pipe.
Climb into the hole, use burger outside the hole and use pipe on the crocodile.
Use wrench on wheel.
Use hand on the wheel.
Use the single coin on panel.
Use knife on panel.
Click on the open panel and use scrabble piece on missing button.
Use hand on the new button.
Keep walking left to the gate.
Use the combined gum and chain on lighter on top of the treasure pile.
Go back up and talk to the shady character.
Talk about the lighter, confirm finding and ask about the location of Thug Inc.
Keep going left until you see bus.
Use the coin pile on the bus.
Walk to the hideout.
Enjoy the ending.

Walkthrough: Johnny Rocketfingers

Johnny Rocketfingers is a point-and-click adventure game created by Ryan Katham. It can be found e.g. on here on Kongregate.

It features a not too complicated plot, funny dialogues and pretty cool action. The animation is somewhat minimalistic, but nicely drawn. The sounds are cool, too. Overall, all you need for a short break.


Part I - The Case

Either accept directly or choose the first answer.
Check out the bar alley.
Click on the empty can.
Click on the trash bin.
Click on the fish.
Click on the dump.
Click on the cat.
Click on the fish.
Leave.
Go to the local thug hang out.
Click on the cat.

Part II - The Break In

Click on the box.
Click on the plank.
Click on the doll.
Click on the plank.
Click on the gun.
Click on the empty can.
Click on the gun.
Click on the gun.
Click on the door.
Click on the crowbar.
Activate Johnny Power.

Part III - The Rescue

Click on the nail in the wall to the right.
Click on the pile of dirt on the floor.
Use screwdriver on the hole at the bottom of the far wall.
Use screwdriver on the door window.
Use screwdriver on the hole at the bottom of the far wall.
Use screwdriver on window.

Part IV - The Conclusion

Enjoy the show.

2009-03-27

How to make an HTTP connection in C++ on Windows (Mobile) using WinINet

Making a programmatical HTTP request from an application is a very common use case. However, I found that there are some obstacles, especially if it is not just a standard GET request.

for example, let's say there is an application that needs to upload a binary file to a web server with SSL. Obviously, this makes it slightly more complicated, since the file needs to be read, custom headers added, HTTPS used instead of HTTP, etc.

The below example, for starters, shows how utilize the WinINet library to send a GET request using either HTTP or HTTPS, depending on whether the flag m_bUseSSL is set. The difference between those two is the port setting in InternetConnect() and also the additional flag INTERNET_FLAG_SECURE in HttpOpenRequest.

One thing that kept me in the dark for a while is the accept type parameter in HttpOpenRequest. On Windows Mobile 5.0, if this parameter is NULL, the function will fail with error code 87 ("invalid parameter"), contrary to what the documentation says. Hence, you need to pass the array as documented and also shown below. this is especially a pain because in the emulator for Win Mobile 6.0, which I used for testing, it tolerates a NULL accept type parameter. I hope this saves you some time.



// Accept any text content
const TCHAR * c_szAcceptTypes[] = { TEXT("text/*"), NULL };

HINTERNET hIntrn = InternetOpen(TEXT("HTTP_Connnect_Example"),
INTERNET_OPEN_TYPE_DIRECT,
NULL, // no proxy
NULL,
0); // make it synchronous


if (!hIntrn)
{ // error handling
}

INTERNET_PORT wPort = (m_bUseSSL ? INTERNET_DEFAULT_HTTPS_PORT
: INTERNET_DEFAULT_HTTP_PORT);
HINTERNET hConn = InternetConnect( hIntrn,
m_szServerName,
wPort,
NULL,
NULL,
INTERNET_SERVICE_HTTP,
0,
NULL);
if (!hConn)
{ // error handling
}
else
{

DWORD dwOpenRequestFlags = INTERNET_FLAG_NO_UI |
INTERNET_FLAG_NO_CACHE_WRITE;
// add more flags here as needed
if (m_bUseSSL)
{
dwOpenRequestFlags = dwOpenRequestFlags |
INTERNET_FLAG_SECURE;
}

HINTERNET hReq = HttpOpenRequest(hConn,
TEXT("GET"),
TEXT("index.html"),
TEXT("HTTP/1.1"),
NULL, // no referer
c_szAcceptTypes,
dwOpenRequestFlags,
NULL); // no asynchronous context

if (!hReq)
{ // error handling
}
else
{
if (!HttpSendRequest(hReq, NULL, 0, NULL, 0))
{ // error handling
}
else
{
// read server response
char* pcBuffer = new char[READBUFFSIZE];
DWORD dwBytesRead;

do
{
dwBytesRead=0;
if(InternetReadFile(hReq, pcBuffer,
READBUFFSIZE-1, &dwBytesRead))
{
pcBuffer[dwBytesRead]=0x00; // Null-terminate buffer
sprintf("%S", pcBuffer);
}
else
{ // error handling
}
}
while(dwBytesRead>0);

delete[] pcBuffer;
pcBuffer = NULL;
}
if (!InternetCloseHandle(hReq))
{ // error handling
}
}
if (!InternetCloseHandle(hConn))
{ // error handling
}
}
if (!InternetCloseHandle(hIntrn))
{ // error handling
}

2009-03-18

Walkthrough: Gateway II

Gateway II is a great point-and-click escape adventure game. It features beautiful atmospheric 3D animations and an original plot. The puzzles have perfect difficulty and the interface makes it nice to play. I like this one very much; it is excellent to play when you need a break! :)

The game was created by Anders Gustafsson and can be found e.g. on Kongregate.

First gateway
-------------
Click on the left gateway
Click on the button next to the door, then on the door
Click on the hand mirror on the sink
Click on the large mirror, then on the warm water tap, wait until combination is visible, then leave mirror
Click on keypad and enter the combination seen in the previous step, click on videotape and click on door to leave
Walk towards gateway, then back underneath the lamp and use bathroom mirror with eye
Enter gateway.
Play all clips on videotape:
Click on TV, use videotape with slot and click on "Transfer"
Click on "1" and "Play", then "2" and "Play"
Click on "Eject" and then leave TV view by clicking to the left of TV

Second gateway
--------------
Click on right gateway
Walk over the transparent bridge. The door will only open if all fields have gone dark, so you will need to step on some fieds more than once
Click on right door
Click on poster, note down combination
Click on lighter and newspaper (on desk)
Click on drawer, then on screwdriver
Use newspaper on door, then use screwdriver on door
Click on newspaper, then use key on lock
Click on door then enter next room
Walk over invisible bridge (about the same distance as the red bridge), then click on videotape
Walk back to TV room. Again, the door behind the red bridge will only open when all fields are dark
Play all clips on videotape (see instructions under first gateway)

Third gateway
-------------
Click on third gateway
Click on lamp six times
Click on phone desk, then click on pen
Move mouse (pen) over the blank area of the paper with mouse button clicked, until number becomes visible
Put down pen (click on the area where you picked it up)
Click on receiver, then dial number shown on paper. Put down receiver, and leave phone view
Click on next door
Use lighter on sprinkler
Pick up videotape
Open fridge, then hide between door and fridge
Click on door to leave
Walk underneath the lamp, then use mirror on water
Memorize or write down color sequence, then click on alarm override
Set the above color sequence, then door should open (if it doesn't work, try it backwards)
Click on door to leave
Click on door to leave
Play all clips on videotape (see instructions under first gateway)

Fourth gateway
--------------
Click on fourth gateway
Note down the three numbers above the far door
Click on window
Let the robot calculate all three numbers (e.g. for the number "24" type "12" and "12")
Punish on wrong answers until the calculation is correct
Leave the robot
Click on door
Click on telescope, wait
Click on lamp six times
Click on telescope, wait
Click on phone desk
Click on receiver
Dial number on paper (11223311)
Click on door
Click on TV and enter combination from poster in 2nd gateway (786)
Click on videotape and go back to starting point

Final
-----
Click on robot
Click on TV and play all clips on videotape
Click on wire on the ground
Click on the robot with the wire in hand
Use the wire with hole
Enter number of the tapes' proper chronological order (264379851)
Follow the robot

2009-03-13

Walkthrough: The Several Journeys Of Reemus, Chapter 1

The following is an instruction how to solve "The Several Journeys Of Reemus, Chapter 2" (I played it on Kongregate). It is a lovely point-and-click adventure with nice graphics and a funny plot.

I tried to keep to telling where to click and not give away any plot information.

Chapter One
-----------
click on the barrel to roll over to the shovel
click on the shovel
click on the mouse trap
click on the bucket
click on the feeding tray
click on the ladder
click on the bucket
click on the hay
click on the rake, then on the parasite

Chapter Two
-----------
click on bird
click on Reemus, then on the bag of the guardian
click on one of the darts
click on the vial to the left of Liam
click on Reemus
click on the dart to roll it in honey
click on the dart again

Chapter Three
-------------
click on the blue animal
click on a the peppermint plant
click on the pepper-plant (the one with the red leaves, not the one with the yellow leaves), then click on the coral-like hollow structure where the Yallerpede is hiding
click on the blue animal
click on the purple plant in the background, then on the air pump plant
click on the air pump plant's tail, then on the tip of the root where the Yallerpede is hiding
click on the air pump plant again

Chapter Four
------------
click on the electric beetle
click on the pink Daiquiri plant to pick one off
go left to the first screen (i.e. click on the arrow), then click on the eyeless beaver
click on the branch where the beaver was sitting, then go right to the second screen
click on the blue-yellow coral plant, then go left to the first screen
click on the bird, then on the bubble slug it is holding
go right to Liams screen, then back to the first screen
click on the big leg bone that was recently dropped, then go back to Liam
click on the purple butterfly nest above the zapper plant (just right from the bird), then immediately on the zapper plant to keep its mouth jammed open
click on the slug the bird is holding

Chapter Five
------------
(Reemus) go to the leftmost screen, click on the antennae of the big yellow flower on the tree, then click on the donut field in the foreground. Go one screen to the right.
(Liam) go one screen to the left. Click the pendulum plants until all of them are aligned at the top of the screen, on the same height as the bowl of cheese. Click on the bird. Walk on screen to the left.
(Liam) click on the twin parallel branches of the leftmost tree, right beneath the spider.
(Reemus) click on the puddle of mud beneath the spider net, then click on the big pile of grapes.
(Liam) should look like a giant bee now. Go to the rightmost screen, then click on the bee.

Chapter Six
-----------
(Liam) click on the hole leading to the honey.
(Reemus) click on the orange plant, then on the blue plant. Then align the six small round animals(?) until the sunlight is reflected onto the blue plant you just clicked on. This should make the weed inside begin to smoke.
(Liam) click on the handrail near the entrance, to get the hook-like pipe loose. Click on the root of the blue plant, then click on the blue bear. Click on the hole leadin to the honey, then on the root with the beak-like thorn.
(Reemus) click on the root in front of Reemus twice, then on the bag of the purple plant.
(Liam) click on the root again, twice.
(Reemus) click on the severed purple plant, then on the root.

Chapter Seven
-------------
There are three different ways to play Chapter Seven:

Chapter Seven - Double Hero

(Reemus) click on the plants in the foreground, then on the cave entrance. Click on the frog to hide inside. Click on the plant next to the frog, then on the evil creature.
(Liam) walk two screens to the right, then back to the entrance. Click on the sleeping hamster twice, then walk to the right. Click on the cactus in the background, then walk back to the left. Click on the burning animal in the foreground, which looks like a coral fish, then walk back to the right and click on the cyan scavenger. Walk to the right and click on the parasite.

Chapter Seven - Lucky Coward

(Reemus) Click on the mouth of the frog.
(Liam) Walk two screens to the right, then back to the cave entrance. Walk to right.

Chapter Seven - Double Coward

(Reemus) Click on the mouth of the frog.
(Liam) Walk two screens to the right, then back to the cave entrance. Walk to left.

2009-03-11

How to query Windows Connection Manager in C++ for Internet connection parameters

Recently I had to create an HTTP connection from an application on Windows Mobile. After a while I figured out that the Connection Manager would be the way to go to determine connection parameters, like proxy settings etc.

You can then use e.g. WinInet functions for the actual data traffic. I will post an example for that later on. The following has been tested on Windows Mobile 5.0 and 6.0.

By the way, I will have to look for a way to get the formatting and syntax highlighting optimized.


int QueryConnMgr()
{
HANDLE hConnMgr = NULL;
BOOL bMgrAvailable = FALSE;
hConnMgr = ConnMgrApiReadyEvent();

if(!hConnMgr)
{ // error handling
return 0;
}
// wait for half a second to allow ConnMgr to get ready
DWORD dwRC = WaitForSingleObject(hConnMgr, 500);
if (WAIT_OBJECT_0 == dwRC)
{
bMgrAvailable = TRUE;
}
if(hConnMgr)
{
CloseHandle(hConnMgr);
}
if(!bMgrAvailable)
{ // error handling
return 0;
}

// create CONNMGR_CONNECTIONINFO structure required for URL mapping
CONNMGR_CONNECTIONINFO ci = {0};
PROXY_CONFIG pcProxy = {0};
DWORD dwIndex = 0;
DWORD dwStatus = 0;
HRESULT hr = S_OK;
HANDLE hOpen = NULL;
HANDLE hConnection = NULL;
ci.cbSize = sizeof(CONNMGR_CONNECTIONINFO);
ci.dwParams = CONNMGR_PARAM_GUIDDESTNET;
ci.dwFlags = CONNMGR_FLAG_PROXY_HTTP;
ci.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE;

// Attempt to map the URL to a target net
hr = ConnMgrMapURL(TEXT("http://your.server.url"), &(ci.guidDestNet), &dwIndex);
if (S_OK != hr)
{ // error handling
return 0;
}

// make synchronous connection attempt with timeout of 15 seconds
hr = ConnMgrEstablishConnectionSync(&ci, &hConnection, 15000, &dwStatus);
if (S_OK != hr)
{ // error handling
return 0;
}

if (dwStatus != CONNMGR_STATUS_CONNECTED)
{ // makes no sense to continue
return 0;
}

// Get proxy information.
hr = ConnMgrProviderMessage( hConnection, &IID_ConnPrv_IProxyExtension, NULL,
0, 0, (PBYTE)&pcProxy, sizeof(pcProxy));

if (S_OK == hr)
{
dwAccessType = INTERNET_OPEN_TYPE_PROXY;
pszProxy = (LPTSTR) LocalAlloc(LPTR, ARRAYSIZE(pcProxy.szProxyServer));
// Make sure pszProxy was allocated.
hr = StringCchCopyN(pszProxy, ARRAYSIZE(pcProxy.szProxyServer),
pcProxy.szProxyServer, ARRAYSIZE(pcProxy.szProxyServer));
if (S_OK != hr)
{ // reset proxy info on error
pszProxy = NULL;
}
}
else if (E_NOINTERFACE == hr)
{
dwAccessType = INTERNET_OPEN_TYPE_DIRECT;
pszProxy = NULL;

// Reset hr, since it's not really an error here.
hr = S_OK;
}
else
{
// unexpected hr code
return 0;
}

ConnMgrReleaseConnection(hConnection, TRUE);
return 1;
}