'YAGAC.BAS ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#define YAGAC_VERSION "1.0."+osgl_builddate

'http://www.darkphear.com

'http://cmcgames.blogspot.com

'Copyright (C) Cleber de Mattos Casali. All rights reserved.


'This file (yagac.bas) is released under the terms of the GNU General Public License (GPL)
'as published by the Free Software Foundation, GPL version 2 or any later version.


'This game was developed specially for the FBGD Competition
'31st of Jan 2012 (deadline for submission).


'FreeBASIC is an excellent, fast and completely free, open-source BASIC compiler.
'Check it at http://www.freebasic.net



'NOTES:
'max jump= 6(w) X 3(h)

#define _osgl_appfullname_ "Y.A.G.A.C"
#define _osgl_gamestyle_arcade_

'#define _osgl_debug_
#define _osgl_nodebug_
'#define _osgl_nosound_
'#define _osgl_nomusic_
'#define _osgl_xscreen_ 800
'#define _osgl_yscreen_ 600
'#define _osgl_windowed_
'#define _osgl_noconsole_

#include once "osgl-lite.bas"

const as integer beginlevel=1, beginlives=5

dim as integer cheat=0, levelselect=0, livescheat=0, cheatcode=0

type savegametype
	level as integer
	lives as integer
	score as longint
	hiscore as longint
	use as integer
end type

dim shared as savegametype savegame

dim shared as string savegamefile : savegamefile=exepath+"/save.dat"

'CHEATS
'#define nosplash
'#define notitle
#define cheatkeys
'#define cheatcodedebug
'#define cheatsave
'#define demo

const as integer syncrate=60

const as integer xres=320, yres=200

osgl_init _osgl_appfullname_ + " (C) Cleber M Casali",xres,yres,syncrate

_osgl_bordertype=-1 'shadow menu borders


const as integer xmax=1000, ymax=1000, ycameraoffset=60

const as integer xtilesize=32, ytilesize=32, ztilesize=64, z0=100

const as integer xprev=6, yprev=3

const as integer xmaxspeed=3

const as single tiltspeed=.25

const as integer tiltmax=6

const as integer spikeframe=20, playerframe=25, enemy1frame=39, ballframe=41, keyframe=42, exitframe=43, heartframe=44, sballframe=45, hitframe=46, sushiframe=47
const as integer score_sushi=5 , score_enemy=10 , score_life=50 , score_color=100 , score_key=100, score_level=500


type tiletype
	
	solid as integer
	
	stairs as integer
	
	tex as integer
	
	colour as uinteger =rgba(255,255,255,255)
	
	blendmode as integer =1
	
	uframe as integer =-1
	dframe as integer =-1
	lframe as integer =-1
	rframe as integer =-1
	bframe as integer =-1
	fframe as integer =-1
	cframe as integer =-1
	sframe as integer =-1
	zsize as integer =ztilesize
	hasshadow as integer=0
	
	uhurt as integer =0
	dhurt as integer =0
	lhurt as integer =0
	rhurt as integer =0
	
	isitem as integer =0
	itemtype as integer =0
	itemvalue as integer =0
	
	tipo as string
	
end type

type maptype
	tile(xmax,ymax) as tiletype
end type

dim shared as maptype map

type playertype
	exist as integer
	x as double
	y as double
	z as double
	xold as double
	yold as double
	dx as double
	dy as double
	yground as double
	ygroundc as double
	xworld as double
	yworld as double
	xwfollow as double
	ywfollow as double
	xwd as double
	ywd as double
	ylook as double
	ylookc as double
	ytilt as double
	
	xinit as integer
	yinit as integer
	
	mode as integer
	tempo as integer
	pose as integer
	side as integer
	angle as integer
	hideshadow as integer
	jump as integer
	roll as integer
	invencible as integer
	
	xaxis as single
	yaxis as single
	jbutton as integer
	
	score as longint
	lives as integer=-999
	sushis as integer
	
	extralives as integer=0
	
	gotitems as string
	
	hiscore as longint
	
end type

dim as playertype p


type screenmessagetype
	text as string
	text2 as string
	colour as colortype
	tempo as integer
	a as integer
end type

dim shared as screenmessagetype screenmessage


sub initplayer(p as playertype)
	p.exist=1
	if p.lives<0 then
		p.lives=beginlives
		p.extralives=0
		p.score=0
	end if
	p.sushis=0
	p.dx=0
	p.dy=0
	p.side=1
	p.jump=0
	p.roll=0
	p.xaxis=0
	p.yaxis=0
	p.jbutton=0
	p.gotitems=""
	screenmessage.text=""
	screenmessage.tempo=0
	screenmessage.a=0
end sub

const as integer maxenemy=200

type enemytype
	exist as integer
	x as double
	y as double
	z as double
	xold as double
	yold as double
	dx as double
	dy as double
	yground as double
	ygroundc as double
	
	xinit as integer
	yinit as integer
	
	mode as integer
	tempo as integer
	pose as integer
	side as integer
	angle as integer
	
	colour as colortype=rgba(255,255,255,255)
	
end type


dim as enemytype e(1 to maxenemy)

dim shared as integer tex_tiles=0, tex_sprites=0, tex_space=0, tex_title=0

dim shared as integer sound_vush, sound_hit, sound_beep, sound_bummer, sound_tru, sound_ball, sound_zeum, sound_life, sound_chpoint


sub loadmedia

'load images
osgl_loadspriteFLC(tex_title,exepath+"/data/title.flc")
osgl_loadspriteFLC(tex_tiles,exepath+"/data/tiles.flc")
osgl_loadtexturepng2(tex_space,exepath+"/data/space.png")

'load sounds
osgl_loadsound(sound_vush,exepath+"/data/vush.wav")
osgl_loadsound(sound_hit,exepath+"/data/hit.wav")
osgl_loadsound(sound_beep,exepath+"/data/beep.wav")
osgl_loadsound(sound_bummer,exepath+"/data/bummer.wav")
osgl_loadsound(sound_tru,exepath+"/data/tru.wav")
osgl_loadsound(sound_ball,exepath+"/data/ball.wav")
osgl_loadsound(sound_zeum,exepath+"/data/zeum.wav")
osgl_loadsound(sound_life,exepath+"/data/life.wav")
osgl_loadsound(sound_chpoint,exepath+"/data/chpoint.wav")

osgl_setmenusounds(sound_tru,sound_beep)

end sub




function gettile(byval x as double, byval y as double) as tiletype
	dim as integer xw, yw
	xw=(x+xtilesize/2)\xtilesize
	osgl_wrap(xw,1,xmax)
	yw=(y+ytilesize/2)\ytilesize
	osgl_wrap(yw,1,ymax)
	function=map.tile(xw,yw)
end function

function char2color(char as string) as uinteger
	select case lcase(char)
		case "r" : function=rgba(255,0,0,255)
		case "o" : function=rgba(255,127,0,255)
		case "y" : function=rgba(255,255,0,255)
		case "g" : function=rgba(0,255,0,255)
		case "b" : function=rgba(0,159,255,255)
		case "d" : function=rgba(0,0,223,255)
		case "p" : function=rgba(255,0,255,255)
		case else : function=rgba(255,255,255,255)
	end select
end function

function char2name(char as string) as string
	select case lcase(char)
		case "r" : function="RED"
		case "o" : function="ORANGE"
		case "y" : function="YELLOW"
		case "g" : function="GREEN"
		case "b" : function="BLUE"
		case "d" : function="DARK BLUE"
		case "p" : function="PURPLE"
		case "k" : function="KEY"
		case else : function="?"
	end select
end function


function getground(byval x as double, byval y as double) as integer
	
	osgl_wrap(x,1,xtilesize*ymax)
	osgl_wrap(y,1,ytilesize*ymax)

'	if x<1 or x>xmax*xtilesize then
'		function=y
'		exit function
'	end if
	
	'x=((x\xtilesize))*xtilesize
	y=((y\ytilesize)+.5)*ytilesize
	'y-=ytilesize
	while gettile(x,y).solid
		'y=((y\ytilesize)-1)*ytilesize
		y-=ytilesize
	wend
	
	if gettile(x,y+ytilesize/2).solid=0 then
		while gettile(x,y+ytilesize/2).solid=0 andalso y<ymax*ytilesize
			y+=ytilesize
		wend
		'y=(y\ytilesize)*ytilesize
	end if
	y-=1
	function=y
end function


dim shared as integer xmax2, ymax2, maxenemy2, textblend, levelclear, gameover, level
dim shared as uinteger heartcolor=rgba(255,255,255,255), shadowcolor=rgba(0,0,0,255), scorecolor=rgba(255,255,255,255)
dim shared as colortype spacecolor=rgba(0,0,0,255), spacecolor2=rgba(0,0,0,127)
dim shared as long timecount
dim as double spacescroll

sub optimizemap(byref map as maptype)
'adjust map
for y as integer=ymax2-1 to 1 step -1
for x as integer=2 to xmax2-1
	select case map.tile(x,y).tipo
	
	case " "
	
	case "'"
		map.tile(x,y).zsize=map.tile(x,y+1).zsize
	
	case "#","%"
		
	case "r","o","y","g","b","d","p" 'color bricks
	'simplify / optimize
	if map.tile(x-1,y).tipo=map.tile(x,y).tipo then map.tile(x,y).lframe=-1
	if map.tile(x,y+1).tipo=map.tile(x,y).tipo then map.tile(x,y).dframe=-1
		
	end select

	'item shadow
	if y<ymax then
	if map.tile(x,y).isitem then
		if map.tile(x,y+1).uframe<>-1 then map.tile(x,y).hasshadow=1
	end if
	end if

	'simplify / optimize
	if map.tile(x,y).solid then
		if map.tile(x-1,y).solid then
		if map.tile(x-1,y).fframe>-1 then
			if map.tile(x,y).zsize=map.tile(x-1,y).zsize then
				map.tile(x,y).lframe=-1
				map.tile(x-1,y).rframe=-1
			end if
			if map.tile(x,y).zsize>map.tile(x-1,y).zsize then map.tile(x-1,y).rframe=-1
			if map.tile(x,y).zsize<map.tile(x-1,y).zsize then map.tile(x,y).lframe=-1
		end if
		end if

		if map.tile(x,y+1).solid then
		if map.tile(x,y+1).fframe>-1 then
			if map.tile(x,y).zsize=map.tile(x,y+1).zsize then
				map.tile(x,y).dframe=-1
				map.tile(x,y+1).uframe=-1
			end if
			if map.tile(x,y).zsize>map.tile(x,y+1).zsize then map.tile(x,y+1).uframe=-1
			if map.tile(x,y).zsize<map.tile(x,y+1).zsize then map.tile(x,y).dframe=-1
		end if
		end if
	end if


next x
next y

end sub


sub loadmap(byval mapfile as string="", byref map as maptype, p as playertype, e() as enemytype)
xmax2=1 : ymax2=1
maxenemy2=0
dim as string mapstring=osgl_LoadString(mapfile)
printdebug mapstring
dim as integer index, eindex
for y as integer=1 to ymax
for x as integer=1 to xmax

index+=1

