To finally jump on the multiprocessor bandwagon, I bought a new computer with AMD Phenom II X4 905e on Monday.
Since I didn't have enough time to install my favorite Gentoo, I decided to quickly give Windows 7 RC a try.
I'm quite impressed with the functionality offered out of the box. All the hardware is usable and I didn't even bothered to install any drivers (except for Catalyst), since I'm going to wipe the partition clean in couple of weeks.
But as I already have Windows 7 up and running, I decided to take part in code7contest. I do not expect to win or anything - I set my goals humbly and want to at least get full version of Windows 7 (hopefully they will give them out to all participants). That's how cheap I am :).
The first couple of milestones/prerequisites are already completed:
Install ViM
Install Visual C++ 2008 Express (for compiler :))
Install Windows 7 SDK RC
Compile program using Win32 API functions introduced in Windows 7
I am very aware about the shortcomings of following code - don't copy paste it - it's just something to test if I can call Windows 7 API functions without any LoadLibrary calls.
//snip
WCHAR *a = (WCHAR *) malloc(100);
SetCurrentProcessExplicitAppUserModelID(L"Hello");
GetCurrentProcessExplicitAppUserModelID((PWSTR *)&a);
MessageBox(NULL, a, a, MB_OK);
//snip
Next task is to prepare a plan and post a milestone overview with dates.
Hopefully regular work on the contest entry will force me into updating this blog more regularly.
While researching an issue with how different versions of Citrix servers and Citrix clients handle copy pasting between remote and local applications I found myself in need of a little app, which would show me what data formats I have in clipboard right now.
So here goes another utility, which I can't imagine anyone will find usefull.
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0610
#define UNICODE
#include <windows.h>
#define IDI_MYICON 201
int main(void)
{
wchar_t full[50000];
wchar_t *index = full;
wchar_t name[255];
unsigned int format = 0;
OpenClipboard(NULL);
do {
format = EnumClipboardFormats(format);
GetClipboardFormatName(format, name, 255);
index += wsprintf(index, L"%d : %ls\n", format, name);
} while (format != 0);
MessageBox(NULL, full, L"Clipboard formats", MB_OK);
CloseClipboard();
return 0;
}
The code quite naïvely assumes, that the output buffer won't be longer than 50 000 characters, so in case you have so many formats in clipboard, the code will overflow. :)
For convenience binary version follows clipview.zip (6.8 kB)
If you copy paste for example Excel data into clipboard and run this program, the output will look like this:
Obligatory thanks to Mark James for creating the amazing Silk icons.
Before reinstalling my Gentoo, I had this strange issue with my mouse when watching movies in MPlayer. Everytime I clicked my left mouse button, MPlayer would increase volume.
I could easily remap the functionality of mouse in MPlayer not to mess with volume, but whichever value I remapped the functionality to, it always unpaused movies and displayed the annoying volume status over the movie.
I was looking for solution for quite some time, but the problem magically disappeared after re-installation, so I quickly forgot about it. Until yesterday of course :)
Since I have new versions of pretty much everything, I concluded, it will be issue with my configuration and not a bug.
I'm using Microsoft SideWinder mouse
so I decided to dig in the logs to find out, what is going on. dmesg and /var/log weren't very helpful, so I decided to look what's going on in MPlayer.
MPlayer was opening some joystick for reading. But I didn't have any joystick plugged in, since I borrowed my gamepad to a friend two days ago.
Heuréka!
Looking in /sys/devices folder, I found out, that Microsoft SideWinder mouse registers itself as mouse device as well as joystick device. Before I unplugged my gamepad, MPlayer was attaching itself to my gamepad at /dev/input/js0 and since I don't have it connected anymore, mouse gets assigned to js0.
It always annoys me a whole lot, when I'm writing some Unix/Linux shell script and I need to send an email with attachments - there simply isn't an easy way.
Standard mail doesn't support any attachments whatsoever, in some versions of mailx one attachment is supported and mpack is generally not available at all.
Since I found out, that some of the servers, I need to deploy my script to, don't even have uuencode installed, I decided to write myself a small standalone utility in Perl for sending multi-attachment emails.
There are lots of existing solutions in CPAN for this, but I specifically needed something, that's using only core Perl modules and sendmail - things I can count to find on every server.
#!/usr/bin/perl
use strict;
use MIME::Base64;
if ($#ARGV < 2)
{
print(STDERR "Not enough parameters\n\n");
print(STDERR "Usage:\n");
print(STDERR "\t./send.pl e\@mail \"Subject\" file1 file2 ...\n");
print(STDERR "\t./send.pl \"e\@mail,a\@ddress\" \"Subject\" file1 file2 ...\n\n");
exit -1;
}
#Sendmail requires email addresses to be separated by comma AND space
my $to = $ARGV[0];
$to =~ s/,/, /g;
open STDOUT, "|/usr/sbin/sendmail -t";
my $boundary = "_----------=_10167391557129230";
print("Content-Transfer-Encoding: 7bit\n");
print("Content-Type: multipart/mixed; boundary=\"$boundary\"\n");
print("MIME-Version: 1.0\n");
print("Date: ".`date`);
print("To: $to\n");
print("Subject: $ARGV[1]\n\n");
for (my $i = 2; $i <= $#ARGV; $i++)
{
my $basename = `basename $ARGV[$i]`;
$basename =~ s/\s//g;
print("\n--".$boundary."\n");
print("Content-Transfer-Encoding: base64\n");
print("Content-Type: application/octet-stream; name=\"$basename\"\n\n");
local $/=undef;
open FILE, $ARGV[$i] or die "Couldn't open file $ARGV[$i]";
binmode FILE;
my $content = <FILE>;
close FILE;
print encode_base64($content)."\n\n";
}
print("--$boundary\n.\n");
The code depends on two things:
sendmail being available in /usr/sbin
Perl core module MIME::Base64 - every standard Perl installation has this.
There is a little issue in the code - the MIME boundary is hard coded and not checked for uniqueness, but since we're using Base64 there is not much possibility of a clash.
When reinstalling my Gentoo, I decided to give the radeon - open source ATI driver - a try. I have Radeon 9600XT and I always had issues with the closed source fglrx driver from ATI.
I wasn't expecting much from the free driver, but the current functionality simply blew me away - dual monitors, 3D acceleration, video playback - everything works nicely. I can't honestly think of anything more I could ask for.
Thank you guys so much!!!
Currently the stable xorg-server is version 1.3 and xorg-x11 is at version 7.2, but since I like my software freshly build (plus I wanted to give the compiz fusing a try), I had to accept the unstable packages when compiling.
Gentoo is a distribution for power users/developers, so I sometimes find the release process little too conservative. I would mark packages as stable much sooner, but that's probably just me :).
So now I'm just moving wobbly windows around my desktop and grinning :))
I was forced to use Windows exclusively for past couple of months due to various reasons and I was missing my Gentoo installation a lot. As a New Year's gift to my computer I decided to reinstall the whole thing, because the installation has been quite dated with lot of unused packages, many obsolete flags and still on gcc 3.4
I was thinking how to do the installation most conveniently, but eventually decided to wipe the whole installation away and keep only
/etc/passwd
/etc/shadow
/etc/fstab
/home/
Accidentally I managed to delete my /lib folder while doing the cleanup and was left with non working system :)
Because my computer doesn't have any working CD/DVD drives and can't boot from USB, I was really happy Grub can find kernel images on FAT32 partitions
So I downloaded the Gentoo LiveCD, unpacked it to my Windows harddrive and restarted the computer
The kernel got loaded and to my extreme surprise the gentoo.igz ramdisk contains a minimal shell with busybox, so I was able to do all the mounting, deleting and copying files I needed. Yeey from Gentoo and Linux.
For Win32 GUI debugging I'm usually using WinSpector (I highly recommend it), but as it turns out WinSpector doesn't display owner windows (or maybe I just can't find it).
I was debugging a foreground activation error when the application was running through Citrix. As it turns out in certain combinations of Citrix clients and Citrix server registry setting, the windows ownership on the client is different than on the desktop.
I highly doubt this will be useful to anyone else but me, but here it goes anyway: lshwnd - program for listing all HWNDs, their parents and their owners.
#define UNICODE
#include <windows.h>
#include <vector>
wchar_t name[1000];
BOOL CALLBACK myEnum(HWND hwnd, LPARAM lParam)
{
std::vector<HWND> *windows = (std::vector<HWND>*)lParam;
windows->push_back(hwnd);
}
void enumerate(HWND hwnd, int depth)
{
std::vector<HWND> windows;
EnumChildWindows(hwnd, myEnum, LPARAM(&windows));
GetWindowText(hwnd, name, 1000);
for (int i = 0; i < depth; i++)
wprintf(L" ");
wprintf(L"%x:%x - %s\n", hwnd, GetAncestor(hwnd, GA_ROOTOWNER), name);
for (int i = 0; i < windows.size(); i++)
{
enumerate(windows[i], depth+1);
}
}
int main()
{
enumerate(NULL, 0);
return 0;
}
Usage is quite easy, you start
lshwnd.exe > hwnd.txt
and you will get a list of all your HWNDs in a tree structure according to parent child relationship. Every HWND is represented as
It's quite often when debugging a networking application, that you have to look at the underlaying data. You might say, this is very easy with existing tools like tcpdump and windump. But let's say you have to do it on a remote server without admin rights. Suddenly the task is not so easy.
You can usually get away with telnet in case you need to simulate the client or more preferably netcat (where you can simulate the server as well). However sometimes you just want to watch the communication between two endpoints.
You basically need a tunnel, that will forward all communication and simultaneously write all the data to file / screen.
I wrote a little program for that, it's called middleman and it saves all communication in files. New file is created for every connection and raw data from both endpoints are written into this one file. If the protocol, you will be monitoring is hard to understand, you can modify the program to split the communication into two files, the program is quite simple, so it shouldn't be much of a problem:
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
class Client
{
int id;
TcpClient local;
TcpClient remote;
NetworkStream localStream;
NetworkStream remoteStream;
FileStream file;
public Client(TcpClient newLocal, string remoteAddress, int remotePort, int nid)
{
local = newLocal;
localStream = local.GetStream();
remote = new TcpClient(remoteAddress, remotePort);
remoteStream = remote.GetStream();
id = nid;
file = new FileStream("session_" + Convert.ToString(nid) + ".txt", FileMode.Create);
}
public void process()
{
int time = 0;
int i;
Byte[] bytes = new Byte[4096];
while(true)
{
if (localStream.DataAvailable)
{
if ( (i = localStream.Read(bytes, 0, bytes.Length)) != 0)
{
try
{
if (remoteStream.CanWrite)
{
remoteStream.Write(bytes, 0, i);
file.Write(bytes, 0, i);
}
}
catch (Exception)
{
break;
}
}
time = 0;
}
if (remoteStream.DataAvailable)
{
if ( (i = remoteStream.Read(bytes, 0, bytes.Length)) != 0)
{
try
{
if (localStream.CanWrite)
{
localStream.Write(bytes, 0, i);
file.Write(bytes, 0, i);
}
}
catch (Exception)
{
break;
}
}
time = 0;
}
time++;
Thread.Sleep(1);
if (time > 5000)
break;
}
remote.Close();
local.Close();
file.Close();
}
}
class ManInTheMiddle
{
static int Main(string[] args)
{
int localPort, remotePort;
string localAddress, remoteAddress;
switch (args.Length)
{
case 2 :
remoteAddress = args[0];
remotePort = localPort = Int32.Parse(args[1]);
localAddress = "127.0.0.1";
break;
case 3:
remoteAddress = args[0];
remotePort = Int32.Parse(args[1]);
localAddress = "127.0.0.1";
localPort = Int32.Parse(args[2]);
break;
case 4:
remoteAddress = args[0];
remotePort = Int32.Parse(args[1]);
localAddress = args[2];
localPort = Int32.Parse(args[2]);
break;
default:
Console.WriteLine("MiddleMan - Tool for snooping on TCP/IP connections");
Console.WriteLine("");
Console.WriteLine("Usage: middleman remote_server port");
Console.WriteLine("Usage: middleman remote_server remote_port local_port");
Console.WriteLine("Usage: middleman remote_server remote_port local_ip_address local_port");
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("MiddleMan starts listening as a server on local_ip_address (default 127.0.0.1)");
Console.WriteLine("on local_port. All incoming connections to this server are forwarded");
Console.WriteLine("to remote_server:remote_port and logged into a file.");
Console.WriteLine("");
Console.WriteLine("");
return 0;
}
TcpListener server = new TcpListener(IPAddress.Parse(localAddress), localPort);
server.Start();
int id = 0;
while(true)
{
Client client = new Client(server.AcceptTcpClient(), remoteAddress, remotePort, id++);
Thread w = new Thread(new ThreadStart(client.process));
w.Start();
}
}
}
The usage is quite simple, you specify the IP address or hostname, which you want to connect your tunnel to and the port
middleman www.google.com 80
From now on, all the communication that goes to localhost:80 will be forwarded to google:80 and will be simultaneously written to a file
In case you specify only one port (as in the example above), middleman will start listening on the same port as is the remote server listening on (in this case 80). If for whatever reason you can't use the same port on the local machine, you can start middleman like this:
middleman www.google.com 80 81
which means - forward all requests from localhost:81 to google.com:80
In the beginning I wanted to use Lua to define the game logic, but I found out, that it's not easy to integrate OPP with Lua, so I wrote the whole logic in C++. But I definitely want to investigate Lua integration with C++ further to use it in my following projects.
What really paid of was my one-click deployment system. I was running a webserver on my development PC and every time I wanted to test something I made a release:
7zip a -r -x!.\* /$(RELEASE_DIR)/angiine.release/angiine$(DATE).7z $(ANGIINE_DIR)
cp /$(RELEASE_DIR)/angiine.release/angiine$(DATE).7z /$(RELEASE_DIR)/angiine.release/angiine_current.7z
And on the target computer I had a batch file looking like this
wget http://server/angiine_current.7z
7z x angiine.current.7z
cd angiine/bin/
./angiine
The whole cycle "recompile, package, download, unpack and start" took about ten to fifteen seconds. I was able to test the game on two different computers almost seamlessly and I can't recommend this hard enough.
For real masochist you can check you all the versions of the game I managed to produce during the 48 hours - angiine.releases.7z 4 MB
The Progress
During the compo, I spent quite some time on loading 3D models to my C++ program. I should have prepared my base library and not waste my time with this during the competition time.
Here are some progress screenshots of the game:
For more information, you can look at my almost award winning journal :) here
Statistics
For anyone interested, here is my timelapse
This is an overview of which programs I used the most during the competition:
Results
Overall
32/59
Fun
39/59
Innovation
28/59
Theme
42/59
Polish
40/59
Graphics
20/59
Audio
42/59
Humor
28/59
Technical
12/59
Food
28/59
Journal
5/59
Towlr
29/59
My best scores were in categories Journal (5th place - link) and Technical (12th place). I'm very happy about that, but I will definitely try to do better next time :).
So that was my Ludum Dare compo overview - I had extreme fun, I slept very little and after turning my game in, I got amazing sense of accomplishment. Kudos to the organizers, I'm already looking forward to the next one.
It's part of the whole Ludum Dare experience to record your desktop every few minutes and create a movie afterwords which overviews your progress.
Since I recently became a proud owner of a second monitor, I found myself in need for a multi-monitor screenshot making tool. There are probably some utilities, which do exactly that, but I'm too lazy to look for them and decided to write my own tool.
This is just a very stupid prototype, which I will be using/testing during the competition. It doesn't save the files into one image but one image per monitor. That's kind of unfortunate, but composing picture from different DCs is no fun.
The other thing the program does is that it records which program was in foreground while you took the screenshot and records the data into sqlite database
So afterwards you can just start sqlite3 data.db and type in following command:
SELECT process, count(*) AS sum FROM work GROUP BY process ORDER BY sum;
You'll receive a nice overview about which application you used the most during the competition / monitoring time.
Here you can see my relative application use in the past 10 months on my work computer:
I guess I'm researching a lot :)
So for anyone interested, the download is - logger-0.1.zip (300 kB)
Thanks to Mark James for creating the amazing Silk icons.