;===========================================================================;
;Title:	  Space Warrior.
;Author:  Paul Manias.
;Started: 5 October 1996
;Version: V0.1 (6 October 1996)
;
;Doc:     This is my first attempt at writing a game from scratch, in GMS.
;	  I've only just started, but you will be able to see my progression
;	  in this game in further beta releases.  If you want to improve
;	  this game or finish it before I do, feel free, and I will start
;	  another game.
;
;	  I've already converted a full-blown game to GMS (a good one), but
;	  unfortunately I can't release it just yet, I will have to wait
;	  until I am happy with the final structures first.
;
;	  Press SPACE or ESCAPE to exit the game.
;
;===========================================================================;

	opt	o+,c+

	INCLUDE	"exec/exec_lib.i"
	INCLUDE	"games/games_lib.i"
	INCLUDE	"games/games.i

CALL	MACRO
	jsr	_LVO\1(a6)
	ENDM

	SECTION	"SpaceWarrior",CODE

;===========================================================================;
;                             INITIALISE DEMO
;===========================================================================;

Start:	MOVEM.L	A0-A6/D1-D7,-(SP)
	lea	DataBase,a5	;a5 = Permanent DataBase pointer.
	move.l	($4).w,a6
	lea	GMS_Name(pc),a1
	moveq	#$00,d0
	CALL	OpenLibrary
	move.l	d0,GMS_Base(a5)
	beq	.Error_GMS

	move.l	GMS_Base(a5),a6
	lea	GameName,a0
	CALL	SetUserPrefs

	CALL	AllocBlitter
	tst.w	d0
	bne	.Error_Blitter

	CALL	AllocAudio
	tst.w	d0
	bne	.Error_Audio

	lea	SND_InitList(pc),a0
	CALL	InitSound
	tst.w	d0
	bne.s	.Error_Sounds

;---------------------------------------------------------------------------;
;First we load in the BOB's.  The palette and planes found in this file will
;serve the basis for the screen that we are going to open.  This way it is
;possible to support a game that can be run on OCS, ECS or AGA, simply if
;the user lessens the colours in the picture!

	lea	Screen(pc),a0
	lea	PIC_Bobs(pc),a1
	CALL	LoadPic
	tst.w	d0
	bne.s	.Error_BOBPic
	move.l	PIC_Palette(a1),GS_Palette(a0)
	move.w	PIC_Planes(a1),GS_Planes(a0)
	move.l	PIC_AmtColours(a1),GS_AmtColours(a0)

;---------------------------------------------------------------------------;
;Initialise the screen here, and load a background picture into the buffers.

	CALL	Add_Screen
	tst.w	d0
	bne.s	.Error_Screen

;---------------------------------------------------------------------------;
;Initialise the BOB's here.

	lea	Screen(pc),a0
	lea	PIC_Bobs(pc),a1
	lea	BOB_InitList(pc),a1
	CALL	Init_BOB
	tst.w	d0
	bne.s	.Error_BOB

;---------------------------------------------------------------------------;
;Here we initiliase the RestoreList.  A RestoreList is required because when
;you draw a BOB on the screen, you will lose the data beneath the BOB.  By
;using a RestoreList, we can stop this from happening.  However, it does
;take extra blitter time.  There are ways to get around this, but then we
;would have to lose our pretty background.

	moveq	#2,d0	;2 buffers.
	moveq	#10,d1	;Room for up to 10 BOB's.
	CALL	Init_RestoreList
	move.l	d0,RestoreList(a5)
	beq.s	.Error_RestoreList

	CALL	Show_Screen

	bsr.s	Main

;---------------------------------------------------------------------------;
;This is the exit code.  We could use list's to make this section shorter
;but it's not such a big deal.

.ReturnToDOS
	move.l	RestoreList(a5),d0
	CALL	Free_RestoreList
.Error_RestoreList
	lea	BOB_SpaceShip(pc),a1
	CALL	Free_BOB
.Error_BOB
	lea	Screen(pc),a0
	CALL	Delete_Screen
.Error_Screen
	lea	PIC_Bobs(pc),a1
	CALL	FreePic
.Error_BOBPic
	lea	SND_InitList(pc),a0
	CALL	FreeSound
.Error_Sounds
	CALL	FreeAudio
.Error_Audio
	CALL	FreeBlitter
.Error_Blitter
	move.l	($4).w,a6
	move.l	GMS_Base(a5),a1
	CALL	CloseLibrary
.Error_GMS
	MOVEM.L	(SP)+,A0-A6/D1-D7
	moveq	#$00,d0
	rts

;===========================================================================;
;                                MAIN LOOP
;===========================================================================;