'defaults
map.tile(x,y).tex=0
map.tile(x,y).uframe=-1
map.tile(x,y).dframe=-1
map.tile(x,y).lframe=-1
map.tile(x,y).rframe=-1
map.tile(x,y).fframe=-1
map.tile(x,y).bframe=-1
map.tile(x,y).cframe=-1
map.tile(x,y).sframe=-1
map.tile(x,y).uhurt=0
map.tile(x,y).dhurt=0
map.tile(x,y).lhurt=0
map.tile(x,y).rhurt=0
map.tile(x,y).solid=0
map.tile(x,y).stairs=0
map.tile(x,y).isitem=0
map.tile(x,y).hasshadow=0
map.tile(x,y).zsize=ztilesize
map.tile(x,y).colour=rgba(255,255,255,255)
map.tile(x,y).blendmode=1

'set
map.tile(x,y).tipo=mid(mapstring, index, 1)

	select case map.tile(x,y).tipo
	
		case "x" 'start point
			map.tile(x,y).tex=0
			map.tile(x,y).uframe=-1
			map.tile(x,y).dframe=-1
			map.tile(x,y).lframe=-1
			map.tile(x,y).rframe=-1
			map.tile(x,y).fframe=-1
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=0
			
			p.xinit=x*xtilesize
			p.yinit=y*ytilesize + ytilesize/2

		case "+" 'start point desmarcado
			map.tile(x,y).tex=0
			map.tile(x,y).uframe=-1
			map.tile(x,y).dframe=-1
			map.tile(x,y).lframe=-1
			map.tile(x,y).rframe=-1
			map.tile(x,y).fframe=-1
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=0
			map.tile(x,y).isitem=1
			
		
	
		case "e" 'enemy
			map.tile(x,y).tex=0
			map.tile(x,y).uframe=-1
			map.tile(x,y).dframe=-1
			map.tile(x,y).lframe=-1
			map.tile(x,y).rframe=-1
			map.tile(x,y).fframe=-1
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=0
			
			eindex+=1
			if eindex<=maxenemy then
				maxenemy2+=1
				e(eindex).exist=1
				e(eindex).x=x*xtilesize
				e(eindex).y=y*ytilesize + ytilesize/2
				e(eindex).yground=e(eindex).y
				e(eindex).xinit=e(eindex).x
				e(eindex).yinit=e(eindex).y
				e(eindex).angle=0
				e(eindex).dx=0
				e(eindex).dy=0
				e(eindex).side=0
				e(eindex).colour.colour=rgba(255,255,255,255)
			end if


		case "s" 'moving spiky ball enemy
			map.tile(x,y).tex=0
			map.tile(x,y).uframe=-1
			map.tile(x,y).dframe=-1
			map.tile(x,y).lframe=-1
			map.tile(x,y).rframe=-1
			map.tile(x,y).fframe=-1
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=0
			
			eindex+=1
			if eindex<=maxenemy then
				maxenemy2+=1
				e(eindex).exist=2
				e(eindex).x=x*xtilesize
				e(eindex).y=y*ytilesize + ytilesize/2
			end if

		case "S" 'moving spiky ball enemy
			map.tile(x,y).tex=0
			map.tile(x,y).uframe=-1
			map.tile(x,y).dframe=-1
			map.tile(x,y).lframe=-1
			map.tile(x,y).rframe=-1
			map.tile(x,y).fframe=-1
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=0
			
			eindex+=1
			if eindex<=maxenemy then
				maxenemy2+=1
				e(eindex).exist=3
				e(eindex).x=x*xtilesize
				e(eindex).y=y*ytilesize + ytilesize/2
			end if
			
			
		case " " 'nothing
			map.tile(x,y).tex=0
			map.tile(x,y).uframe=-1
			map.tile(x,y).dframe=-1
			map.tile(x,y).lframe=-1
			map.tile(x,y).rframe=-1
			map.tile(x,y).fframe=-1
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=0

		case "'" 'back wall
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=-1
			map.tile(x,y).dframe=-1
			map.tile(x,y).lframe=-1
			map.tile(x,y).rframe=-1
			map.tile(x,y).fframe=-1
			map.tile(x,y).bframe=15
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=0
			map.tile(x,y).zsize=ztilesize

		case "." 'score item sushi
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=-1
			map.tile(x,y).dframe=-1
			map.tile(x,y).lframe=-1
			map.tile(x,y).rframe=-1
			map.tile(x,y).fframe=-1
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=sushiframe
			map.tile(x,y).solid=0
			map.tile(x,y).isitem=1
			map.tile(x,y).zsize=ztilesize

		case "=" 'stairs
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=-1
			map.tile(x,y).dframe=-1
			map.tile(x,y).lframe=-1
			map.tile(x,y).rframe=-1
			map.tile(x,y).fframe=-1
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=17
			map.tile(x,y).solid=0
			map.tile(x,y).stairs=1
			map.tile(x,y).zsize=ztilesize

		case "#" 'wall
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=1
			map.tile(x,y).dframe=7
			map.tile(x,y).lframe=7
			map.tile(x,y).rframe=7
			map.tile(x,y).fframe=11
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=1
			map.tile(x,y).zsize=ztilesize

		case "M" 'espinho u
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=-1
			map.tile(x,y).dframe=-1
			map.tile(x,y).lframe=-1
			map.tile(x,y).rframe=-1
			map.tile(x,y).fframe=spikeframe
			map.tile(x,y).bframe=spikeframe
			map.tile(x,y).cframe=spikeframe
			map.tile(x,y).uhurt=1
			map.tile(x,y).solid=1
			map.tile(x,y).zsize=ztilesize/1.5

		case "W" 'espinho d
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=-1
			map.tile(x,y).dframe=-1
			map.tile(x,y).lframe=-1
			map.tile(x,y).rframe=-1
			map.tile(x,y).fframe=spikeframe+1
			map.tile(x,y).bframe=spikeframe+1
			map.tile(x,y).cframe=spikeframe+1
			map.tile(x,y).dhurt=1
			map.tile(x,y).solid=1
			map.tile(x,y).zsize=ztilesize/1.5

		case "E" 'espinho r
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=-1
			map.tile(x,y).dframe=-1
			map.tile(x,y).lframe=-1
			map.tile(x,y).rframe=-1
			map.tile(x,y).fframe=spikeframe+3
			map.tile(x,y).bframe=spikeframe+3
			map.tile(x,y).cframe=spikeframe+3
			map.tile(x,y).rhurt=1
			map.tile(x,y).solid=1
			map.tile(x,y).zsize=ztilesize/1.5

		case "3" 'espinho l
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=-1
			map.tile(x,y).dframe=-1
			map.tile(x,y).lframe=-1
			map.tile(x,y).rframe=-1
			map.tile(x,y).fframe=spikeframe+2
			map.tile(x,y).bframe=spikeframe+2
			map.tile(x,y).cframe=spikeframe+2
			map.tile(x,y).lhurt=1
			map.tile(x,y).solid=1
			map.tile(x,y).zsize=ztilesize/1.5

		case "*" 'spiky ball
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=-1
			map.tile(x,y).dframe=-1
			map.tile(x,y).lframe=-1
			map.tile(x,y).rframe=-1
			map.tile(x,y).fframe=-1
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).sframe=sballframe
			map.tile(x,y).lhurt=1
			map.tile(x,y).rhurt=1
			map.tile(x,y).uhurt=1
			map.tile(x,y).dhurt=1
			map.tile(x,y).solid=0
			map.tile(x,y).zsize=ztilesize/1.5

		case "m" 'extra life
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).cframe=heartframe
			map.tile(x,y).colour=heartcolor
			map.tile(x,y).solid=0
			map.tile(x,y).isitem=1

		case "R" 'RED
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).cframe=ballframe
			map.tile(x,y).colour=osgl_setalpha(char2color(lcase(map.tile(x,y).tipo)),127)
			map.tile(x,y).solid=0
			map.tile(x,y).isitem=1
		case "O" 'ORANGE
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).cframe=ballframe
			map.tile(x,y).colour=osgl_setalpha(char2color(lcase(map.tile(x,y).tipo)),127)
			map.tile(x,y).solid=0
			map.tile(x,y).isitem=1
		case "Y" 'YELLOW
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).cframe=ballframe
			map.tile(x,y).colour=osgl_setalpha(char2color(lcase(map.tile(x,y).tipo)),127)
			map.tile(x,y).solid=0
			map.tile(x,y).isitem=1
		case "G" 'GREEN
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).cframe=ballframe
			map.tile(x,y).colour=osgl_setalpha(char2color(lcase(map.tile(x,y).tipo)),127)
			map.tile(x,y).solid=0
			map.tile(x,y).isitem=1
		case "B" 'BLUE
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).cframe=ballframe
			map.tile(x,y).colour=osgl_setalpha(char2color(lcase(map.tile(x,y).tipo)),127)
			map.tile(x,y).solid=0
			map.tile(x,y).isitem=1
		case "D" 'DARK BLUE
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).cframe=ballframe
			map.tile(x,y).colour=osgl_setalpha(char2color(lcase(map.tile(x,y).tipo)),127)
			map.tile(x,y).solid=0
			map.tile(x,y).isitem=1
			
		case "P" 'PINK PURPLE
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).cframe=ballframe
			map.tile(x,y).colour=osgl_setalpha(char2color(lcase(map.tile(x,y).tipo)),127)
			map.tile(x,y).solid=0
			map.tile(x,y).isitem=1

		case "K" 'KEY
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).cframe=keyframe
			map.tile(x,y).colour=rgba(255,255,255,255)
			map.tile(x,y).solid=0
			map.tile(x,y).isitem=1
			

		case "r" 'red
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=18
			map.tile(x,y).dframe=18
			map.tile(x,y).lframe=18
			map.tile(x,y).rframe=18
			map.tile(x,y).fframe=18
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=0
			map.tile(x,y).colour=char2color(lcase(map.tile(x,y).tipo))
			map.tile(x,y).zsize=ztilesize

		case "g" 'green
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=18
			map.tile(x,y).dframe=18
			map.tile(x,y).lframe=18
			map.tile(x,y).rframe=18
			map.tile(x,y).fframe=18
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=0
			map.tile(x,y).colour=char2color(lcase(map.tile(x,y).tipo))
			map.tile(x,y).zsize=ztilesize

		case "b" 'bright blue
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=18
			map.tile(x,y).dframe=18
			map.tile(x,y).lframe=18
			map.tile(x,y).rframe=18
			map.tile(x,y).fframe=18
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=0
			map.tile(x,y).colour=char2color(lcase(map.tile(x,y).tipo))
			map.tile(x,y).zsize=ztilesize

		case "d" 'dark blue
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=18
			map.tile(x,y).dframe=18
			map.tile(x,y).lframe=18
			map.tile(x,y).rframe=18
			map.tile(x,y).fframe=18
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=0
			map.tile(x,y).colour=char2color(lcase(map.tile(x,y).tipo))
			map.tile(x,y).zsize=ztilesize

		case "y" 'yellow
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=18
			map.tile(x,y).dframe=18
			map.tile(x,y).lframe=18
			map.tile(x,y).rframe=18
			map.tile(x,y).fframe=18
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=0
			map.tile(x,y).colour=char2color(lcase(map.tile(x,y).tipo))
			map.tile(x,y).zsize=ztilesize

		case "p" 'pink purple
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=18
			map.tile(x,y).dframe=18
			map.tile(x,y).lframe=18
			map.tile(x,y).rframe=18
			map.tile(x,y).fframe=18
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=0
			map.tile(x,y).colour=char2color(lcase(map.tile(x,y).tipo))
			map.tile(x,y).zsize=ztilesize

		case "o" 'orange
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=18
			map.tile(x,y).dframe=18
			map.tile(x,y).lframe=18
			map.tile(x,y).rframe=18
			map.tile(x,y).fframe=18
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=0
			map.tile(x,y).colour=char2color(lcase(map.tile(x,y).tipo))
			map.tile(x,y).zsize=ztilesize

		case "k" 'exit
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=-1
			map.tile(x,y).dframe=-1
			map.tile(x,y).lframe=-1
			map.tile(x,y).rframe=-1
			map.tile(x,y).fframe=-1
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=0
			map.tile(x,y).colour=rgba(255,255,255,255)
			map.tile(x,y).zsize=ztilesize

		case "%" 'bigger wall
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=1
			map.tile(x,y).dframe=7
			map.tile(x,y).lframe=7
			map.tile(x,y).rframe=7
			map.tile(x,y).fframe=11
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=1
			map.tile(x,y).zsize=2*ztilesize

		case "H" 'wall variation
			map.tile(x,y).tex=tex_tiles
			map.tile(x,y).uframe=1
			map.tile(x,y).dframe=7
			map.tile(x,y).lframe=7
			map.tile(x,y).rframe=7
			map.tile(x,y).fframe=13
			map.tile(x,y).bframe=-1
			map.tile(x,y).cframe=-1
			map.tile(x,y).solid=1
			map.tile(x,y).zsize=ztilesize
		
		case CR
			x=xmax
			if xmax2<xmax then xmax2=xmax
			ymax2+=1
			index+=1

		case LF
			x=xmax
			if xmax2<xmax then xmax2=xmax
			ymax2+=1
			
		
	end select
	'map.tile(x,y).solid=

	if y>1 then
		if map.tile(x,y-1).tipo="x" then
			map.tile(x,y).uframe=2 'marcado
		end if

		if map.tile(x,y-1).tipo="+" then
			map.tile(x,y).uframe=3 'nao marcado
		end if
	end if

	'some tile variations
	if map.tile(x,y).fframe=11 then
		if rnd<.05 then map.tile(x,y).fframe=12
		if rnd<.05 then map.tile(x,y).fframe=10
	end if
	
	if map.tile(x,y).uframe=1 then
		if rnd<.05 then map.tile(x,y).uframe=4
		if rnd<.05 then map.tile(x,y).uframe=0
	end if

