October 2010

Warning! Some information on this page is older than 6 years now. I keep it for reference, but it probably doesn't reflect my current knowledge and beliefs.

# On/Off Expo

Sat
23
Oct 2010

I've spent whole day on On/Off Expo that currently takes place in Warsaw. I've met many interesting people there from both gamedev.pl and demoscene. Poeple from demoscene organize a place there with "retro games" where everyone can play some games on old computers like Amiga or Commodore. But the rest of expo is about the newest and most advanced technology available to ordinary customer. You can find lots of hardware there like graphics cards, motherboards, pendrives, speakers, headphones, cellphones, 3D TVs and more. You can play on PC, Xbox 360, some driving and flight simulators, Guitar Hero, DJ Hero, Wii, Kinect and even the unreleased Tron Evolution game. Generally there are lots of attractions so if you live in Warsaw, I strongly recommend visiting the expo tomorrow. Here are my photos from this event. One of them:

Comments | #demoscene #hardware #events Share

# Blender 2.5 - Programming Export Plugin

Fri
22
Oct 2010

Today I've been familiarizing myself with Blender 2.5. This new version is still in Beta stage, but as far as I can see everything is aleady in place and the program works OK. I only had to solve one problem at the beginning - my Blender was crashing at startup, because it was looking for PYTHONPATH environmental variable and thus trying to use old version of Python language that I had installed, while new Blender needs Python 3.1. The solution is to clear this environmental variable so Blender can use its bundled Python distribution. I've created a batch script to do this, called "Run Blender.bat":

set PYTHONPATH=
"c:\Program Files\Blender Foundation\Blender\blender.exe"

Many changes have been made in new new Blender version. Fundamental concepts stay the same, so we still have Object Mode, Edit Mode, select objects with right mouse button, grab with G, rotate with R and scale with S. User interface is still nonstandard with all its non-overlapping and non-modal philosophy. But they introduced some new features and made quite big changes to the interface, so it took me some time to play around and discover where is everything now and how it works. Readings on this topic I'd recommend are the new manual for Blender 2.5 and especially Blender 2.5 Changes - a document that highlights what's new.

The function that I've spend much time searching for was showing normals, so in case you also need this and can't find it: 1. You must be in Edit Mode 2. Click on the small (+) symbol in the right-top corner of the 3D View to expand a panel with some parameters 3. In this panel, look for Mesh Display / Normals section and select the checkboxes you want.

When it comes to writing plugins, Python API has been completely redesigned. Information about it can be found in Introduction, Manual and finally Reference. I couldn't find any article about writing export plugin for Blender 2.5, but basing on the information I could find and the source code of the existing plugins I've managed to code one. Here it is: io_export_json.py. It exports some of the data (scenes, objects, meshes, vertices, faces, edges, normals, texture coordinates, vertex colors) in JSON format.

BTW do you know any good program to view JSON documents as a tree? The best I've found so far is JSON Viewer, but it's not ideal. For example, it can't open files so the document has to be pasted via the clipboard.

Blender keeps Python plugins in the user's directory. In my Windows 7 it is C:\Users\%MY_LOGIN%\AppData\Roaming\Blender Foundation\Blender\2.54\scripts\addons. To start using new plugin, you have to:

  1. Copy the .py file to this directory.
  2. Restart Blender or hit F8 to reaload scripts.
  3. Go to File / User Preferences
  4. Navigate to Add-Ons tab.
  5. Find the add-on you want to use. You can filter add-ons by type with buttons on the left.
  6. Select checkbox next to the add-on.
  7. It should now be available in File / Export menu.

Comments | #blender #graphics Share

# Beginning with OpenGL ES on Android

Thu
21
Oct 2010

I've started learning programming for Android. It's (probably) nothing commercial, I just love to learn new technologies and APIs while I have not much experience in either Java, OpenGL ES or mobile technologies at all. The first thing I did was... buying a phone - LG GT540 in my case. It has Android 1.6 (upgrade to 2.1 is scheduled for this year).

Android is a nice platform. Anyone can code for his phone in either Windows or Linux, using Java language (native code development is also possible). To start my coding, I needed to install JDK (SDK for Java), Android SDK, Java version of Eclipse 3.5 (they say Android SDK is not fully compatible with new Eclipse 3.6) and Eclipse JDT plugin to connect them all. Android Developers website does a great job explaining all the steps required to setup the whole development environment so I've came across not so many issues to get annoyed as I often get when installing some C/C++ stuff :)

