Here you'll find the latest updates/changes/infos on the Starcat Developments Jaguar Library Code.
Version 1.3 / 31-12-2002
Basic Requirements to Start Jaguar Coding
Programming Infos:
3 Scaling
Welcome to Atari Jaguar Programming ! As I suppose the Jaguar Development Environment is still completely unknown to you, I'll try to explain the basic things about it:
In order to start Jaguar programming you need a development kit of some kind. That can either be a Hobby Development Kit:
BJL
JUGS
Jaguar Server
JagOS
Or an official Atari Jaguar Development kit:
Alpine Board with Stubulator Jaguar
I suppose you are not willing to pay $500 for the official development kit. To write small games the hobby development kits are more than good enough.
The best and easiest way for you is probably
BJL. (It stands for Behind Jaggy Lines)
It is available either as modification
(Boot Rom replacement) to your Jaguar or (if you want the clean and easy
solution) Protector SE.
Protector SE is a game released
by Songbird Productions (http://songbird.atari.net).
However it contains important features such as "JagFree CD",
memory to save gamestates and also BJL, which basically turns the
game into a hobby dev kit solution.
Besides Protector SE you still need to
build yourself a BJL cable.
That's really the best and easiest way to go, if you don't want to touch the inner workings of the Jag and risk breaking it.
In the future I assume you have a BJL kit, simply because most people use it and because I have never used JUGS, or the other hobby dev kits and I can't say for sure if the procedures are exactly the same.
You also need to know MC68000 assembler
or have a documentation/book and enough interest to learn it.
Some simple programs can probably be created
with this library by just cut and pasting the code, but without an idea
of what you are doing and what the commands do, you'll soon be lost.
Here are again the things that are useful/needed to get started at Jag coding:
-Dev Kit (Protector SE with selfmade BJL
cable)
-Tools (see: Installing
the Library)
-Documentations (Jaguar Development Manual,
Underground Docs, 68000 Doc and this file)
-A Text Editor (You can use notepad or
so, but I highly recommend something like MED
(http://www.med-editor.com), because it features code highlighting
for 68k asm.)
-This Library
In order to install the library on your system you first need Jaguar development tools. You can order a CD with Tools on the Starcat Developments Page. http://www.starcat-dev.de
Get the necessary tools. (Assembler and
Linker are the most important ones. Also get the 8-Bit or 4-Bit BJL Uploader
if you're using BJL)
Unrar the files into a folder... put them
all into the same folder, so that they are all on the same level.
Now you have a whole list of files.
The library can be "installed" on your
system easily. (Tested with DOS and Win95/98)
Create a folder on your harddisc called
"Jaguar"
Open it, create a folder called "Bin"
That Bin folder should be used to put
all the development tools in (all the files you just decompressed). The
most important ones for you are MadMac (the Atari Jaguar Assembler)
and ALN (the Atari Linker to link the object files that are
outputted by MadMac into fully functional Binarys) and the BJL Uploader
(sends the binarys to the Jaguar) for BJL users.
If you have done that, add the following
line to your autoexec.bat file : PATH=%PATH%;C:\JAGUAR\BIN
(I assume your harddisc has the letter
"C", if not correct the line above.)
Now the path is set correctly.
You can now decompress the library into
what ever folder you want. (just keep in mind that it should be DOS compatible...
so 8 signs only.)
Now you can work in that folder. The main.s is the file you should work in most. The include.s is just a collection of preset values. Do not change these unless you know what you are doing. (Also always keep backups of your work.)
After editing main.s you can compile and test your program by executing the link.bat file in the same folder.
You should get a "test.bin" file that
has to be loaded to $4000 on your dev kit.
By buying the Starcat Development Jaguar Dev Tools CD 1.1 or later revision, you also bought the right to use the Starcat Developments Jaguar Library in your project (this is also valid for commercial projects) as long as you add the following Credits as text or image, clearly readable, to your program/game:
Starcat Developments Jaguar Library by Lars Hannig
http://www.starcat-dev.de
Well, either write it yourself, or mail
me and ask if I have time to do it. Maybe others are in need of exactly
the same routine in their projects.
In that case I'm happy to add it to the
Library, when I have the time to do it.
You can reach me here:
http://www.atari-jaguar64.de
http://www.starcat-dev.de
or e-mail me: starcat@atari-jaguar64.de
Object Description | EQU | Alternate EQU | Declared as |
X position of the object | O_XPOS | XPOS | WORD |
Y position of the object (in halflines) | O_YPOS | XPOS | WORD |
address of graphic data | O_DATA | DATA | LONGWORD |
height in pixels | O_HEIGHT | HEIGHT | WORD |
width of object in phrases | O_DWIDTH | WIDTH | WORD |
offset to the next line of the object in phrases | O_IWIDTH | WIDTH_OFFS | WORD |
"how to draw object" flags:
standard (normal display)= 0 HFLIP (Horizontal FLIP)= 1 RMW (Read Modify Write "transparency")= 2 TRANS (don't display color 0 "transparancy")= 4 RELEASE = 8 |
O_FLAGS | FLAGS | BYTE |
Bit count to skip at the beginning of the object data. | O_FIRSTPIX | BYTE | |
Object kind:
0 =Bitmap Object 1= Scaled Object 2=GPU Object 3=Branch Object 4=Stop Object |
O_TYPE | OBJTYPE | BYTE |
Color Depth:
5= 24-Bit 4= 16-Bit 3= 8-Bit (CLUT) 2= 4-Bit (CLUT) 1= 2-Bit (CLUT) 0= 1-Bit (CLUT) |
O_DEPTH | DEPTH | BYTE |
Skip phrases when a new phrases should
be fetched:
0 = repeat the same phrase 1 = continuous data 2 = fetch every second phrase 3 = fetch every third phrase |
O_PITCH | - | BYTE |
Index in CLUT for Objects with CLUT | O_INDEX | - | BYTE |
Scale remainder | O_SCALE | - | WORD |
X scale value (30 = normal size) | O_XSCAL | XSCAL | BYTE |
Y scale value (30 = normal size) | O_YSCAL | YSCAL | BYTE |
Custom Enhanced Object Structure of Jaguar Library V1.2
Object Description | State | EQU | Declared as |
Turn Object Active (1) or Inactive (0=not display). | Reserved | ACTIVE | WORD |
Can be used to identify objects by giving them a certain number. | Unused | KIND | BYTE |
Can be used to store life points of a character. | Unused | HITS | BYTE |
Can be used in collision routines. That way you don't have to multiply to get the real width value... You can load it directly. | Unused | REAL_WIDTH | WORD |
Can be used in collision routines. That way you don't have to multiply with 2 to get the real height value... You can load it directly. | Unused | REAL_HEIGHT | WORD |
Can be used to store acceleration values for X. | Unused | D_X | WORD |
Can be used to store acceleration values for Y. | Unused | D_Y | WORD |
Completely free for your use, if you need it. | Unused | FREE1 | WORD |
Completely free for your use, if you need it. | Unused | FREE2 | WORD |
Completely free for your use, if you need it. | Unused | FREE3 | WORD |
Completely free for your use, if you need it. | Unused | FREE4 | WORD |
Completely free for your use, if you need it. | Unused | FREE5 | WORD |
Completely free for your use, if you need it. | Unused | FREE6 | BYTE |
Used in the Scale Routine. Don't Touch. | Reserved | SCALE_COUNTER | BYTE |
Put Address of Animation List here 0=No Ani | Reserved | ANIMATION | LONGWORD |
Put Address of Scaling List here 0=No Scale List | Reserved | SCALING | LONGWORD |
You can use add this EQUAL to the Obj Address to skip an Object when doing a loop and going through the List. | OBJECTSIZE |
The Object Processor supports 24-Bit and 16-Bit color depth. 8-Bit, 4-Bit, 2-Bit and 1-Bit color depth are emulated by a CLUT that contains the physical 16-Bit color value. This is the reason why lower color depths than 16-Bit aren't faster than 16-Bit. Lists with 24-Bit objects may not contain any objects with lower color depths.
The last line of Objects with CLUT (at least when using 8-Bit RGB) is ALWAYS corrupted, this seems to be a OP Bug of some kind. However you can avoid this Problem adding an empty line at the end of the graphic when you create it. So you add a line of color 0 to for example a 8 line Object and delcare it in the Object List as 8 Line Object. That way you avoid the Problem.
The Jaguar has two linebuffers. The OP
draws the Object List line by line into the linebuffer. The linebuffer
is displayed by a video chip and the picture builds up line by line (this
happens fast enough that you don't see it of course).
When you use 16-Bit color depth (and less)
both linebuffers are used for different lines, when you use 24-Bit both
line buffers are needed for one line, so 16-Bit is twice as fast as 24-Bit.
D0 Longword = Source
D1 Longword = Destination
jsr ice_depack
Note: Keep in mind that both Source and
Destination need to be aligned to even values.
So you might have to place .QPHRASEs
The Animation lists are built up like this:
block_ani: ;LABLE OF ANIMATION LIST
- | - | - |
.ani_1: | ;Animation Frame 1 | |
dc.l | picture | Animation Frame (Picture) |
dc.w | 8/4 | Animation Frame Width |
dc.w | 8 | Animation Frame Height |
dc.b | 4 | Animation Color Depth |
dc.b | 4 | Animation Speed (the higher, the slower) |
dc.w | 0 | Animation Speed Counter (used in Routine, don't touch) |
dc.l | .ani_2 | Address of next animation list obj |
- | - | - |
.ani_2: | ;Animation Frame 2 | |
dc.l | picture1 | Animation Frame (Picture) |
dc.w | 8/4 | Animation Frame Width |
dc.w | 8 | Animation Frame Height |
dc.b | 4 | Animation Color Depth |
dc.b | 4 | Animation Speed (the higher, the slower) |
dc.w | 0 | Animation Speed Counter (used in Routine, don't touch) |
dc.l | .ani_2 | Address of next animation list obj |
- | - | - |
You can simply create your own Animation
lists and then put the address (lable of animation list) into the ANIMATION
flag of the enhenced Object structure.
The Scaling lists are built up like this:
scale_list1: ;LABLE OF SCALING LIST
- | - | - |
.scl_1: | ;Scaling List Object 1 | |
dc.b | 1 | Scale Value X |
dc.b | 1 | Scale Value Y |
dc.b | 30 | Max Scale Value X (ones value is reached, next scale) |
dc.b | 30 | Max Scale Value Y(ones value is reached, next scale) |
dc.l | 1 | Positive (1) or negative (-1) Scale X value |
dc.l | 1 | Positive (1) or negative (-1) Scale Y value |
dc.l | .scl_2 | Address of next scaling list obj |
- | - | - |
.scl_1: | ;Scaling List Object 1 | |
dc.b | 1 | Scale Value X |
dc.b | 1 | Scale Value Y |
dc.b | 1 | Max Scale Value X (ones value is reached, next scale) |
dc.b | 1 | Max Scale Value Y(ones value is reached, next scale) |
dc.l | -1 | Positive (1) or negative (-1) Scale X value |
dc.l | -1 | Positive (1) or negative (-1) Scale Y value |
dc.l | .scl_1 | Address of next scaling list obj |
- | - | - |
You can simply create your own Scaling
lists and then put the address (lable of scaling list) into the SCALING
flag of the enhenced Object structure.
First you call the readpad Routine to get the joypad state:
jsr readpad
Then you move the Joypad state into D0:
move.l joycur,d0
Now you can test the certain BITs to find
out which button was pressed...
We have the following EQUals to make it
easier:
JOY_UP
JOY_DOWN
JOY_LEFT
JOY_RIGHT
FIRE_A
FIRE_B
FIRE_C
FIRE_X ;PRO CONTROLLER
SUPPORT
FIRE_Y ;PRO CONTROLLER
SUPPORT
FIRE_Z ;PRO CONTROLLER
SUPPORT
FIRE_L ;PRO CONTROLLER
SUPPORT
FIRE_R ;PRO CONTROLLER
SUPPORT
OPTION
PAUSE
KEY_0
KEY_1
KEY_2
KEY_3
KEY_4
KEY_5
KEY_6
KEY_7
KEY_8
KEY_9
KEY_STAR
KEY_HASH
It can be done like this
btst.l #JOY_LEFT,d0
bne do_it
;IF Left was pressed branch to do_it
Another way is this:
btst.l #JOY_LEFT,d0
beq next
;if Left was NOT pressed jump to next, if left was pressed execute code
before next:
...
next:
JOY_LEFT can of course simply be replaced with a different Joypad equal to check other buttons...
You can check for reset this way after calling readpad and moving joycur to D0:
;SAMPLE RESET CHECK CODE FOR * AND #
.check_reset:
btst.l #KEY_STAR,d0
;CHECK IF * WAS PRESSED
beq .no_reset
;IF NOT JUMP TO .no_reset
btst.l #KEY_HASH,d0
;CHECK IF # WAS PRESSED
bne game_code
;IF TRUE, THE JUMP TO game_code (or whatever you want to do when
* and # are pressed together)
.no_reset:
The text Routine is now done in pure GPU
code, to make it run faster.
To use the text routine, you create such
a list:
.QPHRASE
text_list:
- | - | - |
dc.l | message1 | ;MESSAGE |
dc.l | user_memory+MEM_TXT_IMAGE | ;DESTINATION |
dc.w | $ffff | ;TEXTCOLOR |
dc.w | 5 | ;TEXT Xpos |
dc.w | 20 | ;TEXT Ypos |
dc.w | 0 | ;DUMMY_TXT |
- | - | - |
- | - | - |
dc.l | 0 | ;MESSAGE |
dc.l | 0 | ;DESTINATION |
dc.w | 0 | ;TEXTCOLOR |
dc.w | 0 | ;TEXT Xpos |
dc.w | 0 | ;TEXT Ypos |
dc.w | 0 | ;DUMMY_TXT |
- | - | - |
The Text Routine always needs an "empty" text object as last object to terminate the text processing.
To Start the Text Processing you do this:
lea gpu_text,a1
lea text_list,a2 ;message
to print
move.l a2,(a1)
You need to put the address of the text list into gpu_text.
(Btw,NEVER let the Jaguar get to declarations or other DATA !! It doesn't know a difference between data and code. That means it will interpret the data as code and most likely crash or react weird.)
The text that is being displayed in this case is: Hello !!
You should also keep in mind to clear the
text image before using it, otherwise you might see old text/graphic junk
in it.
You can do that for example by calling:
jsr
clear_text_screen
Ok, we have the text written into user_memory+MEM_TXT_IMAGE
now.
But we still need to display it !
To do that add a Object to the Object List like this: (keep in mind to add 1 to anz_objects, if you add a new object to the object list)
dc.w 21
; (O_XPOS)
dc.w 42
; (O_YPOS)
dc.l user_memory+MEM_TXT_IMAGE
; (O_DATA)
dc.w 240
; (O_HEIGHT)
dc.w 320/4
; (O_IWIDTH)
dc.w 320/4
; (O_DWIDTH)
dc.b 4
; (O_FLAGS)
dc.b 0
; (O_FIRSTPIX)
dc.b 0
; (O_TYPE)
dc.b 4
; (O_DEPTH)
dc.b 1
; (O_PITCH)
dc.b 0
; (O_INDEX)
dc.w $20
; (O_SCALE)
dc.b 30
; Y-Scaling Faktor
dc.b 30
; X-Skaling Faktor
dc.w 1
; ACTIVE
dc.b 0
; KIND
dc.b 0
; HITS
dc.w 0
; REAL_WIDTH
dc.w 0
; REAL_HEIGHT
dc.w 0
; D_X
dc.w 0
; D_Y
dc.w 0
; FREE1
dc.w 0
; FREE2
dc.w 0
; FREE3
dc.w 0
; FREE4
dc.w 0
; FREE5
dc.b 0
; FREE6
dc.b 0
; SCALE_COUNTER
dc.l 0
; ANIMATION
dc.l 0
; SCALING
That's it. Now you should have text on
your screen.
Ok, let's first set up a suitable Object.
dc.w 21
; (O_XPOS)
dc.w 42
; (O_YPOS)
dc.l user_memory+MEM_SCORE_IMAGE
; (O_DATA)
dc.w SCORE_LAYER_HEIGHT
; (O_HEIGHT)
dc.w 192/4
; (O_IWIDTH)
dc.w 192/4
; (O_DWIDTH)
dc.b 4
; (O_FLAGS)
dc.b 0
; (O_FIRSTPIX)
dc.b 0
; (O_TYPE)
dc.b 4
; (O_DEPTH)
dc.b 1
; (O_PITCH)
dc.b 0
; (O_INDEX)
dc.w $20
; (O_SCALE)
dc.b 30
; Y-Scaling Faktor
dc.b 30
; X-Skaling Faktor
dc.w 1
; ACTIVE
dc.b 0
; KIND
dc.b 0
; HITS
dc.w 0
; REAL_WIDTH
dc.w 0
; REAL_HEIGHT
dc.w 0
; D_X
dc.w 0
; D_Y
dc.w 0
; FREE1
dc.w 0
; FREE2
dc.w 0
; FREE3
dc.w 0
; FREE4
dc.w 0
; FREE5
dc.b 0
; FREE6
dc.b 0
; SCALE_COUNTER
dc.l 0
; ANIMATION
dc.l 0
; SCALING
The important things here to watch out
for are:
Put user_memory+MEM_SCORE_IMAGE
into DATA
Put SCORE_LAYER_HEIGHT into Height
Put 192/4 into both Width fields
(The score image is only 192 pixel in width.
Set DEPTH to 4, because
the score image is 16-Bit color.
Now, Displaying the Score works like this:
D5 Longword = Number to display
A0 Longword = Destination
A1 Longword = Number graphic.
move.l #5,d5
move.l #user_memory+MEM_SCORE_IMAGE,a0
lea
zahlen,a1
jsr
score
The numbers can be up to : 9999999
Should be enough for most games I guess
;-)
That's easy... Just call: jsr
random
And you'll have a random value between
0 and 511 in D0.
Note: D0 and D1 should be unused, before
calling this function, because the old data will be lost otherwise.
You simply have a memory region declared. The size is up to you (as long as it doesn't exceed the free space).
However I have already created some standard memory locations:
MEM_TXT_IMAGE is supposed to be
used for text display.
MEM_SCORE_IMAGE is supposed to
be used for score display.
MEM_DATA can be used for all kind
of ingame data. Like decompressed graphics.
MEM_END marks the point where you want the memory to end.
If you look into the code you'll see it declared like this:
MEM_END
EQU MEM_DATA+((320*240)*2)
In this case that means that the declared
memory area starts at MEM_TXT_IMAGE, includes MEM_SCORE_IMAGE
and two 8-Bit "screens" of MEM_DATA.
I think it is easier to calculate the
memory you need in screens, especially if you use it for graphics ;-)
So if you need more memory you can just
put a 3 or higher number where the 2 is right now.
You can also create more EQUals to find the decompressed images easier... for example let's say we need memory for a 64x64 16-Bit image... you can create an EQU like this:
TEST_IMAGE1 EQU
MEM_DATA ;start at MEM_DATA
TEST_IMAGE2 EQU
TEST_IMAGE1+((64*64)*2) ;the *2 is in this case because we want 64x64 16-Bit
TEST_IMAGE2 starts behind the first image.
...
If you don't need a certain graphic anymore,
you can just overwrite it later. Simply by decompressing something else
into the same memory location.
The idea and programming was done by myself,
Lars Hannig ( Starcat ).
However this project includes parts made
by others.
For example the ICE Decruch Routine by
Gordon Gibson
The Random Number Generator by Steve Scavone
The OP List Build and Score Display originally
made by Duranik, which has been modified by myself a bit.
Thanks a lot to all UGD-Jag members and
all other people who support this project and my other projects as well.
Without you guys, this would not be possible.
If you improve this library in any way,
please contact me.
And of course I also have to thank YOU
for your interest. I hope that you find this Jaguar library useful and
maybe create some Jag progs with it. :-)
You can reach me here:
http://www.atari-jaguar64.de
http://www.starcat-dev.de
or e-mail me: starcat@atari-jaguar64.de
Copyright 2002 Starcat Developments