#include "library/_sms_setz80stackpoint.bas"
#include "library/smsvdp.bas"
#include "library/smsfilvrm.bas"
#include "library/smsldirvm.bas"
#include "library/smsvpoke.bas"
#include "library/sg1000putsprite.bas"
#include "library/smsrnd.bas"
#include "library/backgroundandsprites.bas"
#include "library/attributes.bas"

'#include "library/msxsnsmat.bas"
#include "library/smsjoypad.bas"

'#include "library/msxcolor.bas"
'#include "library/msxscreen.bas"
'#include "library/msxpalette.bas"
'#include "library/_msx16x16sprites.bas"

'#include "library/_msxwaitvbl_deprecated.bas" '- <-!!! - replace
#include "library/smswaitvbl.bas"

'-------------------------------------------------------------------------------
'- including binaries... - is there redundant information to be removed?

goto bininc01end
spr02:
asm
  incbin "library/sprites.bin"
  end asm
map01:
asm
  incbin "library/map.bin"
  end asm
bininc01end:

'-------------------------------------------------------------------------------
'- defining variables - sg1000 ram starts at $C000

dim eee as uinteger at $C000
dim qq2 as uinteger at $C002
dim xpos as uinteger at $C004
dim ypos as uinteger at $C006
dim cpos as uinteger at $C008
dim eez as uinteger at $C00A
dim xdrc as uinteger at $C00C
dim spq0 as uinteger at $C00E
dim ee0 as uinteger at $C010
dim ee1 as uinteger at $C012
dim ee2 as uinteger at $C014
dim ee3 as uinteger at $C016
dim ee4 as uinteger at $C018
dim oxfriso as uinteger at $C01A
dim oxiso as uinteger at $C01C
dim oyiso as uinteger at $C01E
dim shot as uinteger at $C020
dim oxsh as uinteger at $C022
dim oysh as uinteger at $C024
dim seed as uinteger at $C026
dim oxfriso2 as uinteger at $C028
dim score as uinteger at $C02A
dim hiscore as uinteger at $C02C
dim stamina as uinteger at $C02E
dim level as uinteger at $C030

seed=0
score=0
hiscore=0
level=1

'-------------------------------------------------------------------------------
'- sub routines...

sub zprintdecimal(tpos as uinteger,tval as uinteger):
  smsvpoke(6144+tpos+0,48+int(tval/10000) mod 10)
  smsvpoke(6144+tpos+1,48+int(tval/1000) mod 10)
  smsvpoke(6144+tpos+2,48+int(tval/100) mod 10)
  smsvpoke(6144+tpos+3,48+int(tval/10) mod 10)
  smsvpoke(6144+tpos+4,48+tval mod 10)
  end sub

sub zprintdecimal4(tpos as uinteger,tval as uinteger):
  smsvpoke(6144+tpos+0,48+int(tval/1000) mod 10)
  smsvpoke(6144+tpos+1,48+int(tval/100) mod 10)
  smsvpoke(6144+tpos+2,48+int(tval/10) mod 10)
  smsvpoke(6144+tpos+3,48+tval mod 10)
  end sub

sub zprintdecimal2(tpos as uinteger,tval as uinteger):
  smsvpoke(6144+tpos+0,48+int(tval/10) mod 10)
  smsvpoke(6144+tpos+1,48+tval mod 10)
  end sub

'-------------------------------------------------------------------------------
'- whatever...

'msxcolor($6,$F,$1)
smsvdp(7,$61) 'smsvdp(7,F*16+4) '- ink*16+border - color(3,?,1)


'msxscreen(2,0,0,0)
'msx16x16sprites() '- sets 16x16 sprite size, i have no idea how to do it otherwise?
smsvdp(0,%00000010):smsvdp(1,%11100010) '- screen2,2 (graphics1)
'- vdp entries for screen2 - base vram addresses
smsvdp(2,$06) '- $1800
smsvdp(3,$FF) '- $2000
smsvdp(4,$03) '- $0000
smsvdp(5,$36) '- $1B00
smsvdp(6,$07) '- $3800