next x
next y

optimizemap(map)

'position player
p.yinit=getground(p.xinit,p.yinit)
p.yground=p.yinit
p.x=p.xinit
p.y=p.yinit

'position camera
p.xworld=p.x
p.yworld=p.y-180
p.xwfollow=p.xworld
p.ywfollow=p.yworld
p.ygroundc=p.yworld

end sub



sub drawblock(byval x as integer,byval y as integer,byval z as integer,byval tile as tiletype, byval xw as integer)

if tile.tex=0 then exit sub

const as integer depthtest=1
const as double rep=1
dim as double x1=x-xtilesize/2
dim as double x2=x+xtilesize/2
dim as double y1=y-ytilesize/2
dim as double y2=y+ytilesize/2
dim as double z1=z+tile.zsize/2+z0
dim as double z2=z-tile.zsize/2+z0


'back
if tile.bframe<>-1 then
osgl_3dquad ( x1, y1, z1,   x2, y1, z1,   x2, y2, z1,    x1, y2, z1,_
			tile.tex,tile.bframe,_
			0,0,_
			rep,rep,0,0,_
			tile.blendmode,depthtest,_
			tile.colour)

end if

'sframe
if tile.sframe<>-1 then
osgl_render(x, y, 0, 0, z+z0, tile.tex,tile.sframe,_
			0, 1, 1, 0,0, 1,1, 0,0, 1,1, 0,0, 1, 1, rgba(255,255,255,255), -1)
end if


'center
if tile.cframe<>-1 then
dim as single pulse=0, pulse2=0
if tile.isitem then
if tile.tipo<>"k" then

	pulse=-4-sin(radians(10*timecount)+xw*PI_2) 'pulsação
	if tile.tipo="." or tile.tipo="K" then pulse=-4

	pulse2=6-cos(radians(5*timecount)+xw*PI_2) 'altura

	if tile.hasshadow then
		'item shadow
		osgl_3dquad ( x1 -pulse, y2-1, z0-8,   x2+pulse, y2-1, z0-8,   x2+pulse, y2-1, z0+8,  x1-pulse, y2-1, z0+8, _
			tile.tex,tile.cframe,_
			0,0,_
			rep,rep,0,0,_
			tile.blendmode,depthtest,_
			shadowcolor)
	end if

end if
end if

osgl_3dquad ( x1 - pulse, y1 -pulse -pulse2, z0+1,   x2 + pulse, y1 -pulse -pulse2, z0+1,   x2 +pulse, y2 +pulse -pulse2, z0+1,    x1 -pulse, y2 +pulse -pulse2, z0+1,_
			tile.tex,tile.cframe,_
			0,0,_
			rep,rep,0,0,_
			tile.blendmode,depthtest,_
			tile.colour)


end if

'top
if tile.uframe<>-1 then
if tile.solid=0 or y1>0 then
osgl_3dquad (  x2, y1, z1,   x1, y1, z1,   x1, y1, z2,  x2, y1, z2, _
			tile.tex,tile.uframe,_
			0,0,_
			rep,rep,0,0,_
			tile.blendmode,depthtest,_
			tile.colour)
end if
end if

'bottom
if tile.dframe<>-1 then
if tile.solid=0 or y1<0 then
osgl_3dquad ( x2, y2, z1,   x1, y2, z1,   x1, y2, z2,  x2, y2, z2, _
			tile.tex,tile.dframe,_
			0,0,_
			rep,rep,0,0,_
			tile.blendmode,depthtest,_
			tile.colour)
end if
end if

'left
if tile.lframe<>-1 then
if tile.solid=0 or x1>0 then
osgl_3dquad (  x1, y2, z1,   x1, y1, z1,   x1, y1, z2,   x1, y2, z2,_
			tile.tex,tile.lframe,_
			0,0,_
			rep,rep,0,0,_
			tile.blendmode,depthtest,_
			tile.colour)
end if
end if

'right
if tile.rframe<>-1 then
if tile.solid=0 or x2<0 then
osgl_3dquad (  x2, y1, z1,   x2, y2, z1,  x2, y2, z2,   x2, y1, z2, _
			tile.tex,tile.rframe,_
			0,0,_
			rep,rep,0,0,_
			tile.blendmode,depthtest,_
			tile.colour)
end if
end if

'front
if tile.fframe<>-1 then
osgl_3dquad ( x1, y1, z2,   x2, y1, z2,   x2, y2, z2,    x1, y2, z2,_
			tile.tex,tile.fframe,_
			0,0,_
			rep,rep,0,0,_
			tile.blendmode,depthtest,_
			tile.colour)

end if

end sub




sub drawmap(byval x as double, byval y as double)
dim as integer xw, yw
dim as double xrest=-x mod xtilesize
dim as double yrest=-y mod ytilesize
for y1 as integer=yprev+cint((yres/2)/ytilesize) to -yprev-cint((yres/2)/ytilesize) step -1
for x1 as integer=-xprev-cint((xres/2)/xtilesize) to xprev+cint((xres/2)/xtilesize)
	xw=x1+x\xtilesize
	osgl_wrap(xw,1,xmax)
	yw=y1+y\ytilesize
	osgl_wrap(yw,1,ymax)
	if map.tile(xw,yw).tex then
		drawblock (x1*xtilesize+xrest, y1*ytilesize+yrest, 0, map.tile(xw,yw), xw)
	end if
next x1
next y1
end sub


#macro handle_screenmessage()
if screenmessage.tempo>0 then
	screenmessage.tempo-=1
	screenmessage.a+=20
	if screenmessage.tempo<50 then
		screenmessage.a-=40
	end if
	osgl_range(screenmessage.a,0,255)
	screenmessage.colour.a=screenmessage.a
	osgl_print 0,-5,0, screenmessage.text ,0.75*screenmessage.colour.a/255,0.75*screenmessage.colour.a/255,1,1, screenmessage.colour.colour
	osgl_print 0,-5,0, screenmessage.text2 ,0.75*screenmessage.colour.a/255,0.75*screenmessage.colour.a/255,1,1, rgba(255,255,255,255)
end if
#endmacro

#macro set_screenmessage(txt1,txt2,cor1,tempo1)
	screenmessage.text=txt1+space(len(txt2))
	screenmessage.text2=space(len(txt1))+txt2
	screenmessage.colour.colour=cor1
	screenmessage.tempo=tempo1
#endmacro




sub moveplayer(byref p as playertype)

p.xold=p.x
p.yold=p.y

if p.invencible then p.invencible-=1
	
select case p.mode

case -99 'free move (debug)

	p.x+=5*p.xaxis
	p.y+=5*p.yaxis
	p.yground=p.y
	p.hideshadow=1
	if p.lives<0 then p.lives=0
	p.tempo=0

case -3	'morre die

	osgl_joyrumble(1,100,100,800)
	osgl_playsound3d(sound_bummer,p.x-p.xworld,p.y-p.yworld,z0,1)
	set_screenmessage("OUCH!!!", "", heartcolor, 120)
	p.lives-=1
	p.tempo=0

	p.mode=-2

	p.hideshadow=1
	
	p.ygroundc=p.y


case -2 'pisca blink

	p.pose=11
	
	p.tempo+=1

	p.hideshadow=1
	
	if sin(radians(40*p.tempo))<0 then p.pose=-1
	
	if p.tempo>120 then
		p.tempo=0
		p.mode=-1
		if p.lives<0 then gameover=1
		p.pose=0
	end if
	
	

case -1 'return to init volta

	p.angle-=10
	
	p.pose=8
	
	if sin(radians(4*p.angle))<0 then p.pose=-1
	
	
	'p.angle=0
	
	if abs(p.x-p.xinit)>500 then p.x-=20*sgn(p.x-p.xinit)
	if abs(p.y-p.yinit)>500 then p.y-=20*sgn(p.y-p.yinit)

	if abs(p.x-p.xinit)>60 then p.x-=6*sgn(p.x-p.xinit)
	if abs(p.y-p.yinit)>60 then p.y-=6*sgn(p.y-p.yinit)

	if abs(p.x-p.xinit)>3 then p.x-=3*sgn(p.x-p.xinit) else p.x=p.xinit
	if abs(p.y-p.yinit)>3 then p.y-=3*sgn(p.y-p.yinit) else p.y=p.yinit
	
	p.yground=p.y
	p.ygroundc=p.y
	
	if p.x=p.xinit then
	if p.y=p.yinit then
		p.yground=getground(p.x,p.y)
		'p.y=p.yground
		p.dx=0
		p.dy=0
		p.mode=0
		p.invencible=60
		p.pose=0
		p.tempo=0
		osgl_joyrumble(1,0,40,300)
	end if
	end if
		

