How to Make Games That Work With Graphics Boards
USING GRAPHICS BOARDS WITH GAMES
by S.P. Haeuser EMail : haeuser@tick.informatik.uni-stuttgart.de
I. Introduction
As there are often questions in the way of "Does this AGA game run on
my A3000 with Picasso II board ?" and as people with high end Amigas
simply do not understand, why games do not support their graphics boards,
I will talk in this article about the reasons, about what can be done,
about what are the problems with TRUE AGA emulations and I will provide
some example code for game programmers (under EGS and Cybergrafix here,
as those probably will be the leading ones... and the ones to whom I am
most familiar...) The article is mainly intended for programmers, and
especially handles about the EGS system (as this is the system that I know
best...)
To introduce to the problem i will have some words about how
Workbench-Emulations work, at least so far as it is needed for this
article. The Amiga Display is bitmap oriented, that is, each pixel is
splitted in 8 bitplanes, and graphics boards are chunky graphics, that is,
they save each pixel value in one Byte (or in some more Bytes for >8 bit
depths). To do a workbench emulation there has to be some code that
SPREADS these pixel values to the various planes (which is slow) or a
special chip that does this job (like in the Cybervision64) which is fast,
but needs a better technology (you can't just do a VGA board with
ZORRO-interface then...)
Further, you have to be clear, the Amiga OS extensively uses the
copper and the blitter processors. Of course those will get problems, if
they had to deal with graphics memory on the board. Therefore WB-Emus
patch different OS-functions, and if you use WB-Emus for coding you have
to know which calls are still compatible, and which not.
Of course, a lot of code writes directly to the Amiga special chips.
This code will NEVER run on a graphics board, and this is, sadly, for most
games. But this is the most efficent way to do a game, and game coders
are very concrened with efficiency, as they want their games running on as
many systems as possible.
II. Main problems
Now it is the point to name the main problems using Workbench
emulation for games :
1) Speed 2) Using copper 3) Using Double buffered displays 4) Directly using
special chips
Blitter is no problem (as long as you do not access it directly,
but use graphics.library...), the WB-Emus I know handle this well.
As for #1, I have to say, of course the speed will be like in
Amiga modes and better, but you won't get the speed that the graphics
board is capable of. I will provide another solution later. If you NEED
to use a WB-Emu, I recommend making the game compatible to Cybergrafix, as
this one is a quite fast emulation and runs on nearly all boards.
#2 is nearly unsolvable. User-Copperlists will be a problem
to a lot of WB-Emus, and the screen will stay invisible. Better not to
use such a thing.
Some WB-Emus take #3 okay, but others (like EGS), do not like double
buffering methods other than those of their own graphics board specific
libraries. The buest guess is to use the doubble buffering methods around
AllocScreenBuffer of 3.0... of course, then, the game only runs from 3.0
upward.
As to #4, there is no way to run such a code on a graphics board.
But, strangely enough, this is the best solution of all. Do not use the
special chips of the Amiga, but use the special chips of some graphics
boards you want to support. This is a solution of 1) to 3) as well. Of
course, this is more work, as their is no "VGA-Standard" for Amiga... on
PC the situation concerrning graphics boards is better...
III. Solutions
So, the possibilities are clear :
A) Use a workbench emulation, but do not use Copper or Double Buffering
B) Provide drivers for different graphics board, to access the video
memory of these boards directly.
There is currently a project running (Caution! Advertising! :) ), that
is about creating a standard library called rtg.library that will do the
job about B) for you, and will be Freeware in the future... providing
support for most boards and even for ECS/AGA (with c2p code...). The code
will leave the possibility for the coder only to get the start adress
of the video memory from the library, use doubble buffering from the
library, and do the rest himself (as most game coders want to do...)
But up to now, you will need to do that driver things yourself.
At this point I will say something about games actually running on
graphics boards. That is ... ahem... Spaceward Ho! I've heard some
rumours about the Sim games running on gfx boards, but I do not know if
these are true. Sadly, apart from those and a few Shareware games,
those are all of them up to now.
Some games even have problems with the WB-Emu being activated (at
least as far as EGS is concerned). So we have still a far way to go...
IV. Coding section
Now the coding section. In this section I will give you some hints
on how to write data directly to the video memory of EGS boards
(the great thing about EGS is, the egs.library provides a function to
get the base adress of the video memory of a display, and such a thing
I did not find in any other WB-Emu). Then I will give some hints about
Cybergrafix (but I am not an expert there...)
A. EGS
Before you start opening a screen you should choose a screenmode. You
only should use a screenmode that is available on this system (as you
can never be sure, if it is...), and that is done in the following way :
move.l egsbase,a6 ; Base Adress of egs.library jsr E_LockEGSVideo(a6) jsr
E_GetHardInfo(a6) move.l d0,hardinfo ; info structure about this system
jsr E_UnlockEGSVideo(a6)
In the following i will discribe the HardInfo structure. It is a
modified structure, as there are only EGS V 5.x includes out for EGS, but
you will need V 6.x at least... so I had to modify them oneselves... I
would not try to use C, as I got some serious speed problems with Double
Buffering with that language...And of course, this sort of code, as it is
the most internal part of our game, should be FAST...
STRUCTURE E_HardInfo,0
APTR ehi_Product
APTR ehi_Manufact
APTR ehi_Name
WORD ehi_Version
WORD ehi_MaxFreq
ULONG ehi_Flags
APTR ehi_Modes
WORD ehi_ActPixClock
WORD ehi_frameTime
APTR ehi_MemBase
LONG ehi_MemSize
APTR ehi_LibDate
APTR ehi_Drivers
APTR ehi_Monitors
APTR ehi_VideoNodes
APTR ehi_Screen
LABEL ehi_SIZEOF
Most of the entries of these structure do not say anything... and have
no valid information inside... interesting are :
APTR ehi_Modes APTR ehi_Monitors APTR ehi_Drivers
The drivers contain information of the supported EGS drivers, and will
be useful to find out which screenmodes actually run on the graphics
board.
STRUCTURE E_DisplayDriver,0
STRUCT edd_Node,LN_SIZE
WORD edd_Pad0
APTR edd_Prefix
ULONG edd_Depths
STRUCT edd_Freqs,24*emm_SIZEOF
STRUCT edd_Monitors,MLN_SIZE
ULONG edd_Flags
APTR edd_Default
STRUCT edd_MaxPixel,24*4
ULONG edd_MemSize
UWORD edd_MouseSize
UWORD edd_Pad1
APTR edd_description
LABEL edd_SIZEOF
Now we get LN_NAME of the SECOND thing in that list of Drivers
(the first one only contains rubbish...) We will examine the first
four characters of the string we get then, and look for :
PICO, LEGS, RB3a, RB3b or G110
PICO : Display driver for Piccolo/Piccolo SD64 LEGS : Display
driver for EGS Spectrum RB3a,RB3b : Display driver for Rainbow 3 G110 :
Display driver for EGS 110
I do not know what is about EGS Graffiti and A2410 EGS drivers...
If someone knows, maybe he could send me a mail...
Now we examine the screenmodes :
STRUCTURE E_ScreenMode,0
STRUCT esm_Node,LN_SIZE
UWORD esm_Horiz
UWORD esm_Vert
UWORD esm_Pad
ULONG esm_Depths
APTR esm_Driver
STRUCT esm_Specs,24*4
LABEL esm_SIZEOF
Here, LN_NAME contains the names of the screenmodes. We start with the
SECOND element again...
We look in this list for a screenmode that uses the driver we found
before, and supports the Horiz, Vert and Depths values we want...
Depths in this case is a bit-wise representation, so a set bit says
this deptch is available. By the way, we can assume every EGS board
is capable of 24 Bit and 8 Bit displays...
If you want to examine Synchs or Monitor Specs, you have to look
at the array of E_MonitorSpec (esm_Specs), but I do not want to go
THAT MUCH into detail. You could use this to compare if this screenmode
REALLY displayable on the given monitor, for example...
So, lets assume we found a screenmode that fits... then, and only
then, we can assume, we can open a Screen. We will now open an
E_EScreen which is basically some video memory allocated on the board.
It does not support higher EGS constructs like Windows for example,
but we want something FAST ...
Now we need a E_ENewScreen structure...
move.l #ens_SIZEOF,d0 move.l #MEMF_CLEAR,d1 move.l $4,a6 jsr -198(a6)
move.l screenmodename,ens_Mode(a0) move.w Depth,ens_Depth(a0) move.l
egsbase,a6 jsr E_OpenScreen(a6)
As next thing we will allocate a doubble buffering bitmap. Be sure
all fits in the display memory, if you use 24 Bit displays...
for doubble buffering you need of course display memory for BOTH
displays on your board...
move.w Width,d0 move.w Height,d1 move.w Depth,d2 move.l type,d3 ; colour
model, described below... move.l #0,d4 add.l #E_EB_DISPLAYABLE,d4 add.l
#E_EB_BLITABLE,d4 add.l #E_EB_SWAPABLE,d4 add.l #E_EB_CLEARMAP,d4 move.l
screen,a0 move.l esc_Map(a0),a0 ; The FRIEND BITMAP move.l egsbase,a6 jsr
E_AllocBitMap(a6)
Now we are nearly finished. We still have to LOCK the screen (so
EGS does not put the screen to Fast RAM while we are writing directly
to video memory (there will be some strange results, if you switch back
to the WB-Emu while our program runs... ghost pics... but do not
bother...)
move.l screen,a0 move.l esc_Map(a0),a0 add.b #1,ebm_Lock(a0) move.l
BackBitMap,a0 add.b #1,ebm_Lock(a0)
After locking the system needs some time to make the change happened.
You should do a delay of about 0.1 seconds (for example dos.library
Delay with a value of 5 ...), else you risk some crashes...
After that you can write to the two bitmaps :
move.l screen,a0 move.l esc_Map(a0),a0 move.l ebm_Plane(a0),a0 move.l
#$ff000000,(a0)
For example... the colour model used is RGBx per default, or, if
you specify a custom bitmap, you can use xRGB too... in 8 Bit
a standard chunky colour model (in 1 Byte) will be used...
the x is for the Alpha channel... but sadly, I have no documentation
for this, so ignore it... the constants for the type are found
in the EGS autodocs (orion.etsu.edu is a site where they can be
found... or contact INGENIEURBUERO HELFRICH, the makers of the Piccolo
and Piccolo SD64 boards...
To unlock, just subtract from the Lock values again... for unlocking
you do not need to vaste processor time like it is done while locking.
The next thing we do is Double Buffering.
move.l screen,a0 move.l BackBitMap,a1 move.l egsbase,a6 jsr E_FlipMap(a6)
move.l d0,BackBitMap
The flip will happen after the next vertical blank interrupt. And as
I said before: In C I got some graphics errors, strange thing, but in
Assembler it worked perfectly and consumed almost no time...
Functions for EGS board blitter support are in the egsblit.library,
but those are self explaining. If you have difficulties, feel free
to send me mail. In egsalphablit.library there are blitting functions
for Alpha channel... but it seems nobody has documentations for
them :((( Not even the coders of EGS ...
Do not use any Pixelsetting functions of the libraries. If you do it
yourself with this ebm_Plane-thing you will be MUCH faster...And,
remember, you will need EGS V.6 includes... I will provide my EGS V.6
Bitmap structure here (self-made :) )
STRUCTURE E_EBitMap,0
WORD ebm_Width
WORD ebm_Height
UWORD ebm_BytesPerRow
BYTE ebm_Depth
UBYTE ebm_Type
* Enumeration type descriptor for access to union fields
APTR ebm_Plane
BYTE ebm_Lock
UBYTE ebm_Display
UWORD ebm_Pad0
ULONG ebm_Pad1
STRUCT ebm_BitPlanes,24*4 ; because Ptr size is 4 Bytes
; in C BitPlanes[24]
APTR ebm_Colors
ULONG ebm_Flags
APTR ebm_Class
LABEL ebm_SIZEOF
If you need another structure of EGS, and only have V.5 ASM-include,
try to get the ASM-includes out of the V.6 C-Includes ... or send
me mail, maybe i have the correct includes...
Closing the Screen:
move.l screen,a0 move.l egsbase,a6 jsr E_CloseScreen(a6)
Closing the BackBitMap :
move.l BackBitMap,a0 move.l egsbase,a6 jsr E_DisposeBitMap
And remember : Before closing the screen, the CORRECT Bitmap has to be
in front again... if not, perform an additional Double Buffering followed
by a
move.l screen,a0 move.l egsbase,a6 jsr E_WaitTOF(a6)
Okay, that's all about EGS. All the examples are taken from my code
about the EGS version of rtg.library. So you will get a much easier
interface, as soon as rtg.library is finished.
B) Cybergrafix
Cybergrafix supports a function to get some information about the
(modified) Bitmap structure, but (sadly) you do not get the adress of the
video memory. So you can't write directly to the video memory, if you do
not have the specs of the used board, but you have to use Cybergrafix as
WB-Emulation. But, luckily, Cybergrafix is quite fast.
Cybergrafix supports some very fine functions to select a screenmode,
for example BestCModeIDTagList, which gets the best screenmode for a
specified tag list of screen attributes. In EGS you had to do this
yourself (some additional advertising: In rtg.library you have not
to do it yourself, either... like in Cybergrafix, but with directly
writing to the video memory...)
For writing pixels, reading Pixels and blitting, there are the
functions FillPixelArray, MovePixelArray, ReadPixelArray, ScalePixelArray,
SwapPixelArray, WritePixelArray and WriteRGBPixel. I think what they do
is quite clear.
For double buffering you use standard Double Buffering functions
like the functions around AllocScreenBuffer. Cybergrafix is a very
compatible and fast WB-Emu.
As color models you are able to use a LOT of them (look at your
Cybergrafix developping docs). As I am no expert in Cybergrafix, that is
all about it now. I do not know how good the graphics board blitter
support for Cybergrafix is.
So, at the end of this article, I wish you fun and success with your
programming of Amiga graphics boards. And i hope, we soon will see some
games or demos using graphics boards. Support them...
[Contents] [Browse ->] [Browse <-]
HTML Conversion by AG2HTML.pl V2.950424, perl 5.001 & witbrock@cs.cmu.edu