'-------------------------------------------------------------------------------
'- palette... - apagar
'if (msxsnsmat(2) band 64)<>0 then '- key "a" pressed on booting for default palette
'  msxpalettehx($1,$222) '- RGB format (hexcolour 12bit, $0C84 means #CC8844)
'  msxpalettehx($4,$006)
'  msxpalettehx($6,$D00)
'  msxpalettehx($7,$0BE)
'  msxpalettehx($A,$FD0)
'  msxpalettehx($C,$0A0)
'  msxpalettehx($D,$E08)
'  msxpalettehx($F,$FFF)
'  end if

'-------------------------------------------------------------------------------
'- filling the vram somehow...

for eee=0 to $17FF step $800
  smsldirvm(eee,@charset01,1024)        '-bitmap from the character set (i think)
  smsfilvrm(eee+$2000,$AF,1024)         '-$AF= yellow and white in the background
  smsfilvrm(eee+1024+$2000,$7A,1024)    '-$7A= no idea... :S
  smsldirvm(eee+$2000+256,@attr01,768)  '-attributes from the character set (i think)
  next

'-------------------------------------------------------------------------------
'- sprites

smsldirvm($3800,@spr02,1024)
smsldirvm($3800+1024,@spr02,1024)

'-------------------------------------------------------------------------------
'- main loop

mainloop01:

'- still filling the vram somehow... (background area?)
for ee0=0 to 23
  smsldirvm((ee0*32)+$1800,@map01+(ee0*64),32)
  next

'- title
smsldirvm($1800+18*32+3,@text01,@text01end-@text01)
smsldirvm($1800+19*32+3,@text02,@text02end-@text02)
smsldirvm($1800+21*32+3,@text03,@text03end-@text03)

'- key checking
loopkeyboard01:
eee=(smsjoypad1()band 15)bor(smsjoypad2()band 15)
if eee=0 then: goto loopkeyboard01:end if

eee=127

'-------------------------------------------------------------------------------
'- starting some variables...

xdrc=112
xpos=40:ypos=114:cpos=$7
oxsh=xpos:oysh=ypos:shot=0
eee=0:ee4=999
score=0:stamina=99:level=1

'-------------------------------------------------------------------------------
'- randomizing enemies - defining $E040 to $E04F for that (might change...) - xpos,ypos,xdir,ydir

for ee0=0 to 3
  poke $E040+(ee0*4),240
  poke $E041+(ee0*4),0
  poke $E042+(ee0*4),seed:seed=smsrnd(seed)
  poke $E043+(ee0*4),seed:seed=smsrnd(seed)
  next

'----
'- game loop
gameloop01:
'msxwaitvbldeprecated()
smswaitvbl(1)

eee=eee+1
ee4=ee4-1

'----
'- moving the ship

if (smsjoypad1() band 8)<>0 then:
'if (msxsnsmat(8) band 128)=0 then:
xpos=xpos+2:xdrc=xdrc+16:end if '- right 

if (smsjoypad1() band 4)<>0 then:
'if (msxsnsmat(8) band 16)=0 then:
xpos=xpos-2:xdrc=xdrc-16:end if  '- left

if (smsjoypad1() band 2)<>0 then:
'if (msxsnsmat(8) band 64)=0 then:
ypos=ypos+2:xdrc=xdrc+16:end if  '- down

if (smsjoypad1() band 1)<>0 then:
'if (msxsnsmat(8) band 32)=0 then:
ypos=ypos-2:xdrc=xdrc-16:end if  '- up

'if (msxsnsmat(8) band 1)=0 and shot=0 then:shot=1:end if
if (smsjoypad1() band 16)<>0 and shot=0 then:shot=1:end if



'----
'- checking boundaries '- fine tune needed
if xpos<8 then:xpos=8:end if
if ypos<16 then:ypos=16:end if
if xpos>232 then:xpos=232:end if
if ypos>160 then:ypos=160:end if

'----
'- stabilizing ship rotation when not moving, i guess?
if xdrc<112 then: xdrc=xdrc+8: end if
if xdrc>112 then: xdrc=xdrc-8: end if
if xdrc<32 then: xdrc=32: end if
if xdrc>192 then: xdrc=192: end if

'----
'- isometric calculation
oxfriso=(int(ypos/4)+int(xpos/8))
ee1=(int(eee/2)+int(oxfriso/1)) mod 32
ee2=((23-((int(eee/4))mod 24)+int(oxfriso/2)) mod 24)
oxfriso2=(int(ypos*2)+int(xpos*1))

'----
'- ship sprite number
spq0=((16*(eee band 2))+64+(int(xdrc/32)-1)*4)

'----
'- displaying ship
if shot=0 then
  sg1000putsprite(0,xpos,ypos,spq0,cpos)
  sg1000putsprite(1,xpos,200,spq0,14)
  oxsh=xpos:oysh=ypos
else
  sg1000putsprite(0,xpos,ypos,(6*4),cpos)
  sg1000putsprite(1,oxsh,oysh,spq0-64,cpos)
  oxsh=oxsh+16:oysh=oysh-8
  end if
if oysh<0 or oxsh>256 then:shot=0:oxsh=xpos:oysh=ypos:end if

'----
'- displaying enemies

for ee0=0 to 3
  'sg1000putsprite(16+ee0,peek($E040+(ee0*4)),peek($E041+(ee0*4)),(7*4),13)
  sg1000putsprite(16+ee0,peek($E040+(ee0*4))-oxfriso2,peek($E041+(ee0*4))-int(oxfriso2/2),(7*4),13)
  poke $E040+(ee0*4),peek($E040+(ee0*4))+((peek($E042+(ee0*4)))/32)-(128/32)
  poke $E041+(ee0*4),peek($E041+(ee0*4))+((peek($E043+(ee0*4)))/32)-(128/32)
  next

'----
'- colision: rocket on "enemy"
if shot<>0 then
  for ee0=0 to 3
    if (abs( ( (peek($E040+(ee0*4))-oxfriso2) band 255) -oxsh)<16) and (abs( ( (peek($E041+(ee0*4))-int(oxfriso2/2)) band 255) -oysh)<16) then
      seed=smsrnd(seed):poke $E040+(ee0*4),seed
      seed=smsrnd(seed):poke $E041+(ee0*4),seed
      score=score+1
      end if
    next
  end if

if score>hiscore then
  hiscore=score
  end if

'----
'- colision: "enemies" on ship
for ee0=0 to 3
  if (abs( ( (peek($E040+(ee0*4))-oxfriso2) band 255) -xpos)<16) and (abs( ( (peek($E041+(ee0*4))-int(oxfriso2/2)) band 255) -ypos)<16) then
    stamina=stamina-1
    end if
  next

'----
'- randomize enemy motions

seed=smsrnd(seed)
if (seed band 255)<32 then
  seed=smsrnd(seed):ee0=seed band 3
  poke $E042+(ee0*4),seed:seed=smsrnd(seed)
  poke $E043+(ee0*4),seed:seed=smsrnd(seed)
  end if

'----
'- update background 
for ee0=0 to 23
  smsldirvm((ee0*32)+$1800,@map01+((ee0+ee2)*64)+ee1,32) '- fine tune needed?
  next

'----
'- stages? :D (each minute increment the stage, what a bullshit! :D )

if eee>3000 then
  level=level+1
  end if

'----
'- score table
smsldirvm(6144+23*32+6,@text04,2)
zprintdecimal4(23*32+8,score)
smsldirvm(6144+23*32+13,@text04+6,2)
zprintdecimal4(23*32+15,hiscore)
smsldirvm(6144+23*32+20,@text04+12,2)
zprintdecimal2(23*32+22,stamina)
smsldirvm(6144+23*32+25,@text04+16,2)
zprintdecimal2(23*32+27,level)

if stamina>0 then:
  goto gameloop01
  end if

hiscore=score


smsldirvm(6144+16*32+10,@text05,12)

'for ee0=0 to 100
'  msxwaitvbldeprecated()
'  next
smswaitvbl(100)


goto mainloop01

'-------------------------------------------------------------------------------

text01:
asm
  defb "CMJN"
  end asm
text01end:
text02:
asm
  defb "Paulo Silva - jun'14"
  end asm
text02end:
text03:
asm
  defb "Push any key"
  end asm
text03end:
text04:
asm
  defb "sc0000hs0000pw99st01"
  end asm
text04end:
text05:
asm
  defb "Game over..."
  end asm
text05end:

'-------------------------------------------------------------------------------