case 0 'walk / jump

	p.hideshadow=0

		select case as const p.tempo
			case 0 to 50 : p.pose=0
			case 51 to 100 : p.pose=1
			case 101 to 150 : p.pose=0
			case 151 to 200 : p.pose=2
			case else : p.tempo=0
		end select

	if abs(p.xaxis)>.1 then
		if p.y=p.yground then p.side=sgn(p.xaxis)
		if sgn(p.xaxis)=-sgn(p.dx) then p.dx=.9*p.dx 'derrapa
		p.dx+=p.xaxis*.05
		osgl_range(p.dx,-xmaxspeed,xmaxspeed)
		p.x+=2*p.xaxis
		p.tempo+=(6+2*abs(p.dx))
	else
		if p.roll=0 then
			p.dx=.93*p.dx 'inercia
		else
			p.dx=.95*p.dx 'inercia rolada
		end if
		if abs(p.dx)<.05 then
			p.dx=0 'para de vez
			p.pose=0
			p.tempo=60
		else
			p.tempo+=6
		end if
	end if
	
	p.x+=p.dx 'velocidade

	if gettile(p.x+(sgn(p.side)*xtilesize/4),p.y-ytilesize/2+1).solid or gettile(p.x-(sgn(p.side)*xtilesize/4),p.y-ytilesize/2+1).solid then 'side wall
		if gettile(p.x-xtilesize/4,p.y).rhurt then
			p.x-=4 : p.mode=-3 'espinho
			goto endpmodes
		end if
		if gettile(p.x+xtilesize/4,p.y).lhurt then
			p.x+=4 : p.mode=-3 'espinho
			goto endpmodes
		end if
		p.dx=0
		p.x=p.xold
	end if

	p.yground=getground(p.x,p.y)

	if abs(p.y-p.yground)>ytilesize/2 then 'desagarra no pulo
		if gettile(p.x,p.y-ytilesize/2+1).solid then p.y+=ytilesize/2 : p.dy=0
	end if
	
	if p.roll=0 andalso p.y<p.yground then
		'cai
		osgl_playsound3d(sound_vush,p.x-p.xworld,p.y-p.yworld,z0,1)
		p.jump=1
		p.roll=1
	end if

	if p.y>=p.yground then 'chao
	
		p.y=p.yground
		p.dy=0
	
		if p.jump then
			'step ground
			osgl_playsound3d(sound_tru,p.x-p.xworld,p.y-p.yworld,z0)
			p.jump=0
			if gettile(p.x,p.y+1).uhurt then
				p.y+=8 : p.yground+=8 : p.mode=-3 'espinho chão
				goto endpmodes
			end if
		else
			if abs(p.dx)<xmaxspeed then 'passa direto nos espinhos se correr
				if gettile(p.x,p.y+1).uhurt then
					p.y+=8 : p.yground+=8 :  p.mode=-3 'espinho chão
					goto endpmodes
				end if
			end if
		end if


		'look
		if abs(p.xaxis)<.1 then
			if p.jbutton=0 then
			if p.yaxis<-.1 then
				if gettile(p.x,p.y-ytilesize/2).stairs then 'climb
					p.y-=2
					p.mode=1
					p.tempo=0
				else
					if p.angle=0 then
						p.pose=4 'look up
						p.ylook-=2
					end if
				end if
			end if
			end if
			if p.yaxis>.1 then
				if abs(p.dx)<1.5 then
					p.pose=3 'abaixa
					p.ylook+=2
				else
					'rola
					if p.angle=0 then
						p.side=sgn(p.dx)
						p.angle=p.side*25
						if sgn(p.xaxis)=sgn(p.side) or abs(p.xaxis)<.1 then
							p.dx=1.6*p.dx
							osgl_playsound3d(sound_vush,p.x-p.xworld,p.y-p.yworld,z0,1)
						end if
					end if
				end if
			end if
		else
			p.yaxis=0
		end if
		
		if abs(p.yaxis)<.1 then 'volta ylook
			p.ylook=.8*p.ylook
			if abs(p.ylook)<1 then p.ylook=0
		end if
		
		osgl_range(p.ylook,-yprev*ytilesize,1.5*yprev*ytilesize) 'limites do ylook
	
		if p.jbutton=1 then
			p.jump=1
			p.roll=1
			osgl_playsound3d(sound_vush,p.x-p.xworld,p.y-p.yworld,z0,1)
			p.y-=1
			p.dy=-9-int(abs(p.dx/3))
			p.pose=3
		end if
		
		if abs(p.angle)>15 then
			if abs(p.angle)>90 then p.pose=8 else p.pose=2
			
				if abs(p.dx)>.2 then
					p.angle+=20*p.side
					p.roll=1
				else
					p.angle=.8*p.angle
				end if
				
				osgl_wrap(p.angle,-180,180)
				
				if abs(p.angle)<30 then
					p.angle=0
					p.roll=0
					p.pose=2
					p.tempo=30
				else
					p.roll=1
				end if
				
		else
			p.angle=0
		end if
		
	else
		
		'p.pose=5*rnd
		p.angle+=20*p.side
		p.roll=1
		osgl_wrap(p.angle,-180,180)
		
		'look
		p.ylook=.8*p.ylook
		if abs(p.ylook)<1 then p.ylook=0
	
		'jump/fall
		if p.y<p.yground then
			p.dy+=.5
			osgl_range(p.dy,-ytilesize/2,ytilesize/2)
			p.y+=p.dy
			
			if p.jbutton=0 then 'cai mais rápido se soltar o botão
			if p.dy<0 then
				p.dy+=.5
			end if
			end if

			if gettile(p.x,p.y-ytilesize/1.5-1).dhurt then
				p.y-=5 : p.mode=-3 'espinho up
				goto endpmodes
			else
				if gettile(p.x,p.y-ytilesize/1.5-1).solid then 'teto ceiling
					p.y=p.yold+1
					p.dy=.5
				end if
			end if
			
			if p.jbutton=0 or p.dy>=0 then
			if gettile(p.x,p.y-ytilesize/2).stairs then 'climb
				if abs(p.yaxis)>.1 then
					p.mode=1
					p.tempo=0
				end if
			end if
			end if

			select case p.dx
			case is <0
				if gettile(p.x-xtilesize/4,p.y-ytilesize/2+1).rhurt then
					p.x-=4 : p.mode=-3 'espinho
					goto endpmodes
				end if
			
			case is >0
				if gettile(p.x+xtilesize/4,p.y-ytilesize/2+1).lhurt then
					p.x+=4 : p.mode=-3 'espinho
					goto endpmodes
				end if
			end select

			if gettile(p.x-xtilesize/4,p.y-ytilesize/2+1).solid then p.x+=xtilesize/4 'side wall
			if gettile(p.x+xtilesize/4,p.y-ytilesize/2+1).solid then p.x-=xtilesize/4 'side wall
			
		
		end if
		
		if gettile(p.x,p.y).solid then 'chao
			p.yground=getground(p.x,p.y)
			p.y=p.yground
			p.dy=0
		end if
		
	end if

case 1 'stairs  ladder

	p.angle=0
	p.roll=0
	p.dx=0
	p.ylook=0
	p.hideshadow=1
	p.ygroundc=p.y+ycameraoffset/2+p.yaxis*ycameraoffset/2
	
	if abs(p.xaxis)>.1 then
		p.x+=2*p.xaxis 'anda de lado na escada
		p.side=sgn(p.xaxis)
		p.yground=getground(p.x,p.y) 'acha o chão
	end if
	
	if gettile(p.x+(sgn(p.side)*xtilesize/4),p.y-ytilesize/2).solid then 'side wall
		p.x=p.xold
	end if

	if gettile(p.x+(sgn(p.side)*xtilesize/4),p.y-ytilesize/2).solid then 'side wall
		p.x-=p.side
	end if

	if gettile(p.x-(sgn(p.side)*xtilesize/4),p.y-ytilesize/2).solid then 'side wall
		p.x+=p.side
	end if

	if abs(p.yaxis)>.1 then
		p.y+=2*p.yaxis
		if p.yaxis<-.1 then
		if gettile(p.x,p.y-ytilesize-1).solid then
			p.y=p.yold
		end if
		end if
	end if
	
	if abs(p.yaxis)>.1 or abs(p.xaxis)>.1 then
		p.tempo+=10
		select case as const p.tempo
			case 0 to 50 : p.pose=5
			case 51 to 100 : p.pose=6
			case 101 to 150 : p.pose=5
			case 151 to 200 : p.pose=7
			case else : p.tempo=0
		end select

	end if

	if p.jbutton=1 or gettile(p.x,p.y-ytilesize/2).stairs=0 or gettile(p.x,p.y+1).solid then 'pula da escada
		osgl_playsound3d(sound_vush,p.x-p.xworld,p.y-p.yworld,z0,1)
		p.mode=0
		p.roll=1
		p.jump=1
		p.yground=getground(p.x,p.y)
		if p.y>=p.yground then
			p.dy=0
			p.y=p.yground
			p.angle=25*sgn(p.xaxis)
			p.dx=.4*sgn(p.xaxis)
		else
			if p.yaxis<-.1 then p.dy=-8 else p.dy=0
		end if
	end if

end select

endpmodes:

osgl_wrap(p.x,1,xtilesize*xmax)
osgl_wrap(p.y,1,ytilesize*ymax)

end sub


sub drawplayer(byref p as playertype)
if p.pose=-1 then exit sub

'player shadow
dim as integer mir=0
if p.side=-1 then mir=1

if p.hideshadow=0 then
	osgl_sprite(	p.x,p.yground-.1,z0-4,_ 'shadow
				tex_tiles,playerframe+p.pose,,_
 				-p.angle-5,1.0,1.0,1.0,0.1,_
				mir,0,_
				0,0,_
				1,1,_
				shadowcolor, 4)
end if

osgl_sprite(	p.x,p.y,z0-2,_
				tex_tiles,playerframe+p.pose,,_
				p.angle,1.0,1.0,1.0,1.0,_
				mir,0,_
				0,-ytilesize/2+1,_
				1,1,_
				rgba(255,255,255,255), -1)

end sub



sub moveenemy(byref ee as enemytype, byref p as playertype)

select case as const ee.exist

case 0
	exit sub

case 1 'robot
	
	ee.xold=ee.x
	ee.yold=ee.y

	if ee.side=0 then
		if p.x>ee.x then ee.side=1 else ee.side=-1
		
			if len(p.gotitems) then 'change enemy color
			
				if rnd<.4 then
					ee.colour.colour = rgba(255,255,255,255)
				else
					ee.dx=int(rnd*(len(p.gotitems)+1))
					ee.colour.colour =  char2color( mid(p.gotitems,1+ee.dx,1) )
				end if
				
				if ee.colour.colour=rgba(255,255,255,255) then ee.dx=0

			end if

	end if
	
	ee.x+=(.5+.1*ee.dx)*ee.side + .1*rnd
	
	ee.tempo+=1
	
	if ee.tempo>3 then
		ee.tempo=0
		if ee.pose=0 then ee.pose=1 else ee.pose=0
	end if

	if gettile(ee.x+(sgn(ee.side)*xtilesize/2),ee.y-ytilesize/2+1).fframe<>-1  or  gettile(ee.x+(sgn(ee.side)*xtilesize/4),ee.y+1).solid=0  then 'side wall or hole
		ee.x=ee.xold
		if gettile(ee.x-(sgn(ee.side)*xtilesize/2),ee.y-ytilesize/2+1).fframe<>-1 then 'se ficar cercado, muda de posição
			ee.x-=ee.side*xtilesize/2
		else
			ee.side=-ee.side
		end if
	end if
	
	ee.y=getground(ee.x,ee.y)
	ee.yground=ee.y