Main:	move.l	GMS_Base(a5),a6	;a6 = Permanent GMSBase pointer.
.loop	bsr.s	Move_Ship	;Do all movements first.
	bsr	Move_Fire
	bsr	Draw_All	;Now draw all the stuff to screen.
	CALL	Wait_OSVBL	;Wait for VBL.
	CALL	SwapBuffers	;Swap the screen buffers.
	lea	Keys(pc),a1
	CALL	Read_Key
	cmp.b	#"",d0
	beq.s	.done
	cmp.b	#" ",d0
	bne.s	.loop
.done	rts

;===========================================================================;
;                        MOVEMENT ROUTINE FOR SHIP
;===========================================================================;
;This routine moves and animates the ship for us.  Because our ship has no
;bob clipping we also have to restrict it's movement to the physical
;screen.

SPEED_BULLET =	5
SPEED_FLAME =	3

Move_Ship:
	lea	BOB_SpaceShip(pc),a1
	moveq	#JPORT1,d0
	moveq	#JT_ZBXY,d1
	CALL	Read_JoyPort
	move.w	d0,Joy1Data(a5)
	bne.s	.Moving

.Still	addq.w	#1,ShipSpeed(a5)
	cmp.w	#SPEED_FLAME,ShipSpeed(a5)
	ble	.done
	clr.w	ShipSpeed(a5)
	addq.w	#1,BOB_Frame(a1)
	cmp.w	#5,BOB_Frame(a1)
	blt.s	.done
	move.w	#3,BOB_Frame(a1)
	rts

.Moving	addq.w	#1,ShipSpeed(a5)
	cmp.w	#SPEED_FLAME,ShipSpeed(a5)
	ble.s	.Move
	clr.w	ShipSpeed(a5)
	addq.w	#1,BOB_Frame(a1)
	cmp.w	#3,BOB_Frame(a1)
	blt.s	.Move
	clr.w	BOB_Frame(a1)

.Move	move.w	d0,d1
	ext.w	d0
	add.w	d0,BOB_YPos(a1)
	asr.w	#8,d1
	add.w	d1,BOB_XPos(a1)
.ChkLX	cmp.w	#4,BOB_XPos(a1)	;Check left edge.
	bge.s	.ChkRX
	move.w	#4,BOB_XPos(a1)
.ChkRX	cmp.w	#320-16,BOB_XPos(a1)	;Check right edge.
	ble.s	.ChkTY
	move.w	#320-16,BOB_XPos(a1)
.ChkTY	cmp.w	#10,BOB_YPos(a1)	;Check top edge
	bge.s	.ChkBY
	move.w	#10,BOB_YPos(a1)
.ChkBY	cmp.w	#256-35,BOB_YPos(a1)	;Check bottom edge
	ble.s	.done
	move.w	#256-35,BOB_YPos(a1)
.done	rts

;===========================================================================;
;                    MANAGEMENT FOR SHIP'S FIRE BUTTON
;===========================================================================;
;Check if the fire button has been pressed, and if so, do we create
;a new bullet or not?  Move the fire bob if one is currently on screen.

Move_Fire:
	lea	BOB_SpaceShip(pc),a2
	lea	BOB_ShipFire1(pc),a1
	move.w	Joy1Data(a5),d0
	btst	#MB_LMB,d0
	beq.s	.MoveFire

	tst.w	FireOn(a5)
	bne.s	.MoveFire
.Fire	move.w	BOB_YPos(a2),BOB_YPos(a1)
	move.w	BOB_XPos(a2),BOB_XPos(a1)
	subq.w	#5,BOB_YPos(a1)
	clr.w	BOB_Frame(a1)
	move.w	#1,FireOn(a5)
	lea	SND_Fire1(pc),a0
	CALL	PlaySoundPri
	rts
.MoveFire
	tst.w	FireOn(a5)
	beq.s	.done
	move.w	#1,BOB_Frame(a1)
	subq.w	#SPEED_BULLET,BOB_YPos(a1)
	tst.w	BOB_YPos(a1)
	bge.s	.done
	clr.w	FireOn(a5)
.done	rts

;===========================================================================;
;                             DRAW EVERYTHING
;===========================================================================;

Draw_All:
	lea	Screen(pc),a0	;Restore previously drawn BOB's.
	move.l	RestoreList(a5),a1
	CALL	Restore_List

	lea	BOB_SpaceShip(pc),a1
	move.l	RestoreList(a5),a2
	CALL	Draw_BOB

	tst.w	FireOn(a5)
	beq.s	.done
	lea	BOB_ShipFire1(pc),a1
	CALL	Draw_BOB
.done	rts

;===========================================================================;
;                           MISCELLANEOUS DATA
;===========================================================================;

GMS_Name:
	dc.b	"games.library",0
	even

GameName:
	dc.b	"SpaceWarrior",0
	even

Keys:	ds.b	KP_SIZEOF
	even