I've read a bit about the fundamentals of developing applications for Android and I like the API. All these ideas like Activity, Service, Intent, View, Widget, Task etc. seem very well designed. But just like PC game developers learn WinAPI to only initialize an empty window and launch DirectX or OpenGL in it, I went straight to OpenGL on my Android. Android 1.6 has OpenGL ES 1.1, which in turn is the embedded equivalent for OpenGL 1.5. This 3D API has no shaders, so all the graphics has to be done using fixed function pipeline, including MODELVIEW and PROJECTION matrices, 2 textures with register combiners, 8 dynamic per-vertex lights, 1 user clip plane, fog etc. - something like on the old good GeForce 2 MX :)

It's easy to start using OpenGL for someone who has experience in DirectX because all the concepts that are so diffcult to understand at the beginning of the game programming adventure stay the same - like 3D coordinate system, vertex, triange, matrix, texture and so on. Some things are only reversed - textures are addressed from left-bottom corner in OGL, matrices are stored in column-major order, matrix multiplication is right-to-left like Point2 = Xform2 * Xform1 * Point1, post-projective space is -1..1, -1..1, -1..1, coordinate system is right-handed so Z points to the viewer, angles are given in degrees, counterclockwise oriented triangles are considered front-facing by default and so one. Some objects have also different names, so in OGL there is "model" not "world" matrix, "fragment" not "pixel" operation etc.

Here is the list of Internet sources I already know about and I've been learning from:

Now you can expect more entries about Android development on my blog :)

Comments | #android #opengl #mobile Share

# The Fate of PC Gamer

Tue
19
Oct 2010

Today I finished single player campaign in the new Medal of Honor on my PC. It's a good game. It's also well optimized because desipte having very good graphics it was running very smoothly on my Radeon HD 5770 in the Full HD resolution and highest quality settings.

When planning to write that, I was thinking many of you could say "who cares?" There are so many types of games these days that the feelings of a PC gamer can be hard to understand for many. Some poeple play only casual/social/online games, some play on consoles... There is also a kind of people who enjoy games, but have no interest in the new positions on the market. Which seems strange to me because have you ever seen a sports fan, let's say a soccer fan, who is not interested in matches his favourite team plays in the current season but only talks about the matches that took place many years ago? :)

That's why (and maybe because I fill a little sick today) I've created a silly drawing: "The Fate of PC Gamer". Enjoy :)

Comments | #games Share

# Static Code Analysis with Cppcheck

Sun
10
Oct 2010

Yesterday I've tried Cppcheck - an open source tool for static C++ code analysis. That was my first practical experience with this kind of tools and I like it quite a lot. Static code analysis is the analysis performed without actually executing a program. Source code is checked against some rules to find common bugs and mistakes.

I expected to see a program that must be given paths to my IDE and all libraries I use in some configuration file before I could execute some console application with poper command line parameters and get some crypic report as the result. All in all, that's the way many programmer's tools work, especially open source ones and specially these for C or C++ languages. But here it was not the case. Cppcheck is a GUI program in which I could just click Check / Directory and read the results of the analysis while the processing was still being done in the background.

Developers of Cppcheck state on their website that "The goal is no false positives.". Apparently they haven't high-performance gamedev code in mind :) The program reported many warnings like "Member variable not initialzed in the constructor 'VEC3::x'". Generally speaking it could be dangerous, but if I want my 3D vector structure to behave like a built-in type and work as fast as possible, leaving its fields uninitialized in the default constructor is exactly what should be done.

But Cppcheck also found some real mistakes in my code, like passing "const VEC3 lhs" parameter (where I forgot about the reference "&") or some local variables that were assigned but never used. So overall I think static code analysis could be of some help to a C++ programmer.

Comments | #c++ #tools Share

# JustSendIt Prototype

Thu
07
Oct 2010

It's not a new idea for me, but last weekend it made me angry again that I couldn't send a file from my laptop to my desktop PC over my home local network. It may seem strange and it's really shocking to me because transferring data is the most fundamental thing we do when using any kind of network. But at the same time I don't know about any program that would simply allow me to send a file to a destination machine without being overly sophisticated or causing some strange technical problems. Here are solutions I've considered:

Network Neighbourhood - most natural way of passing files between Windows computers. I tried to share some folder on my laptop to access it from my PC and it didn't work, despite machines could contact each other via hostname or IP. Same happened when I shared a folder on my desktop and tried to enter it from my laptop. Well, we all know that this service often stop working randomly... Disabling Windows Firewall on both machines didn't help either.

FTP - I have FileZilla FTP server installed on both machines and I know it's quite good software, but that day I couldn't make it work. I could logon to the server from remote machine, but not to transfer any file. I tried different settings on client side like Passive Mode etc., but it changed nothing. I don't like the idea of using FTP to transfer files anyway, because why do I have to install the server, setup user accounts etc. when I just want to transfer a file? Besides, FTP protocol is known for causing technical problems because it opens separate connections on different ports to transfer data.

