Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Simple Cross-platform Program

0.00/5 (No votes)
13 Aug 2009 3  
How to write a program that allows a simple game to run on Linux and Windows

Introduction

I wrote the original code for my Sudoku program using Visual Basic on Microsoft's Visual Studio IDE. This restricts the program to Windows. To allow the code to execute successfully on Windows and Linux, I decided to use the portability of both the C and C++ languages. I abstract the program to a series of functions which can be interfaced to the native GUI toolkits. The GUI interface needs only some buttons, an image box and mouse position. It is used only to call the functions in the core C or C++ program. In Windows, I still use Visual Basic IDE to provide the GUI. The functions are provided by compiling the C++ core to a managed assembly DLL. In Linux, I use Glade to develop the GUI and associated code. The functions are added to the GUI code directly. The image of the Sudoku uses an uncompressed bitmap file in Windows BMP file format. This can be displayed in Windows and Linux. It can also be directly worked on to produce the various images necessary for the program.

Image Generation

The Visual Basic program, sudoku_bmp, is used to generate the start image used by the core code in the program. It was written with Visual Basic 2008 Express Edition. Run this program to produce a window which displays the Sudoku start image. Unfortunately we cannot directly get at a BMP file image by...

Dim soduku As New Bitmap(10, 10)
'generate the graphics as per sudoku_bmp program
soduku.Save("soduku.bmp")

...because all bitmaps are stored in PNG file format. This uses a complex lossless compression and we can't use it directly at the color byte level. We can do a screen copy and then cut as necessary using a paint type program to produce start.bmp with 24 bits per pixel.

Below is a byte listing of a 1x1 black pixel using BMP file format: 00000000 42 4D 3A 00 00 00 00 00-00 00 36 00 00 00 28 00 BM:.......6...(. 00000010 00 00 01 00 00 00 01 00-00 00 01 00 18 00 00 00 ................ 00000020 00 00 04 00 00 00 13 0B-00 00 13 0B 00 00 00 00 ................ 00000030 00 00 00 00 00 00 next is data 00 00-00 00 .......... First two bytes BM next two bytes size of file (little endian) H003A = 58 bytes. Next 6 bytes zeros H36 little end of 54 bytes = size of header next is size 01 by 01 ect including H18 = 24 bits per pixel. The data on each row is rounded up to make an even number. 00 00 00 with a filler byte of 00 data is backwards, i.e. BGR.

The start.bmp is 573 pixels wide and 598 pixels high. The file has a 54 byte header and the pixel data is stored in a raster arrangement. Each horizontal line has 573 x 3 bytes for the data and one filler byte = 1720 bytes. There are 598 lines giving a total of 1028614 bytes. When the image is displayed on the screen, the top line corresponds to the last line stored in the file.

cross_platform

The start.bmp contains all the individual images needed to run the Sudoku program.

Core Program

The core program is written in C++ for Windows. It is written with Visual C++ 2008 Express Edition. The core is functionally the same but down sized to C for Linux. It is written by modifying the C++ .cpp and .h files with the text editor in Linux. The functions which are used by the GUI interface are:

sudoku(); 			//constructor to get the main image
				//and extract the images for the Sudoku program
void userselect(int x,int y, int number);	//user selects number
void stepback(); 			//go back one step in the solution
void highlight(int x, int y); 	//change the pencil number to yellow
void randomgame(int level); 	//start hard, medium or easy game
void solveexisting(); 		//solve existing Sudoku
void startenter(); 		//start Sudoku at from step 0

The core has these global variables:

char *mainimage = new char[1028614];	//allocate memory as needed -dynamic
// won't be pushed on stack which is set at about 1M
char selectnumber[10][10800]; 	//error(0) and selected(1-9) numbers
char pencilnumber[2][10][1200]; 	//blank(0) and pencil(1-9) numbers
//dim [0] is pencil...dim[1] is select pencil
char sudokuarray[82][3][3][3][3][3][3]; //0 to 81 steps in solution
//x large..y large..x small..y small..x number..y number
int sudokustep =0; 		//step counter used in all solutions as current step
int yellow[2] = {27,27}; 		//x-y record of pencilnumbers highlighted

When the program starts, we load the main image:

fstream inclientfile ("start.bmp",ios::binary); 	//1,028,614 bytes in file
inclientfile.read(mainimage,1028614 ); 		//read raw bytes to the array

Then we extract the images of pencil numbers and select numbers from the mainimage array. These images are then used in the core program to generate the image which shows the progress of the game. At each step, the new image is then stored:

ofstream outClientFile( "copy.bmp", ios::binary ); 	// copy the file
outClientFile.write(mainimage,1028614 ); 		//write raw bytes to the array

The GUI then displays the new image in an image box on its window.

Windows

The Visual C++ program sudokudll is used to produce a managed assembly DLL. Open the project file with VC++2008 Express and build solution to compile sudokudll.dll. The Visual Basic program MySudoku references this DLL. This program is used to produce the GUI window for the program. As each step in the program occurs, we update the image on the window:

Dim st As Stream = File.Open("copy.bmp", FileMode.Open, FileAccess.Read)
PictureBox1.Image = Image.FromStream(st)
st.Dispose()

Open the project file with VB2008 Express and build MySudoku to compile the .exe file.

Linux

The program Glade3 is used to produce the GUI window for the Sudoku core. As each step in the program occurs, we update the image on the window:

gtk_image_set_from_file(image1, "copy.bmp");

Open the file MySudoku.glade, then select build to produce the code for the GUI. Open a terminal window and in the directory which has the .glade file and type: ./autogen.sh. This gives us all the code for the user GUI window. Copy all the files in src_add_replace and paste them using "replace all" into the src folder. Change the terminal to the src directory and type "make" to compile the Linux executable file.

References

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here