; ; SHOCKWAVE (c) COPYRIGHT Ian Cowburn 2004 ; ; $Id: shockwave.bb,v 1.6 2005-03-06 01:40:21 ianc Exp $ ; Include "gfx/font.bb" ; ============================================ ; TYPES ; ============================================ ; Type Particle Field id Field a# Field ai# Field life End Type Type SpriteText Field id Field txt Field a# Field ai# Field xi# Field yi# Field zi# Field life End Type Type Shockwave Field id Field length Field z# End Type Type SWLine Field x1#,y1# Field r1,g1,b1 Field x2#,y2# Field r2,g2,b2 End Type Type Asteroid Field id Field size Field colcnt Field speed# Field dx#,dy# Field power Field split End Type Type PowerUp Field id Field chance Field max Field count End Type Type QSound Field snd Field time Field obj End Type ; ============================================ ; CONSTS ; ============================================ ; Const DEBUGMODE=False Const MAPSIZE=256 Const FIELDSIZE=246 Const RADSCALE=16 Const RADSIZE=(MAPSIZE*2)/RADSCALE Const RADMID=RADSIZE/2 Const TXTSIZE=256 Const SPRTXTSIZE=128 Const SHIPZ#=149 Const WAVEZ#=150 Const SHIPSZ#=2 Const ASTLARGE=20 Const ASTMEDIUM=10 Const ASTSMALL=5 Const ASTMAXSPEED#=0.5 Const ASTMINSPEED#=0.4 Const ASTSHIELD=200 Const MAXSHIELD=100 Const SHIPTYPE=1 Const SWTYPE=2 Const ASTTYPE=3 Const POWNONE=0 Const POWSPLIT=1 Const POWTURBOTURN=2 Const POWSHIELD=3 Const TURN_NORMAL#=3 Const TURN_TURBO#=5 Const MAXSPEED_NORMAL#=1 Const MAXSPEED_TURBO#=2 ; ============================================ ; GLOBLS ; ============================================ ; Global WINW=800 Global WINH=600 Global sw.Shockwave=Null ; ============================================ ; MAIN ; ============================================ ; Graphics3D WINW,WINH,32;,2 SetBuffer BackBuffer() Global camera=CreateCamera() Global listener=CreateListener(camera,0.001) Dim snd_emitter(7) For f=0 To 7 snd_emitter(f)=CreatePivot(camera) Next PositionEntity snd_emitter(0),0,0,2 PositionEntity snd_emitter(1),1,0,1 PositionEntity snd_emitter(2),2,0,0 PositionEntity snd_emitter(3),1,0,-1 PositionEntity snd_emitter(4),0,0,-2 PositionEntity snd_emitter(5),-1,0,-1 PositionEntity snd_emitter(6),-2,0,0 PositionEntity snd_emitter(7),-1,0,1 CameraRange camera,0.1,10000 CameraFogMode camera,0 AmbientLight 255,255,255 Global vectex=CreateVectex() Global asttex=CreateAsttex() Global powertex=CreatePowertex() Global shieldtex=CreateShieldtex() Global maptex=CreateMaptex() Global radar=CreateTexture(RADSIZE,RADSIZE,1+2+16+32+256) Global hud=CreateTexture(TXTSIZE,TXTSIZE,1+2+16+32+256) Global ship=CreateShip() Global particle=CreateParticle() Global large_asteroid=CreateAsteroid(ASTLARGE) Global medium_asteroid=CreateAsteroid(ASTMEDIUM) Global small_asteroid=CreateAsteroid(ASTSMALL) Global map=CreateMap() Global radar_spr=CreateSprite(camera) Global hud_spr=CreateSprite(camera) Global start_sfx=Load3DSound("sfx/start.wav") Global bonus_level_sfx=Load3DSound("sfx/bonus_level.wav") Global laugh_sfx=Load3DSound("sfx/laugh.wav") Global explode_sfx=Load3DSound("sfx/explode.wav") Global pop_sfx=Load3DSound("sfx/pop.wav") Global turbostart_sfx=Load3DSound("sfx/powerstart.wav") Global turbostop_sfx=Load3DSound("sfx/powerstop.wav") Global turnstart_sfx=Load3DSound("sfx/powerstart.wav") Global turnstop_sfx=Load3DSound("sfx/powerstop.wav") Global smartbomb_sfx=Load3DSound("sfx/smartbomb.wav") HideEntity particle HideEntity large_asteroid HideEntity medium_asteroid HideEntity small_asteroid EntityType ship,SHIPTYPE EntityRadius large_asteroid,ASTLARGE/2 EntityRadius medium_asteroid,ASTMEDIUM/2 EntityRadius small_asteroid,ASTSMALL/2 EntityRadius ship,SHIPSZ ;Collisions ASTTYPE,SWTYPE,2,1 ;Collisions ASTTYPE,SHIPTYPE,2,0 Collisions ASTTYPE,ASTTYPE,1,1 PositionEntity radar_spr,7,5,15 EntityTexture radar_spr,radar PositionEntity hud_spr,0,0,2 EntityTexture hud_spr,hud ScaleSprite hud_spr,1.15,0.85 Global globang=0 Global start_level=1 Global start_bonus=0 Global quit=False Global MAX_SPEED#=MAXSPEED_NORMAL Global turn#=TURN_NORMAL Global speed#=0 Global score=0 Global shield=0 Global dead=False Global highscore=0 Global highlostchain=0 Global new_highscore=False Global new_highlostchain=False Global hit_count=0 Global hit_timer=0 Global turbo_count=0 Global turn_count=0 Global is_bonus_level=False LoadHighScore() CreatePowerUp(POWSPLIT,99,1) CreatePowerUp(POWSHIELD,97,0) CreatePowerUp(POWTURBOTURN,95,10) Global timer=CreateTimer(100) Restore InstructionData Read a$ Global instruction$ While a$<>"END" instruction$=instruction$+a$ Read a$ Wend Repeat SetCameraFOV(60) Menu() If quit Exit EndIf speed=0 MAX_SPEED#=MAXSPEED_NORMAL turn#=TURN_NORMAL ClearText() PositionEntity ship,0,0,SHIPZ RotateMesh ship,0,0,0 ClearParticles() ClearSpriteText() InitShockwave(180,WAVEZ) InitAsteroids() score=0 shield=MAXSHIELD dead=False done=False level=start_level total_chain=0 hit_timer=0 hit_count=0 new_level=True end_level=False FlushKeys Delete Each QSound While (Not dead) And (Not done) And (Not KeyHit(1)) If new_level If (level Mod 5)=0 is_bonus_level=True Else is_bonus_level=False EndIf ClearText() ResetPowerUps() AddScore(0) SubShield(0) noast=5+2*level If noast>100 noast=100 EndIf For f=1 To noast NewAsteroid(ASTLARGE,Rand(-FIELDSIZE,FIELDSIZE),Rand(-FIELDSIZE,FIELDSIZE)) Next If is_bonus_level For f=30 To 50 Step 4 NewCameraSpriteText("BONUS LEVEL "+Str$(level),$ffffff,0,0,EntityZ(camera)+f,-0.4,1,0.01) Next EmitSound(bonus_level_sfx,camera) Else For f=30 To 50 Step 4 NewCameraSpriteText("LEVEL "+Str$(level),$ffffff,0,0,EntityZ(camera)+f,-0.4,1,0.01) Next EmitSound(start_sfx,camera) EndIf total_chain=0 hit_count=0 turn_count=0 turbo_count=0 new_level=False EndIf If (First Asteroid)=Null And (Not end_level) If hit_timer>0 hit_timer=0 If hit_count>5 bonus=hit_count*50 NewCameraSpriteText("CHAIN BONUS",$ff0000,0,5,EntityZ(camera)+50,-0.2,1,0.005) NewCameraSpriteText(Str$(bonus),$ffff00,0,3,EntityZ(camera)+50,-0.2,1,0.005) AddScore(bonus) total_chain=total_chain+hit_count EndIf EndIf end_level=True end_levelc=500 HudTextCentre(50,"LEVEL COMPLETE!",$ffffff) If start_bonus>0 HudTextCentre(100,"START BONUS",$ff0000) HudTextCentre(110,Str$(start_bonus),$ffff00) AddScore(start_bonus) start_bonus=0 EndIf If total_chain>0 bonus=total_chain*17 HudTextCentre(160,"CHAIN BONUS",$ff0000) HudTextCentre(170,Str$(bonus),$ffff00) AddScore(bonus) EndIf If shield=0 HudTextCentre(190,"SECRET ZERO SHIELD BONUS",$ff0000) HudTextCentre(200,"99999",$ffff00) AddScore(99999) SubShield(-MAXSHIELD) ElseIf shield=MAXSHIELD HudTextCentre(190,"PERFECT SHIELD BONUS",$ff0000) HudTextCentre(200,"20000",$ffff00) AddScore(20000) ElseIf total_chain>0 bonus=total_chain If (shield+bonus)>MAXSHIELD bonus=MAXSHIELD-shield EndIf HudTextCentre(190,"NEW SHIELDS WON",$ff0000) HudTextCentre(200,Str$(bonus),$ffff00) SubShield(-bonus) EndIf level=level+1 EndIf If end_level end_levelc=end_levelc-1 If end_levelc<200 HudTextCentre(128,"GET READY!",$ffffff) EndIf If end_levelc=0 end_level=False new_level=True EndIf EndIf If turn_count>0 turn_count=turn_count-1 If turn_count=0 CircleQSound(turnstop_sfx,1) turn=TURN_NORMAL EndIf EndIf If turbo_count>0 turbo_count=turbo_count-1 If turbo_count=0 CircleQSound(turbostop_sfx,1) MAX_SPEED=MAXSPEED_NORMAL EndIf EndIf If KeyDown(203) TurnEntity ship,0,0,turn EndIf If KeyDown(205) TurnEntity ship,0,0,-turn EndIf If KeyHit(25) FlushKeys c=$ffff00 ci=-$111100 While (Not KeyHit(25)) And (Not KeyHit(1)) HudTextCentre(124,"P A U S E D",c) c=c+ci If c=0 Or c=$ffff00 Then ci=-ci RenderWorld Flip Wend HudTextCentre(124," ",$ffff00) EndIf If speedMAX_SPEED Then speed=MAX_SPEED ElseIf speed>MAX_SPEED speed=speed-0.02 If speed0 hit_timer=hit_timer-1 If hit_timer=0 If hit_count>5 bonus=hit_count*50 NewCameraSpriteText("CHAIN BONUS",$ff0000,0,5,EntityZ(camera)+50,-0.2,1,0.005) NewCameraSpriteText(Str$(bonus),$ff0000,0,3,EntityZ(camera)+50,-0.2,1,0.005) AddScore(bonus) total_chain=total_chain+hit_count EndIf hit_count=0 EndIf EndIf MoveEntity ship,0,speed,0 PositionEntity camera,EntityX(ship),EntityY(ship),0 ;PointEntity camera,ship UpdateParticles() UpdateSpriteText() UpdateWorld RenderWorld UpdateAsteroids() AddShockwave(ship) DrawRadar() ex=EntityX(ship) ey=EntityY(ship) If ex<-MAPSIZE Or ex>MAPSIZE RotateEntity ship,0,0,-EntityRoll(ship) MoveEntity ship,0,speed,0 EndIf If ey<-MAPSIZE Or ey>MAPSIZE RotateEntity ship,0,0,180-EntityRoll(ship) MoveEntity ship,0,speed,0 EndIf ProcessQSounds() Flip WaitTimer(timer) globang=(globang+10) Mod 360 If DEBUGMODE If KeyHit(200) MAX_SPEED=MAX_SPEED+0.1 NewCameraSpriteText(Str$(MAX_SPEED),$ff0000,0,5,EntityZ(camera)+50,-0.2,1,0.005) EndIf If KeyHit(208) MAX_SPEED=MAX_SPEED-0.1 NewCameraSpriteText(Str$(MAX_SPEED),$ff0000,0,5,EntityZ(camera)+50,-0.2,1,0.005) EndIf If KeyHit(65) SubShield(shield) NewCameraSpriteText("NOSHLD",$ff0000,0,5,EntityZ(camera)+50,-0.2,1,0.005) EndIf If KeyHit(66) SubShield(-MAXSHIELD) NewCameraSpriteText("FULLSHLD",$ff0000,0,5,EntityZ(camera)+50,-0.2,1,0.005) EndIf EndIf Wend new_highscore=False new_highlostchain=False If dead CircleQSound(explode_sfx,25) fov#=60 NewCameraSpriteText("GAME OVER!",$ffffff,0,0,EntityZ(camera)+0.5,0,0.1,-0.005) If hit_count>5 NewCameraSpriteText("LOST A",$800000,0,-2,EntityZ(camera)+0.5,0,0.1,-0.005) NewCameraSpriteText("CHAIN OF",$800000,0,-4,EntityZ(camera)+0.5,0,0.1,-0.005) NewCameraSpriteText(Str$(hit_count)+"!",$800000,0,-6,EntityZ(camera)+0.5,0,0.1,-0.005) EndIf If score>highscore new_highscore=True highscore=score EndIf If hit_count>5 And hit_count>highlostchain new_highlostchain=True highlostchain=hit_count EndIf If new_highscore Or new_highlostchain SaveHighScore() EndIf f=0 While (f<700) And (Not (KeyDown(57) Or KeyDown(1))) ProcessQSounds() SetCameraFOV(fov) If fov<175 fov=fov+1 EndIf UpdateAsteroids() DrawRadar() UpdateParticles() UpdateSpriteText() UpdateWorld RenderWorld Flip f=f+1 Wend While fov>60 ProcessQSounds() SetCameraFOV(fov) fov=fov-5 UpdateAsteroids() DrawRadar() UpdateParticles() UpdateSpriteText() UpdateWorld RenderWorld Flip Wend SetCameraFOV(60) EndIf Forever End ; ============================================ ; Utils ; ============================================ ; .Utils Function SetCameraFOV(FOV#) CameraZoom camera, 1.0 / Tan(FOV#/2.0) End Function Function Info() Color 255,255,255 Text 0,0,"M:"+MeshWidth(ship)+","+MeshHeight(ship)+","+MeshDepth(ship) Text 0,10,"S:"+MeshWidth(sw\id)+","+MeshHeight(sw\id)+","+MeshDepth(sw\id) End Function Function AddScore(s) score=score+s HudText(0,0,"SCORE") HudTextCol(48,0,score,$ff0000) End Function Function SubShield(s) orig=shield shield=shield-s If shield<0 And (Not dead) Then shield=0:dead=True:EmitSound(laugh_sfx,snd_emitter(Rand(0,7))) If shield>300 Then shield=300 If orig=>50 And shield<50 Then EmitSound(laugh_sfx,snd_emitter(Rand(0,7))) If orig=>20 And shield<20 Then EmitSound(laugh_sfx,snd_emitter(Rand(0,7))) HudText(150,0,"SHEILD") HudTextCol(206,0,shield+" ",$ff0000) End Function Function ClearTexture(t) w=TextureWidth(t)-1 h=TextureHeight(t)-1 b=TextureBuffer(t) LockBuffer b For x=0 To w For y=0 To h WritePixelFast x,y,0,b Next Next UnlockBuffer b End Function Function RectTexture(t,x,y,w,h,c) tw=TextureWidth(t)-1 th=TextureHeight(t)-1 b=TextureBuffer(t) LockBuffer b For xc=x To x+w-1 For yc=y To y+h-1 If xc>=0 And xc=0 And yc=RADSIZE x=RADSIZE-1 EndIf For y=0 To RADSIZE-1 WritePixelFast x,y,$7fffffff,b Next y=RADMID-EntityY(ship)/RADSCALE If y<0 y=0 EndIf If y>=RADSIZE y=RADSIZE-1 EndIf For x=0 To RADSIZE-1 WritePixelFast x,y,$7fffffff,b Next For a.Asteroid=Each Asteroid If a\size=ASTLARGE c=$ffffff00 ElseIf a\size=ASTMEDIUM c=$ffc8c8c8 Else c=$ffa0a0a0 EndIf x=RADMID+EntityX(a\id)/RADSCALE y=RADMID-EntityY(a\id)/RADSCALE If x>-1 And x-1 And y0 a\colcnt=a\colcnt-1 If a\colcnt=0 If a\power=POWNONE EntityTexture a\id,asttex Else EntityTexture a\id,powertex EndIf EntityType a\id,ASTTYPE EndIf hit_ship=False hit_sw=False Else hit_ship=EntityDistance(a\id,ship)<(a\size/2+SHIPSZ) hit_sw=HitSW(a\id,a\size) EndIf If hit_ship SubShield(1) ElseIf hit_sw Or a\split If Not dead AddScore(a\size) hit_timer=200 hit_count=hit_count+1 If Not a\split EmitSound(pop_sfx,a\id) For f=10 To 100 Step 10 NewAlphaParticle(particle,EntityX(a\id),EntityY(a\id),EntityZ(a\id)-f,1.0,-0.01) Next EndIf If a\size>ASTSMALL x#=EntityX(a\id) y#=EntityY(a\id) NewAsteroid(a\size/2,x,y) NewAsteroid(a\size/2,x,y) EndIf If a\power<>POWNONE If a\split ReturnPowerUp(a\power) Else Select a\power Case POWSPLIT NewCameraSpriteText("SMART BOMB!",$ff0000,0,0,EntityZ(camera)+30,-0.4,1,0.01) do_split=True CircleQSound(smartbomb_sfx,2) Case POWSHIELD NewCameraSpriteText("SHEILD UP!",$ff0000,0,0,EntityZ(camera)+31,-0.4,1,0.01) SubShield(-10) Case POWTURBOTURN If Rand(100)>50 NewCameraSpriteText("TURBO NUTTER!",$ff0000,0,0,EntityZ(camera)+32,-0.4,1,0.01) CircleQSOund(turbostart_sfx,1) turbo_count=turbo_count+500 MAX_SPEED=MAXSPEED_TURBO Else NewCameraSpriteText("TURN NUTTER!",$ff0000,0,0,EntityZ(camera)+33,-0.4,1,0.01) CircleQSound(turnstart_sfx,1) turn_count=turn_count+500 turn=TURN_TURBO EndIf End Select EndIf EndIf FreeEntity a\id Delete a upd=False EndIf EndIf If upd If CountCollisions(a\id)>0 a\dx=CollisionNX(a\id,1)*a\speed a\dy=CollisionNY(a\id,1)*a\speed EndIf TurnEntity a\id,0,a\dx*2,0 TranslateEntity a\id,a\dx,a\dy,0 ex=EntityX(a\id) ey=EntityY(a\id) If ex<-MAPSIZE Or ex>MAPSIZE s=Sgn(ex) PositionEntity a\id,s*MAPSIZE,ey,WAVEZ a\dx=-a\dx EndIf If ey<-MAPSIZE Or ey>MAPSIZE s=Sgn(ey) PositionEntity a\id,ex,s*MAPSIZE,WAVEZ a\dy=-a\dy EndIf EndIf Next If do_split For a=Each Asteroid a\split=True Next EndIf End Function ; ============================================ ; Shockwave ; ============================================ ; .Shochwave Function InitShockwave(length,z#) If sw<>Null FreeEntity sw\id Else sw=New Shockwave EndIf Delete Each SWLine CreateSWLine(0,0,0) sw\length=length sw\id=CreateMesh() PositionEntity sw\id,0,0,z EntityType sw\id,SWTYPE EntityRadius sw\id,1 CreateSurface(sw\id) sw\z=z EntityFX sw\id,1+2+16+32 End Function Function CreateSWLine.SWLine(x#,y#,roll#) s.SWLine=New SWLine sz#=0.5 s\x1=x-sz*Cos(roll) s\x2=x+sz*Cos(roll) s\y1=y-sz*Sin(roll) s\y2=y+sz*Sin(roll) s\r1=Rand(100,255) s\g1=Rand(0,100) s\b1=Rand(0,100) s\r2=Rand(100,255) s\g2=Rand(0,100) s\b2=Rand(0,100) End Function Function AddShockwave(base) x#=EntityX(base) y#=EntityY(base) roll#=EntityRoll(base) CreateSWLine(x,y,roll) If sw\length>0 sw\length=sw\length-1 Else Delete First SWLine EndIf s=GetSurface(sw\id,1) ClearSurface s,True,True al#=0.1 prev.SWLine=Null For sl.SWLine=Each SWLine If prev<>Null If True v0=AddVertex(s,sl\x1,sl\y1,0) v1=AddVertex(s,sl\x2,sl\y2,0) v2=AddVertex(s,prev\x1,prev\y1,0) v3=AddVertex(s,prev\x2,prev\y2,0) VertexColor s,v0,sl\r1,sl\g1,sl\b1,al VertexColor s,v1,sl\r2,sl\g2,sl\b2,al VertexColor s,v2,prev\r1,prev\g1,prev\b1,al VertexColor s,v3,prev\r2,prev\g2,prev\b2,al AddTriangle(s,v0,v1,v2) AddTriangle(s,v1,v3,v2) EndIf If False v0=AddVertex(s,sl\x1,sl\y1,-1) v1=AddVertex(s,sl\x2,sl\y2,-1) v2=AddVertex(s,prev\x1,prev\y1,-1) v3=AddVertex(s,prev\x2,prev\y2,-1) v4=AddVertex(s,sl\x1,sl\y1,1) v5=AddVertex(s,sl\x2,sl\y2,1) v6=AddVertex(s,prev\x1,prev\y1,1) v7=AddVertex(s,prev\x2,prev\y2,1) VertexColor s,v0,sl\r1,sl\g1,sl\b1,al VertexColor s,v1,sl\r2,sl\g2,sl\b2,al VertexColor s,v2,prev\r1,prev\g1,prev\b1,al VertexColor s,v3,prev\r2,prev\g2,prev\b2,al AddTriangle(s,v0,v1,v2) AddTriangle(s,v1,v3,v2) AddTriangle(s,v4,v6,v5) AddTriangle(s,v4,v6,v7) EndIf If al<1.0 al=al+0.05 EndIf EndIf prev=sl Next End Function ; ============================================ ; Particles ; ============================================ ; .Particles Function ClearParticles() For p.Particle=Each Particle FreeEntity p\id Delete p Next End Function Function UpdateParticles() For p.Particle=Each Particle If p\life=0 Or p\a<=0 FreeEntity p\id Delete p Else p\life=p\life-1 p\a=p\a+p\ai EntityAlpha p\id,p\a EndIf Next End Function Function NewParticle(base,x#,y#,z#,life) p.Particle=New Particle p\id=CopyEntity(base) ShowEntity p\id PositionEntity p\id,x,y,z p\life=life End Function Function NewAlphaParticle(base,x#,y#,z#,a#,ai#) p.Particle=New Particle p\id=CopyEntity(base) ShowEntity p\id EntityAlpha p\id,a PositionEntity p\id,x,y,z p\life=9999999 p\a=a p\ai=ai End Function ; ============================================ ; Mesh and Texture ; ============================================ ; .MeshAndTexture Function CreateVectex() s=256 t=CreateTexture(s,s,1+4+8+256) i=CreateImage(s,s) b=BackBuffer() SetBuffer ImageBuffer(i) Color 128,128,128 Rect 0,0,s,s,True For f=0 To 128 Color 255-f,255-f,255-f Rect f,f,s-f*2,s-f*2,False Next SetBuffer b CopyRect 0,0,s,s,0,0,ImageBuffer(i),TextureBuffer(t) FreeImage i Return t End Function Function CreateParticle() m=CreateMesh() b=CreateBrush(255,0,0) s=CreateSurface(m,b) sz#=2 v0=AddVertex(s,0,sz,0) v1=AddVertex(s,-sz,-0,0) v2=AddVertex(s,0,-sz,0) v3=AddVertex(s,sz,0,0) AddTriangle(s,v0,v2,v1) AddTriangle(s,v0,v3,v2) UpdateNormals m Return m End Function Function CreateShip() m=CreateMesh() b=CreateBrush(255,255,255) BrushTexture b,vectex s=CreateSurface(m,b) sz#=SHIPSZ v0=AddVertex(s,0,sz,0,0,0) v1=AddVertex(s,-sz,-sz,0,0,1) v2=AddVertex(s,0,-sz/2,1,0,1) v3=AddVertex(s,sz,-sz,0,1,0) AddTriangle(s,v0,v2,v1) AddTriangle(s,v0,v3,v2) UpdateNormals m Return m End Function Function CreateAsttex() s=256 t=CreateTexture(s,s,1+4+8+256) i=CreateImage(s,s) b=BackBuffer() SetBuffer ImageBuffer(i) Color 0,0,128 Rect 0,0,s,s,True Color 64,64,255 For f=0 To 256 Step 32 Rect f,0,4,256,True Rect 0,f,256,4,True Next SetBuffer b CopyRect 0,0,s,s,0,0,ImageBuffer(i),TextureBuffer(t) FreeImage i Return t End Function Function TRANS_CreateAsttex() s=256 t=CreateTexture(s,s,1+4+8+256) ClearTexture(t) For f=0 To 256 Step 32 RectTexture(t,f,0,4,256,$ffffffff) RectTexture(t,0,f,256,4,$ffffffff) Next Return t End Function Function CreatePowertex() s=256 t=CreateTexture(s,s,1+4+8+256) i=CreateImage(s,s) b=BackBuffer() SetBuffer ImageBuffer(i) Color 128,128,0 Rect 0,0,s,s,True Color 255,255,0 For f=0 To 256 Step 32 Rect f,0,4,256,True Rect 0,f,256,4,True Next SetBuffer b CopyRect 0,0,s,s,0,0,ImageBuffer(i),TextureBuffer(t) FreeImage i Return t End Function Function TRANS_CreatePowertex() s=256 t=CreateTexture(s,s,1+4+8+256) ClearTexture(t) For f=0 To 256 Step 32 RectTexture(t,f,0,4,256,$ffffff00) RectTexture(t,0,f,256,4,$ffffff00) Next Return t End Function Function OLD_CreateShieldtex() sz=32 t=CreateTexture(sz,sz,1+4+8+256) i=CreateImage(sz,sz) b=BackBuffer() SetBuffer ImageBuffer(i) For f=0 To sz-1 Color Rand(255),Rand(255),Rand(255) Line 0,f,sz-1,f Next SetBuffer b CopyRect 0,0,sz,sz,0,0,ImageBuffer(i),TextureBuffer(t) FreeImage i Return t End Function Function CreateShieldtex() s=32 t=CreateTexture(s,s,1+4+8+256) ClearTexture(t) For x=0 To s Step 2 For y=0 To s Step 2 RectTexture(t,x+(y Mod 2),y,1,1,$ffffffff) ;RectTexture(t,x,y,1,1,$ffffffff) Next Next Return t End Function Function CreateAsteroid(size#) size=size/2 m=CreateSphere() ScaleEntity m,size,size,size Return m m=CreateMesh() s=CreateSurface(m) pt#=16.0 ai#=360.0/pt AddVertex(s,0,0,0,0.5,0.5) For f=0 To pt-1 a#=f*ai x#=Sin(a)*size y#=Cos(a)*size AddVertex(s,x,y,z,Abs(Sin(a)),Abs(Cos(a))) Next For f=1 To pt-1 AddTriangle(s,0,f,f+1) Next AddTriangle(s,0,pt,1) UpdateNormals m Return m End Function Function CreateMaptex() s=256 t=CreateTexture(s,s,1+4+8+256) i=CreateImage(s,s) b=BackBuffer() SetBuffer ImageBuffer(i) Color 0,0,64 Rect 0,0,s,s,True For f=0 To 128 rd=Rand(128,255) gn=Rand(128,255) bl=Rand(128,255) x=Rand(1,s-1) y=Rand(1,s-1) Color rd/2,gn/2,bl/2 Plot x-1,y Plot x+1,y Plot x,y-1 Plot x,y+1 Color rd,gn,bl Plot x,y Next Color 0,0,128 Rect 0,0,s,s,False SetBuffer b CopyRect 0,0,s,s,0,0,ImageBuffer(i),TextureBuffer(t) FreeImage i Return t End Function Function MapSurface(m,b,x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4) s=CreateSurface(m,b) v0=AddVertex(s,x1,y1,z1,0,0) v1=AddVertex(s,x2,y2,z2,1,0) v2=AddVertex(s,x3,y3,z3,0,1) v3=AddVertex(s,x4,y4,z4,1,1) AddTriangle(s,v0,v1,v2) AddTriangle(s,v1,v3,v2) End Function Function CreateMap() m=CreateMesh() b=CreateBrush(255,255,255) BrushTexture b,maptex sz=MAPSIZE+10 MapSurface(m,b, -sz,sz,sz, sz,sz,sz, -sz,-sz,sz, sz,-sz,sz) MapSurface(m,b, -sz,sz,-sz, sz,sz,-sz, -sz,sz,sz, sz,sz,sz) MapSurface(m,b, -sz,-sz,-sz, -sz,sz,-sz, -sz,-sz,sz, -sz,sz,sz) MapSurface(m,b, sz,sz,-sz, sz,-sz,-sz, sz,sz,sz, sz,-sz,sz) MapSurface(m,b, sz,-sz,-sz, -sz,-sz,-sz, sz,-sz,sz, -sz,-sz,sz) UpdateNormals m Return m End Function ; ============================================ ; Menu ; ============================================ ; .TitleRoutines Function Menu() FlushKeys InitAsteroids() ClearText() PositionEntity ship,0,0,SHIPZ RotateMesh ship,0,0,0 ClearParticles() ClearSpriteText() InitShockwave(180,WAVEZ) done=False turn=0 count=100 speed=0 r=0 g=0 b=0 i=1 tl$="abcdefgh" ic=1 icl=Len(instruction$) icp=1 HudTextCentre(20,"SHOCKWAVE",$ffffff) HudTextCentre(30,"(C) 2004 IAN C",$ffffff) If DEBUGMODE HudTextCentre(150,"**** DEBUG KEYS ENABLED ****",$ff0000) EndIf HudTextCentre(50,"PRESS F1 FOR LEVEL",$ffff00) HudTextCentre(60,"PRESS SPACE TO PLAY",$ffff00) HudTextCentre(80,"PRESS ESC TO QUIT",$ffff00) HudTextCentre(170,"HIGH SCORE",$ffffff) HudTextCentre(200,"LARGEST LOST CHAIN",$ffffff) AddScore(0) ti=MilliSecs() While Not done HudText(245,0,Mid$(tl$,i,1)) If (MilliSecs()-ti)>200 i=(i Mod Len(tl$))+1 ti=MilliSecs() EndIf HudTextCentre(100," START LEVEL " + start_level+" ",$00ffff) HudTextCentre(110," BONUS " + start_bonus+" ",$00ffff) If new_highscore HudTextCentre(170,"NEW HIGH SCORE",(g Shl 16) Or (b Shl 8) Or r) EndIf If new_highlostchain HudTextCentre(200,"NEW LARGEST LOST CHAIN",(g Shl 16) Or (b Shl 8) Or r) EndIf HudTextCentre(180,Str$(highscore),(r Shl 16) Or (g Shl 8) Or b) HudTextCentre(210,Str$(highlostchain),(r Shl 16) Or (g Shl 8) Or b) r=(r+7) And 255 g=(g+5) And 255 b=(b+3) And 255 ic=ic-1 If ic=0 NewCameraSpriteTextScroll(Mid$(instruction$,icp,1),$ffffff,5,-2,EntityZ(camera)+5,-0.02,0,0,500) ;NewCameraSpriteTextScroll(Mid$(instruction$,icp,1),$111188,5,-2,EntityZ(camera)+5.1,-0.02,0,0,500) ic=6 icp=icp+1 If icp>icl icp=1 EndIf EndIf If KeyHit(1) done=True quit=True EndIf If KeyHit(57) done=True EndIf If KeyHit(59) start_level=start_level+5 If start_level>30 start_level=1 EndIf start_bonus=(start_level-1)^2*1000 EndIf count=count-1 If count=0 turn=Rand(-1,1) If turn=0 count=Rand(1,200) Else count=Rand(10,200) EndIf EndIf If turn=-1 TurnEntity ship,0,0,TURN_NORMAL EndIf If turn=1 TurnEntity ship,0,0,-TURN_NORMAL EndIf If speedMAPSIZE RotateEntity ship,0,0,-EntityRoll(ship) MoveEntity ship,0,speed,0 EndIf If ey<-MAPSIZE Or ey>MAPSIZE RotateEntity ship,0,0,180-EntityRoll(ship) MoveEntity ship,0,speed,0 EndIf Flip globang=(globang+10) Mod 360 Wend End Function ; ============================================ ; Highscore Routines ; ============================================ ; .HiScoreRoutines Function LoadHighScore() fp=ReadFile("hiscore.dat") If fp=0 Return EndIf highscore=ReadInt(fp) highlostchain=ReadInt(fp) CloseFile fp End Function Function SaveHighScore() fp=WriteFile("hiscore.dat") If fp=0 Return EndIf WriteInt fp,highscore WriteInt fp,highlostchain CloseFile fp End Function ; ============================================ ; Power Up Routines ; ============================================ ; .PowerUpRoutines Function CreatePowerUp(id,chance,max) p.PowerUp=New PowerUp p\id=id p\chance=chance p\max=max End Function Function ResetPowerUps() For p.PowerUp=Each PowerUp p\count=0 Next End Function Function PowerUp() If is_bonus_level Return POWSPLIT EndIf i=Rand(100) For p.PowerUp=Each PowerUp If i>p\chance And p\count