case 2 'spiky ball U/D

	ee.yold=ee.y

	if ee.dy=0 then ee.dy=-1
	
	ee.angle+=ee.dy*5
	
	osgl_wrap(ee.angle,0,359)
	
	ee.dy=1.05*ee.dy
	
	osgl_range(ee.dy,-ytilesize/3,ytilesize/3)
	
	ee.y+=ee.dy
	
	ee.pose=0

	if gettile(ee.x,ee.y-ytilesize).fframe>-1 then
		if abs(p.x-ee.x)<300 andalso abs(p.y-ee.y)<200 then
			osgl_playsound3d(sound_ball,ee.x-p.xworld,ee.y-p.yworld,z0+500)
		end if
		ee.dy=1 : ee.y=ee.yold
	end if

	if gettile(ee.x,ee.y-2).fframe>-1 then
		if abs(p.x-ee.x)<300 andalso abs(p.y-ee.y)<200 then
			osgl_playsound3d(sound_ball,ee.x-p.xworld,ee.y-p.yworld,z0+500)
		end if
		ee.dy=-1 : ee.y=ee.yold
	end if

case 3 'spiky ball L/R

	ee.xold=ee.x

	if ee.dx=0 then ee.dx=-1
	
	ee.angle+=ee.dx*2.5
	
	osgl_wrap(ee.angle,0,359)
	
	ee.dx=1.04*ee.dx
	
	osgl_range(ee.dx,-xtilesize/3,xtilesize/3)
	
	ee.x+=ee.dx
	
	ee.pose=0

	if gettile(ee.x-xtilesize/3,ee.y-ytilesize/2).fframe>-1 then
		if abs(p.x-ee.x)<300 andalso abs(p.y-ee.y)<200 then
			osgl_playsound3d(sound_ball,ee.x-p.xworld,ee.y-p.yworld,z0+500)
		end if
		ee.dx=1 : ee.x=ee.xold
	end if

	if gettile(ee.x+xtilesize/3,ee.y-ytilesize/2).fframe>-1 then
		if abs(p.x-ee.x)<300 andalso abs(p.y-ee.y)<200 then
			osgl_playsound3d(sound_ball,ee.x-p.xworld,ee.y-p.yworld,z0+500)
		end if
		ee.dx=-1 : ee.x=ee.xold
	end if


end select

osgl_wrap(ee.x,1,xtilesize*xmax)
osgl_wrap(ee.y,1,ytilesize*ymax)
	
end sub



sub drawenemy(byref ee as enemytype)

select case as const ee.exist

case 0 'null
	exit sub

	case 1 'robot

dim as integer mir=0
if ee.side=-1 then mir=1

osgl_sprite(	ee.x+1,ee.yground-.1,z0-8,_ 'shadow
				tex_tiles,enemy1frame+ee.pose,,_
				-ee.angle-5,1.0,0.1,1.0,0.02,_
				mir,0,_
				0,0,_
				1,1,_
				shadowcolor, 4)

osgl_sprite(	ee.x,ee.y,z0-2,_
				tex_tiles,enemy1frame+ee.pose,,_
				ee.angle,1.0,1.0,1.0,1.0,_
				mir,0,_
				0,-ytilesize/2+1,_
				1,1,_
				ee.colour.colour, -1)
				
case 2, 3 'sball

osgl_sprite(	ee.x,ee.y,z0-2,_
				tex_tiles,sballframe,,_
				ee.angle,1.0,1.0,1.0,1.0,_
				0,0,_
				0,-ytilesize/2+1,_
				1,1,_
				rgba(255,255,255,255), -1)
				
end select

end sub




#macro color_explode(x,y,r,g,b)

								osgl_particle(    x, y-6, z0-5,_
								tex_tiles,_
								0.001,0.001,1.5,1.5,_
								ballframe, ballframe, 400,_
								0, 0, 0, 0, ,_
								rnd*360, 20,_
								0, 0,_
								3,_
								r,g,b,255, 7)

#endmacro


#macro red_explode(x,y)
if instr(p.gotitems,"R") then
								osgl_particle(    x, y-6, z0-5,_
								tex_tiles,_
								0.001,0.001,0.25,0.25,_
								ballframe, ballframe, 30,_
								0, 0, 0, 0, ,_
								rnd*360, 20,_
								0, 0,_
								3,_
								255,0,0,255, 15)
else
								osgl_particle(    x, y-6, z0-5,_
								tex_tiles,_
								0.01,0.01,0.05,0.05,_
								ballframe, ballframe, 16,_
								0, 0, 0, 0, ,_
								rnd*360, 20,_
								0, 0,_
								1,_
								255,255,255,255, 0)
end if
#endmacro


#macro item_explode(x,y)
if len(p.gotitems)>0 then
								osgl_particle(    x, y-6, z0-5,_
								tex_tiles,_
								0.01,0.01,0.05,0.05,_
								ballframe, ballframe, 24,_
								0, 0, 0, 0, ,_
								rnd*360, 20,_
								0, 0,_
								3,_
								255,255,255,255, 15)

else
								osgl_particle(    x, y-6, z0-5,_
								tex_tiles,_
								0.01,0.01,0.05,0.05,_
								ballframe, ballframe, 16,_
								0, 0, 0, 0, ,_
								rnd*360, 20,_
								0, 0,_
								1,_
								255,255,255,255, 0)
								
end if
#endmacro


#macro enemy_fall(x,y,eside,r,g,b)
								osgl_particle(    x, y-ytilesize/2, z0-5,_
								tex_tiles,_
								1.0,1.0,0.01,0.01,_
								enemy1frame, enemy1frame, 120,_
								p.dx+p.xaxis+p.side, -5, 0, .5, ,_
								0, p.side+p.dx,_
								iif(eside=1,0,1), 0,_
								1,_
								r,g,b,255, 0)

#endmacro


#macro white_explode(x,y)

if len(p.gotitems)>0 then
								osgl_particle(    x, y-ytilesize/2, z0-5,_
								tex_tiles,_
								0.1,0.1,0.15,0.15,_
								hitframe, hitframe, 15,_
								0, 0, 0, 0, ,_
								0, 3,_
								0, 0,_
								3,_
								255,255,255,255, 5)


								osgl_particle(    x, y-ytilesize/2, z0-5,_
								tex_tiles,_
								0.1,0.1,0.25,0.25,_
								ballframe, ballframe, 20,_
								0, 0, 0, 0, ,_
								rnd*360, 20,_
								0, 0,_
								3,_
								spacecolor.r,spacecolor.g/2,0,255, 15)
else

								osgl_particle(    x, y-ytilesize/2, z0-5,_
								tex_tiles,_
								0.1,0.1,0.15,0.15,_
								hitframe, hitframe, 15,_
								0, 0, 0, 0, ,_
								0, 3,_
								0, 0,_
								1,_
								255,255,255,255, 0)

end if

#endmacro


#macro white_particles(x,y,num)
scope
dim as integer gnd=getground(x,y)
	for mm as integer=1 to num
								osgl_particle(    x+(3-6*rnd), y+(-8*rnd), z0-4,_
								tex_tiles,_
								0.1,0.1,-0.0022,-0.0022,_
								ballframe, ballframe, 260,_
								3*rnd-3*rnd, -4-1*rnd, 0, .3*rnd+.2,gnd,_
								0, 0,_
								0, 0,_
								1,_
								255,255,255,255, 0)
	next mm
end scope
#endmacro


#macro white_particles2(x,y,num)
scope
dim as integer gnd=getground(x,y)
	for mm as integer=1 to num
								osgl_particle(    x+(3-6*rnd), y+(-8*rnd), z0-4,_
								tex_tiles,_
								0.05,0.05,-0.001,-0.001,_
								ballframe, ballframe, 260,_
								3*rnd-3*rnd, -2-1*rnd, 0, .1*rnd+.2,gnd,_
								0, 0,_
								0, 0,_
								1,_
								255,255,255,255, 0)
	next mm
end scope
#endmacro

const as long extralifepoints=5000


#macro gotscore(n)
scope
	p.score+=n
	if p.score>p.hiscore then p.hiscore=p.score
	'extra life every extralifepoints
	if p.score\extralifepoints>p.extralives then
		set_screenmessage("1UP", "", rgba(255,255,255,255), 120)
		osgl_playsound3d(sound_life,p.x-p.xworld,p.y-p.yworld,z0)
		p.lives+=1
		p.extralives+=1
	end if
end scope
#endmacro


sub checkcollision(p as playertype, e() as enemytype)

if p.mode<0 then exit sub

for i as integer=1 to maxenemy2
if e(i).exist then

if distance(p.x,p.y-ytilesize/2,e(i).x+(xtilesize/2)*e(i).side,e(i).y-ytilesize/2)<5 then
	if p.invencible=0 then
		'hit player (robot arm)
		p.mode=-3
		i=maxenemy 'sai do for
	end if
else

	dim as integer eradius=ytilesize/2
	if e(i).exist>1 then eradius=.75*ytilesize

	if distance(p.x,p.y-ytilesize/2,e(i).x,e(i).y-ytilesize/2)<eradius then
		if (p.y<>p.yground or p.roll) andalso e(i).exist<2 then
		
			'hit enemy
			osgl_joyrumble(1,30,30,150)
			osgl_playsound3d(sound_hit,e(i).x-p.xworld,e(i).y-p.yworld,z0)
			gotscore(score_enemy)
			enemy_fall(e(i).x,e(i).y,e(i).side, e(i).colour.r,e(i).colour.g,e(i).colour.b)
			white_explode((e(i).x+p.x)/2,(e(i).y+p.y)/2)
			white_particles(e(i).x,e(i).y,8)

			if p.jump then
				p.dy=-6-abs(p.dy/3)
				p.y+=p.dy
			else
				p.roll=1
				p.dx=p.dx*1.2
			end if
	
			respawnenemy:
			'respawn enemy
			if abs(p.y-e(i).yinit)>200 orelse abs(p.x-e(i).xinit)>400 then
				e(i).x=e(i).xinit
				e(i).y=e(i).yinit
				e(i).yground=e(i).y
			else
				if rnd<.5 then e(i).y+=3*yprev*ytilesize else e(i).y-=3*yprev*ytilesize 
				if rnd<.5 then e(i).x+=2*xprev*xtilesize else e(i).x-=2*xprev*xtilesize
				osgl_wrap( e(i).y, ytilesize, (ymax2-1)*ytilesize )
				osgl_wrap( e(i).x, xtilesize, (xmax2-1)*xtilesize )
				e(i).yground=e(i).y
			end if

			'too close
			if abs(p.y-e(i).y)<200 andalso abs(p.x-e(i).x)<400 then
				goto respawnenemy
			end if
			
			'cercado
			if gettile(e(i).x-(sgn(e(i).side)*xtilesize/2),e(i).y-ytilesize/2+1).fframe<>-1  and  gettile(e(i).x+(sgn(e(i).side)*xtilesize/2),e(i).y+1).solid=0  then 'se ficar cercado, muda de posição
				e(i).x+=2*e(i).side*xtilesize
				goto respawnenemy
			end if

			'cercado
			if gettile(e(i).x+(sgn(e(i).side)*xtilesize/2),e(i).y-ytilesize/2+1).fframe<>-1  and  gettile(e(i).x-(sgn(e(i).side)*xtilesize/2),e(i).y+1).solid=0  then 'se ficar cercado, muda de posição
				e(i).x-=2*e(i).side*xtilesize
				goto respawnenemy
			end if

			
			e(i).yground=getground(e(i).x,e(i).y)
			e(i).y=e(i).yground
			e(i).side=0
			
			i=maxenemy 'sai do for
			
		else
			if p.invencible=0 then
				'hit player
				p.mode=-3
				i=maxenemy 'sai do for
			end if
		end if
	end if
	