;===========================================================================;
;                               SCREEN DATA
;===========================================================================;

Screen:	dc.l	GSV1,0	;Structure version.
	dc.l	0,0,0	;Screen_Mem1/2/3
	dc.l	0	;Screen link.
	dc.l	0	;Address of screen palette.
	dc.l	0	;Address of rasterlist.
	dc.l	0	;Amt of colours in palette.
	dc.w	320,256	;Screen Width and Height.
	dc.w	320/8,256	;Picture Width and Height.
	dc.w	0	;Amt of planes.
	dc.w	0,0	;X/Y screen offset.
	dc.w	0,0	;X/Y picture offset.
	dc.l	DBLBUFFER	;Special attributes.
	dc.w	LORES|COL12BIT	;Screen Mode.
	dc.b	INTERLEAVED	;Screen Type
	dc.b	0	;Reserved.
	even

;===========================================================================;
;                                BOB DATA
;===========================================================================;

BOB_InitList:
	dc.l	"LIST"
	dc.l	BOB_SpaceShip
	dc.l	BOB_ShipFire1
	dc.l	LISTEND

PIC_Bobs:
	dc.l	PCV1,0	;Version header.
	dc.l	0	;Source data.
	dc.w	320/8,256	;Width, Height.
	dc.w	0	;Amount of Planes.
	dc.l	0	;Amount of colours.
	dc.l	0	;Source palette.
	dc.w	LORES|COL12BIT	;Screen mode.
	dc.w	INTERLEAVED	;Destination
	dc.l	VIDEOMEM|GETPALETTE	;Parameters.
	dc.l	.File
.File	dc.b	"GAMESLIB:data/IFF.WarBobs",0
	even

BOB_SpaceShip:
	dc.l	BBV1,0	;Structure version.
	dc.w	BUFFER2	;Buffer.
	dc.l	0,0	;Graphics and mask data.
	dc.w	0	;Current frame.
	dc.l	.Frames	;Pointer to frame list.
	dc.w	0	;Modulo (skip in source) in bytes.
	dc.w	16/8,28	;Width in bytes, Height in pixels.
	dc.w	100,100	;X/Y destination.
	dc.w	0,0,0,0	;Border restrictions.
	dc.w	0,0	;Amount of planes.
	dc.l	0	;Size of plane, not required.
	dc.w	MASK|RESTORE	;Attributes.
	dc.l	PIC_Bobs	;Pointer to bob origin.
.Frames	dc.w	00,16,00,128	;X/Y Graphic, X/Y Mask
	dc.w	16,16,16,128	;...
	dc.w	32,16,32,128
	dc.w	48,16,48,128
	dc.w	64,16,64,128
	dc.w	-1

BOB_ShipFire1:
	dc.l	BBV1,0	;Structure version.
	dc.w	BUFFER2	;Buffer.
	dc.l	0,0	;Graphics and mask data.
	dc.w	0	;Current frame.
	dc.l	.Frames	;Pointer to frame list.
	dc.w	0	;Modulo (skip in source) in bytes.
	dc.w	16/8,5	;Width in bytes, Height in pixels.
	dc.w	0,0	;X/Y destination.
	dc.w	0,0,0,0	;Border restrictions.
	dc.w	0,0	;Amount of planes.
	dc.l	0	;Size of plane, not required.
	dc.w	CLIP|MASK|RESTORE	;Attributes.
	dc.l	PIC_Bobs	;Pointer to bob origin.
.Frames	dc.w	0,44,0,156	;X/Y Graphic, X/Y Mask
	dc.w	0,49,0,161	;X/Y Graphic, X/Y Mask
	dc.w	-1

;===========================================================================;
;                            SOUND STRUCTURES
;===========================================================================;

SND_InitList:
	dc.l	"LIST"
	dc.l	SND_Fire1
	dc.l	LISTEND

SND_Fire1:
	dc.l	SMV1,0	;Structure version.
	dc.w	CHANNEL_ALL	;Channel to play through.
	dc.w	1	;Priority.
	dc.l	0	;Sample header
	dc.l	0	;Sample address.
	dc.l	0	;Sample length.
	dc.w	OCT_C1S	;Sample period.
	dc.w	100	;Sample volume.
	dc.l	0	;Sound attributes.
	dc.l	.File	;Sound file.
.File	dc.b	"GAMESLIB:data/SND.Fire1",0
	even

;===========================================================================;
;                               EMPTY DATA
;===========================================================================;

	STRUCTURE DATASTUFF,0
	APTR	GMS_Base
	APTR	RestoreList
	UWORD	FireOn
	UWORD	ShipSpeed
	UWORD	Joy1Data
	LABEL	RS_TOTAL

	SECTION	"EmptyData",BSS

DataBase:
	ds.b	RS_TOTAL
	even