Other possibilities to send a file over a network are:

So finally I've used an USB flash memory stick to copy this file :P But after this, I've recalled my old idea about a simple program to transfer files over a network called JustSendIt [PL]. Then I decided to code a quick prototype of such program in C# and here it is: JustSendIt Prototype. It requires .NET Framework 4.0 to work.


If you have some computers at home or at work that you transfer files between or if you want to a file to your friend over the Internet, you are sure one of the computers have public IP or is set as DMZ so the other can connect to it, the way to send a file is:

  1. Run JustSendIt Prototype on both machines.
  2. On the receiving machine, go to Receive tab and press Load button to see your computer name and IP address..
  3. On the sending machine, go to Send tab, click Browse button to select a file to be sent, as well as enter the name or IP of the destination computer.
  4. On receiving machine, press the big Receive! buton to start waiting for incoming connections.
  5. On sending machine, press the big Send! button to connect to the second machine.
  6. On the receiving machine, a dialog pops-up to as user about the directory where to save the incoming file.
  7. After confirming this dialog, the file is transferred until finished.

I hope some day I'll find enough motivation to polish and finish this program :)

Comments | #networking #tools #windows Share

# My new address: www.asawicki.info

Tue
05
Oct 2010

I've bought the "asawicki.info" domain, so now the address of my website is www.asawicki.info and my new personal e-mail address is adam__DELETE__@asawicki.info (without the "__DELETE__" part - it's here to fool spambots). Why did I do that? I'm not a proponent of a belief that when you write from a Gmail account, you are an amateur while having a SuperProMegaSoftware.com domain looks professional.

But my previous address - regedit.gamedev.pl - was associated by Google with "Geographic target" of Poland and I couldn't change it in Google Webmaster Tools because of this ".pl" suffix. Maybe that was the reason why my website was being visieted mainly from Poland despite I write in English here for quite a long time? Also, I don't like my old nickname a little bit. All in all, it's more than 10 years old now.

Why did I choose the .info ending? Well, obviously I'm not an .org-anization, my website is not .com-mercial and I don't do any .biz-ness here. This website has just some .info-rmation about me and the things I do :) Besides, other top-level domains with my name were already taken.

Comments | #web #homepage Share

# Technology for Data Processing

Mon
04
Oct 2010

When doing some engineering work on a computer, no matter if gamedev or any other field, there is sometimes a need to process or visualize some tabular data, especially numbers, e.g. statistics about performance or something gathered during program execution. What technology is best for this purpose? At the moment I know about following solutions:

Spreadsheet software, like Microsoft Excel or OpenOffice Calc. They can import CSV files and draw great variety of plots, but for more advanced data processing it would be useful to have something more like a programming language.

At the other end of the spectrum, we can write normal C++ or C# programs to do the work. It can be hard though as we have to code everything on our own, including data structures, loading files and drawing plots. It would be nice to use some higher-level, scripting language with rich standard library, built-in data structures and the like.

Any scripting language can do this. For example, PHP (which I know the best) can be used as a normal scripting language, not only in connection with a web server. All in all, its name means "PHP Hypertext Prerocessor", because it's suited for processing strings and text files.

A technology designed specially for the purpose of crunching numbers is Matlab and its free alternative - Scilab. It provides its own programming language with convenient built-in data types like matrix and is also able to draw plots.

Python is something in between - a normal scripting language with weird but nice syntax and a language-level support for operations like array slicing and complex numbers. It looks like many scientists and engineers use it for computation and data analysis, because there are Python libraries designed for this, like Numpy and Scipy.

There is also The R Project metioned at the Nick Darnells' Blog. It looks like another environment with its own, different programming language, designed especially for statistical computing. It can also load data from files and draw plots.

And finally, some tasks can be accomplished in environments that allow playing around with computer graphics, like EvalDraw (with its own, C-like simple programming language) or Processing (with a language based on Java).

So there are many possibilities in this subject. I've played a bit with all of them at some time, but obviously learning chosen one thoroughly would require much time and effort. So maybe you can help me decide? Which solution would you recommend? Personally I feel a little more convinced to Python, because it is a general purpose language that I can use in different fields too, like coding Blender plugins.

Comments | #math #languages #tools Share

# Sunday in Warsaw - a Time-Lapse Video

Sun
03
Oct 2010

I've made my first time-lapse video today. This is a technique in which you capture an image every several seconds, merge these images into a video and the result looks like the time is moving very fast. Here it is:

To make it, I used my webcam connected to my laptop (because USB cable was to short to connect it to my desktop PC :) Of course a special program had to be used to utilize webcam this way, taking snapshot to a JPEG file every several seconds. The program I used is booru WebCam 2.0. It does a good job and it's free, opposite to many others tools of its kind. The result of this program working for several hours was 805 MB of files named like "image-4887.jpg". I had to use another program to convert them to a video.

This can be done with powerful and free VirtualDub. It's not so obvious how to do it though, because there is no "Import images" command in the menu. Instead, one have to know that it's enough to issue a standard File / Open video file command and open first image with it. VirtualDub automatically recognizes subsequent images as video frames. Now the only thing that remained was to set Video / Frame Rate, Audio / Audio from other file, setup filters (resize in my case), video codec and encode final video with File / Export as AVI.

Comments | #video #tools Share

# Coding Windows Services in C++

Fri
01
Oct 2010

Services in Windows are like daemons in Linux - resident programs that work in background. I've recently learned how to code them in C++ using WinAPI. Here is a quick tutorial about this:

All the documentation you need to develop services can be found in MSDN Library. If you have it offline, go to: Win32 and COM Development / System Services / DLLs, Processes and Threads / SDK Documentation / DLLs, Processed, and Threads / Services. You can also read it online HERE. I talk only about native C and C++ code here, but services can also be written in .NET.

What are pros and cons of services, comparing to normal applications? Service can be automatically started with the system and work all the time, no matter if any user logs on and off. It can have extensive priviledges to access files on hard disk and the like, no matter what limitations do the logged-in user have. But service cannot interact directly with the user - it cannot show console or any window. So the only way for a service to do any input/output is to read some configuration files, write some log files or to communicate with some other client process ran by the user, e.g. via TCP socket connected to "localhost".

Service is written as a console application that uses special WinAPI functions to communicate with so called SCM - Service Control Manager. Example entry point routine looks like this:

// Standard console application entry point.
int main(int argc, char **argv)
{
    SERVICE_TABLE_ENTRY serviceTable[] = {
        { _T(""), &ServiceMain },
        { NULL, NULL }
    };
       
    if (StartServiceCtrlDispatcher(serviceTable))
        return 0;
    else if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
        return -1; // Program not started as a service.
    else
        return -2; // Other error.
}

StartServiceCtrlDispatcher is the first service-related function used here. It needs an array because a process can implement multiple different services, but I show only single-service process here. The function blocks for the entire execution time of working service and fails if program was run as normal application, not as a service. While service is working, a callback function is being executed, which I called ServiceMain here. It should initialize service and then execute all the code in loop until system wants to stop the service. You can also exit the function and thus stop the service at any time if you want (e.g. if some critical error occured).

// Main function to be executed as entire service code.
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
    // Must be called at start.
    g_ServiceStatusHandle = RegisterServiceCtrlHandlerEx(_T("SERVICE NAME"), &HandlerEx, NULL);
   
    // Startup code.
    ReportStatus(SERVICE_START_PENDING);
    g_StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    /* Here initialize service...
    Load configuration, acquire resources etc. */
    ReportStatus(SERVICE_RUNNING);

    /* Main service code
    Loop, do some work, block if nothing to do,
    wait or poll for g_StopEvent... */
    while (WaitForSingleObject(g_StopEvent, 3000) != WAIT_OBJECT_0)
    {
        // This sample service does "BEEP!" every 3 seconds.
        Beep(1000, 100);
    }

    ReportStatus(SERVICE_STOP_PENDING);
    /* Here finalize service...
    Save all unsaved data etc., but do it quickly.
    If g_SystemShutdown, you can skip freeing memory etc. */
    CloseHandle(g_StopEvent);
    ReportStatus(SERVICE_STOPPED);
}

RegisterServiceCtrlHandlerEx is a function that must be called first to register your application as a service, pass its name and a pointer to your control event handler function. Then you do some initialization, execute main service code in a loop and after it's time to stop it, do the cleanup and exit.

Service should report its state to the SCM with SetServiceStatus function. It can be called at any time and from any thread and informs the system about if your service is stopped, running, starting, stopping, paused etc. This function takes quite sophisticated SERVICE_STATUS structure, but I believe it can be simplified to three main cases which I enclosed in the following functions: ReportStatus reports basic status like SERVICE_STOPPED, SERVICE_RUNNING, SERVICE_START_PENDING or SERVICE_STOP_PENDING.

SERVICE_STATUS_HANDLE g_ServiceStatusHandle; 
HANDLE g_StopEvent;
DWORD g_CurrentState = 0;
bool g_SystemShutdown = false;