end if

end if

next i

end sub


#macro opendoor()
'open the level exit door
for y1 as integer=1 to ymax2
for x1 as integer=1 to xmax2
	if map.tile(x1,y1).tipo="k" then
			map.tile(x1,y1).tex=tex_tiles
			map.tile(x1,y1).uframe=-1
			map.tile(x1,y1).dframe=-1
			map.tile(x1,y1).lframe=-1
			map.tile(x1,y1).rframe=-1
			map.tile(x1,y1).fframe=-1
			map.tile(x1,y1).bframe=-1
			map.tile(x1,y1).cframe=exitframe
			map.tile(x1,y1).isitem=1
	end if
next x1
next y1
#endmacro


#macro makesolid(cor)
for y1 as integer=1 to ymax2
for x1 as integer=1 to xmax2
	'make solid
	if map.tile(x1,y1).tipo=cor then
			map.tile(x1,y1).tex=tex_tiles
			map.tile(x1,y1).uframe=1
			map.tile(x1,y1).dframe=7
			map.tile(x1,y1).lframe=7
			map.tile(x1,y1).rframe=7
			map.tile(x1,y1).fframe=11
			map.tile(x1,y1).bframe=-1
			map.tile(x1,y1).cframe=-1
			map.tile(x1,y1).solid=1
	end if
	'heart color extra life color
	if map.tile(x1,y1).tipo="m" then
		map.tile(x1,y1).colour=heartcolor
	end if
next x1
next y1
#endmacro


#macro unmark_startpoint()
for y1 as integer=1 to ymax2
for x1 as integer=1 to xmax2
	if map.tile(x1,y1).tipo="x" then
			map.tile(x1,y1+1).uframe=3
			map.tile(x1,y1).tipo="+"
			map.tile(x1,y1).isitem=1
	end if
next x1
next y1
#endmacro




#macro update_colors()

if instr(p.gotitems,"R") then heartcolor=rgba(255,31,31,255) else heartcolor=rgba(255,255,255,255)
if instr(p.gotitems,"Y") then scorecolor=rgba(255,255,31,255) else scorecolor=rgba(255,255,255,255)
if len(p.gotitems)>0 then textblend=1
if len(p.gotitems)>1 then shadowcolor=rgba(0,0,0,127) else shadowcolor=rgba(0,0,0,255)

		if instr(p.gotitems,"K") then
		
			spacecolor.colour=rgba(255,255,255,255) : spacecolor2.colour=rgba(255,255,255,127) 

		else
		
			if p.gotitems<>"" then
			
				for i as integer=1 to len(p.gotitems)
				
					dim as colortype aa : aa.colour=char2color(mid(p.gotitems,i,1))
					dim as integer tmp
					
					tmp=spacecolor.r+aa.r\5
					if tmp>255 then tmp=255
					spacecolor.r=tmp
					
					tmp=spacecolor.g+aa.g\5
					if tmp>255 then tmp=255
					spacecolor.g=tmp
					
					tmp=spacecolor.b+aa.b\5
					if tmp>255 then tmp=255
					spacecolor.b=tmp
				
					spacecolor.a=255*len(p.gotitems)/7
	
					spacecolor2.r=spacecolor.r
					spacecolor2.g=spacecolor.g
					spacecolor2.b=spacecolor.b
					spacecolor2.a=spacecolor.a\2
			
				next i
			end if
			
		end if


#endmacro


#macro getitem()
scope

	dim as integer xw, yw
	xw=cint(p.x/xtilesize)
	osgl_wrap(xw,1,xmax)
	yw=cint(p.y/ytilesize)
	osgl_wrap(yw,1,ymax)
	dim as string aa=map.tile(xw,yw).tipo

	select case aa
	case "R","O","Y","G","B","D","P" 'color items
		osgl_joyrumble(1,10,30,200)
		
		osgl_playsound3d(sound_zeum,p.x-p.xworld,p.y-p.yworld,z0)
		map.tile(xw,yw).tex=0
		map.tile(xw,yw).isitem=0
		map.tile(xw,yw).tipo=" "
		
		if instr(p.gotitems,aa)=0 then p.gotitems+=aa
		gotscore(score_color*len(p.gotitems))

		update_colors()

		makesolid(lcase(aa))
		
		optimizemap(map)

		dim as colortype cor
		cor.colour=char2color(aa)
		color_explode(p.x,p.y,cor.r,cor.g,cor.b)
		
		set_screenmessage(char2name(aa)," is released", cor.colour, 200)
		

	case "+" 'checkpoint / unmarked start point
		if p.jump=0 then
			'set a new start point
			osgl_joyrumble(1,10,10,200)
			osgl_playsound3d(sound_chpoint,p.x-p.xworld,p.y-p.yworld,z0)
			unmark_startpoint()
			map.tile(xw,yw).isitem=0
			map.tile(xw,yw).tipo="x"
			map.tile(xw,yw+1).uframe=2
			p.xinit=xw*xtilesize
			p.yinit=yw*ytilesize + ytilesize/2
			p.yinit=getground(p.xinit,p.yinit)
			set_screenmessage("Checkpoint","", iif(len(p.gotitems)>0,rgba(127,127,127,255),rgba(255,255,255,255)) , 120)
		end if
		
	case "K" 'key
		osgl_joyrumble(1,10,30,200)
		osgl_playsound3d(sound_zeum,p.x-p.xworld,p.y-p.yworld,z0)
		map.tile(xw,yw).tex=0
		map.tile(xw,yw).isitem=0
		map.tile(xw,yw).tipo=" "
		
		opendoor()

		color_explode(p.x,p.y,255,255,255)
		
		if instr(p.gotitems,aa)=0 then p.gotitems+=aa
		
		spacecolor.colour=rgba(255,255,255,255) : spacecolor2.colour=rgba(255,255,255,127) 
		
		gotscore(score_key*len(p.gotitems))
		
		set_screenmessage("You have got the KEY"+CRLF+"Now find the EXIT DOOR","", spacecolor.colour, 240)

	case "." 'score item sushi
		item_explode(xw*xtilesize,yw*ytilesize)
		'white_particles2(xw*xtilesize,yw*ytilesize,3)
		
		osgl_joyrumble(1,0,20,150)
		osgl_playsound3d(sound_beep,p.x-p.xworld,p.y-p.yworld,z0)
		map.tile(xw,yw).tex=0
		map.tile(xw,yw).isitem=0
		map.tile(xw,yw).tipo=" "
		
		gotscore(score_sushi)
		
		p.sushis+=1
		
		if (p.sushis mod 100)=0 then '100 sushis=1 extra life
			set_screenmessage("1UP","", rgba(255,255,255,255), 120)
			osgl_playsound3d(sound_life,p.x-p.xworld,p.y-p.yworld,z0)
			p.lives+=1
		end if


	case "m" 'extra life
		osgl_joyrumble(1,10,30,200)
		map.tile(xw,yw).tex=0
		map.tile(xw,yw).isitem=0
		map.tile(xw,yw).tipo=" "
		red_explode(xw*xtilesize,yw*ytilesize)
		osgl_playsound3d(sound_life,p.x-p.xworld,p.y-p.yworld,z0)
		p.lives+=1
		gotscore(score_life)
		set_screenmessage("1UP","", rgba(255,255,255,255), 120)


	case "k" 'exit door
		if p.jump=0 then
		if abs(p.x-xw*xtilesize)<xtilesize/5 then
			osgl_joyrumble(1,10,30,200)
			osgl_playsound3d(sound_chpoint,p.x-p.xworld,p.y-p.yworld,z0)
			levelclear=1
		end if
		end if
	
	end select
	
	
end scope
#endmacro

splash:

osgl_fadein

do
	osgl_box
	osgl_print 0,-20,0,"A Cleber de Mattos Casali Game"+CRLF+" "+CRLF+"Music by Achim Tober (Softworkxs.de)",0.5,0.5,1,1,rgba(255,255,255,255)
	osgl_sync
loop until osgl_fadein_complete

loadmedia()

#ifdef nosplash
	goto title
#endif

osgl_delay 180

osgl_fadeout





#macro end_screen()
scope
osgl_loadmusic(exepath+"/music/Achim_Tober_softworkxs/0014-gm_hero.ogg")

osgl_playmusic

osgl_fadein

dim as integer tmp=0, tmp2=200

do

tmp+=10

if tmp2>0 then tmp2-=5

osgl_wrap(tmp,0,359)

osgl_box(,,,,1,_
		203,255,255,255,_
		0,127,255,255,_
		0,127,255,255,_
		0,103,103,255)

osgl_render(0, tmp2-16, 0, 0, 0, tex_title, 2,_
			-3, 0.9, 0.55, 0,0, 1,1, 0,0, 1,1, 0,0, 1, 0, rgba(255,255,255,250)) 'rainbow

osgl_render(0, tmp2-16, 0, 0, 0, tex_title, 2,_
			-4, 0.9, 0.55, 0,0, 1,1, 0,0, 1,1, 0,0, 3, 0, rgba(255,255,255,31)) 'rainbow

osgl_render(0, tmp2-20, 0, 0, 0, tex_title, 1,_
			-3, 0.95, 0.6, 0,0, 1,1, 0,0, 1,1, 0,0, 1, 0, rgba(255,255,255,255)) 'clouds

osgl_render(0, tmp2+24, 0, 0, 0, tex_title, 0,_
			-3, 0.75, 0.75, 0,0, 1,1, 0,0, 1,1, 0,0, 1, 0, rgba(255,255,255,255)) 'ninja


osgl_print 0,-90-tmp2/3,0,"C              ",1.25,1.25,1,1,rgba(255,255,0,255) 'y
osgl_print 0,-90-tmp2/3,0," O             ",1.25,1.25,1,1,rgba(255,127,0,255) 'o
osgl_print 0,-90-tmp2/3,0,"  N            ",1.25,1.25,1,1,rgba(255,0,0,255) 'r
osgl_print 0,-90-tmp2/3,0,"   G           ",1.25,1.25,1,1,rgba(255,0,255,255) 'p
osgl_print 0,-90-tmp2/3,0,"    R          ",1.25,1.25,1,1,rgba(0,0,255,255) 'd
osgl_print 0,-90-tmp2/3,0,"     A         ",1.25,1.25,1,1,rgba(0,157,255,255) 'b
osgl_print 0,-90-tmp2/3,0,"      T        ",1.25,1.25,1,1,rgba(0,255,0,255) 'g
osgl_print 0,-90-tmp2/3,0,"       U       ",1.25,1.25,1,1,rgba(255,255,0,255) 'y
osgl_print 0,-90-tmp2/3,0,"        L      ",1.25,1.25,1,1,rgba(255,127,0,255) 'o
osgl_print 0,-90-tmp2/3,0,"         A     ",1.25,1.25,1,1,rgba(255,0,0,255) 'r
osgl_print 0,-90-tmp2/3,0,"          T    ",1.25,1.25,1,1,rgba(255,0,255,255) 'p
osgl_print 0,-90-tmp2/3,0,"           I   ",1.25,1.25,1,1,rgba(0,0,255,255) 'd
osgl_print 0,-90-tmp2/3,0,"            O  ",1.25,1.25,1,1,rgba(0,157,255,255) 'b
osgl_print 0,-90-tmp2/3,0,"             N ",1.25,1.25,1,1,rgba(0,255,0,255) 'g
osgl_print 0,-90-tmp2/3,0,"              S",1.25,1.25,1,1,rgba(255,255,0,255) 'y

