dev, computing and games

Project-- Porting a Tetris game I wrote a long time ago in X86 to run on modern 64-bit Windows

The game was written in about 1000 lines of X86, and assembled with the A86 assembler tools. This was 12 years ago, in 2006.

It is extremely low tech and not super complicated or flashy, it was meant to be a personal effort back then to learn about it and becoming more comfortable debugging it. It was built as a 16-bit DOS COM executable. Although it ran on Windows at the time, the binary format was not very current even back then. Sadly time passed, the binary rotted and it does not run anymore.

There are three reasons why it does not run anymore
1. It's a .COM executable. Running these requires an MS-DOS emulation subsystem of Windows which is not present on 64 bit Windows
2. It's a 16-bit executable, which does not have support on 64 bit Windows
3. It uses DOS interrupts in order to work. These interrupts are not supported in modern OS. Modern Windows behavior is that they just crash the app

In addition to the broken binary, I had the source code still. So I decided to resurrect it by porting it so that it can be run natively now on a modern 64 bit Windows OS (where 'natively' here means 'not with an emulator'). Yeah you can run it in DOSBox, but meh

Although the program was originally assembled with A86, I ported it to use MASM (a Microsoft product). I want to say using MASM is not necessary for fixing the above problems. It would actually be possible to fix the above problems while still using A86. As it turns out, building Win32 programs with A86 is easier than ever because the author has (since 2006) created a new set of convenience tools for that, just barely too late for me to have taken advantage of. Looks promising.

The thing is, if I'm going to set out to make it work on Win32 anyway, it is almost certainly going to be easier with MASM. It has easy-to-set-up integration with Visual Studio, it's basically automatic setting up my project to link against the right libraries, and there are built-in conveniences which make the Win32 APIs (or anything) syntactically nicer to call for the purposes of doing this. MASM has different syntax than A86 but switching over to its syntax wasn't such a bad price to pay. Mnemonics themselves and the syntax for the addressing modes are basically the same. I thought I'd have to change over some things on this front, but as it turned out I didn't. In general I don't think the compatibility of mnemonics is standardized or guaranteed, but I didn't run into problems in this area.