void ReportStatus(DWORD state)
{
    g_CurrentState = state;
    SERVICE_STATUS serviceStatus = {
        SERVICE_WIN32_OWN_PROCESS,
        g_CurrentState,
        state == SERVICE_START_PENDING ? 0 : SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN,
        NO_ERROR,
        0,
        0,
        0,
    };
    SetServiceStatus(g_ServiceStatusHandle, &serviceStatus);
}

Third member of the SERVICE_STATUS structure - dwControlsAccepted - indicates which events will be accepted by the service after this call. I want to accept events informing about system shutdown and allow user to stop the service. I could also pass SERVICE_ACCEPT_PAUSE_CONTINUE here, which means I supported pausing and resuming the service.

ReportProgressStatus function reports service status during initialization and finalization - SERVICE_START_PENDING, SERVICE_STOP_PENDING, SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING. I don't actually use it, but if the startup or shutdown of your service takes a lot of time, you should periodically report progress with this function. CheckPoint is simply a counter that should be incremented with each call, telling that service is making some progress. WaitHint is an estimated time it will take to finish initialization, finalization or to perform its next step. By default, system waits about 30 seconds for your service to start or stop and you should not exceed that without a good reason.

void ReportProgressStatus(DWORD state, DWORD checkPoint, DWORD waitHint)
{
    g_CurrentState = state;
    SERVICE_STATUS serviceStatus = {
        SERVICE_WIN32_OWN_PROCESS,
        g_CurrentState,
        state == SERVICE_START_PENDING ? 0 : SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN,
        NO_ERROR,
        0,
        checkPoint,
        waitHint,
    };
    SetServiceStatus(g_ServiceStatusHandle, &serviceStatus);
}

Finally, there is a way for a service to shutdown and inform the system that some critical error occured. To do this, report SERVICE_STOPPED and pass error code. The code will be saved along with information about service failture to the system event log.

void ReportErrorStatus(DWORD errorCode)
{
    g_CurrentState = SERVICE_STOPPED;
    SERVICE_STATUS serviceStatus = {
        SERVICE_WIN32_OWN_PROCESS,
        g_CurrentState,
        0,
        ERROR_SERVICE_SPECIFIC_ERROR,
        errorCode,
        0,
        0,
    };
    SetServiceStatus(g_ServiceStatusHandle, &serviceStatus);
}

HandlerEx is a function to handle events sent by the system to control your service - stop it, pause, inform about the system shutdown or simply query for current status. You must always call SetServiceStatus in this function. It can be executed in different thread, so you must synchronize it with the code in ServiceMain. I do this with g_StopEvent - an event that will be set when the service should exit.

// Handler for service control events.
DWORD WINAPI HandlerEx(DWORD control, DWORD eventType, void *eventData, void *context)
{
    switch (control)
    {
    // Entrie system is shutting down.
    case SERVICE_CONTROL_SHUTDOWN:
        g_SystemShutdown = true;
        // continue...
    // Service is being stopped.
    case SERVICE_CONTROL_STOP:
        ReportStatus(SERVICE_STOP_PENDING);
        SetEvent(g_StopEvent);
        break;
    // Ignoring all other events, but we must always report service status.
    default:
        ReportStatus(g_CurrentState);
        break;
    }
    return NO_ERROR;
}

That's all the code I wanted to show. Now, because service cannot be run as normal program, you must learn how to install and uninstall it. Fortunately there is a simple command line program for this distributed with Windows - sc. To install your service, enter following command (exactly like this, with "binPath=" SPACE "PATH"):

sc create SERVICE_NAME binPath= FULL_PATH_TO_EXE_FILE

To uninstall it:

sc delete SERVICE_NAME

To control your service - start it, stop it or query its status - use commands:

sc start SERVICE_NAME
sc stop SERVICE_NAME
sc query SERVICE_NAME

Or simply run Administrative Tools / Services (another way to access it is Start / Run / "services.msc").

Two kinds of command line arguments can be passed to a service. First are argc, argv parameters taken by main function. They come from a command line fixed during installation of the service. Second are argc, argv arguments taken by ServiceMain function. They are different - argv[0] is the service name and the rest are arguments that you passed as additional parameters when calling "sc start" command.

Of course there is more to be told on this subject. Service can depend on some other services, can be automatically started with the system or only on demand, can have priviledges of a selected user or one of standard ones, like "LocalSystem" (biggest priviledges on local system, the default), "LocalService" or "NetworkService". See MSDN Library for details.

Comments | #c++ #windows #winapi Share

[Download] [Dropbox] [pub] [Mirror] [Privacy policy]
Copyright © 2004-2024