osgl_print 0,-60-tmp2/3,0,"All levels clear!",0.5,0.5,1,1,rgba(255,255,255,255)


osgl_print 0,60-tmp2/3,0,"Thanks to you the universe is colorful again.",0.5,0.5,1,1,rgba(255,255,255,255)

osgl_print 0,92-tmp2/3,0,"Visit http://cmcgames.blogspot.com to get more games.",0.35,0.4,1,1,rgba(255,255,255,255)

osgl_sync

loop until osgl_fadein_complete andalso osgl_button

osgl_fadeout

osgl_stopmusic

end scope
#endmacro



#macro draw_score()

'draw level
osgl_print -110,-99,0, "LEVEL"+CRLF+str(level), 0.5, 0.5, 1, textblend, rgba(255,255,255,255)

'draw score
osgl_print -60,-99,0, "SCORE"+CRLF+str(p.score), 0.5, 0.5, 1, textblend, rgba(255,255,255,255)

'draw hiscore
'osgl_print 0,-99,0, "HISCORE"+CRLF+str(p.hiscore), 0.5, 0.5, 1, textblend, rgba(255,255,255,255)


'draw items
osgl_print 0, -99, 0, "ITEMS"+CRLF+"[        ]" , 0.5, 0.5, 1, textblend, rgba(255,255,255,255)
for i as integer=1 to len(p.gotitems)
	dim as string aa=mid(p.gotitems,i,1)
	osgl_print 0, -99, 0, " "+CRLF+space(i-1) + ucase(aa) + space(8-i) , 0.5, 0.5, 1, textblend, char2color(aa)
next i

'draw time
osgl_print 60,-99,0, "TIME"+CRLF+osgl_frames2minutes(timecount), 0.5, 0.5, 1, textblend, rgba(255,255,255,255)


'draw sushi
osgl_render(111,-95, 0, 0, 0, tex_tiles, sushiframe,_
			0, .5,.5, 0,0, 1,1, 0,0, 1,1, 0,0, textblend, 0, rgba(255,255,255,255))
osgl_print 116,-98,0, "x"+str(p.sushis), 0.5, 0.5, 0, textblend, rgba(255,255,255,255)

'draw lives
osgl_render(110,-85, 0, 0, 0, tex_tiles, heartframe,_
			0, .5,.5, 0,0, 1,1, 0,0, 1,1, 0,0, textblend, 0, heartcolor)
if p.lives>-1 then
osgl_print 116,-87,0, "x"+str(p.lives), 0.5, 0.5, 0, textblend, rgba(255,255,255,255)
end if


#endmacro



sub message(msg as string, byval pause as integer=1, byref p as playertype)
	osgl_fadein
	do
		osgl_box
		draw_score()
		osgl_print 0,-10,0,msg,0.75,0.75,1,1,rgba(255,255,255,255)
		osgl_sync
	loop until (osgl_button or pause=0) andalso osgl_fadein_complete
	if pause then osgl_fadeout
end sub



#macro check_cheatcode()
select case as const cheatcode
	case 0 
		if osgl_axis(1,2)<-.5 then cheatcode=1 'up - cheat
		if osgl_axis(1,2)>.5 then cheatcode=101 'down - level select
		if osgl_axis(1,1)>.5 then cheatcode=201 'right - 99 lives
		if osgl_axis(1,1)<-.5 then cheatcode=0 'left - 0


	'cheat code  U U D D U U L R
	case 1
		if abs(osgl_axis(1,2))<.1 then cheatcode=2 '0

	case 2
		if osgl_axis(1,2)<-.5 then cheatcode=3 'up
		if osgl_axis(1,2)>.5 then cheatcode=0 'down (erra)
		if abs(osgl_axis(1,1))>.1 then cheatcode=0 'left right (erra)

	case 3
		if abs(osgl_axis(1,2))<.1 then cheatcode=4 '0

	case 4
		if osgl_axis(1,2)>.5 then cheatcode=5 'down
		if osgl_axis(1,2)<-.5 then cheatcode=0 'up (erra)
		if abs(osgl_axis(1,1))>.1 then cheatcode=0 'left right (erra)
		
	case 5
		if abs(osgl_axis(1,2))<.1 then cheatcode=6 '0

	case 6
		if osgl_axis(1,2)>.5 then cheatcode=7 'down
		if osgl_axis(1,2)<-.5 then cheatcode=0 'up (erra)
		if abs(osgl_axis(1,1))>.1 then cheatcode=0 'left right (erra)

	case 7
		if abs(osgl_axis(1,2))<.1 then cheatcode=8 '0

	case 8
		if osgl_axis(1,2)<-.5 then cheatcode=9 'up
		if osgl_axis(1,2)>.5 then cheatcode=0 'down (erra)
		if abs(osgl_axis(1,1))>.1 then cheatcode=0 'left right (erra)

	case 9
		if abs(osgl_axis(1,2))<.1 then cheatcode=10 '0

	case 10
		if osgl_axis(1,2)<-.5 then cheatcode=11 'up
		if osgl_axis(1,2)>.5 then cheatcode=0 'down (erra)
		if abs(osgl_axis(1,1))>.1 then cheatcode=0 'left right (erra)

	case 11
		if abs(osgl_axis(1,2))<.1 then cheatcode=12 '0

	case 12
		if osgl_axis(1,1)<-.5 then cheatcode=13 'left
		if abs(osgl_axis(1,2))>.1 then cheatcode=0 'up down (erra)
		if osgl_axis(1,1)>.5 then cheatcode=0 'right (erra)

	case 13
		if abs(osgl_axis(1,1))<.1 then cheatcode=14 '0

	case 14
		if osgl_axis(1,1)>.5 then cheatcode=15 'right
		if abs(osgl_axis(1,2))>.1 then cheatcode=0 'up down (erra)
		if osgl_axis(1,1)<-.5 then cheatcode=0 'left (erra)

	case 15
		if abs(osgl_axis(1,1))<.1 then cheatcode=16 '0
		
	case 16
		cheatcode=0
		cheat=1
		osgl_playsound3d(sound_zeum)
		color_explode(0,0, 0,255,0)



	'level select code D D L R U D
	case 101
		if abs(osgl_axis(1,2))<.1 then cheatcode=102 '0

	case 102
		if osgl_axis(1,2)>.5 then cheatcode=103 'down
		if osgl_axis(1,2)<-.5 then cheatcode=0 'up (erra)
		if abs(osgl_axis(1,1))>.1 then cheatcode=0 'left right (erra)

	case 103
		if abs(osgl_axis(1,2))<.1 then cheatcode=104 '0


	case 104
		if osgl_axis(1,1)<-.5 then cheatcode=105 'left
		if abs(osgl_axis(1,2))>.1 then cheatcode=0 'up down (erra)
		if osgl_axis(1,1)>.5 then cheatcode=0 'right (erra)

	case 105
		if abs(osgl_axis(1,1))<.1 then cheatcode=106 '0

	case 106
		if osgl_axis(1,1)>.5 then cheatcode=107 'right
		if abs(osgl_axis(1,2))>.1 then cheatcode=0 'up down (erra)
		if osgl_axis(1,1)<-.5 then cheatcode=0 'left (erra)

	case 107
		if abs(osgl_axis(1,1))<.1 then cheatcode=108 '0

	case 108
		if osgl_axis(1,2)<-.5 then cheatcode=109 'up
		if osgl_axis(1,2)>.5 then cheatcode=0 'down (erra)
		if abs(osgl_axis(1,1))>.1 then cheatcode=0 'left right (erra)

	case 109
		if abs(osgl_axis(1,2))<.1 then cheatcode=110 '0

	case 110
		if osgl_axis(1,2)>.5 then cheatcode=111 'down
		if osgl_axis(1,2)<-.5 then cheatcode=0 'up (erra)
		if abs(osgl_axis(1,1))>.1 then cheatcode=0 'left right (erra)

	case 111
		if abs(osgl_axis(1,2))<.1 then cheatcode=112 '0

	case 112
		cheatcode=0
		levelselect=1
		osgl_playsound3d(sound_chpoint)
		color_explode(0,0, 0,0,255)




	'99 lives code R R L R D U
	case 201
		if abs(osgl_axis(1,1))<.1 then cheatcode=202 '0

	case 202
		if osgl_axis(1,1)>.5 then cheatcode=203 'right
		if abs(osgl_axis(1,2))>.1 then cheatcode=0 'up down (erra)
		if osgl_axis(1,1)<-.5 then cheatcode=0 'left (erra)

	case 203
		if abs(osgl_axis(1,1))<.1 then cheatcode=204 '0


	case 204
		if osgl_axis(1,1)<-.5 then cheatcode=205 'left
		if abs(osgl_axis(1,2))>.1 then cheatcode=0 'up down (erra)
		if osgl_axis(1,1)>.5 then cheatcode=0 'right (erra)

	case 205
		if abs(osgl_axis(1,1))<.1 then cheatcode=206 '0

	case 206
		if osgl_axis(1,1)>.5 then cheatcode=207 'right
		if abs(osgl_axis(1,2))>.1 then cheatcode=0 'up down (erra)
		if osgl_axis(1,1)<-.5 then cheatcode=0 'left (erra)

	case 207
		if abs(osgl_axis(1,1))<.1 then cheatcode=208 '0

	case 208
		if osgl_axis(1,2)>.5 then cheatcode=209 'down
		if osgl_axis(1,2)<-.5 then cheatcode=0 'up (erra)
		if abs(osgl_axis(1,1))>.1 then cheatcode=0 'left right (erra)

	case 209
		if abs(osgl_axis(1,2))<.1 then cheatcode=210 '0

	case 210
		if osgl_axis(1,2)<-.5 then cheatcode=211 'up
		if osgl_axis(1,2)>.5 then cheatcode=0 'down (erra)
		if abs(osgl_axis(1,1))>.1 then cheatcode=0 'left right (erra)

	case 211
		if abs(osgl_axis(1,2))<.1 then cheatcode=212 '0

	case 212
		cheatcode=0
		livescheat=1
		osgl_playsound3d(sound_life)
		color_explode(0,0, 255,0,0)

end select


#ifdef cheatcodedebug
	osgl_print -100,-100,0,str(cheatcode)
#endif

#endmacro


#macro loadgame()
'load game  loadgame
if dir(savegamefile)<>"" then
	dim as integer filenum=freefile
	open savegamefile for input as #filenum
		get #filenum,,savegame
	close #filenum
else
	savegame.level=beginlevel
	savegame.lives=beginlives
	savegame.score=0
	savegame.hiscore=0
end if
#endmacro


title:
'title here

loadgame()

cheat=0
levelselect=0
livescheat=0
cheatcode=0

level=beginlevel
gameover=0
levelclear=0
p.lives=-999

#ifdef notitle
	goto newlevel
#endif

osgl_loadmusic(exepath+"/music/Achim_Tober_softworkxs/0014-gm_hero.ogg")