The annoyance-- which would been there for MASM or A86 regardless-- was graphics, because this part had to be changed the most. I decided to go with GDI which is not going to be anything like mode 13h (If you haven't had to ever program with mode 13h it basically gives you a pointer to the aperture and writing to it draws indexed-color pixels on the screen) For GDI on Win32 the program needs to be structured a lot differently. It needs to create a window and window resources, the code for drawing the grid needed to be moved to a paint message handler, needs to update with a timer, it should be scaled up too since a 320x200 resolution 1:1 is not a great time on a modern display, etc.

Coming at this I had wanted to be able to treat the game as a black box. Change a few things to get it working in Windows and that's it. But in the end, I needed to understand nearly all parts of it to do what I wanted to do. There were all these long stretches of code organized horribly where I'd long forgotten how they work. Doing this was a gigantic hassle

Anyway I got it working. It is still extremely low tech but that's kind of the point, and to just get it working. I got to add a couple new things too:
- Different colors for the different pieces
- Fixed a bug where rows would sometimes not get cleared correctly
- Added a 'next piece' UI
- When you get game over instead of crashing it displays a message and you can press Escape to start again

I wonder... when it will rot again?? (As a GDI Win32 app) maybe it's good for a while

The code for the Win32 version is all in one file located here.

May 14th, 2018 at 10:43 pm | Comments & Trackbacks (0) | Permalink

This game was made for a graphics course that had an open-ended choice of a final project. We were allowed to produce any sort of demo that used either OpenGL or raytracing techniques. I chose to do a use OpenGL (realtime) for the opportunity to make an interactive demo.

Features:

  • Textured meshes exported from 3DS Max in OBJ format, then saved as a serialized format by the game
  • Environment/cube map to serve as a background
  • Instanced geometry for faster drawing
  • Samples from the environment to create a reflective metal effect
  • Uses Cairo to render font glyphs to a texture, and composes them to make text
  • Uses a deformable mesh to create an animated explosion

In the game, the player shoots down enemy ships and scores points. The missles are shot from the player's ship outward depending on where the ship is pointing.

The ship is controlled with the I,J,K, and L keys. Dragging the right mouse button can be used to rotate the camera, and the scroll wheel zooms in and out.

Pressing 'S' will enable/disable some sliders which control certain program parameters, used mostly for debugging/testing.

Pressing 'Z' fires a missile. If an enemy ship is hit by a missile, it disappears and the player's score is increased.

The source code is compiled using Visual Studio 2008.
Download binary (Windows .exe)

Download Source

September 13th, 2012 at 5:00 pm | Comments & Trackbacks (0) | Permalink

This is a game submitted for a contest held by UW GameDev Club, where the game has to be done entirely in 24 hours (honour system). Any choice of language or API was allowed, and all entries have to follow the theme: the theme this time was "color, or a lack thereof". I decided to make a small 2D arcade game. My entry was in C++ using GDI+ for graphics.

My entry (2nd place winner) was called Color Dungeon, and overhead-view arcade game where the main character walks around the map, avoiding orbs of the opposite color, getting to the stairs in the lower right corner.

There are 4 floors, each successive one is a little bit harder. The enemies are more numerous, move more quickly and a higher proportion of them will 'home' toward the character.

The maze as generated by recursively partitioning the map area into rectangular 'rooms'. At each step the room will either be partitioned vertically, horizontally, or have another 'room' placed within it. 'Exits' (clearings in the wall) are added for reachability. Reachability is ensured for all areas in the map.

Arrow keys are used to move the character around the map. Touching orbs of the opposite colour will damage the character. The goal for each floor is to make it to the stairs, which are placed near the lower right corner.

Swords are an area-of-effect item that can be found scattered around the map; they are more frequent when there are more enemies. To use one, press 'b'.

Download Game Binary (Win32)

The source code is compiled using Visual Studio 2008. There is one project file for the game.

Download Source

September 13th, 2012 at 5:00 pm | Comments & Trackbacks (0) | Permalink

This is a tool for estimating the amount of shift (displacement) between two images using FFT (Fast Fourier Transform). The images can be of different sizes. This method is faster than enumerating all the possible (x,y) shifts and selecting the right one, especially for large images. To perform the transforms it uses the fftw library.

More specifically it uses the 2D convolution function between the images. The steps for this are:
1. take the Fourier coefficients of the first image
2. take the same the second image,
3. find the element-wise product of the two results,
4. find the inverse Fourier transform of the above.

It shows the resulting image, with scaled colour channels so the darkest is black and the lightest is white. The light areas indicate likely amounts of shift. For example, a light area at co-ordinate (5, 6) means the second image was probably shifted 5 pixels across, 6 units down from the first.

As an example of using it, consider cropping an image so that the resulting image is 47 units across and 30 units down.

Point the program toward the two image files and hit 'Estimate'.

The dialog will (quickly) show a visual result of the convolution, and the estimated shift. The shift matches with where the image was cropped. The units are the position of the first image, in pixels, relative to the second one.

A brute-force implementation of the same thing is very doable but takes around 30 seconds on this sample, so it's a pretty significant speedup!


Download binary (Windows .exe) + sample images

The source code is compiled using Visual Studio 2008. There are three project files. ConvolveShift is the main executable, a Windows Forms program in C#. Native is a C++ DLL that does most of the real work. NativeDriver is a non-graphical program for testing Native.

Download Source

September 13th, 2012 at 5:00 pm | Comments & Trackbacks (0) | Permalink

NOTE: Twitter has geared up and improved security for their API, changing login to use OAuth. Unfortunately, it makes the extension below obsolete. It's still online as a proof-of-concept only.

This is a Game Maker extension used to send Twitter messages. It uses an unmanaged DLL that calls into the managed .NET runtime library to connect with Twitter. It sends an HTTP POST message to send an update. The reason for doing it this way was because Game Maker can only call into native code, but the circumstances for making/using this were competition-based so 3rd party libraries were allowed (all code must be original). Yes it's kind of a judgement call. Anyway there is no standard C++ networking library that provides enough abstraction, but the standard .NET runtime library makes it easy.

In Game Maker, it provides the following functions:

twitter_set_user(user :string)

     - Call this first to set the Twitter username to use.

twitter_set_password(password :string)

     - Call this to set the Twitter password. The game author may want to take some form of security measures.

twitter_send(message :string)

     - Tweets a message.

twitter_set_timeout(timeout :real)

     - Optional. The maximum time, in milliseconds to wait for a network message to be sent. The default is 5000 (5 seconds).

The user name and password only need to be set once.

The extension was built for/tested on Game Maker 8.

Download Game Maker Extension (.gex)

The source code is compiled using Visual Studio 2008. There are two project files, one that builds the DLL itself and one .exe used for testing the DLL. I made the DLL into a .gex using Extension Maker.

Download Source+Binary

September 13th, 2012 at 5:00 pm | Comments & Trackbacks (0) | Permalink

This game was a team effort with myself and 4 other students, for a contest called Games4Girls. The contest is run by University of Illinois. The objective is to make a 2D game, of any kind, targeted toward a female highschool-age demographic, with the restriction that we use Game Maker. Game Maker is a proprietary program used for scripting 2D games, using a C-like language. The choice of Game Maker had something to do with problems with past entries that depended on a wide assortment of platforms/runtimes. Many games wouldn't run. So, they ruled that all entries had to use Game Maker.

We decided to make a platformer type of game, which is familiar to most people. The player controls a character named Alessa, and uses her various weapons to defeat enemies and move through the levels.

Because there were restrictions on using copyrighted content, we created all the graphics and music ourselves.

My personal role was

  • coding object collisions
  • coding scene transitions, scoring
  • creating sprite and background graphics and getting them into the game

Overall the project was a lot of fun to work on. As it turned out, our entry was very well-recieved and we finished in first place. We won a cash prize for our team and some money donated to our CS faculty at University of Waterloo.

https://info.uwaterloo.ca/www/profiles/research_profiles/profile-archive.php?id=193

The levels contain various enemies and obstacles.

The game includes some dialogue segments, illustrated by our group, with larger character graphics illustrated by my super-artistically-inclined groupmate! The dialogue provides some story background to the game.

Controls:

  • Left/right arrows: move Alessa
  • Up arrow: Jump
  • Any arrow(in water): swim
  • A key: Shoot an arrow
  • S key: Swing a sword

My team consisted of (big thanks to my teammates!):

Download Win32 binary

The game was originally built and tested on a Windows 7 environment.

Notes for running on Windows 10 and later:

  • Windows may mark the game executable as protected by SmartScreen. Although anything downloaded here is at your own risk, I attest that we did not put malware into the game and do not distribute it knowingly with any malware. To proceed past the SmartScreen filter should you choose to do so click "More Info" and "Run".
  • The Game Maker environment relies on DirectPlay which, from Windows 7 to 10, was changed from a built-in feature of the OS into an optional component which is downloaded on demand. If Windows prompts you to download it, choose Yes to proceed with downloading it and enable playing the game.
June 18th, 2010 at 3:00 pm | Comments & Trackbacks (0) | Permalink

This is a game of Tetris written in x86 assembly, in a personal effort to learn more about the instruction set. It uses mode 13h for all drawing, writing directly to address 0xA000 to plot. The index written for each pixel determines the color in a 256-indexed color palette.

It uses DOS interrupts for other functionality like random number generation, and keyboard interaction. For random numbers, it uses the modulus of the current system time. The game keeps going until pieces reach the top of the screen.

The keys i,j,k, and l (or arrow keys for the Win32 version) are used to move the pieces.

In the normal way, rows are cleared when pieces occupy the entire row with no holes.

The form of each 'tetrad' (piece) is hardcoded at the top of the source file, and used for drawing the grid and checking for collisions. The walls of the game are fixed. An array called 'predict' is used to foreshadow where the user is trying to move the tetrad, so that it cannot be moved through a wall or other landed pieces.

After every 'tick' of the game, the current tetrad in play is moved down by one square if possible, or committed to the grid if there are other pieces blocking the way. The game determines the timing using an interrupt, and advances the game after 10 time units, which is around every half a second.

Download binary (DOS com executable)

The source code was assembled using the A86 assembler.

View Source File

-----------------------------------

Update (5/14/2018): Since the time of writing and building this program, the binary has rotted 🙁

However, I ported the code to Win32 with GDI and built it as a 32-bit PE executable.

Here's the newly updated Windows version:

Download binary (32-bit Windows executable)

The Win32 source code was assembled using MASM.

View Source File or Download Visual Studio 2018 Project (zip)

The Windows version also has the following changes:

  • Different colors for the different pieces
  • Fixed a bug where rows would sometimes not get cleared correctly
  • Added a 'next piece' UI
  • When you get game over instead of crashing it displays a message and you can press Escape to start again

Besides i,j,k,l you can also use the arrow keys.

November 15th, 2006 at 4:04 pm | Comments & Trackbacks (0) | Permalink

This is a school project. Used Visual C++ 6.0 with MFC. At the time I was trying to do two things: learn C++ language, and Windows programming. I ended up getting a good mark on the project. It was scoped to something I can do in the time constraints.

The program was made to look like SimCity for the SNES which is a game I liked playing at the time.

Find it posted here: https://github.com/clandrew/SimCityMfc

June 9th, 2004 at 8:12 pm | Comments & Trackbacks (0) | Permalink

An old contest question.

Taken from this forum post--
http://compsci.ca/v3/viewtopic.php?t=2192

The question

A spiral of numbers can start and end with any positive integers less than 100. Write a program which will accept two positive integers x and y as input, and output a list of numbers from x to y inclusive, shown in a spiral. You may assume that the end value is greater than or equal to the start value.


A spiral starts with the first number in the centre. The next number appears immediately below the first number. The spiral continues with the numbers increasing in a counter-clockwise direction until the last number is printed. Read the input from the keyboard and display the output on the screen.

Sample session:

Start value:
10
End value:
27
27 26
16 15 14 25
17 10 13 24
18 11 12 23
19 20 21 22


Start value:
10
End value:
12


12 11
7 10
8 9

In Object-Oriented Turing, the solution:

var start, finish, r, c, counter, i, rchange, cchange : int
get start, finish
r := 13
c := 40
counter := 1
i := start
rchange := 1
cchange := 4
loop
exit when i >= finish
for j : 1 .. counter
locate (r, c)
if i < 10 then put " ", i .. else put i .. end if exit when i >= finish
i += 1
r += rchange
end for
for j : 1 .. counter
locate (r, c)
if i < 10 then put " ", i .. else put i .. end if exit when i >= finish
i += 1
c += cchange
end for
rchange *= -1
cchange *= -1
counter += 1
end loop
November 8th, 2003 at 12:31 pm | Comments & Trackbacks (0) | Permalink