Porting MS-DOS Graphics Applications
I first started VGA programming under MS-DOS, using the popular DJGPP C compiler. In recent years, this protected-mode 32-bit compiler, which is basically an MS-DOS port of gcc, has established itself as one of the preferred compilers in the MS-DOS game programmers' community. DJGPP was in fact the MS-DOS compiler of choice for idsoftware's game Quake. For the Linux console port of Quake, the Linux Super VGA library, SVGALIB was used.
When I first decided that I was going to port my own 3-D Model Viewer, jaw3d, from MS-DOS to Linux, it seemed logical to use the same approach. SVGALIB is very intuitive and allows me to easily maintain and further develop my 3-D Model Viewer for both platforms.
I found the easiest way to work with one set of source files for both platforms was to use preprocessor directives in places where different code was needed. Since I had already written and used DJGPP's low-level VGA and mouse instructions for the MS-DOS version, I simply added the equivalent SVGALIB Linux code in each instance, and separated the MS-DOS and Linux code using the preprocessor directive #ifdef. The following code snippet represents one of the many ways in which this can be accomplished:
#ifdef __DJGPP__ ... ... #endif #ifndef __DJGPP__ ... ... #endif
__DJGPP__ is automatically defined by the DJGPP compiler, and is not defined by gcc under Linux.
An additional advantage of using SVGALIB under Linux is the fact that there is also a DJGPP version of SVGALIB. Let's try not to get confused at this point: SVGALIB is a graphics library that does some behind-the-scenes low-level VGA and mouse work for the user. Although SVGALIB was first developed for Linux, someone eventually released a version that worked with DJGPP under MS-DOS. Why not use SVGALIB for both MS-DOS and Linux? This would allow us to have 100% identical code for both platforms.
I don't recommend this approach, however, for two reasons. First, when I made speed comparisons of my 3-D engine between the two platforms, I noticed that when using SVGALIB with DJGPP under MS-DOS, graphics performance was sluggish in comparison with SVGALIB under Linux. Second, the MS-DOS executable was unnecessarily big because it had to be statically linked with the SVGALIB library. Using SVGALIB under Linux did not seem to present any problems. Due to the use of shared libraries under Linux, the executable remained tiny when dynamically linked, and graphics performance was actually slightly better under Linux than under MS-DOS. For the sake of performance and executable size, I found it best to use DJGPP's low-level instructions under MS-DOS and to use SVGALIB under Linux. This makes a difference, especially in a setting like 3-D engines, where every frame-per-second counts.
The advantage obtained from using the DJGPP port of SVGALIB is the fact that you can test your SVGALIB Linux code under MS-DOS, without having to reboot. Except for speed and executable size, both versions of SVGALIB behave identically.
Note that the DJGPP port of SVGALIB is still in beta, but I ran across only one minor problem and that was easily fixed. The file vgakeybo.h included with the DJGPP port of SVGALIB seemed to differ from the file vgakeyboard.h under Linux; therefore, making cross compilations was impossible in cases where keyboard code was used. The two files should be identical, of course, and the solution is to copy the Linux version of the include file over the DOS one.
The three compiler-specific code aspects are VGA, mouse input and keyboard input. If you have completed an MS-DOS graphics application, you may be using much of this code already and can quickly add on the SVGALIB equivalent code. On the other hand, if you do not have any previous graphics programming experience, you will find the code shown in Listings 1 through 4 to be very useful.
In the case of my 3-D Model Viewer, jaw3d, a complete frame is first rendered onto a buffer which has the same dimensions as the screen, and then copied to video memory all at once, allowing us to display frequently updated screens successively without any flickering. This is done as follows:
memcpy (video_buff, image_buffer, DIM_X * DIM_Y); /* video_buff was initialized above */ dosmemput (image_buffer, DIM_X * DIM_Y, 0xA0000); /* 0xA0000 is the video memory in VGA mode * 13h */
|Non-Linux FOSS: libnotify, OS X Style||Jun 18, 2013|
|Containers—Not Virtual Machines—Are the Future Cloud||Jun 17, 2013|
|Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer||Jun 12, 2013|
|Weechat, Irssi's Little Brother||Jun 11, 2013|
|One Tail Just Isn't Enough||Jun 07, 2013|
|Introduction to MapReduce with Hadoop on Linux||Jun 05, 2013|
- Containers—Not Virtual Machines—Are the Future Cloud
- Non-Linux FOSS: libnotify, OS X Style
- Linux Systems Administrator
- Validate an E-Mail Address with PHP, the Right Way
- Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Introduction to MapReduce with Hadoop on Linux
- RSS Feeds
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?