osgl_playmusic

osgl_fadein


scope 'title

dim as integer tmp=0, tmp2=200, but=0

do

osgl_sync

tmp+=10

if tmp2>0 then tmp2-=5

osgl_wrap(tmp,0,359)

osgl_box

osgl_render(0, tmp2, 0, 0, 0, tex_title, 0,_
			-3, 0.75, 0.75, 0,0, 1,1, 0,0, 1,1, 0,0, 0, 0, rgba(255,255,255,255))

osgl_print 0,-90-tmp2/3,0," . . . . ",1.75,1.75,1,1,rgba(255,255,255,255)
osgl_print 0,-85-tmp2/3,0,"Y        ",1.75,1.75,1,1,rgba(255,255,0,255)
osgl_print 0,-85-tmp2/3,0,"  A      ",1.75,1.75,1,1,rgba(255,127,0,255)
osgl_print 0,-85-tmp2/3,0,"    G    ",1.75,1.75,1,1,rgba(255,0,0,255)
osgl_print 0,-85-tmp2/3,0,"      A  ",1.75,1.75,1,1,rgba(255,0,255,255)
osgl_print 0,-85-tmp2/3,0,"        C",1.75,1.75,1,1,rgba(0,127,255,255)

osgl_print 0,-60-tmp2/3,0,"Yet Another Game About Colors",0.5,0.5,1,1,rgba(255,255,255,255)

osgl_print 0,85,0,"Copyright (C) Cleber M. Casali"+CRLF+"http://cmcgames.blogspot.com"+CRLF+"v"+YAGAC_VERSION,0.25,0.25,1,1,rgba(255,255,255,255)

'osgl_print 110,-99,0, "HI "+str(p.hiscore), 0.5, 0.5, 1, textblend, rgba(255,255,255,255)

check_cheatcode()

'buttons
if osgl_fadein_complete then

	if osgl_pausebutton(1) or osgl_esckey or osgl_button then
		osgl_playsound(sound_beep)
		osgl_sync(1)
		if dir(savegamefile)<>"" andalso cheat=0 andalso levelselect=0 andalso livescheat=0 andalso cheatcode=0 then 'won't continue if cheating
			select case osgl_menu(0,48,,"New Game,Continue,Quit",0)
				case 3
					osgl_fadeout
					goto endprogram
				case 2
					but=1
					savegame.use=1
				case 1
					but=1
					savegame.use=0
			end select
		else
			select case osgl_menu(0,48,,"New Game,Quit",0)
				case 2
					osgl_fadeout
					goto endprogram
				case 1
					but=1
					savegame.use=0
			end select
		end if
	else
		osgl_print 0,60,0,"Press button to start",0.5,0.5,1,1,rgba(255,255,255,iif(sin(radians(tmp))>0,0,255))
	end if

end if

osgl_drawparticles()

loop until but

osgl_sync(1)

end scope 'title

osgl_joyrumble(1,30,30,150)

'start menu
'scope
'dim as integer tmp=osgl_menu(0,20,,"NEW GAME,CONTINUE,QUIT")
'select case tmp
'	case 2
'		'continue game - load data here
'	case 3
'		goto endprogram
'end select
'end scope

'osgl_playsound3d(sound_beep)

if levelselect then
	dim as integer lastlevel=0, ii=0
	do
		ii+=1
		if dir(exepath+"/data/"+str(ii)+".map")<>"" then lastlevel=ii else exit do
	loop
	if lastlevel<1 then
		osgl_popup "Problem?","Oh crap! Where are my files?"
		goto endprogram
	end if
	level=osgl_numbermenu(0,20,"LEVEL SELECT", 1,lastlevel ,1)
	if level<1 then goto title
end if

osgl_fadeout

goto newlevel




'new level
newlevel:

'use data from savegame
if savegame.use then
	loadgame()
	p.lives=savegame.lives
	p.score=savegame.score
	level=savegame.level
	p.hiscore=savegame.hiscore
	savegame.use=0
end if

osgl_stopmusic

osgl_clearparticles

if livescheat andalso p.lives<0 then p.lives=99 : p.score=0

initplayer(p)

timecount=0
gameover=0
levelclear=0
textblend=0
heartcolor=rgba(255,255,255,255)
scorecolor=rgba(255,255,255,255)
shadowcolor=rgba(0,0,0,255)
spacecolor.colour=rgba(0,0,0,255)
spacecolor2.colour=rgba(0,0,0,127)

if level=0 then level=beginlevel

#ifndef nosplash
	message "LEVEL "+str(level)+" START",0, p
#endif

if (level mod 2) then
	osgl_loadmusic(exepath+"/music/Achim_Tober_softworkxs/0016-sidfever.ogg")
else
	osgl_loadmusic(exepath+"/music/Achim_Tober_softworkxs/0014-gm_hero.ogg")
end if

loadmap(exepath+"/data/"+str(level)+".map", map, p, e())

osgl_keypause

osgl_fadeout

osgl_playmusic


'player input
#macro handle_input()

p.xaxis=osgl_axis(1,1)
p.yaxis=osgl_axis(1,2)
p.jbutton=osgl_button(1,1) or osgl_button(1,2) or osgl_button(1,3) or osgl_button(1,4)

'pause
if osgl_pausebutton(1) or osgl_esckey then
	osgl_playsound(sound_beep)
	dim as integer tmp=osgl_menu(0,20,"GAME PAUSED","Resume Game,Restart Level,Quit")
	select case as const tmp
		case 2 'restart level
			if p.lives>0 then p.lives-=1 else p.score=0
			osgl_fadeout
			osgl_stopmusic
			goto newlevel
		case 3 'quit
			osgl_fadeout
			osgl_stopmusic
			goto title
	end select
end if

if cheat then
#ifdef cheatkeys

	if multikey(59) or osgl_button(1,7) then 'F1 ou botao 7
		if p.mode<>-99 then p.mode=-99 else p.mode=0 'free move
		osgl_delay 10
	end if
	
	if multikey(60) then 'F2
		if instr(p.gotitems,"K")=0 then
			p.gotitems+="K" 'get key
			opendoor() 'open exit door
		end if
		osgl_delay 10
	end if
	
	if multikey(61) then 'F3
		if instr(p.gotitems,"K") then
			p.gotitems="ROYGBDPK" 'all items
		else
			p.gotitems="ROYGBDP" 'all but key
		end if
		update_colors()
		for i as integer=1 to 7
			makesolid(lcase(mid(p.gotitems,i,1)))
		next i
		optimizemap(map)
		osgl_delay 10
	end if

	if multikey(62) then 'F4
		p.lives=99
	end if

#endif
end if


#endmacro



'rotina
rotina:
do

timecount+=1

handle_input()

if abs(p.xaxis)>.1 andalso p.mode>-1 then
	p.ytilt-=tiltspeed*p.xaxis
else
	p.ytilt-=.5*tiltspeed*sgn(p.ytilt)
end if
if abs(p.ytilt)<.1 then p.ytilt=0
osgl_range(p.ytilt,-tiltmax, tiltmax)

moveplayer(p)

'items
if p.mode>-1 then
if gettile(p.x,p.y).isitem then
	getitem()
end if
end if

if p.mode>-2 then
for i as integer=1 to maxenemy2
	if abs(p.xworld-e(i).x)<xres*1.2 andalso abs(p.yworld-e(i).y)<yres*1.2 then 'só move enemies próximos
		moveenemy(e(i),p)
	end if
next i
end if

'camera
if p.y<p.yground then
	p.ygroundc+=sgn(p.yground-p.ygroundc)
else
	p.ygroundc=p.yground
end if

p.xwfollow=p.x+20*p.dx
p.ywfollow=p.ygroundc-ycameraoffset

if abs(p.ylook)>ycameraoffset then p.ylookc=p.ylook else p.ylookc=0

p.xwd=.1*(p.xwfollow-p.xworld)
p.ywd=.1*(p.ywfollow-p.yworld+p.ylookc)


if abs(p.xwd)>1 then p.xworld+=p.xwd
if abs(p.ywd)>1 then p.yworld+=p.ywd

checkcollision(p,e())

osgl_sync

if spacecolor.colour=rgba(0,0,0,255) then
	osgl_cls()
else

osgl_3dquad ( -1100, -1000, 1200,   1100, -1000, 1200,   1100, 1000, 1300,    -1100, 1000, 1200,_
			tex_space,,_
			0,0,_
			2.0,4.0,p.xworld/51200 + spacescroll,p.yworld/51200  + spacescroll,_
			0,0,_
			spacecolor.colour)

osgl_3dquad ( -700, -600, 600,   700, -600, 600,   700, 600, 600,    -700, 600, 600,_
			tex_space,,_
			1,1,_
			1.0,2.0,-p.xworld/51200 - spacescroll,-p.yworld/51200  - spacescroll,_
			13,0,_
			spacecolor2.colour)

	select case p.mode
		'case -2 'para
		case -1 : spacescroll-=.008 'volta
		case else   : spacescroll+=.000125 'normal
	end select
osgl_wrap(spacescroll,0,1)

end if

'osgl_cameraangle(0,0,-abs(p.ytilt),0,p.ytilt,0)
osgl_camera(0,0,p.ytilt,-3*p.ytilt,0,0,0)

drawmap(p.xworld,p.yworld)

drawplayer(p)

for i as integer=1 to maxenemy2
	if abs(p.xworld-e(i).x)<500 andalso abs(p.yworld-e(i).y)<300 then 'só desenha enemies próximos
		drawenemy(e(i))
	end if
next i

osgl_drawsprites(p.xworld,p.yworld)

osgl_drawparticles(p.xworld,p.yworld)

osgl_camera()

draw_score()

handle_screenmessage()

loop until levelclear or gameover
'rotina



if levelclear then
	dim as integer levelbonus=500+level*score_level
	osgl_fadeout 5
	gotscore(levelbonus)
	message "LEVEL "+str(level)+" CLEAR!"+CRLF+"BONUS "+str(levelbonus)+" POINTS",, p
	if dir(exepath+"/data/"+str(level+1)+".map")="" then
		if cheat or levelselect or livescheat then
			'final falso com cheat - fake endgame with cheat
			message "GAME OVER"+CRLF+" "+CRLF+"Try again without cheating!",, p
			goto title
		else
			'all levels clear - endgame
			end_screen()
			goto title
		end if
	else
		'next level
		#ifdef demo
			'one level demo
			message "All clear!"+CRLF+"For more levels, wait for the full version."+CRLF+" "+CRLF+"http://cmcgames.blogspot.com",, p
			goto title
		#else
			'next level
			level+=1

			'save game  savegame
		#ifndef cheatsave
			if cheat=0 andalso levelselect=0 andalso livescheat=0 andalso cheatcode=0 then 'won't save if cheating
		#endif
		
				savegame.level=level
				savegame.lives=p.lives
				savegame.score=p.score
				savegame.hiscore=p.hiscore
				dim as integer filenum=freefile
				open savegamefile for output as #filenum
					put #filenum,,savegame
				close #filenum
				
		#ifndef cheatsave
			end if
		#endif
			
			
			goto newlevel
		#endif
	end if
end if

if gameover then
	'game over
	osgl_fadeout
	message "GAME OVER",, p
	goto title
end if

goto endprogram



endprogram:

osgl_stopmusic

osgl_end

'end of YAGAC.BAS ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
