This took me much longer than it should have. I wanted to get the graphic fade in/fade out functions done.Because I'm not using color palettes I thought I would be cheeky and try my own implementation of fading in and out the graphics. Nermal has the following API functions.
void FadeBlack();
void FadeIn(int mapnum);
void FadeOut();
void FadePunchIn();
void FadePunchOut(int newmap);
void FadeWhite();
I thought I would be clever and just cover whatever is being displayed with a transparent blank bitmap and then turn the opacity up with the alpha channel to fade to black/white/whatever. Turns out ROE preloads the graphics to the screen with all the colors turned off. Then it turns on the colors without page flipping. When I use my opaque bitmap method, I overwrite the graphic on the screen.
The upshot is I can fade out and fade to black, but I can't fade in because I overwrite the graphic that was there. I will need to mix the original graphic and the alpha on the fly. I'll wage that battle later as I sunk too much time into this is the first place. I just turned off the faders for now and marked them a TODO. (CGA doesn't use them anyway).
(Also The TODOs are just reminders that the Nermal function is not all the way implemented yet. Most often it's just single argument being ignored that is used later in the game. When I come across the need to use that argument, I'll come back and refactor)
I spent the rest of my evening fleshing out some of the other required functions to get the title sequence going. Not done yet, but getting closer.
Clock timers work, which is what the title sequence is based on. The master INT 1Ch timer (used for mater event handling) does not yet, but that will be handled by an ALLEGRO_EVENT event handler.
Things will be a little slow until my "Day Job" winds down later on this week.
Monday, November 27, 2017
Saturday, November 25, 2017
Breaking Down and Building Up.
This is me |
I'm basically writing a Nermal wrapper around Allegro, but there is so much legacy stuff that needs to be rifled though. Many variables are no longer needed and much of the internal Nermal API can be replaced with a one or two line Allegro equivalent. As Allegro uses 32 bit graphics (24 bit + 8 alpha), I still have to work out the color mapping. Amusingly enough, I find myself cribbing from the 4-color CGA code because of it's straightforward video memory mapping. I may also steal the CGA "color" code as EGA and VGA rely on palette cycles that I won't be using in 24 bit mode.
Also, Allegro does not have a GIF loader like what ROE used to load it's graphics Allegro's GIF loader was most likely not implemented due to patents, and when they expired Allegro became TrueColor anyway. I'll be converting the graphics to 32 bit PNG files. That said, my goal for this first pass is to get everything running as close as stock as possible. After that, then I hone the presentation a smidgen.
One of the more amusing things I ran across is what I've had to do to the prepossessor so that it can compile. In the years since 1991, C compilers go nuts if you try and use string commands that are prone to buffer overruns. For example scanf() as opposed to sscanf(). I had to put a prepossessor directive in MSVC to allow me to use them anyway. (Which I will remove when I do my second pass). Also there are #ifdefs for three architectures in there, IBM, Amiga, and Atari. Visual Studio does not recognize "IBM" as a predefined macro, as that would mean something profoundly different nowadays, so I had to put it in there so I have at least one valid codepath.
It loads data though, so that's cool.
Friday, November 24, 2017
Setting Up the Enviroment
My first goal was to
pull the code for ROE into a modern development environment. Even
though I want to use POSIX as my baseline, I decided to pick Visual
Studio 2015 as my IDE. It has a few things going for it. First, some
of the legacy headers originally developed for QuickC are still
hanging around. Direct.h is one example (used for directory
management). However, it appears that Allegro also has wrappers for
filesystems too. I may have to do a pass to see if most of my POSIX
stuff may have an Allegro equivalent. I may have to retarget later
on.
The Allegro
libraries are available via NuGet, which makes life much easier. On a
previous project, I literally spent two days trying to get Allegro to
work with Code::Blocks under Win10, which is my preferred IDE for GCC. Visual
Studio is great, but it’s compiler has some glaring deficiencies.
Two of my favorites is as follows:
1) In 2017, MSVC
STILL can not process
Unicode string literals. You want to see the IDE go bananas? Plop an
emoji into the source. (It’s a valid Unicode character). It
will stop everything telling you that there is an invalid character
from the current codepage and it’s unable to save. That’s right,
Microsoft still uses codepages for non-Latin text. This shouldn’t
be a huge problem as I don’t plan on using Unicode (for now)
2) Microsoft
absolutely, positively refuses to support C99 and above. It’s
considers C a “deprecated” language. Now I know that this may
seem a strange thing for whine about, as C++ is a superset of C.
However there exists little things that can be irksome such as.
-Bool support (Not
really needed as the ROE typedef’ed it’s own Boolean type.)
-Universal character
names, for example...
int 番号
= 1;
..is invalid. That's might be a good thing though.
-Variable length
arrays
-Etc…
To Microsoft’s
credit, they recommend that if you need to use an actual C compiler,
it does have front-end support for Clang. As ROE was written in 1991,
I don’t think I need to rip out half my toolchain be able to create
obnoxious variable names.
Other than that,
I’ve also put the code into an honest-to-goodness version control
system. The Git support in 2015 is pretty sweet. I’m keeping the
repo local for now, I can probably spin up a git server on a Linux
kick-box I have hanging around if I feel inclined to work remotely.
One of the last
things I’ve also set up is Doxygen. It basically scans the source
tree and auto-generates documentation so I can follow where
everything is. ROE was written before Object Orientated Programming
was a mainstream thing. Globals Globals Gobals! Lots of them.
Encapsulation? What’s that? Doxygen helps by giving me a local
web-based source code search engine. I don’t have to put on snorkel
gear and dive in to see where some pesky extern was declared at. I'm planning to merge into Doxygen most of the documenttation that was graciously given to me by OTSW. This means not only will there be living, portable code, but with plethora of inline documentation to go with it.
Looking good so far.
Thursday, November 23, 2017
Assesment
Before I given the
whole Rules of Engagement project, I was given a few code files at
first to gauge the feasibility of porting this old game to modern
architectures. This consisted of a section of the graphics library
and a bit of the tactical display code. The idea was that I needed to
gauge if the game was too tied to legacy libraries or some kind of
paradigm what would be simply unworkable in modern systems. I also
was keen to see if I could forge it into some kind of POSIX
compliance to make it a little more targetable to other platforms.
The idea is that I plan to use a C game library named “Allegro”
that I’ve been using on and off since the 90s for little game
projects of mine. It’s in it’s 5th iteration now and still
maintains much of it’s legacy DOS concepts but adapted to a little
more modern and platform neutral. Many of the old DOS/Real Mode
interrupt calls have been replaced with legitimate functions, but are
still single-fire methods with striking similarity. This makes sense
because when Allegro was young, it wrapped it’s library functions
around basic DOS calls such as INT 21h(filesystem), INT 33h(mouse),
and INT 10h(video).
Still seeing some of
the old library headers in the ROE was kind of a nostalgic walk down
memory lane. It was also quite pleasant to see that many of them can
be tossed as modern systems handle the more low-level stuff
automatically, or there is a simple POSIX equivalent. Here is a quick
copy/paste from the graphics lib.
#include
"stdio.h" <-- POSIX
#include
"stdlib.h" <-- POSIX
#include "dos.h" <--
Delays and sound are Allegro - Time Functions are POSIX
#include
"time.h" <-- POSIX
#include
"malloc.h" <-- Allegro has malloc wrappers so that it’s
platform independent
#include
"graph.h" <-- Allegro handles low-level graphics
#include
"string.h" <-- POSIX
#include
"conio.h" <-- Text I/O interrupt wrappers - Allegro
handles this now
#include
"bios.h" <-- No need to make BIOS calls anymore –
Allegro has equivalents
#include "xmm.h" <--
We use a Protected mode flat memory model now. No need for XMM
#include
"rules.h" <-- This in turn has direct.h, this can
be replaced with unistd.h (POSIX)
Real mode interrupt
calls do not function in protected mode, and is DOS legacy anyway.
The other thing that will make live much easier is that ROE can be a
monolithic executable. For space reasons, the game was broken up into
pieces called “overlays” would block swap parts of itself into
memory from disk while it was running. Nowadays we have virtual
memory and shared runtime libraries (.dll /.so files) that manged by
the OS.
This caught my eye
too…
#define DPI 6.283185308
This can now be defined as TAU and hopefully won’t break much :)
One final though as
that Allegro handles bitmaps in a device independent way so gone are
the legacy bitplanes of CGA/EGA/VGA of old. Also mp3s and GIF files
are out of patent.
Wednesday, November 22, 2017
Introduction
The Button Pad |
Star Raiders |
I remember taking
all the couch cushions, pillows, and blankets I had access to and
constructing an elaborate pillow-ship in front of the TV. I draped
the blankets around the television, blocking out the outside world.
Once ensconced within my fluffy cockpit, my imagination went wild. To
me I was in space. My spaceship held the battle lines until it was
ultimately destroyed. Not by the alien invaders, but by my little
sister who was mad I was “hogging the TV” and wanted to watch
“Land of the Lost”
I’ve been told I’m
not the first person to do this.
Rules of Engagement |
“Rules” was a
deeply engrossing game for me. I would play on my 8088 PC and from
time to time I would pretend my CRT was an actual touch screen;
tapping the screen with my left hand while my right hand moved the
mouse and did the actual articulation. I felt like I was in control
of a starship fleet, issuing commands on my screen and battling 16
color alien races.
Jumping time once
again, let’s skip to a few months ago. Somehow Rules of Engagement
popped in my head I decided to see whatever happened to the company
that made the game. As it would seem they are still around. The
company appeared to have moved on to making communications software,
and the old games they used was nowhere on their website. On a whim I
decided to send an email to the generic looking sales@ email address
and asked of the game even existed anymore or if anyone at the
company even heard of it.
I was thinking to
myself, “If they still had the source code, couldn’t it be pretty
cool to port this game to a device with touch screen, or at least get
it into a state where it was playable again?” You see the game
itself has not fared well with time. It’s a 16-bit DOS game that
will simply not execute under 64-bit windows. Graphics chips nowadays
are beginning to drop lots of the old legacy video modes like the
2-bit CGA and 4-bit EGA. Heck, I’m beginning to see 8-bit VGA modes
being depreciated too. Another issue is that it runs very poorly in
both virtual and emulated environments. If I was a betting person,
it’s most likely due to the frame rate limiter. Hedging all my bets
there is probably an interrupt that’s firing that’s a bit
time-sensitive and causing the system to hang on the opening credits.
This next bit of the
store is going to be a bit vague as it deals with company email
correspondence that I’m not sure I’m allowed to divulge. The
upshot was I able to contact one of the original developers of ROE.
Though what I can only guess as my winning charm, I was able to
procure the original C source code and project files for the game. I
pitched that the idea of porting this game to modern architectures
and giving it a bit of a face lift is a good idea, and they agreed.
This blog is going
to be my adventure as I port a professionally developed and sold
video game from 1991 to something platform independent. Trust me,
having looked behind the curtain a little, it’s time capsule of
glorious treasure. Old programming philosophies came flooding back at
me as I did my assessment of the code. This is going to be a fun ride
I think..
Thanks again Tom,
for the opportunity to do this.
Subscribe to:
Posts (Atom)