Maths problem with basic camera

Advanced game related topics
miso
Enthusiast
Enthusiast
Posts: 406
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Maths problem with basic camera

Post by miso »

Caronte3D wrote: Tue Mar 04, 2025 3:09 pm I don't see the ships :?
You can't miss the onscreen airships/spaceships, planes anymore.

Code: Select all

;UPDATED 2
EnableExplicit
#PSEUDORANDOM_SEED = 5000
RandomSeed(#PSEUDORANDOM_SEED)
UsePNGImageDecoder()
;-MODULES FILES 
EnableExplicit

DeclareModule line
  Global initialized.b =#False , sprite_ID.i = -1, circlesprite_ID.i = -1, circlesprite_o_ID.i = -1
  Declare init(resolution.i)
  Declare destroy()
  Declare draw(x1.i,y1.i,x2.i,y2.i,color.i=-16776961,width.i=10,intensity.i = 255)
  Declare drawwindow(x.i,y.i,width.i,height.i,color.i=-16776961,intensity.i = 255)
  Declare drawcircle(x.i,y.i,radius,color.i=-16776961,intensity.i = 255)
  Declare drawcircleoutline(x.i,y.i,radius,color.i=-16776961,intensity.i = 255)
EndDeclareModule

Module line
  Procedure init(resolution.i)
    line::sprite_ID = CreateSprite(#PB_Any,1,1,#PB_Sprite_AlphaBlending)
    If Not IsSprite(line::sprite_ID) : ProcedureReturn #False : EndIf
    StartDrawing(SpriteOutput(line::sprite_ID))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Box(0,0,OutputWidth(),OutputHeight(),RGBA(255,255,255,255))
    StopDrawing()
    
    line::circlesprite_ID = CreateSprite(#PB_Any,resolution.i,resolution.i,#PB_Sprite_AlphaBlending)
    If Not IsSprite(circlesprite_ID) : ProcedureReturn #False : EndIf
    StartDrawing(SpriteOutput(line::circlesprite_ID))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Circle(OutputWidth()/2,OutputHeight()/2,OutputWidth()/2,RGBA(255,255,255,255))
    StopDrawing()
    
    line::circlesprite_o_ID = CreateSprite(#PB_Any,resolution.i,resolution.i,#PB_Sprite_AlphaBlending)
    If Not IsSprite(circlesprite_o_ID) : ProcedureReturn #False : EndIf
    StartDrawing(SpriteOutput(line::circlesprite_o_ID))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Circle(OutputWidth()/2,OutputHeight()/2,OutputWidth()/2,RGBA(255,255,255,255))
    Circle(OutputWidth()/2,OutputHeight()/2,OutputWidth()/2-20,RGBA(0,0,0,0))
    StopDrawing()

    
    line::initialized = #True : ProcedureReturn #True  
  EndProcedure

  Procedure destroy()
    If IsSprite(line::sprite_ID) : FreeSprite(line::sprite_ID) : EndIf : line::initialized = #False
  EndProcedure
  
  Procedure draw(x1.i,y1.i,x2.i,y2.i,color.i=-16776961,width.i=10,intensity.i = 255)
    ;MIJIKAI and STARGATE code
    Protected.f length, dx, dy
    length = Sqr((X1-X2)*(X1-X2) + (Y1-Y2)*(Y1-Y2))
    dy = (X2-X1)*Width/(2*length)
    dx = (Y1-Y2)*Width/(2*length)
    ZoomSprite(line::sprite_ID,length,length)
    TransformSprite(line::sprite_ID, X1-dx, Y1-dy, X2-dx, Y2-dy, X2+dx, Y2+dy, X1+dx, Y1+dy)
    DisplayTransparentSprite(line::sprite_ID,0,0,intensity,color)
  EndProcedure
  
  Procedure drawwindow(x.i,y.i,width.i,height.i,color.i=-16776961,intensity.i = 255)
    ZoomSprite(line::sprite_ID,width,heigth)
    TransformSprite(line::sprite_ID, x, y, x+width, Y, X+width, Y+height, X, Y+height)
    DisplayTransparentSprite(line::sprite_ID,0,0,intensity,color)
    line::draw(x,y,x+width,y,RGBA(255,255,255,255),1,255)
    line::draw(x,y+height,x+width,y+height,RGBA(255,255,255,255),1,255)
    line::draw(x,y,x,y+height,RGBA(255,255,255,255),1,255)
    line::draw(x+width,y,x+width,y+height,RGBA(255,255,255,255),1,255)
  EndProcedure
  
  Procedure drawcircle(x.i,y.i,radius,color.i=-16776961,intensity.i = 255)
    Protected hradius.f =radius/2
    ZoomSprite(line::circlesprite_ID,radius,radius)
    DisplayTransparentSprite(line::circlesprite_ID,x,y,intensity,color)
  EndProcedure
  
  Procedure drawcircleoutline(x.i,y.i,radius,color.i=-16776961,intensity.i = 255)
    Protected hradius.f =radius/2
    ZoomSprite(line::circlesprite_O_ID,radius,radius)
    DisplayTransparentSprite(line::circlesprite_o_ID,x,y,intensity,color)
  EndProcedure

EndModule

DeclareModule petskii
  Declare init()
  Declare textout(x,y,text.s,color.i,intensity.i=255)
  Declare textoutlined(x,y,text.s,color.i,outlinecolor.i,intensity.i=255)
  Declare destroy()
EndDeclareModule

Module petskii
;-HIDDEN VARIABLES/CONSTANTS  
  #USED_CHARACTERS="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+[{]};:',<.>/?"+Chr(34)
  Global Dim petskiifont(370):Global Dim fontimport.i(370)
;-SUB PROCEDURES
  Procedure sub_loadfont()
    Protected x.i,i.i,j.i,sprline.a
    For i = 1 To Len(#USED_CHARACTERS):fontImport(Asc(Mid(#USED_CHARACTERS,i,1)))=1 : Next i 
    Restore petskii_font
      For x= 1 To 370
        If fontimport(x)=1
          petskiifont(x)=CreateSprite(-1,8,12,#PB_Sprite_AlphaBlending)
          StartDrawing(SpriteOutput(petskiifont(x)))
          DrawingMode(#PB_2DDrawing_AllChannels)
          For j=0 To 11  
            Read.a sprline 
            For i=0 To 7
              If sprline&%1 :Plot(i,j,RGBA(255,255,255,255)): Else : Plot(i,j,RGBA(0,0,0,0)) : EndIf
              sprline>>1 
            Next i
          Next j
          StopDrawing()
          ZoomSprite(petskiifont(x),16,24)
        EndIf
      Next x
  EndProcedure
  
  ;-PUBLIC PROCEDURES  
  Procedure init()
    sub_loadfont()
  EndProcedure
  
  Procedure textout(x,y,text.s,color.i,intensity.i=255) : Protected.i textlength,i,character
    textlength.i = Len(text.s)
    For i = 1 To textlength.i
      character.i = Asc(Mid(text.s,i,1))
      If IsSprite(petskiifont(character))
        DisplayTransparentSprite(petskiifont(character),(x+((i-1) * 16)),(y),intensity,color.i)
      EndIf
    Next i
  EndProcedure
  
  Procedure textoutlined(x,y,text.s,color.i,outlinecolor.i,intensity=255)
    textout(x-2,y,text.s,outlinecolor,intensity)
    textout(x+2,y,text.s,outlinecolor,intensity)
    textout(x,y-2,text.s,outlinecolor,intensity)
    textout(x,y+2,text.s,outlinecolor,intensity)
    textout(x,y,text.s,color,intensity)
  EndProcedure
  
  
  Procedure destroy()
    Protected i.i
    For i = 1 To Len(#USED_CHARACTERS)
      If IsSprite(petskiifont(i)) : FreeSprite(petskiifont(i)) : EndIf
    Next i
  EndProcedure
  
  ;-MODULE DATA
  DataSection
  petskii_font:
  Data.a $00,$00,$38,$38,$38,$38,$38,$38,$00,$38,$00,$00,$00,$00,$EE,$EE,$EE,$00,$00,$00,$00,$00,$00,$00,$00,$00,$EE,$EE,$EE,$FF,$EE,$FF,$EE,$EE,$00,$00,$00,$00,$38,$38,$FC,$0E,$7C,$E0,$7E,$38,$00,$00
  Data.a $00,$00,$CE,$CE,$EE,$70,$38,$1C,$EE,$E6,$00,$00,$00,$00,$7C,$7C,$EE,$7C,$3C,$EE,$EE,$FC,$00,$00,$00,$00,$E0,$E0,$70,$38,$00,$00,$00,$00,$00,$00,$00,$00,$70,$70,$38,$1C,$1C,$1C,$38,$70,$00,$00
  Data.a $00,$00,$1C,$1C,$38,$70,$70,$70,$38,$1C,$00,$00,$00,$00,$00,$00,$EE,$7C,$FF,$7C,$EE,$00,$00,$00,$00,$00,$00,$00,$38,$38,$FE,$38,$38,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$38,$38,$1C,$00
  Data.a $00,$00,$00,$00,$00,$00,$FE,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$38,$38,$00,$00,$00,$00,$00,$00,$C0,$E0,$70,$38,$1C,$0E,$00,$00,$00,$00,$7C,$7C,$EE,$FE,$FE,$EE,$EE,$7C,$00,$00
  Data.a $00,$00,$38,$38,$38,$3C,$38,$38,$38,$FE,$00,$00,$00,$00,$7C,$7C,$EE,$E0,$70,$1C,$0E,$FE,$00,$00,$00,$00,$7C,$7C,$EE,$E0,$78,$E0,$EE,$7C,$00,$00,$00,$00,$E0,$E0,$F0,$F8,$EE,$FE,$E0,$E0,$00,$00
  Data.a $00,$00,$FE,$FE,$0E,$7E,$E0,$E0,$EE,$7C,$00,$00,$00,$00,$7C,$7C,$EE,$0E,$7E,$EE,$EE,$7C,$00,$00,$00,$00,$FE,$FE,$EE,$70,$38,$38,$38,$38,$00,$00,$00,$00,$7C,$7C,$EE,$EE,$7C,$EE,$EE,$7C,$00,$00
  Data.a $00,$00,$7C,$7C,$EE,$EE,$FC,$E0,$EE,$7C,$00,$00,$00,$00,$38,$38,$38,$00,$00,$00,$38,$38,$00,$00,$00,$00,$38,$38,$38,$00,$00,$00,$38,$38,$1C,$00,$00,$00,$F0,$F0,$38,$1C,$0E,$1C,$38,$F0,$00,$00
  Data.a $00,$00,$00,$00,$00,$FE,$00,$FE,$00,$00,$00,$00,$00,$00,$1E,$1E,$38,$70,$E0,$70,$38,$1E,$00,$00,$00,$00,$7C,$7C,$EE,$E0,$70,$38,$00,$38,$00,$00,$00,$00,$7C,$7C,$EE,$FE,$FE,$0E,$CE,$7C,$00,$00
  Data.a $00,$00,$38,$38,$7C,$EE,$FE,$EE,$EE,$EE,$00,$00,$00,$00,$7E,$7E,$EE,$EE,$7E,$EE,$EE,$7E,$00,$00,$00,$00,$7C,$7C,$EE,$0E,$0E,$0E,$EE,$7C,$00,$00,$00,$00,$3E,$3E,$7E,$EE,$EE,$EE,$7E,$3E,$00,$00
  Data.a $00,$00,$FE,$FE,$0E,$0E,$3E,$0E,$0E,$FE,$00,$00,$00,$00,$FE,$FE,$0E,$0E,$3E,$0E,$0E,$0E,$00,$00,$00,$00,$7C,$7C,$EE,$0E,$FE,$EE,$EE,$7C,$00,$00,$00,$00,$EE,$EE,$EE,$EE,$FE,$EE,$EE,$EE,$00,$00
  Data.a $00,$00,$7C,$7C,$38,$38,$38,$38,$38,$7C,$00,$00,$00,$00,$F8,$F8,$70,$70,$70,$70,$7E,$3C,$00,$00,$00,$00,$EE,$EE,$7E,$3E,$1E,$3E,$7E,$EE,$00,$00,$00,$00,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$FE,$00,$00
  Data.a $00,$00,$CE,$CE,$FE,$FE,$FE,$CE,$CE,$CE,$00,$00,$00,$00,$EE,$EE,$FE,$FE,$FE,$FE,$EE,$EE,$00,$00,$00,$00,$7C,$7C,$EE,$EE,$EE,$EE,$EE,$7C,$00,$00,$00,$00,$7E,$7E,$EE,$EE,$7E,$0E,$0E,$0E,$00,$00
  Data.a $00,$00,$7C,$7C,$EE,$EE,$EE,$EE,$7C,$F0,$00,$00,$00,$00,$7E,$7E,$EE,$EE,$7E,$3E,$7E,$EE,$00,$00,$00,$00,$7C,$7C,$EE,$0E,$7C,$E0,$EE,$7C,$00,$00,$00,$00,$FE,$FE,$38,$38,$38,$38,$38,$38,$00,$00
  Data.a $00,$00,$EE,$EE,$EE,$EE,$EE,$EE,$EE,$7C,$00,$00,$00,$00,$EE,$EE,$EE,$EE,$EE,$EE,$7C,$38,$00,$00,$00,$00,$CE,$CE,$CE,$CE,$FE,$FE,$FE,$CE,$00,$00,$00,$00,$EE,$EE,$EE,$7C,$38,$7C,$EE,$EE,$00,$00
  Data.a $00,$00,$EE,$EE,$EE,$EE,$7C,$38,$38,$38,$00,$00,$00,$00,$FE,$FE,$E0,$70,$38,$1C,$0E,$FE,$00,$00,$00,$00,$7C,$7C,$1C,$1C,$1C,$1C,$1C,$7C,$00,$00,$00,$00,$7C,$7C,$70,$70,$70,$70,$70,$7C,$00,$00
  Data.a $00,$00,$38,$38,$7C,$FE,$38,$38,$38,$38,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$00,$00,$00,$00,$00,$00,$00,$7C,$E0,$FC,$EE,$FC,$00,$00,$00,$00,$00,$00,$0E,$0E,$7E,$EE,$EE,$7E,$00,$00
  Data.a $00,$00,$00,$00,$00,$7C,$0E,$0E,$0E,$7C,$00,$00,$00,$00,$00,$00,$E0,$E0,$FC,$EE,$EE,$FC,$00,$00,$00,$00,$00,$00,$00,$7C,$EE,$FE,$0E,$7C,$00,$00,$00,$00,$00,$00,$F0,$38,$FC,$38,$38,$38,$00,$00
  Data.a $00,$00,$00,$00,$00,$FC,$EE,$EE,$FC,$E0,$7E,$00,$00,$00,$0E,$0E,$0E,$7E,$EE,$EE,$EE,$EE,$00,$00,$00,$00,$38,$38,$00,$3C,$38,$38,$38,$7C,$00,$00,$00,$00,$00,$00,$70,$00,$70,$70,$70,$70,$3C,$00
  Data.a $00,$00,$0E,$0E,$0E,$0E,$7E,$3E,$7E,$EE,$00,$00,$00,$00,$3C,$3C,$38,$38,$38,$38,$38,$7C,$00,$00,$00,$00,$00,$00,$00,$EE,$FE,$FE,$FE,$CE,$00,$00,$00,$00,$00,$00,$00,$7E,$EE,$EE,$EE,$EE,$00,$00
  Data.a $00,$00,$00,$00,$00,$7C,$EE,$EE,$EE,$7C,$00,$00,$00,$00,$00,$00,$00,$7E,$EE,$EE,$7E,$0E,$0E,$00,$00,$00,$00,$00,$00,$FC,$EE,$EE,$FC,$E0,$E0,$00,$00,$00,$00,$00,$00,$7E,$EE,$0E,$0E,$0E,$00,$00
  Data.a $00,$00,$00,$00,$00,$FC,$0E,$7C,$E0,$7E,$00,$00,$00,$00,$00,$00,$38,$FE,$38,$38,$38,$F0,$00,$00,$00,$00,$00,$00,$00,$EE,$EE,$EE,$EE,$FC,$00,$00,$00,$00,$00,$00,$00,$EE,$EE,$EE,$7C,$38,$00,$00
  Data.a $00,$00,$00,$00,$00,$CE,$FE,$FE,$FC,$FC,$00,$00,$00,$00,$00,$00,$00,$EE,$7C,$38,$7C,$EE,$00,$00,$00,$00,$00,$00,$00,$EE,$EE,$EE,$FC,$70,$3E,$00,$00,$00,$00,$00,$00,$FE,$70,$38,$1C,$FE,$00,$00
  Data.a $00,$00,$F0,$F0,$38,$38,$1E,$38,$38,$F0,$00,$00,$00,$00,$1E,$1E,$38,$38,$F0,$38,$38,$1E,$00,$00
  EndDataSection
EndModule

DeclareModule stripes
  Global spr_id.i
  Global columns.i
  Declare create(size.i)
  Declare draw(animationsteps.f)  
EndDeclareModule

Module stripes
  Procedure.i Create(size.i)
    Protected img_stripe.i
    img_stripe=CreateImage(#PB_Any,size,size,24,RGBA(1,1,1,255))
    StartVectorDrawing(ImageVectorOutput(img_stripe))
      MovePathCursor(0,size) : AddPathLine(size/2,0) : AddPathLine(size,0) : AddPathLine(size/2,size) : ClosePath()
      VectorSourceColor(RGBA(255,128,0,255)) : FillPath()
    StopVectorDrawing()
    stripes::spr_id=CreateSprite(#PB_Any,size,size)
    StartDrawing(SpriteOutput(stripes::spr_id)) : DrawImage(ImageID(img_stripe),0,0) : StopDrawing()
    FreeImage(img_stripe)
    columns.i = ScreenWidth()/SpriteWidth(stripes::spr_id)
    If IsSprite(stripes::spr_id) :ProcedureReturn #True : EndIf
    ProcedureReturn #False  
  EndProcedure
  
  Procedure.i draw(animationstep.f)
    Protected i.i
    Static offset.f =0
    For i=-1 To columns+1
      DisplaySprite(stripes::spr_id,i*SpriteWidth(stripes::spr_id)+offset,0)
      DisplaySprite(stripes::spr_id,i*SpriteWidth(stripes::spr_id)-offset,ScreenHeight()-SpriteHeight(stripes::spr_id))
    Next i
    offset.f + animationstep.f
    If offset>SpriteWidth(stripes::spr_id) : offset -SpriteWidth(stripes::spr_id) : EndIf
  EndProcedure  
EndModule

;-MAINPROGRAM FILE START HERE

;-CONSTANTS
#MAINDESKTOP_H = 0
#WINDOW_H = 0
#WINDOW_WIDTH = 1366
#WINDOW_HEIGHT = 768
#WINDOW_FLAGS  = #PB_Window_Invisible|#PB_Window_BorderLess|#PB_Window_ScreenCentered
#MAINLOOP_DELAY = 1
#STRIPESIZE = 32
#STRIPESPEED = 2

#ship_count = 10000
#SPRSIZE = 5
#ARROWDIST = 20
#GRID_COUNT = 1500
#GRIDSIZE = 100

#LEFTBORDER = 0
#RIGHTBORDER = (1+#GRID_COUNT)*#GRIDSIZE
#TOPBORDER =0
#BOTTOMBORDER = (1+#GRID_COUNT)*#GRIDSIZE

#off = -45
#off2 = -225
#ROTATION_SPEED = 0.5
#MOUSEWHEEL_SENSITIVY = 0.05

#MINZOOM = 0.25
#MAXZOOM = 5
#MAX_INTENSITY = 255

#MUSICVOL =10

;-TYPES
Structure cameratype
  x.f
  y.f
  tx.f
  ty.f
  angle.f
  zoom.f
  tzoom.f
  scrollspeed.f
EndStructure

Structure spritetype
  spid.i
  ospid.i
  basesize.f
  hb.f
  x.f
  y.f
  destx.f
  desty.f
  angle.f
  tangle.f
  color.i
  speed.f
  linealpha.f
  name.s
EndStructure
#ALPHASTEP = 10
;-GLOBALS
Global.i airship_sprite_id , arrowsprite_ID, gridsprite_ID, gridsprite2_ID
Global camera.cameratype
Global Dim sprs.spritetype(#ship_count)
Global Dim grid.spritetype(#GRID_COUNT,#GRID_COUNT)
Global sincounter.f
Global music_id.i
Global Dim tiles.i(50)

;-AUXILIARY PROCEDURES

Procedure loadtiles()
  Protected imageid.i, i.i
  imageid = CatchImage(#PB_Any,?grasspng)
  
  For i=0 To 4
    tiles(i) = CreateSprite(#PB_Any,16,16)
    StartDrawing(SpriteOutput(tiles(i)))
    DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawAlphaImage(ImageID(imageid),0-i*16,0)
    StopDrawing()
  Next i
  
  
  
  imageid = CatchImage(#PB_Any,?deadgrasspng)
  tiles(5) = CreateSprite(#PB_Any,16,16)
  StartDrawing(SpriteOutput(tiles(5)))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawAlphaImage(ImageID(imageid),0,0)
  StopDrawing()
  
  tiles(6) = CreateSprite(#PB_Any,16,16)
  StartDrawing(SpriteOutput(tiles(6)))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawImage(ImageID(imageid),-16,0)
  StopDrawing()
  
  tiles(7) = CreateSprite(#PB_Any,16,16)
  StartDrawing(SpriteOutput(tiles(7)))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawImage(ImageID(imageid),-16,-16)
  StopDrawing()
    
  tiles(8) = CreateSprite(#PB_Any,16,16)
  StartDrawing(SpriteOutput(tiles(8)))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawImage(ImageID(imageid),0,-16)
  StopDrawing()
  FreeImage(imageid)
  
  imageid = CatchImage(#PB_Any,?treespng)
  tiles(9) = CreateSprite(#PB_Any,16,16,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(tiles(9)))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawAlphaImage(ImageID(imageid),0,0)
  StopDrawing()
    
  tiles(10) = CreateSprite(#PB_Any,16,16,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(tiles(10)))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawAlphaImage(ImageID(imageid),-16,0)
  StopDrawing()
    
  tiles(11) = CreateSprite(#PB_Any,16,16,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(tiles(11)))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawAlphaImage(ImageID(imageid),-32,0)
  StopDrawing()
    
  tiles(12) = CreateSprite(#PB_Any,16,16,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(tiles(12)))
  DrawingMode(#PB_2DDrawing_Default)
    DrawAlphaImage(ImageID(imageid),-48,0)
  StopDrawing()
FreeImage(imageid)
  
EndProcedure

Procedure.i floor(f.f)
  ProcedureReturn Round(f.f,#PB_Round_Down)
EndProcedure

Procedure.i ceil(f.f)
  ProcedureReturn Round(f.f,#PB_Round_Up)
EndProcedure

Procedure sub_checks()
  If #PB_Compiler_Debugger
    Debug "Please run without debugger"
    End
  EndIf
  
EndProcedure

Procedure sub_createsprite()
  loadtiles()
  
  airship_sprite_id.i=CreateSprite(#PB_Any,#SPRSIZE,#SPRSIZE,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(airship_sprite_id.i))
  DrawingMode(#PB_2DDrawing_Outlined|#PB_2DDrawing_AllChannels)
  Box(0,0,OutputWidth(),OutputHeight())
  StopDrawing()
  
  arrowsprite_ID.i=CreateSprite(#PB_Any,#SPRSIZE,#SPRSIZE,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(arrowsprite_ID.i))
  DrawingMode(#PB_2DDrawing_Outlined|#PB_2DDrawing_AllChannels)
  Box(#SPRSIZE/2,0,1,#SPRSIZE)
  Plot(#SPRSIZE/2-1,1):Plot(#SPRSIZE/2+1,1)
  StopDrawing()
  
  gridsprite_ID.i=CreateSprite(#PB_Any,#GRIDSIZE,#GRIDSIZE,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(gridsprite_ID.i))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
  Box(0,0,OutputWidth(),OutputHeight(),RGBA(0,50,0,255))
  Protected x.i
  For x = 1 To 1000
    Plot(Random(OutputWidth()-1),Random(OutputHeight()-1),RGBA(Random(10),20+Random(50),Random(10),255))
  Next x
  StopDrawing()
  
  gridsprite2_ID.i=CreateSprite(#PB_Any,#GRIDSIZE,#GRIDSIZE,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(gridsprite2_ID.i))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
  Box(0,0,OutputWidth(),OutputHeight(),RGBA(0,0,50,255))
  
  For x = 1 To 1000
    Plot(Random(OutputWidth()-1),Random(OutputHeight()-1),RGBA(Random(40),Random(40),40+Random(80),255))
  Next x

  
  StopDrawing()
EndProcedure

Procedure sub_camerasetup()
  With camera
    \x=ScreenWidth()*2
    \y=ScreenHeight()*2
    \tx=\x
    \ty=\y
    \angle = 0
    \zoom = 2.0
    \tzoom = 0.25
    \scrollspeed = 2.0
  EndWith
EndProcedure

Procedure sub_airship_setup()
  Protected x.i
  For x = 0 To #ship_count
    With sprs(x)
      \spid = airship_sprite_id
      \x = Random(#GRID_COUNT*#GRIDSIZE)/20
      \y = Random(#GRID_COUNT*#GRIDSIZE)/20
      \destx = \x
      \desty = \y
      \tangle = Random(359)
      \angle = \tangle
      \basesize = 40.0
      \hb = \basesize/2.0
      \speed = (5+Random(5,1))/2
      \color.i = RGBA(255,5,5,255)
    EndWith
  Next x
EndProcedure

Procedure sub_grid_setup()
  Protected i.i,j.i
  For i = 0 To #grid_count
    For j = 0 To #grid_count
      With grid(i,j)
        
        \spid = tiles(0)
        \name = "Water"
        
        \x = i*#GRIDSIZE
        \y = j*#GRIDSIZE
        \destx = i*#GRIDSIZE
        \desty = j*#GRIDSIZE
        \tangle = 0
        \angle = 0
        \basesize = #GRIDSIZE
        \hb = \basesize/2.0
        \color.i = RGBA(0+Random(10),Random(Random(55)+25),0+Random(10),255)
     EndWith
    Next j
  Next i
  Protected x.i
  
  
  For x = i To 15000
    i=Random(Random(80,20)*#GRID_COUNT/100+Random(6,1)-3)
    j=Random(Random(80,20)*#GRID_COUNT/100+Random(6,1)-3)
    grid(i,j)\spid = tiles(Random(8,1))
    grid(i,j)\name = "Land"
  Next x
  
  
  
  For x = i To 5000
    i=Random(#GRID_COUNT)
    j=Random(#GRID_COUNT)
    grid(i,j)\spid = tiles(Random(8,1))
    grid(i,j)\name = "Land"
  Next x
  
  For x = i To 2000000
    i=Random(#GRID_COUNT-1,1)
    j=Random(#GRID_COUNT-1,1)
    If grid(i+1,j)\spid<>tiles(0) Or grid(i-1,j)\spid<>tiles(0) Or grid(i,j+1)\spid<>tiles(0) Or grid(i-1,j)\spid<>tiles(0)
      grid(i,j)\spid = tiles(Random(8,1))
      grid(i,j)\name = "Land"
    EndIf
    
      If grid(i+1,j+1)\spid<>tiles(0) Or grid(i-1,j+1)\spid<>tiles(0) Or grid(i+1,j-1)\spid<>tiles(0) Or grid(i-1,j-1)\spid<>tiles(0)
        grid(i,j)\spid = tiles(Random(8,1))
        grid(i,j)\name = "Land"
    EndIf

  Next x
  
      
  For i = 0 To #grid_count
    For j = 0 To #grid_count
      With grid(i,j)
        If \spid =tiles(1) Or \spid =tiles(2) 
          If Random(4)<2
            \ospid = tiles(10+Random(2))
            grid(i,j)\name = "Forest"
          EndIf
        EndIf
       
        If \spid =tiles(5) Or \spid =tiles(8) 
          If Random(4)<2
            \ospid = tiles(9)
            grid(i,j)\name = "Cleared Forest"
          EndIf
        EndIf
     EndWith
    Next j
  Next i
  
  
  
EndProcedure

Procedure sub_draw_UI()
    Protected cw = 1.5*#GRIDSIZE*camera\zoom
    line::drawcircleoutline(ScreenWidth()/2-cw/2,ScreenHeight()/2-cw/2,cw,RGBA(0,0,0,255),255)
    line::drawcircleoutline(ScreenWidth()/2-5,ScreenHeight()/2-5,10,RGBA(0,0,0,255),255)

  stripes::draw(#STRIPESPEED)
  line::drawwindow(1,32,450,185,RGBA(5,5,5,255),200)
    petskii::textoutlined(5,2,"mouse = Scroll",RGBA(255,0,0,255),RGBA(5,5,5,5))
    petskii::textoutlined(350,2,"mwheel = zoom",RGBA(0,255,0,255),RGBA(5,5,5,255))
    
    
    Protected tilex.i,tiley.i
    tilex=Abs(((#GRIDSIZE/2+camera\x)/#GRIDSIZE)-1)
    tiley = Abs(((#GRIDSIZE/2+camera\y)/#GRIDSIZE)-1)
    
    petskii::textoutlined(700,2,"mousebutton left+right = rotate direction",RGBA(255,255,55,255),RGBA(5,5,5,255))
    petskii::textoutlined(450,741,"mousebutton middle = move",RGBA(255,255,255,255),RGBA(5,5,5,255))
    petskii::textoutlined(1150,741,"Escape = Quit",RGBA(255,55,55,255),RGBA(5,5,5,255))
    petskii::textoutlined(5,38,"Zoom level = ",RGBA(5,5,5,255),RGBA(255,5,5,255))
    petskii::textoutlined(210,38,StrF(camera\zoom,0),RGBA(5,5,5,255),RGBA(255,255,125,255))
    
    petskii::textoutlined(5,60,"Camera Tile = ",RGBA(5,5,5,255),RGBA(155,155,250,255))
    petskii::textoutlined(215,60," ("+Str(tilex)+","+Str(tiley)+")",RGBA(155,155,250,255),RGBA(5,5,5,255))
    petskii::textoutlined(5,132,grid(tilex,tiley)\name,RGBA(5,5,5,255),RGBA(155,155,250,255))
    
    petskii::textoutlined(5,82,"Number of Tiles = "+Str(#GRID_COUNT*#GRID_COUNT),RGBA(255,200,0,255),RGBA(5,5,5,5))
    petskii::textoutlined(5,104,"Number of Ships = "+Str(#ship_count),RGBA(255,200,0,255),RGBA(5,5,5,5))
    line::drawwindow(1,696,1002,32,RGBA(5,5,5,255),200)
    petskii::textoutlined(5,700,"Thank's to Mijikai and Stargate for the awesome line function! ",RGBA(255,255,100,255),RGBA(5,5,5,255))
    
    Protected mem.i = MemoryStatus(#PB_System_FreePhysical)/(1024*1024)
    If mem>2024
      petskii::textoutlined(5,190,"Free Memory = "+Str(mem)+" Mb",RGBA(55,255,0,255),RGBA(5,5,5,5))
    ElseIf mem<1000
      petskii::textoutlined(5,190,"Free Memory = "+Str(mem)+" Mb",RGBA(255,20,0,255),RGBA(5,5,5,5))
    Else
      petskii::textoutlined(5,190,"Free Memory = "+Str(mem)+" Mb",RGBA(255,200,0,255),RGBA(5,5,5,5))
    EndIf
    ;If IsMusic(music_id) : petskii::textoutlined(5,168,"Music row: = "+Str(GetMusicRow(music_id)),RGBA(55,255,0,255),RGBA(5,5,5,5)) :EndIf
    ;If IsMusic(music_id) : petskii::textoutlined(5,190,"Music Pos: = "+Str(GetMusicPosition(music_id)),RGBA(55,255,0,255),RGBA(5,5,5,5)) :EndIf
    If GetMusicPosition(music_id) = 255 :  SetMusicPosition(music_id,0) : EndIf
    petskii::textoutlined(5,741,FormatDate("%hh:%ii:%ss",Date()),RGBA(255,255,55,255),RGBA(5,5,5,255))
EndProcedure

Procedure Load_Music()
  music_id=CatchMusic(#PB_Any,?music_start,?music_end-?music_start)
  PlayMusic(music_id)
  MusicVolume(music_id,#MUSICVOL)        
EndProcedure


;-PROCEDURES
Procedure app_start()
  sub_checks()
  ExamineDesktops()
  InitMouse()
  InitSprite()
  InitSound()
  InitKeyboard()
  OpenWindow(#WINDOW_H,0,0,#WINDOW_WIDTH,#WINDOW_HEIGHT,"2d Zoom Camera",#WINDOW_FLAGS)
  OpenWindowedScreen(WindowID(#WINDOW_H),0,0,#WINDOW_WIDTH,#WINDOW_HEIGHT,1,0,0,#PB_Screen_WaitSynchronization)
  ResizeWindow(#WINDOW_H,0,0,DesktopUnscaledX(DesktopWidth(#MAINDESKTOP_H)),DesktopUnscaledY(DesktopHeight(#MAINDESKTOP_H)))
  HideWindow(#WINDOW_H,#False)
  petskii::init()
  sub_createsprite()
  stripes::Create(#STRIPESIZE)
  sub_camerasetup()
  sub_airship_setup()
  sub_grid_setup()
  line::init(256)
  Load_Music()
EndProcedure


Procedure controls_update()
  Protected x.i, multiplier.i
    If MouseButton(#PB_MouseButton_Left)
    For x = 0 To #ship_count
      sprs(x)\tangle - #ROTATION_SPEED
    Next x
  EndIf
  
  If MouseButton(#PB_MouseButton_Right)
    For x = 0 To #ship_count
      sprs(x)\tangle + #ROTATION_SPEED
    Next x
  EndIf
  
  multiplier.i = (2*camera\zoom)
  If multiplier<1 : multiplier = 1 : EndIf  :  If multiplier>20 : multiplier = 20 : EndIf
  
  camera\tx + camera\scrollspeed*((MouseDeltaX()/(multiplier*2)))
  camera\ty + camera\scrollspeed*((MouseDeltaY()/(multiplier*2)))
  
  If camera\tx<#LEFTBORDER : camera\tx=#LEFTBORDER : EndIf
  If camera\tx>#RIGHTBORDER : camera\tx=#RIGHTBORDER : EndIf
  If camera\ty<#TOPBORDER : camera\ty=#TOPBORDER : EndIf
  If camera\ty>#BOTTOMBORDER : camera\ty=#BOTTOMBORDER : EndIf
  
  camera\x = camera\x*0.9+camera\tx*0.1
  camera\y = camera\y*0.9+camera\ty*0.1
  camera\zoom = camera\zoom*0.95+camera\tzoom*0.05
  
  For x = 0 To #ship_count
    sprs(x)\angle = sprs(x)\angle*0.9+sprs(x)\tangle*01
  Next x
    
  If MouseButton(#PB_MouseButton_Middle)
    For x = 0 To #ship_count
      sprs(x)\destx = sprs(x)\x- Sin(Radian(#off2+sprs(x)\angle))*sprs(x)\speed-Cos(Radian(#off2+sprs(x)\angle))*sprs(x)\speed
      sprs(x)\desty = sprs(x)\y-(-Cos(Radian(#off2+sprs(x)\angle)))*sprs(x)\speed-Sin(Radian(#off2+sprs(x)\angle))*sprs(x)\speed
    Next x
  EndIf
  
  If MouseWheel()<>0
    camera\tzoom=camera\tzoom+MouseWheel() * #MOUSEWHEEL_SENSITIVY * multiplier
    If camera\tzoom<#MINZOOM : camera\tzoom = #MINZOOM : EndIf
    If camera\tzoom>#MAXZOOM : camera\tzoom = #MAXZOOM : EndIf
  EndIf
EndProcedure

Procedure draw_gridmap()
  Protected.i startgridx,endgridx,startgridy,endgridy, i.i, j.i,trx.f,try.f
  For i = 0 To 15
    If IsSprite(tiles(i))
      ZoomSprite(tiles(i),ceil(grid(1,1)\basesize*camera\zoom),ceil(grid(1,1)\basesize*camera\zoom))
    EndIf
  Next i
  
  For i = 0 To #grid_count
    trx = floor(i*(#gridsize)-(camera\x)+ScreenWidth())
    If trx>-ScreenWidth()-4*SpriteWidth(grid(i,0)\spid)
      startgridx = i 
      endgridx = startgridx+55 :
      If endgridx > #GRID_COUNT : endgridx = #GRID_COUNT : EndIf
      i = #grid_count
    EndIf
  Next i
  
  For i = 0 To #grid_count
    try = floor(i*(#gridsize)-(camera\y)+ScreenHeight())
    If try>-ScreenHeight()-SpriteHeight(grid(i,0)\spid)
      startgridy = i 
      endgridy = startgridy+29 
      If endgridy > #GRID_COUNT : endgridy = #GRID_COUNT : EndIf
      i = #grid_count
    EndIf
  Next i
  
  For i = startgridx To endgridx
    For j = startgridy To endgridy
      With grid(i,j)
        trx = floor(i*(#gridsize*camera\zoom)-(camera\x*camera\zoom)+ScreenWidth()/2)
        try = floor(j*(#gridsize*camera\zoom)-(camera\y*camera\zoom)+ScreenHeight()/2)
        DisplayTransparentSprite(\spid,trx,try)
        If \ospid<>0 : DisplayTransparentSprite(\ospid,trx,try) : EndIf
      EndWith
    Next j
  Next i
EndProcedure


Procedure draw_ships()
  Protected x.i,trx.f,try.f,tmod.f
  ZoomSprite(airship_sprite_id,2*sprs(0)\hb*camera\zoom,2*sprs(0)\hb*camera\zoom)
  ZoomSprite(arrowsprite_ID,2*sprs(0)\hb*camera\zoom,2*sprs(0)\hb*camera\zoom)
  
  For x = 0 To #ship_count
    With sprs(x)
      trx = \x*(\basesize*camera\zoom)-(camera\x*camera\zoom)+ScreenWidth()/2
      try = \y*(\basesize*camera\zoom)-(camera\y*camera\zoom)+ScreenHeight()/2
      \x=\destx*0.05+\x*0.95
      \y=\desty*0.05+\y*0.95
      tmod = SpriteWidth(airship_sprite_id)/-2+SpriteWidth(arrowsprite_ID)*0.5
      RotateSprite(arrowsprite_ID,floor(\angle),#PB_Absolute)
      
      Protected coox.i,cooy.i
      coox = floor(trx+\hb*camera\zoom)
      cooy = floor(try+\hb*camera\zoom)
      
      Protected cw = 400      
      
      line::drawcircle(ScreenWidth()-(ScreenWidth()-coox)+\basesize/2*camera\zoom-cw/2*camera\zoom,ScreenHeight()-(ScreenHeight()-cooy)+\basesize/2*camera\zoom-cw/2*camera\zoom,cw*camera\zoom,RGBA(255,2,2,255),100)
      line::drawcircleoutline(ScreenWidth()-(ScreenWidth()-coox)+\basesize/2*camera\zoom-cw/2*camera\zoom,ScreenHeight()-(ScreenHeight()-cooy)+\basesize/2*camera\zoom-cw/2*camera\zoom,cw*camera\zoom,RGBA(255,2,2,255),150)
      DisplayTransparentSprite(\spid,coox,cooy,#MAX_INTENSITY,\color)
        
        If ScreenWidth()-trx<ScreenWidth() And ScreenHeight()-try<ScreenHeight()-#STRIPESIZE/2
          If ScreenWidth()-trx>-10 And ScreenHeight()-try>#STRIPESIZE/2
            \linealpha+(#ALPHASTEP*2)
          EndIf
        EndIf
          
        If \linealpha<0 :\linealpha=0 : EndIf
        If \linealpha>0
          \linealpha-#ALPHASTEP
        EndIf
        
        If \linealpha>255 :\linealpha=255 : EndIf
        
        If floor(\linealpha)>0
          
          ;SpriteBlendingMode(#PB_Sprite_BlendDestinationAlpha,#PB_Sprite_BlendDestinationColor)
          line::draw(ScreenWidth()/2,ScreenHeight()/2,ScreenWidth()-(ScreenWidth()-coox)+\basesize/2*camera\zoom,ScreenHeight()-(ScreenHeight()-cooy)+\basesize/2*camera\zoom,RGBA(0,100,0,255),4,floor(\linealpha))        
          petskii::textoutlined(ScreenWidth()-(ScreenWidth()-coox)+\basesize/2*camera\zoom,ScreenHeight()-(ScreenHeight()-cooy)+\basesize/2*camera\zoom,"Airship_"+RSet(Str(x),5,"0"),RGBA(255,255,100,255),RGBA(5,5,5,255))
        EndIf
        
        DisplayTransparentSprite(arrowsprite_ID,floor(tmod+trx+SpriteWidth(airship_sprite_id)/2+((Sin(Radian(#off+\angle)))*#ARROWDIST*camera\zoom+Cos(Radian(#off+\angle))*#ARROWDIST*camera\zoom)),floor(tmod+try+SpriteWidth(airship_sprite_id)/2+(-Cos(Radian(#off+\angle)))*#ARROWDIST*camera\zoom+Sin(Radian(#off+\angle))*#ARROWDIST*camera\zoom))
    EndWith
  Next x
EndProcedure



Procedure app_update()
  Protected x.i,i.i,j.i, multiplier.i
  Protected ddist.f = camera\zoom*8
  Protected dx.f, dy.f, trx.f,try.f, tmod.f
  Delay(#MAINLOOP_DELAY)
  Repeat : Until Not WindowEvent()
  ClearScreen(0)
  ExamineKeyboard()
  ExamineMouse()
  
  controls_update()  
  draw_gridmap()  
  draw_ships()
  sub_Draw_UI()
  FlipBuffers()
EndProcedure
;-MAIN PROGRAM PROCEDURE
Procedure main()
  app_start()
  Repeat
    app_update()
  Until KeyboardPushed(#PB_Key_Escape)
  petskii::destroy()
  End
EndProcedure

;-MAIN PROGRAM
main()


DataSection
grasspng:
Data.a $89,$50,$4E,$47,$0D,$0A,$1A,$0A,$00,$00,$00,$0D,$49,$48,$44,$52,$00,$00,$00,$50,$00,$00,$00,$10,$08,$06,$00,$00,$00,$81,$49,$F8,$C1,$00,$00,$01
Data.a $85,$69,$43,$43,$50,$49,$43,$43,$20,$70,$72,$6F,$66,$69,$6C,$65,$00,$00,$28,$91,$7D,$91,$3D,$48,$C3,$40,$1C,$C5,$5F,$53,$4B,$45,$2A,$0E,$ED,$20
Data.a $22,$18,$B0,$3A,$59,$10,$15,$71,$94,$2A,$16,$C1,$42,$69,$2B,$B4,$EA,$60,$72,$E9,$87,$D0,$A4,$21,$49,$71,$71,$14,$5C,$0B,$0E,$7E,$2C,$56,$1D,$5C
Data.a $9C,$75,$75,$70,$15,$04,$C1,$0F,$10,$27,$47,$27,$45,$17,$29,$F1,$7F,$49,$A1,$45,$8C,$07,$C7,$FD,$78,$77,$EF,$71,$F7,$0E,$10,$1A,$15,$A6,$9A,$5D
Data.a $E3,$80,$AA,$59,$46,$3A,$11,$17,$73,$F9,$15,$31,$F8,$8A,$20,$C2,$08,$60,$08,$C3,$12,$33,$F5,$64,$66,$21,$0B,$CF,$F1,$75,$0F,$1F,$5F,$EF,$62,$3C
Data.a $CB,$FB,$DC,$9F,$A3,$57,$29,$98,$0C,$F0,$89,$C4,$B3,$4C,$37,$2C,$E2,$75,$E2,$E9,$4D,$4B,$E7,$BC,$4F,$1C,$61,$65,$49,$21,$3E,$27,$1E,$33,$E8,$82
Data.a $C4,$8F,$5C,$97,$5D,$7E,$E3,$5C,$72,$58,$E0,$99,$11,$23,$9B,$9E,$23,$8E,$10,$8B,$A5,$0E,$96,$3B,$98,$95,$0D,$95,$78,$8A,$38,$AA,$A8,$1A,$E5,$0B
Data.a $39,$97,$15,$CE,$5B,$9C,$D5,$4A,$8D,$B5,$EE,$C9,$5F,$18,$2A,$68,$CB,$19,$AE,$D3,$1C,$44,$02,$8B,$48,$22,$05,$11,$32,$6A,$D8,$40,$05,$16,$62,$B4
Data.a $6A,$A4,$98,$48,$D3,$7E,$DC,$C3,$3F,$E0,$F8,$53,$E4,$92,$C9,$B5,$01,$46,$8E,$79,$54,$A1,$42,$72,$FC,$E0,$7F,$F0,$BB,$5B,$B3,$38,$39,$E1,$26,$85
Data.a $E2,$40,$E0,$C5,$B6,$3F,$46,$80,$E0,$2E,$D0,$AC,$DB,$F6,$F7,$B1,$6D,$37,$4F,$00,$FF,$33,$70,$A5,$B5,$FD,$D5,$06,$30,$F3,$49,$7A,$BD,$AD,$45,$8F
Data.a $80,$BE,$6D,$E0,$E2,$BA,$AD,$C9,$7B,$C0,$E5,$0E,$D0,$FF,$A4,$4B,$86,$E4,$48,$7E,$9A,$42,$B1,$08,$BC,$9F,$D1,$37,$E5,$81,$F0,$2D,$D0,$B3,$EA,$F6
Data.a $D6,$DA,$C7,$E9,$03,$90,$A5,$AE,$96,$6E,$80,$83,$43,$60,$B4,$44,$D9,$6B,$1E,$EF,$EE,$EE,$EC,$ED,$DF,$33,$AD,$FE,$7E,$00,$7C,$89,$72,$AB,$1A,$50
Data.a $E7,$4E,$00,$00,$00,$06,$62,$4B,$47,$44,$00,$93,$00,$67,$00,$4D,$2A,$10,$06,$37,$00,$00,$00,$09,$70,$48,$59,$73,$00,$00,$0B,$13,$00,$00,$0B,$13
Data.a $01,$00,$9A,$9C,$18,$00,$00,$00,$07,$74,$49,$4D,$45,$07,$E4,$07,$13,$06,$02,$1A,$7A,$54,$30,$1F,$00,$00,$00,$19,$74,$45,$58,$74,$43,$6F,$6D,$6D
Data.a $65,$6E,$74,$00,$43,$72,$65,$61,$74,$65,$64,$20,$77,$69,$74,$68,$20,$47,$49,$4D,$50,$57,$81,$0E,$17,$00,$00,$00,$BB,$49,$44,$41,$54,$58,$C3,$63
Data.a $F4,$DB,$B3,$F3,$3F,$03,$05,$A0,$54,$6A,$1E,$25,$DA,$19,$DE,$FD,$FD,$4B,$91,$7E,$33,$26,$7B,$86,$AF,$EF,$5F,$C3,$F9,$DC,$82,$A2,$0C,$0C,$0C,$0C
Data.a $28,$62,$C8,$E2,$C8,$72,$DC,$82,$A2,$58,$F5,$92,$02,$98,$18,$86,$01,$E0,$16,$14,$85,$63,$6C,$72,$E4,$8A,$11,$02,$5F,$DF,$BF,$1E,$1E,$01,$88,$2B
Data.a $50,$89,$0D,$30,$72,$02,$6F,$58,$A5,$40,$62,$02,$91,$56,$60,$58,$07,$20,$AD,$03,$99,$5B,$50,$74,$34,$00,$29,$05,$2C,$A3,$41,$40,$1E,$80,$D5,$DE
Data.a $4C,$A3,$01,$F1,$1A,$A3,$C9,$43,$6C,$E0,$8D,$A6,$40,$32,$CB,$40,$E4,$B6,$E6,$68,$19,$48,$61,$16,$1E,$2D,$03,$29,$4C,$B9,$A3,$29,$70,$B4,$1D,$38
Data.a $1A,$80,$54,$29,$8B,$06,$42,$FF,$B0,$A9,$44,$70,$05,$02,$BE,$C0,$41,$96,$23,$27,$10,$87,$5D,$25,$82,$3C,$44,$45,$AC,$5A,$52,$F4,$E0,$AA,$44,$00
Data.a $0C,$38,$49,$A7,$A3,$33,$11,$6F,$00,$00,$00,$00,$49,$45,$4E,$44,$AE,$42,$60,$82
EndDataSection

DataSection
deadgrasspng:
Data.a $89,$50,$4E,$47,$0D,$0A,$1A,$0A,$00,$00,$00,$0D,$49,$48,$44,$52,$00,$00,$00,$30,$00,$00,$00,$20,$08,$06,$00,$00,$00,$54,$D4,$FB,$1C,$00,$00,$01
Data.a $85,$69,$43,$43,$50,$49,$43,$43,$20,$70,$72,$6F,$66,$69,$6C,$65,$00,$00,$28,$91,$7D,$91,$3D,$48,$C3,$40,$18,$86,$DF,$A6,$4A,$45,$2A,$0E,$16,$14
Data.a $71,$08,$58,$5D,$B4,$20,$2A,$E2,$28,$55,$2C,$82,$85,$D2,$56,$68,$D5,$C1,$E4,$D2,$3F,$68,$D2,$90,$A4,$B8,$38,$0A,$AE,$05,$07,$7F,$16,$AB,$0E,$2E
Data.a $CE,$BA,$3A,$B8,$0A,$82,$E0,$0F,$88,$93,$A3,$93,$A2,$8B,$94,$F8,$5D,$52,$68,$11,$E3,$1D,$C7,$3D,$BC,$F7,$BD,$2F,$77,$DF,$01,$42,$BD,$CC,$54,$B3
Data.a $63,$02,$50,$35,$CB,$48,$C6,$A2,$62,$26,$BB,$2A,$06,$5E,$11,$44,$3F,$CD,$31,$0C,$4B,$CC,$D4,$E3,$A9,$C5,$34,$3C,$C7,$D7,$3D,$7C,$7C,$BF,$8B,$F0
Data.a $2C,$EF,$BA,$3F,$47,$8F,$92,$33,$19,$E0,$13,$89,$E7,$98,$6E,$58,$C4,$1B,$C4,$33,$9B,$96,$CE,$79,$9F,$38,$C4,$8A,$92,$42,$7C,$4E,$3C,$6E,$D0,$05
Data.a $89,$1F,$B9,$2E,$BB,$FC,$C6,$B9,$E0,$B0,$C0,$33,$43,$46,$3A,$39,$4F,$1C,$22,$16,$0B,$6D,$2C,$B7,$31,$2B,$1A,$2A,$F1,$34,$71,$58,$51,$35,$CA,$17
Data.a $32,$2E,$2B,$9C,$B7,$38,$AB,$E5,$2A,$6B,$DE,$93,$BF,$30,$98,$D3,$56,$52,$5C,$A7,$35,$84,$18,$96,$10,$47,$02,$22,$64,$54,$51,$42,$19,$16,$22,$B4
Data.a $6B,$A4,$98,$48,$D2,$79,$D4,$C3,$3F,$E8,$F8,$13,$E4,$92,$C9,$55,$02,$23,$C7,$02,$2A,$50,$21,$39,$7E,$F0,$3F,$F8,$DD,$5B,$33,$3F,$35,$E9,$26,$05
Data.a $A3,$40,$E7,$8B,$6D,$7F,$8C,$00,$81,$5D,$A0,$51,$B3,$ED,$EF,$63,$DB,$6E,$9C,$00,$FE,$67,$E0,$4A,$6B,$F9,$2B,$75,$60,$F6,$93,$F4,$5A,$4B,$0B,$1F
Data.a $01,$BD,$DB,$C0,$C5,$75,$4B,$93,$F7,$80,$CB,$1D,$60,$E0,$49,$97,$0C,$C9,$91,$FC,$B4,$84,$7C,$1E,$78,$3F,$A3,$6F,$CA,$02,$7D,$B7,$40,$F7,$9A,$DB
Data.a $B7,$E6,$39,$4E,$1F,$80,$34,$F5,$6A,$F9,$06,$38,$38,$04,$46,$0B,$94,$BD,$EE,$F1,$EE,$AE,$F6,$BE,$FD,$5B,$D3,$EC,$DF,$0F,$DE,$34,$72,$D2,$94,$1E
Data.a $82,$6D,$00,$00,$00,$06,$62,$4B,$47,$44,$00,$E7,$00,$D5,$00,$93,$81,$F3,$95,$95,$00,$00,$00,$09,$70,$48,$59,$73,$00,$00,$0B,$13,$00,$00,$0B,$13
Data.a $01,$00,$9A,$9C,$18,$00,$00,$00,$07,$74,$49,$4D,$45,$07,$E4,$0C,$18,$01,$31,$37,$6E,$7E,$A9,$CF,$00,$00,$00,$19,$74,$45,$58,$74,$43,$6F,$6D,$6D
Data.a $65,$6E,$74,$00,$43,$72,$65,$61,$74,$65,$64,$20,$77,$69,$74,$68,$20,$47,$49,$4D,$50,$57,$81,$0E,$17,$00,$00,$01,$6C,$49,$44,$41,$54,$58,$C3,$ED
Data.a $97,$CD,$6A,$83,$40,$14,$85,$BF,$16,$91,$41,$74,$61,$98,$6C,$5C,$84,$AC,$F2,$92,$79,$AC,$42,$9F,$A4,$AB,$AC,$D2,$D2,$66,$53,$69,$16,$11,$11,$11
Data.a $DA,$8D,$77,$08,$1A,$FF,$D0,$29,$A4,$9D,$BB,$12,$9D,$39,$73,$CE,$9C,$C3,$8C,$F7,$E1,$F9,$69,$FF,$CD,$1D,$D7,$23,$77,$5E,$4E,$C0,$9F,$14,$B0,$59
Data.a $EF,$D8,$AC,$77,$00,$14,$79,$49,$91,$97,$AD,$F7,$4B,$CD,$B3,$22,$E0,$ED,$F3,$60,$16,$56,$81,$6F,$9E,$AF,$BF,$0D,$CD,$03,$50,$81,$3F,$38,$CF,$5B
Data.a $9A,$BC,$EC,$5A,$5E,$65,$00,$E8,$38,$21,$E5,$44,$5E,$65,$A4,$E7,$D3,$28,$F1,$3A,$4E,$50,$81,$8F,$8E,$13,$83,$23,$B8,$B2,$21,$D6,$1C,$90,$05,$DE
Data.a $3F,$8E,$00,$86,$F4,$18,$F2,$52,$CD,$39,$82,$D5,$24,$6F,$C5,$81,$6B,$CB,$A7,$90,$EE,$13,$D3,$17,$A5,$C5,$1D,$38,$BC,$BE,$98,$E8,$2C,$55,$82,$25
Data.a $D8,$D6,$23,$34,$36,$EF,$53,$5C,$C8,$AB,$EC,$66,$84,$AC,$9C,$42,$4B,$92,$1F,$C2,$74,$17,$99,$13,$F0,$DF,$05,$78,$A1,$E7,$3B,$07,$9C,$00,$27,$C0
Data.a $09,$68,$D7,$2A,$DE,$B2,$8A,$B7,$00,$64,$55,$49,$56,$95,$AD,$F7,$73,$C6,$5B,$17,$F0,$75,$3E,$1A,$02,$72,$D2,$09,$11,$F9,$D6,$35,$1E,$20,$F4,$FC
Data.a $DE,$F1,$D6,$7E,$A7,$65,$07,$01,$54,$DD,$8C,$A8,$48,$C3,$25,$25,$AF,$32,$8A,$4B,$DA,$2B,$5A,$45,$9A,$D0,$F3,$51,$91,$36,$CD,$8C,$E0,$DD,$3A,$F2
Data.a $AD,$38,$20,$0B,$C9,$0F,$98,$90,$EE,$23,$6F,$3A,$BA,$C6,$58,$C1,$E8,$BA,$AF,$3C,$6B,$F9,$AF,$77,$74,$0C,$E9,$3E,$31,$43,$51,$B2,$DA,$D4,$AB,$48
Data.a $CF,$EF,$2F,$6A,$8C,$5F,$6B,$EA,$C5,$EE,$A1,$BC,$4F,$71,$81,$A8,$3B,$42,$D6,$4E,$A1,$25,$C8,$8F,$C1,$72,$17,$99,$13,$30,$B3,$7E,$00,$3E,$54,$C7
Data.a $DB,$58,$06,$50,$88,$00,$00,$00,$00,$49,$45,$4E,$44,$AE,$42,$60,$82
EndDataSection

DataSection
treespng:
Data.a $89,$50,$4E,$47,$0D,$0A,$1A,$0A,$00,$00,$00,$0D,$49,$48,$44,$52,$00,$00,$00,$40,$00,$00,$00,$10,$08,$06,$00,$00,$00,$A6,$E7,$79,$29,$00,$00,$01
Data.a $85,$69,$43,$43,$50,$49,$43,$43,$20,$70,$72,$6F,$66,$69,$6C,$65,$00,$00,$28,$91,$7D,$91,$3D,$48,$C3,$40,$1C,$C5,$5F,$53,$4B,$45,$2A,$0E,$ED,$20
Data.a $22,$18,$B0,$3A,$59,$10,$15,$71,$94,$2A,$16,$C1,$42,$69,$2B,$B4,$EA,$60,$72,$E9,$87,$D0,$A4,$21,$49,$71,$71,$14,$5C,$0B,$0E,$7E,$2C,$56,$1D,$5C
Data.a $9C,$75,$75,$70,$15,$04,$C1,$0F,$10,$27,$47,$27,$45,$17,$29,$F1,$7F,$49,$A1,$45,$8C,$07,$C7,$FD,$78,$77,$EF,$71,$F7,$0E,$10,$1A,$15,$A6,$9A,$5D
Data.a $E3,$80,$AA,$59,$46,$3A,$11,$17,$73,$F9,$15,$31,$F8,$8A,$20,$C2,$08,$60,$08,$C3,$12,$33,$F5,$64,$66,$21,$0B,$CF,$F1,$75,$0F,$1F,$5F,$EF,$62,$3C
Data.a $CB,$FB,$DC,$9F,$A3,$57,$29,$98,$0C,$F0,$89,$C4,$B3,$4C,$37,$2C,$E2,$75,$E2,$E9,$4D,$4B,$E7,$BC,$4F,$1C,$61,$65,$49,$21,$3E,$27,$1E,$33,$E8,$82
Data.a $C4,$8F,$5C,$97,$5D,$7E,$E3,$5C,$72,$58,$E0,$99,$11,$23,$9B,$9E,$23,$8E,$10,$8B,$A5,$0E,$96,$3B,$98,$95,$0D,$95,$78,$8A,$38,$AA,$A8,$1A,$E5,$0B
Data.a $39,$97,$15,$CE,$5B,$9C,$D5,$4A,$8D,$B5,$EE,$C9,$5F,$18,$2A,$68,$CB,$19,$AE,$D3,$1C,$44,$02,$8B,$48,$22,$05,$11,$32,$6A,$D8,$40,$05,$16,$62,$B4
Data.a $6A,$A4,$98,$48,$D3,$7E,$DC,$C3,$3F,$E0,$F8,$53,$E4,$92,$C9,$B5,$01,$46,$8E,$79,$54,$A1,$42,$72,$FC,$E0,$7F,$F0,$BB,$5B,$B3,$38,$39,$E1,$26,$85
Data.a $E2,$40,$E0,$C5,$B6,$3F,$46,$80,$E0,$2E,$D0,$AC,$DB,$F6,$F7,$B1,$6D,$37,$4F,$00,$FF,$33,$70,$A5,$B5,$FD,$D5,$06,$30,$F3,$49,$7A,$BD,$AD,$45,$8F
Data.a $80,$BE,$6D,$E0,$E2,$BA,$AD,$C9,$7B,$C0,$E5,$0E,$D0,$FF,$A4,$4B,$86,$E4,$48,$7E,$9A,$42,$B1,$08,$BC,$9F,$D1,$37,$E5,$81,$F0,$2D,$D0,$B3,$EA,$F6
Data.a $D6,$DA,$C7,$E9,$03,$90,$A5,$AE,$96,$6E,$80,$83,$43,$60,$B4,$44,$D9,$6B,$1E,$EF,$EE,$EE,$EC,$ED,$DF,$33,$AD,$FE,$7E,$00,$7C,$89,$72,$AB,$1A,$50
Data.a $E7,$4E,$00,$00,$00,$06,$62,$4B,$47,$44,$00,$93,$00,$67,$00,$4D,$2A,$10,$06,$37,$00,$00,$00,$09,$70,$48,$59,$73,$00,$00,$0B,$13,$00,$00,$0B,$13
Data.a $01,$00,$9A,$9C,$18,$00,$00,$00,$07,$74,$49,$4D,$45,$07,$E4,$07,$13,$09,$14,$05,$E0,$98,$CF,$00,$00,$00,$00,$19,$74,$45,$58,$74,$43,$6F,$6D,$6D
Data.a $65,$6E,$74,$00,$43,$72,$65,$61,$74,$65,$64,$20,$77,$69,$74,$68,$20,$47,$49,$4D,$50,$57,$81,$0E,$17,$00,$00,$03,$72,$49,$44,$41,$54,$58,$C3,$D5
Data.a $56,$4B,$48,$1B,$51,$14,$3D,$E3,$67,$2F,$52,$9D,$C4,$45,$DB,$58,$6C,$17,$B5,$50,$1B,$63,$DA,$45,$C5,$85,$52,$1B,$14,$4B,$84,$A9,$A5,$69,$A4,$0A
Data.a $45,$C4,$A5,$88,$64,$13,$BA,$09,$22,$71,$55,$11,$37,$B1,$68,$53,$2A,$81,$16,$4A,$C4,$0A,$7E,$28,$B8,$8A,$51,$52,$DA,$A2,$A2,$A0,$B6,$A2,$E6,$83
Data.a $A2,$28,$6E,$34,$79,$5D,$24,$33,$9D,$97,$BC,$19,$93,$5A,$29,$3D,$30,$CC,$FB,$DC,$F3,$EE,$DC,$73,$EF,$7B,$F3,$38,$9C,$13,$01,$97,$E5,$5C,$FC,$B2
Data.a $56,$37,$73,$9C,$E7,$79,$02,$00,$A1,$50,$88,$4B,$C7,$FF,$DA,$49,$04,$00,$50,$9C,$5B,$C0,$6C,$B3,$E6,$00,$20,$07,$17,$80,$5A,$DB,$24,$91,$F7,$27
Data.a $1C,$35,$DC,$59,$1C,$97,$AB,$16,$00,$D0,$DA,$3A,$01,$9E,$E7,$C9,$D8,$7C,$13,$00,$A0,$AE,$7C,$94,$38,$1C,$65,$9C,$38,$27,$B7,$13,$B1,$76,$12,$81
Data.a $D9,$5A,$0A,$8D,$CE,$2D,$F9,$0D,$AE,$5B,$38,$79,$1F,$00,$06,$5E,$DE,$E6,$CC,$D6,$52,$00,$C0,$87,$91,$EF,$28,$CE,$2D,$F8,$7B,$02,$7C,$CE,$D9,$07
Data.a $00,$F4,$74,$F9,$A5,$8F,$97,$04,$29,$1F,$25,$DD,$BD,$06,$AE,$EA,$34,$4F,$B2,$AB,$3A,$CD,$A3,$82,$7F,$F0,$BC,$2C,$9E,$79,$5B,$80,$E2,$8F,$CD,$37
Data.a $A1,$AE,$7C,$94,$2C,$EC,$B4,$70,$2E,$40,$B2,$73,$25,$89,$A0,$D1,$B9,$25,$9E,$3F,$1A,$83,$46,$E7,$26,$76,$9F,$00,$43,$76,$96,$34,$D6,$6E,$F4,$10
Data.a $B3,$B5,$94,$4A,$86,$24,$80,$D3,$D6,$98,$51,$C0,$9D,$8E,$F7,$54,$F0,$95,$56,$23,$4C,$9A,$FE,$94,$E0,$E5,$41,$A0,$D7,$C0,$55,$5A,$8D,$71,$CE,$88
Data.a $8F,$12,$21,$1D,$18,$EF,$6A,$99,$E3,$ED,$F6,$2F,$C4,$EE,$13,$A4,$BE,$21,$3B,$0B,$F2,$E0,$E5,$63,$1A,$9D,$9B,$04,$D7,$2D,$1C,$25,$80,$D3,$D6,$88
Data.a $CA,$F2,$22,$14,$95,$E4,$63,$7B,$75,$0F,$45,$25,$F9,$00,$80,$ED,$D5,$3D,$00,$A0,$FA,$A2,$8D,$D3,$D6,$48,$89,$90,$0E,$EE,$DC,$2B,$52,$9D,$D7,$6B
Data.a $87,$14,$05,$D4,$6B,$87,$C8,$C2,$4E,$8B,$EA,$56,$F2,$47,$63,$19,$57,$AE,$24,$91,$18,$A4,$F8,$4E,$6E,$2B,$D9,$88,$30,$69,$FA,$A9,$2C,$24,$C3,$EE
Data.a $13,$20,$DC,$FF,$48,$70,$41,$D8,$08,$C7,$B3,$2C,$CF,$BA,$3F,$1A,$A3,$9E,$8D,$30,$A4,$2A,$48,$11,$40,$09,$AC,$60,$33,$CD,$42,$3A,$99,$D1,$6B,$87
Data.a $88,$DD,$27,$50,$B6,$62,$DB,$1F,$8D,$C1,$EE,$13,$A0,$D7,$0E,$11,$D6,$81,$6B,$F7,$09,$B8,$5A,$08,$AA,$DC,$C5,$B7,$5C,$14,$B9,$4D,$CA,$19,$70,$1E
Data.a $F4,$74,$F9,$49,$B3,$57,$38,$33,$E0,$66,$AF,$00,$93,$A6,$9F,$8C,$07,$3B,$D2,$2E,$E5,$4C,$CA,$FA,$4F,$B6,$00,$53,$00,$7D,$F5,$20,$A5,$F4,$C2,$54
Data.a $1B,$87,$0B,$84,$CD,$16,$A0,$04,$54,$42,$B3,$57,$60,$9E,$05,$1B,$61,$A4,$64,$78,$23,$0C,$A0,$30,$06,$96,$9D,$AA,$00,$FA,$EA,$41,$E2,$1F,$78,$0C
Data.a $4D,$61,$FC,$A2,$10,$0C,$47,$A0,$AF,$1E,$24,$0B,$53,$6D,$9C,$FC,$80,$54,$DA,$87,$AC,$32,$53,$72,$AE,$C4,$67,$AD,$A3,$C2,$E7,$86,$EB,$3D,$A4,$D9
Data.a $2B,$A4,$D8,$B0,$38,$C3,$F5,$1E,$00,$E0,$54,$CF,$00,$31,$F8,$E4,$76,$BA,$87,$11,$EB,$C9,$84,$CF,$5A,$47,$09,$13,$8E,$9A,$8C,$2B,$2E,$B8,$6E,$81
Data.a $AA,$00,$C1,$70,$84,$D9,$56,$01,$97,$50,$56,$15,$C9,$EA,$FF,$2B,$7E,$64,$79,$17,$5F,$97,$F7,$E8,$2D,$20,$2F,$EF,$83,$C3,$43,$1C,$1C,$1E,$2A,$2E
Data.a $24,$DE,$0F,$44,$74,$F7,$1A,$D0,$D3,$E5,$E7,$86,$EB,$3D,$04,$00,$DE,$76,$56,$50,$F3,$4F,$9D,$73,$D2,$87,$8E,$07,$3B,$52,$D6,$B3,$3C,$BB,$02,$F7
Data.a $9B,$1F,$69,$F1,$A7,$67,$4C,$D8,$5F,$0A,$62,$71,$E9,$F7,$37,$B4,$3D,$B9,$8C,$C1,$77,$3F,$D3,$E2,$7F,$FB,$F4,$90,$7D,$0F,$60,$05,$C6,$9A,$63,$D9
Data.a $AC,$2C,$EE,$C2,$33,$DB,$20,$65,$87,$2F,$B8,$44,$3D,$A2,$73,$CF,$6C,$03,$8E,$56,$37,$71,$B4,$BA,$89,$95,$C5,$5D,$6A,$8D,$E9,$19,$D3,$99,$FC,$84
Data.a $0D,$13,$89,$C0,$54,$F9,$C9,$C1,$4B,$15,$20,$BF,$D1,$F1,$3C,$CF,$74,$50,$61,$7E,$A5,$E8,$FC,$C5,$F5,$6B,$C0,$EC,$31,$26,$1C,$35,$A8,$B5,$4D,$2A
Data.a $EF,$D5,$D9,$63,$9A,$93,$40,$9F,$73,$0E,$7D,$89,$2C,$29,$F9,$0F,$85,$42,$28,$BD,$F9,$9A,$39,$F7,$E8,$D6,$0D,$6C,$05,$4E,$CF,$F4,$BF,$15,$38,$A5
Data.a $38,$4A,$BF,$C1,$F3,$FE,$F2,$FE,$2B,$FE,$2F,$86,$32,$BB,$EA,$DC,$7F,$AC,$90,$00,$00,$00,$00,$49,$45,$4E,$44,$AE,$42,$60,$82
EndDataSection

DataSection
music_start:
Data.a $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$1A,$10,$00,$00,$02,$00,$01,$00,$0A,$00,$00,$00,$31,$51,$02,$00,$53,$43,$52,$4D,$40,$06,$7D
Data.a $B0,$10,$FC,$00,$14,$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$FF,$0A,$00,$0F,$00
Data.a $00,$00,$1D,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$28,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$80
Data.a $80,$80,$80,$80,$80,$80,$80,$01,$74,$72,$69,$61,$6E,$67,$6C,$65,$5F,$38,$5F,$36,$00,$27,$00,$40,$00,$00,$00,$00,$00,$00,$00,$40,$00,$00,$00,$40,$00,$00,$01,$56,$41,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
Data.a $00,$00,$00,$00,$74,$72,$69,$61,$6E,$67,$6C,$65,$5F,$38,$5F,$36,$34,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$53,$43,$52,$53,$D7,$00,$A0,$40,$01,$01,$10,$00,$20,$42,$01,$00,$A0,$43,$01
Data.a $12,$33,$00,$00,$A0,$43,$01,$12,$33,$00,$20,$45,$00,$00,$20,$47,$01,$00,$00,$20,$47,$01,$00,$20,$4A,$01,$00,$20,$45,$01,$00,$20,$FF,$01,$00,$20,$43,$01,$00,$20,$42,$01,$00,$20,$40,$01,$00,$00,$20,$40,$01
Data.a $00,$20,$42,$01,$00,$20,$43,$01,$00,$00,$20,$43,$01,$00,$20,$45,$00,$00,$20,$47,$01,$00,$00,$20,$47,$01,$00,$20,$4A,$01,$00,$20,$50,$01,$00,$20,$FF,$01,$00,$20,$4A,$01,$00,$20,$52,$01,$00,$20,$50,$01,$00
Data.a $00,$20,$50,$01,$00,$20,$52,$01,$00,$20,$53,$01,$00,$00,$20,$52,$01,$00,$00,$20,$50,$01,$00,$20,$FF,$01,$00,$20,$4A,$01,$00,$00,$20,$48,$01,$00,$00,$20,$47,$01,$00,$00,$20,$45,$01,$00,$00,$00,$20,$FF,$01
Data.a $00,$20,$FF,$01,$00,$20,$FF,$01,$00,$20,$43,$00,$00,$20,$47,$01,$00,$20,$45,$01,$00,$00,$20,$FF,$01,$00,$20,$FF,$01,$00,$00,$20,$43,$01,$00,$20,$42,$00,$00,$A0,$40,$01,$01,$14,$00,$00,$00,$00,$00,$00,$00
Data.a $00,$00,$00,$00,$00,$9F,$00,$20,$44,$01,$00,$20,$47,$01,$00,$20,$49,$01,$00,$20,$44,$01,$00,$20,$47,$01,$00,$20,$49,$01,$00,$00,$00,$00,$00,$00,$00,$20,$44,$00,$00,$20,$47,$00,$00,$20,$49,$00,$00,$20,$44
Data.a $00,$00,$20,$47,$00,$00,$20,$49,$00,$00,$00,$00,$20,$44,$00,$00,$20,$47,$00,$00,$20,$44,$00,$00,$20,$49,$00,$00,$20,$47,$00,$00,$20,$52,$00,$00,$00,$00,$20,$40,$00,$00,$20,$40,$00,$00,$20,$40,$00,$00,$00
Data.a $20,$40,$00,$00,$00,$20,$40,$00,$00,$00,$20,$40,$00,$00,$00,$20,$45,$00,$00,$00,$00,$00,$20,$50,$00,$00,$00,$00,$00,$20,$47,$00,$00,$00,$20,$45,$00,$00,$00,$20,$44,$00,$00,$00,$20,$42,$00,$00,$00,$20,$50
Data.a $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$80,$88,$91,$97,$A0,$A8,$B0,$B7,$BF,$C7,$D0,$D6,$DF,$E7,$EF,$F6,$FE,$F6,$EF,$E7,$DF,$D6,$D0,$C7,$BF,$B7,$B0,$A8,$A0,$97,$91,$88,$80,$78,$6F,$69,$60,$58,$50
Data.a $47,$41,$39,$30,$28,$20,$19,$11,$08,$00,$08,$11,$19,$20,$28,$30,$39,$41,$47,$50,$58,$60,$69,$6F,$78
music_end:
EndDataSection


Additional code has been used from here: https://www.purebasic.fr/english/viewtopic.php?t=86449
Last edited by miso on Fri Mar 07, 2025 10:07 pm, edited 6 times in total.
User avatar
Mijikai
Addict
Addict
Posts: 1517
Joined: Sun Sep 11, 2016 2:17 pm

Re: Maths problem with basic camera

Post by Mijikai »

Great work @miso, it looks really cool 8)
(EndDataSection is missing at the end of the code - prob due to char limit)
miso
Enthusiast
Enthusiast
Posts: 406
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Maths problem with basic camera

Post by miso »

EndDataSection is missing
Hasty copy from IDE. Fixed. I've seen much bigger code here than this one.
miso
Enthusiast
Enthusiast
Posts: 406
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Maths problem with basic camera

Post by miso »

I started to think about creating a minimalistic turn based strategy, or maybe a roguelike, so I continued messing with this and updated the code.
Now it can retrieve zoomed 2d tile data under the mouse, and meanwhile fixed the angle and movement behavior of those flying vehicles.
I'm not sure if my messy prototype code may help to anyone, but maybe. If I ever finish prototyping this, I may modularize it in a nicer way.

EDIT: Updated the 2d drawing formulas to be 6.21 beta 2-3 compatible.

Code: Select all

;UPDATED 4 - 6.21 beta 2-3 compatible
;bugs found and fixed regarding ship angles
;ships now fly toward destination coordinates with various speed, choose new target location upon reach
;can retrive zoomed tile data under the "mouse"

EnableExplicit
#PSEUDORANDOM_SEED = 5000
RandomSeed(#PSEUDORANDOM_SEED)
UsePNGImageDecoder()
;-MODULES FILES 
EnableExplicit

DeclareModule line
  Global initialized.b =#False , sprite_ID.i = -1, circlesprite_ID.i = -1, circlesprite_o_ID.i = -1
  Declare init(resolution.i)
  Declare destroy()
  Declare draw(x1.i,y1.i,x2.i,y2.i,color.i=-16776961,width.i=10,intensity.i = 255)
  Declare drawwindow(x.i,y.i,width.i,height.i,color.i=-16776961,intensity.i = 255)
  Declare drawCircle(x.i,y.i,radius,color.i=-16776961,intensity.i = 255)
  Declare drawCircleoutline(x.i,y.i,radius,color.i=-16776961,intensity.i = 255)
EndDeclareModule

Module line
  Procedure init(resolution.i)
    line::sprite_ID = CreateSprite(#PB_Any,1,1,#PB_Sprite_AlphaBlending)
    If Not IsSprite(line::sprite_ID) : ProcedureReturn #False : EndIf
    StartDrawing(SpriteOutput(line::sprite_ID))
    
    DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    Box(0,0,OutputWidth(),OutputHeight(),RGBA(255,255,255,255))
    StopDrawing()
    
    line::circlesprite_ID = CreateSprite(#PB_Any,resolution.i,resolution.i,#PB_Sprite_AlphaBlending)
    If Not IsSprite(circlesprite_ID) : ProcedureReturn #False : EndIf
    StartDrawing(SpriteOutput(line::circlesprite_ID))
    
    DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    Box(0,0,OutputWidth(),OutputHeight(),RGBA(0,0,0,0))
    Circle(OutputWidth()/2,OutputHeight()/2,OutputWidth()/2,RGBA(255,255,255,255))
    StopDrawing()
    
    line::circlesprite_o_ID = CreateSprite(#PB_Any,resolution.i,resolution.i,#PB_Sprite_AlphaBlending)
    If Not IsSprite(circlesprite_o_ID) : ProcedureReturn #False : EndIf
    StartDrawing(SpriteOutput(line::circlesprite_o_ID))
    DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    Box(0,0,OutputWidth(),OutputHeight(),RGBA(0,0,0,0))
    Circle(OutputWidth()/2,OutputHeight()/2,OutputWidth()/2,RGBA(255,255,255,255))
    Circle(OutputWidth()/2,OutputHeight()/2,OutputWidth()/2-15,RGBA(0,0,0,0))
    StopDrawing()
    line::initialized = #True : ProcedureReturn #True  
  EndProcedure

  Procedure destroy()
    If IsSprite(line::sprite_ID) : FreeSprite(line::sprite_ID) : EndIf 
    If IsSprite(line::circlesprite_ID) : FreeSprite(line::circlesprite_ID):EndIf
    If IsSprite(line::circlesprite_o_ID) : FreeSprite(line::circlesprite_o_ID):EndIf
    line::initialized = #False
  EndProcedure
  
  Procedure draw(x1.i,y1.i,x2.i,y2.i,color.i=-16776961,width.i=10,intensity.i = 255)
    ;MIJIKAI and STARGATE code
    Protected.f length, dx, dy
    length = Sqr((X1-X2)*(X1-X2) + (Y1-Y2)*(Y1-Y2))
    dy = (X2-X1)*Width/(2*length)
    dx = (Y1-Y2)*Width/(2*length)
    ZoomSprite(line::sprite_ID,length,length)
    TransformSprite(line::sprite_ID, X1-dx, Y1-dy, X2-dx, Y2-dy, X2+dx, Y2+dy, X1+dx, Y1+dy)
    DisplayTransparentSprite(line::sprite_ID,0,0,intensity,color)
  EndProcedure
  
  Procedure drawwindow(x.i,y.i,width.i,height.i,color.i=-16776961,intensity.i = 255)
    ZoomSprite(line::sprite_ID,width,heigth)
    TransformSprite(line::sprite_ID, x, y, x+width, Y, X+width, Y+height, X, Y+height)
    DisplayTransparentSprite(line::sprite_ID,0,0,intensity,color)
    line::draw(x,y,x+width,y,RGBA(255,255,255,255),1,255)
    line::draw(x,y+height,x+width,y+height,RGBA(255,255,255,255),1,255)
    line::draw(x,y,x,y+height,RGBA(255,255,255,255),1,255)
    line::draw(x+width,y,x+width,y+height,RGBA(255,255,255,255),1,255)
  EndProcedure
  
  Procedure drawCircle(x.i,y.i,radius,color.i=-16776961,intensity.i = 255)
    Protected hradius.f =radius/2
    ZoomSprite(line::circlesprite_ID,radius,radius)
    DisplayTransparentSprite(line::circlesprite_ID,x,y,intensity,color)
  EndProcedure
  
  Procedure drawCircleoutline(x.i,y.i,radius,color.i=-16776961,intensity.i = 255)
    Protected hradius.f =radius/2
    ZoomSprite(line::circlesprite_O_ID,radius,radius)
    DisplayTransparentSprite(line::circlesprite_o_ID,x,y,intensity,color)
  EndProcedure
EndModule

DeclareModule petskii
  Declare init()
  Declare textout(x,y,text.s,color.i,intensity.i=255)
  Declare textoutlined(x,y,text.s,color.i,outlinecolor.i,intensity.i=255)
  Declare destroy()
EndDeclareModule

Module petskii
;-HIDDEN VARIABLES/CONSTANTS  
  #USED_CHARACTERS="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+[{]};:',<.>/?"+Chr(34)
  Global Dim petskiifont(370):Global Dim fontimport.i(370)
;-SUB PROCEDURES
  Procedure sub_loadfont()
    Protected x.i,i.i,j.i,sprline.a
    For i = 1 To Len(#USED_CHARACTERS):fontImport(Asc(Mid(#USED_CHARACTERS,i,1)))=1 : Next i 
    Restore petskii_font
      For x= 1 To 370
        If fontimport(x)=1
          petskiifont(x)=CreateSprite(-1,8,12,#PB_Sprite_AlphaBlending)
          StartDrawing(SpriteOutput(petskiifont(x)))
          DrawingMode(#PB_2DDrawing_AllChannels)
          For j=0 To 11  
            Read.a sprline 
            For i=0 To 7
              If sprline&%1 :Plot(i,j,RGBA(255,255,255,255)): Else : Plot(i,j,RGBA(0,0,0,0)) : EndIf
              sprline>>1 
            Next i
          Next j
          StopDrawing()
          ZoomSprite(petskiifont(x),16,24)
        EndIf
      Next x
  EndProcedure
  
  ;-PUBLIC PROCEDURES  
  Procedure init()
    sub_loadfont()
  EndProcedure
  
  Procedure textout(x,y,text.s,color.i,intensity.i=255) : Protected.i textlength,i,character
    textlength.i = Len(text.s)
    For i = 1 To textlength.i
      character.i = Asc(Mid(text.s,i,1))
      If character.i>ArraySize(petskiifont()) : ProcedureReturn #Null : EndIf
      If IsSprite(petskiifont(character))
        DisplayTransparentSprite(petskiifont(character),(x+((i-1) * 16)),(y),intensity,color.i)
      EndIf
    Next i
  EndProcedure
  
  Procedure textoutlined(x,y,text.s,color.i,outlinecolor.i,intensity=255)
    textout(x-2,y,text.s,outlinecolor,intensity)
    textout(x+2,y,text.s,outlinecolor,intensity)
    textout(x,y-2,text.s,outlinecolor,intensity)
    textout(x,y+2,text.s,outlinecolor,intensity)
    textout(x,y,text.s,color,intensity)
  EndProcedure
  
  Procedure destroy()
    Protected i.i
    For i = 1 To Len(#USED_CHARACTERS)
      If IsSprite(petskiifont(i)) : FreeSprite(petskiifont(i)) : EndIf
    Next i
  EndProcedure
  
  ;-MODULE DATA
  DataSection
  petskii_font:
  Data.a $00,$00,$38,$38,$38,$38,$38,$38,$00,$38,$00,$00,$00,$00,$EE,$EE,$EE,$00,$00,$00,$00,$00,$00,$00,$00,$00,$EE,$EE,$EE,$FF,$EE,$FF,$EE,$EE,$00,$00,$00,$00,$38,$38,$FC,$0E,$7C,$E0,$7E,$38,$00,$00
  Data.a $00,$00,$CE,$CE,$EE,$70,$38,$1C,$EE,$E6,$00,$00,$00,$00,$7C,$7C,$EE,$7C,$3C,$EE,$EE,$FC,$00,$00,$00,$00,$E0,$E0,$70,$38,$00,$00,$00,$00,$00,$00,$00,$00,$70,$70,$38,$1C,$1C,$1C,$38,$70,$00,$00
  Data.a $00,$00,$1C,$1C,$38,$70,$70,$70,$38,$1C,$00,$00,$00,$00,$00,$00,$EE,$7C,$FF,$7C,$EE,$00,$00,$00,$00,$00,$00,$00,$38,$38,$FE,$38,$38,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$38,$38,$1C,$00
  Data.a $00,$00,$00,$00,$00,$00,$FE,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$38,$38,$00,$00,$00,$00,$00,$00,$C0,$E0,$70,$38,$1C,$0E,$00,$00,$00,$00,$7C,$7C,$EE,$FE,$FE,$EE,$EE,$7C,$00,$00
  Data.a $00,$00,$38,$38,$38,$3C,$38,$38,$38,$FE,$00,$00,$00,$00,$7C,$7C,$EE,$E0,$70,$1C,$0E,$FE,$00,$00,$00,$00,$7C,$7C,$EE,$E0,$78,$E0,$EE,$7C,$00,$00,$00,$00,$E0,$E0,$F0,$F8,$EE,$FE,$E0,$E0,$00,$00
  Data.a $00,$00,$FE,$FE,$0E,$7E,$E0,$E0,$EE,$7C,$00,$00,$00,$00,$7C,$7C,$EE,$0E,$7E,$EE,$EE,$7C,$00,$00,$00,$00,$FE,$FE,$EE,$70,$38,$38,$38,$38,$00,$00,$00,$00,$7C,$7C,$EE,$EE,$7C,$EE,$EE,$7C,$00,$00
  Data.a $00,$00,$7C,$7C,$EE,$EE,$FC,$E0,$EE,$7C,$00,$00,$00,$00,$38,$38,$38,$00,$00,$00,$38,$38,$00,$00,$00,$00,$38,$38,$38,$00,$00,$00,$38,$38,$1C,$00,$00,$00,$F0,$F0,$38,$1C,$0E,$1C,$38,$F0,$00,$00
  Data.a $00,$00,$00,$00,$00,$FE,$00,$FE,$00,$00,$00,$00,$00,$00,$1E,$1E,$38,$70,$E0,$70,$38,$1E,$00,$00,$00,$00,$7C,$7C,$EE,$E0,$70,$38,$00,$38,$00,$00,$00,$00,$7C,$7C,$EE,$FE,$FE,$0E,$CE,$7C,$00,$00
  Data.a $00,$00,$38,$38,$7C,$EE,$FE,$EE,$EE,$EE,$00,$00,$00,$00,$7E,$7E,$EE,$EE,$7E,$EE,$EE,$7E,$00,$00,$00,$00,$7C,$7C,$EE,$0E,$0E,$0E,$EE,$7C,$00,$00,$00,$00,$3E,$3E,$7E,$EE,$EE,$EE,$7E,$3E,$00,$00
  Data.a $00,$00,$FE,$FE,$0E,$0E,$3E,$0E,$0E,$FE,$FF,$00,$FF,$00,$FE,$FE,$0E,$0E,$3E,$0E,$0E,$0E,$00,$00,$00,$00,$7C,$7C,$EE,$0E,$FE,$EE,$EE,$7C,$00,$00,$00,$00,$EE,$EE,$EE,$EE,$FE,$EE,$EE,$EE,$00,$00
  Data.a $00,$00,$7C,$7C,$38,$38,$38,$38,$38,$7C,$00,$00,$00,$00,$F8,$F8,$70,$70,$70,$70,$7E,$3C,$00,$00,$00,$00,$EE,$EE,$7E,$3E,$1E,$3E,$7E,$EE,$00,$00,$00,$00,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$FE,$00,$00
  Data.a $00,$00,$CE,$CE,$FE,$FE,$FE,$CE,$CE,$CE,$00,$00,$00,$00,$EE,$EE,$FE,$FE,$FE,$FE,$EE,$EE,$00,$00,$00,$00,$7C,$7C,$EE,$EE,$EE,$EE,$EE,$7C,$00,$00,$00,$00,$7E,$7E,$EE,$EE,$7E,$0E,$0E,$0E,$00,$00
  Data.a $00,$00,$7C,$7C,$EE,$EE,$EE,$EE,$7C,$F0,$00,$00,$00,$00,$7E,$7E,$EE,$EE,$7E,$3E,$7E,$EE,$00,$00,$00,$00,$7C,$7C,$EE,$0E,$7C,$E0,$EE,$7C,$00,$00,$00,$00,$FE,$FE,$38,$38,$38,$38,$38,$38,$00,$00
  Data.a $00,$00,$EE,$EE,$EE,$EE,$EE,$EE,$EE,$7C,$00,$00,$00,$00,$EE,$EE,$EE,$EE,$EE,$EE,$7C,$38,$00,$00,$00,$00,$CE,$CE,$CE,$CE,$FE,$FE,$FE,$CE,$00,$00,$00,$00,$EE,$EE,$EE,$7C,$38,$7C,$EE,$EE,$00,$00
  Data.a $00,$00,$EE,$EE,$EE,$EE,$7C,$38,$38,$38,$00,$00,$00,$00,$FE,$FE,$E0,$70,$38,$1C,$0E,$FE,$00,$00,$00,$00,$7C,$7C,$1C,$1C,$1C,$1C,$1C,$7C,$00,$00,$00,$00,$7C,$7C,$70,$70,$70,$70,$70,$7C,$00,$00
  Data.a $00,$00,$38,$38,$7C,$FE,$38,$38,$38,$38,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$00,$00,$00,$00,$00,$00,$00,$7C,$E0,$FC,$EE,$FC,$00,$00,$00,$00,$00,$00,$0E,$0E,$7E,$EE,$EE,$7E,$00,$00
  Data.a $00,$00,$00,$00,$00,$7C,$0E,$0E,$0E,$7C,$00,$00,$00,$00,$00,$00,$E0,$E0,$FC,$EE,$EE,$FC,$00,$00,$00,$00,$00,$00,$00,$7C,$EE,$FE,$0E,$7C,$00,$00,$00,$00,$00,$00,$F0,$38,$FC,$38,$38,$38,$00,$00
  Data.a $00,$00,$00,$00,$00,$FC,$EE,$EE,$FC,$E0,$7E,$00,$00,$00,$0E,$0E,$0E,$7E,$EE,$EE,$EE,$EE,$00,$00,$00,$00,$38,$38,$00,$3C,$38,$38,$38,$7C,$00,$00,$00,$00,$00,$00,$70,$00,$70,$70,$70,$70,$3C,$00
  Data.a $00,$00,$0E,$0E,$0E,$0E,$7E,$3E,$7E,$EE,$00,$00,$00,$00,$3C,$3C,$38,$38,$38,$38,$38,$7C,$00,$00,$00,$00,$00,$00,$00,$EE,$FE,$FE,$FE,$CE,$00,$00,$00,$00,$00,$00,$00,$7E,$EE,$EE,$EE,$EE,$00,$00
  Data.a $00,$00,$00,$00,$00,$7C,$EE,$EE,$EE,$7C,$00,$00,$00,$00,$00,$00,$00,$7E,$EE,$EE,$7E,$0E,$0E,$00,$00,$00,$00,$00,$00,$FC,$EE,$EE,$FC,$E0,$E0,$00,$00,$00,$00,$00,$00,$7E,$EE,$0E,$0E,$0E,$00,$00
  Data.a $00,$00,$00,$00,$00,$FC,$0E,$7C,$E0,$7E,$00,$00,$00,$00,$00,$00,$38,$FE,$38,$38,$38,$F0,$00,$00,$00,$00,$00,$00,$00,$EE,$EE,$EE,$EE,$FC,$00,$00,$00,$00,$00,$00,$00,$EE,$EE,$EE,$7C,$38,$00,$00
  Data.a $00,$00,$00,$00,$00,$CE,$FE,$FE,$FC,$FC,$00,$00,$00,$00,$00,$00,$00,$EE,$7C,$38,$7C,$EE,$00,$00,$00,$00,$00,$00,$00,$EE,$EE,$EE,$FC,$70,$3E,$00,$00,$00,$00,$00,$00,$FE,$70,$38,$1C,$FE,$00,$00
  Data.a $00,$00,$F0,$F0,$38,$38,$1E,$38,$38,$F0,$00,$00,$00,$00,$1E,$1E,$38,$38,$F0,$38,$38,$1E,$00,$00
  EndDataSection
EndModule

DeclareModule stripes
  Global spr_id.i
  Global columns.i
  Declare create(size.i)
  Declare draw(animationsteps.f)  
EndDeclareModule

Module stripes
  Procedure.i Create(size.i)
    Protected img_stripe.i
    img_stripe=CreateImage(#PB_Any,size,size,32,RGBA(1,1,1,255))
    StartVectorDrawing(ImageVectorOutput(img_stripe))
      MovePathCursor(0,size) : AddPathLine(size/2,0) : AddPathLine(size,0) : AddPathLine(size/2,size) : ClosePath()
      VectorSourceColor(RGBA(255,128,0,255)) : FillPath()
    StopVectorDrawing()
    stripes::spr_id=CreateSprite(#PB_Any,size,size,#PB_Sprite_AlphaBlending)
    StartDrawing(SpriteOutput(stripes::spr_id)) 
    DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawImage(ImageID(img_stripe),0,0) 
    StopDrawing()
    FreeImage(img_stripe)
    columns.i = ScreenWidth()/SpriteWidth(stripes::spr_id)
    If IsSprite(stripes::spr_id) :Debug "ISSPRITE":ProcedureReturn #True : EndIf
    Debug "NOT SPRITE"
    ProcedureReturn #False  
  EndProcedure
  
  Procedure.i draw(animationstep.f)
    Protected i.i
    Static offset.f =0
    For i=-1 To columns+1
      DisplayTransparentSprite(stripes::spr_id,i*SpriteWidth(stripes::spr_id)+offset,0)
      DisplayTransparentSprite(stripes::spr_id,i*SpriteWidth(stripes::spr_id)-offset,ScreenHeight()-SpriteHeight(stripes::spr_id))
    Next i
    offset.f + animationstep.f
    If offset>SpriteWidth(stripes::spr_id) : offset -SpriteWidth(stripes::spr_id) : EndIf
  EndProcedure  
EndModule

;-MAINPROGRAM FILE START HERE

;-CONSTANTS
#MAINDESKTOP_H = 0
#WINDOW_H = 0
#WINDOW_WIDTH = 1366
#WINDOW_HEIGHT = 768
#WINDOW_FLAGS  = #PB_Window_Invisible|#PB_Window_BorderLess|#PB_Window_ScreenCentered
#MAINLOOP_DELAY = 1
#STRIPESIZE = 32
#STRIPESPEED = 2

#ship_count = 2500
#SPRSIZE = 5
#ARROWDIST = 20
#GRID_COUNT = 1500
#GRIDSIZE = 100

#LEFTBORDER = 0
#RIGHTBORDER = (1+#GRID_COUNT)*#GRIDSIZE
#TOPBORDER =0
#BOTTOMBORDER = (1+#GRID_COUNT)*#GRIDSIZE

#off = -45
#off2 = -225
#ROTATION_SPEED = 0.5
#MOUSEWHEEL_SENSITIVY = 0.05

#MINZOOM = 0.25
#MAXZOOM = 5
#MAX_INTENSITY = 255

#MUSICVOL =10
#DEBUG_TESTSHIP=2735

;-TYPES
Structure cameratype
  x.f
  y.f
  tx.f
  ty.f
  angle.f
  zoom.f
  tzoom.f
  scrollspeed.f
EndStructure

Structure spritetype
  spid.i
  ospid.i
  basesize.f
  hb.f
  x.f
  y.f
  destx.f
  desty.f
  mindestx.f
  mindesty.f
  angle.f
  tangle.f
  color.i
  speed.f
  linealpha.f
  name.s
EndStructure
#ALPHASTEP = 10
;-GLOBALS
Global.i airship_sprite_id , arrowsprite_ID, gridsprite_ID, gridsprite2_ID
Global camera.cameratype
Global Dim sprs.spritetype(#ship_count)
Global Dim grid.spritetype(#GRID_COUNT,#GRID_COUNT)
Global sincounter.f
Global music_id.i
Global Dim tiles.i(50)

;-AUXILIARY PROCEDURES

Procedure loadtiles()
  Protected imageid.i, i.i
  imageid = CatchImage(#PB_Any,?grasspng)
  
  For i=0 To 4
    tiles(i) = CreateSprite(#PB_Any,16,16)
    StartDrawing(SpriteOutput(tiles(i)))
    DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawAlphaImage(ImageID(imageid),0-i*16,0)
    StopDrawing()
  Next i
  
  imageid = CatchImage(#PB_Any,?deadgrasspng)
  tiles(5) = CreateSprite(#PB_Any,16,16)
  StartDrawing(SpriteOutput(tiles(5)))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawAlphaImage(ImageID(imageid),0,0)
  StopDrawing()
  
  tiles(6) = CreateSprite(#PB_Any,16,16)
  StartDrawing(SpriteOutput(tiles(6)))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawImage(ImageID(imageid),-16,0)
  StopDrawing()
  
  tiles(7) = CreateSprite(#PB_Any,16,16)
  StartDrawing(SpriteOutput(tiles(7)))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawImage(ImageID(imageid),-16,-16)
  StopDrawing()
    
  tiles(8) = CreateSprite(#PB_Any,16,16)
  StartDrawing(SpriteOutput(tiles(8)))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawImage(ImageID(imageid),0,-16)
  StopDrawing()
  FreeImage(imageid)
  
  imageid = CatchImage(#PB_Any,?treespng)
  tiles(9) = CreateSprite(#PB_Any,16,16,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(tiles(9)))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawAlphaImage(ImageID(imageid),0,0)
  StopDrawing()
    
  tiles(10) = CreateSprite(#PB_Any,16,16,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(tiles(10)))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawAlphaImage(ImageID(imageid),-16,0)
  StopDrawing()
    
  tiles(11) = CreateSprite(#PB_Any,16,16,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(tiles(11)))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawAlphaImage(ImageID(imageid),-32,0)
  StopDrawing()
    
  tiles(12) = CreateSprite(#PB_Any,16,16,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(tiles(12)))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
    DrawAlphaImage(ImageID(imageid),-48,0)
  StopDrawing()
FreeImage(imageid)
  
EndProcedure

Procedure.i floor(f.f)
  ProcedureReturn Round(f.f,#PB_Round_Down)
EndProcedure

Procedure.i ceil(f.f)
  ProcedureReturn Round(f.f,#PB_Round_Up)
EndProcedure

Procedure sub_checks()
  If #PB_Compiler_Debugger
    Debug "Please run without debugger"
    End
  EndIf
EndProcedure

Procedure sub_createsprite()
  loadtiles()
  
  airship_sprite_id.i=CreateSprite(#PB_Any,#SPRSIZE,#SPRSIZE,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(airship_sprite_id.i))
  DrawingMode(#PB_2DDrawing_Outlined|#PB_2DDrawing_AllChannels)
  Box(0,0,OutputWidth(),OutputHeight())
  StopDrawing()
  
  arrowsprite_ID.i=CreateSprite(#PB_Any,#SPRSIZE,#SPRSIZE,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(arrowsprite_ID.i))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
  Box(0,0,OutputWidth(),OutputHeight(),RGBA(0,0,0,0))
  Box(#SPRSIZE/2,0,1,#SPRSIZE,RGBA(255,255,255,255))
  Plot(#SPRSIZE/2-1,1):Plot(#SPRSIZE/2+1,1,RGBA(255,255,255,255))
  StopDrawing()
  
  gridsprite_ID.i=CreateSprite(#PB_Any,#GRIDSIZE,#GRIDSIZE,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(gridsprite_ID.i))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
  Box(0,0,OutputWidth(),OutputHeight(),RGBA(0,50,0,255))
  Protected x.i
  For x = 1 To 1000
    Plot(Random(OutputWidth()-1),Random(OutputHeight()-1),RGBA(Random(10),20+Random(50),Random(10),255))
  Next x
  StopDrawing()
  
  gridsprite2_ID.i=CreateSprite(#PB_Any,#GRIDSIZE,#GRIDSIZE,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(gridsprite2_ID.i))
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AllChannels)
  Box(0,0,OutputWidth(),OutputHeight(),RGBA(0,0,50,255))
  
  For x = 1 To 1000
    Plot(Random(OutputWidth()-1),Random(OutputHeight()-1),RGBA(Random(40),Random(40),40+Random(80),255))
  Next x
  StopDrawing()
EndProcedure

Procedure sub_camerasetup()
  With camera
    \x=(#GRIDSIZE*#GRID_COUNT)/2-ScreenWidth()/2
    \y=(#GRIDSIZE*#GRID_COUNT)/2-ScreenHeight()/2
    \tx=\x
    \ty=\y
    \angle = 0
    \zoom = 2.0
    \tzoom = 0.25
    \scrollspeed = 2.0
  EndWith
EndProcedure

Procedure sub_airship_setup()
  Protected x.i
  For x = 0 To #ship_count
    With sprs(x)
      \spid = airship_sprite_id
      \x = Random(#GRID_COUNT*#GRIDSIZE)
      \y = Random(#GRID_COUNT*#GRIDSIZE)
      \destx = Random(#GRID_COUNT*#GRIDSIZE)
      \desty = Random(#GRID_COUNT*#GRIDSIZE)
      \tangle = 180+((ATan2(\desty-\y,\destx-\x))*#PI*180)
      \angle = \tangle
      \basesize = 40.0
      \hb = \basesize/2.0
      \speed = (100+Random(100,1))
      \color.i = RGBA(255,5,5,255)
    EndWith
  Next x
EndProcedure

Procedure sub_grid_setup()
  Protected i.i,j.i,x.i
  For i = 0 To #grid_count
    For j = 0 To #grid_count
      With grid(i,j)
        \spid = tiles(0)
        \name = "Water"
        \x = i*#GRIDSIZE
        \y = j*#GRIDSIZE
        \destx = i*#GRIDSIZE
        \desty = j*#GRIDSIZE
        \tangle = 0
        \angle = 0
        \basesize = #GRIDSIZE
        \hb = \basesize/2.0
        \color.i = RGBA(0+Random(10),Random(Random(55)+25),0+Random(10),255)
     EndWith
    Next j
  Next i

  For x = i To 15000
    i=Random(Random(80,20)*#GRID_COUNT/100+Random(6,1)-3)
    j=Random(Random(80,20)*#GRID_COUNT/100+Random(6,1)-3)
    grid(i,j)\spid = tiles(Random(8,1))
    grid(i,j)\name = "Land"
  Next x
  
  For x = i To 5000
    i=Random(#GRID_COUNT)
    j=Random(#GRID_COUNT)
    grid(i,j)\spid = tiles(Random(8,1))
    grid(i,j)\name = "Land"
  Next x
  
  For x = i To 2000000
    i=Random(#GRID_COUNT-1,1)
    j=Random(#GRID_COUNT-1,1)
    If grid(i+1,j)\spid<>tiles(0) Or grid(i-1,j)\spid<>tiles(0) Or grid(i,j+1)\spid<>tiles(0) Or grid(i-1,j)\spid<>tiles(0)
      grid(i,j)\spid = tiles(Random(8,1))
      grid(i,j)\name = "Land"
    EndIf
    If grid(i+1,j+1)\spid<>tiles(0) Or grid(i-1,j+1)\spid<>tiles(0) Or grid(i+1,j-1)\spid<>tiles(0) Or grid(i-1,j-1)\spid<>tiles(0)
      grid(i,j)\spid = tiles(Random(8,1))
      grid(i,j)\name = "Land"
    EndIf
  Next x
      
  For i = 0 To #grid_count
    For j = 0 To #grid_count
      With grid(i,j)
        If \spid =tiles(1) Or \spid =tiles(2) 
          If Random(4)<2
            \ospid = tiles(10+Random(2))
            grid(i,j)\name = "Forest"
          EndIf
        EndIf
       
        If \spid =tiles(5) Or \spid =tiles(8) 
          If Random(4)<2
            \ospid = tiles(9)
            grid(i,j)\name = "Cleared Forest"
          EndIf
        EndIf
     EndWith
    Next j
  Next i
EndProcedure

Procedure sub_draw_UI()
  Protected cw = 1.5*#GRIDSIZE*camera\zoom,tilex.i,tiley.i,mem.i
  tilex=Abs(((#GRIDSIZE/2+camera\x)/#GRIDSIZE)-1) : tiley = Abs(((#GRIDSIZE/2+camera\y)/#GRIDSIZE)-1)
  mem.i = MemoryStatus(#PB_System_FreePhysical)/(1024*1024)
  
  line::drawcircleoutline(ScreenWidth()/2-cw/2,ScreenHeight()/2-cw/2,cw,RGBA(0,0,0,255),255)
  line::drawcircle(ScreenWidth()/2-5*camera\zoom,ScreenHeight()/2-5*camera\zoom,10*camera\zoom,RGBA(0,0,0,255),255)
  stripes::draw(#STRIPESPEED)
  line::drawwindow(1,1,450,185,RGBA(5,5,5,255),200)
  petskii::textoutlined(200,741,"mouse = Scroll",RGBA(255,0,0,255),RGBA(5,5,5,5))
  petskii::textoutlined(610,741,"mouse wheel = zoom",RGBA(0,255,0,255),RGBA(5,5,5,255))
  petskii::textoutlined(1150,741,"Escape = Quit",RGBA(255,55,55,255),RGBA(5,5,5,255))
  petskii::textoutlined(5,8,"Zoom level = ",RGBA(5,5,5,255),RGBA(255,5,5,255))
  petskii::textoutlined(210,8,StrF(camera\zoom,0),RGBA(5,5,5,255),RGBA(255,255,125,255))
  petskii::textoutlined(5,30,"Camera Tile = ",RGBA(5,5,5,255),RGBA(155,155,250,255))
  petskii::textoutlined(215,30," ("+Str(tilex)+","+Str(tiley)+")",RGBA(155,155,250,255),RGBA(5,5,5,255))
  petskii::textoutlined(5,102,grid(tilex,tiley)\name,RGBA(5,5,5,255),RGBA(155,155,250,255))
  petskii::textoutlined(5,52,"Number of Tiles = "+Str(#GRID_COUNT*#GRID_COUNT),RGBA(255,200,0,255),RGBA(5,5,5,5))
  petskii::textoutlined(5,74,"Number of Ships = "+Str(#ship_count),RGBA(255,200,0,255),RGBA(5,5,5,5))
  line::drawwindow(1,696,1002,32,RGBA(5,5,5,255),200)
  petskii::textoutlined(5,700,"Thank's to Mijikai and Stargate for the awesome line function! ",RGBA(255,255,100,255),RGBA(5,5,5,255))
  If mem>2024 : petskii::textoutlined(5,160,"Free Memory = "+Str(mem)+" Mb",RGBA(55,255,0,255),RGBA(5,5,5,5))
  ElseIf mem<1000
    petskii::textoutlined(5,160,"Free Memory = "+Str(mem)+" Mb",RGBA(255,20,0,255),RGBA(5,5,5,5))
  Else
    petskii::textoutlined(5,160,"Free Memory = "+Str(mem)+" Mb",RGBA(255,200,0,255),RGBA(5,5,5,5))
  EndIf
  If GetMusicPosition(music_id) = 255 :  SetMusicPosition(music_id,0) : EndIf ;This behaves buggy after a time:(
  petskii::textoutlined(5,741,FormatDate("%hh:%ii:%ss",Date()),RGBA(255,255,55,255),RGBA(5,5,5,255))
EndProcedure

Procedure Load_Music()
  music_id=CatchMusic(#PB_Any,?music_start,?music_end-?music_start)
  PlayMusic(music_id)
  MusicVolume(music_id,#MUSICVOL)        
EndProcedure


;-PROCEDURES
Procedure app_start()
  sub_checks()
  ExamineDesktops()
  InitMouse()
  InitSprite()
  InitSound()
  InitKeyboard()
  OpenWindow(#WINDOW_H,0,0,#WINDOW_WIDTH,#WINDOW_HEIGHT,"2d Zoom Camera",#WINDOW_FLAGS)
  OpenWindowedScreen(WindowID(#WINDOW_H),0,0,#WINDOW_WIDTH,#WINDOW_HEIGHT,1,0,0,#PB_Screen_WaitSynchronization)
  ResizeWindow(#WINDOW_H,0,0,DesktopUnscaledX(DesktopWidth(#MAINDESKTOP_H)),DesktopUnscaledY(DesktopHeight(#MAINDESKTOP_H)))
  HideWindow(#WINDOW_H,#False)
  petskii::init()
  sub_createsprite()
  stripes::Create(#STRIPESIZE)
  sub_camerasetup()
  sub_airship_setup()
  sub_grid_setup()
  line::init(256)
  Load_Music()
EndProcedure

Procedure controls_update()
  Protected x.i, multiplier.i
    If MouseButton(#PB_MouseButton_Left)
    For x = 0 To #ship_count
      sprs(x)\tangle - #ROTATION_SPEED
    Next x
  EndIf
  
  If MouseButton(#PB_MouseButton_Right)
    For x = 0 To #ship_count
      sprs(x)\tangle + #ROTATION_SPEED
    Next x
  EndIf
  
  multiplier.i = (2*camera\zoom)
  If multiplier<1 : multiplier = 1 : EndIf  :  If multiplier>20 : multiplier = 20 : EndIf
  
  camera\tx + camera\scrollspeed*((MouseDeltaX()/(multiplier*2)))
  camera\ty + camera\scrollspeed*((MouseDeltaY()/(multiplier*2)))
  
  If camera\tx<#LEFTBORDER : camera\tx=#LEFTBORDER : EndIf
  If camera\tx>#RIGHTBORDER : camera\tx=#RIGHTBORDER : EndIf
  If camera\ty<#TOPBORDER : camera\ty=#TOPBORDER : EndIf
  If camera\ty>#BOTTOMBORDER : camera\ty=#BOTTOMBORDER : EndIf
  
  camera\x = camera\x*0.9+camera\tx*0.1
  camera\y = camera\y*0.9+camera\ty*0.1
  camera\zoom = camera\zoom*0.95+camera\tzoom*0.05
  
  If MouseWheel()<>0
    camera\tzoom=camera\tzoom+MouseWheel() * #MOUSEWHEEL_SENSITIVY * multiplier
    If camera\tzoom<#MINZOOM : camera\tzoom = #MINZOOM : EndIf
    If camera\tzoom>#MAXZOOM : camera\tzoom = #MAXZOOM : EndIf
  EndIf
EndProcedure

Procedure draw_gridmap()
  Protected.i startgridx,endgridx,startgridy,endgridy, i.i, j.i,trx.f,try.f
  For i = 0 To 15
    If IsSprite(tiles(i))
      ZoomSprite(tiles(i),ceil(grid(1,1)\basesize*camera\zoom),ceil(grid(1,1)\basesize*camera\zoom))
    EndIf
  Next i
  
  For i = 0 To #grid_count
    trx = floor(i*(#gridsize)-(camera\x)+ScreenWidth())
    If trx>-ScreenWidth()-4*SpriteWidth(grid(i,0)\spid)
      startgridx = i 
      endgridx = startgridx + 55
      If endgridx > #GRID_COUNT : endgridx = #GRID_COUNT : EndIf
      i = #grid_count
    EndIf
  Next i
  
  For i = 0 To #grid_count
    try = floor(i*(#gridsize)-(camera\y)+ScreenHeight())
    If try>-ScreenHeight()-SpriteHeight(grid(i,0)\spid)
      startgridy = i 
      endgridy = startgridy+29
      If endgridy > #GRID_COUNT : endgridy = #GRID_COUNT : EndIf
      i = #grid_count
    EndIf
  Next i
  
  For i = startgridx To endgridx
    For j = startgridy To endgridy
      With grid(i,j)
        trx = floor(i*(#gridsize*camera\zoom)-(camera\x*camera\zoom)+ScreenWidth()/2)
        try = floor(j*(#gridsize*camera\zoom)-(camera\y*camera\zoom)+ScreenHeight()/2)
        DisplayTransparentSprite(\spid,trx,try)
        If \ospid<>0 : DisplayTransparentSprite(\ospid,trx,try) : EndIf
      EndWith
    Next j
  Next i
EndProcedure

Procedure updateship(x)
    sprs(x)\angle = sprs(x)\angle*0.9+sprs(x)\tangle*0.1
    If Abs(sprs(x)\destx-sprs(x)\x)>100 And Abs(sprs(x)\desty-sprs(x)\y)>100
      sprs(x)\mindestx = sprs(x)\x- Sin(Radian(#off2+sprs(x)\angle))*sprs(x)\speed-Cos(Radian(#off2+sprs(x)\angle))*sprs(x)\speed
      sprs(x)\mindesty = sprs(x)\y-(-Cos(Radian(#off2+sprs(x)\angle)))*sprs(x)\speed-Sin(Radian(#off2+sprs(x)\angle))*sprs(x)\speed
    Else
      sprs(x)\destx = Random(#GRID_COUNT*#GRIDSIZE)
      sprs(x)\desty = Random(#GRID_COUNT*#GRIDSIZE)
    EndIf
    sprs(x)\tangle = 180+(ATan2(sprs(x)\destx-sprs(x)\x,sprs(x)\desty-sprs(x)\y)*#PI*180)
    
    
EndProcedure

Procedure draw_ships()
  Protected coox.i,cooy.i,cw = 300,x.i,trx.f,try.f,tmod.f
  
  ZoomSprite(airship_sprite_id,2*sprs(0)\hb*camera\zoom,2*sprs(0)\hb*camera\zoom)
  ZoomSprite(arrowsprite_ID,2*sprs(0)\hb*camera\zoom,2*sprs(0)\hb*camera\zoom)
  
  For x = 0 To #ship_count
    updateship(x)
    With sprs(x)
      trx = \x*(camera\zoom)-(camera\x*camera\zoom)+ScreenWidth()/2
      try = \y*(camera\zoom)-(camera\y*camera\zoom)+ScreenHeight()/2
      \x=\mindestx*0.05+\x*0.95
      \y=\mindesty*0.05+\y*0.95
      tmod = SpriteWidth(airship_sprite_id)/-2+SpriteWidth(arrowsprite_ID)*0.5
      RotateSprite(arrowsprite_ID,floor(\angle),#PB_Absolute)

      coox = floor(trx+\hb*camera\zoom) : cooy = floor(try+\hb*camera\zoom)
      line::drawcircle(ScreenWidth()-(ScreenWidth()-coox)+\basesize/2*camera\zoom-cw/2*camera\zoom,ScreenHeight()-(ScreenHeight()-cooy)+\basesize/2*camera\zoom-cw/2*camera\zoom,cw*camera\zoom,RGBA(255,2,2,255),100)
      line::drawcircleoutline(ScreenWidth()-(ScreenWidth()-coox)+\basesize/2*camera\zoom-cw/2*camera\zoom,ScreenHeight()-(ScreenHeight()-cooy)+\basesize/2*camera\zoom-cw/2*camera\zoom,cw*camera\zoom,RGBA(255,2,2,255),150)
      DisplayTransparentSprite(\spid,coox,cooy,#MAX_INTENSITY,\color)
        
        If ScreenWidth()-trx<ScreenWidth() And ScreenHeight()-try<ScreenHeight()-#STRIPESIZE/2
          If ScreenWidth()-trx>-10 And ScreenHeight()-try>#STRIPESIZE/2
            \linealpha+(#ALPHASTEP*2)
          EndIf
        EndIf
          
        If \linealpha<0 :\linealpha=0 : EndIf
        If \linealpha>0 : \linealpha-#ALPHASTEP : EndIf
        If \linealpha>255 :\linealpha=255 : EndIf
        
        If floor(\linealpha)>0
          line::draw(ScreenWidth()/2,ScreenHeight()/2,ScreenWidth()-(ScreenWidth()-coox)+\basesize/2*camera\zoom,ScreenHeight()-(ScreenHeight()-cooy)+\basesize/2*camera\zoom,RGBA(0,100,0,255),4,floor(\linealpha))        
          petskii::textoutlined(ScreenWidth()-(ScreenWidth()-coox)+\basesize/2*camera\zoom,ScreenHeight()-(ScreenHeight()-cooy)+\basesize/2*camera\zoom,"Airship_"+RSet(Str(x),5,"0"),RGBA(255,255,100,255),RGBA(5,5,5,255))
        EndIf
        DisplayTransparentSprite(arrowsprite_ID,floor(tmod+trx+SpriteWidth(airship_sprite_id)/2+((Sin(Radian(#off+\angle)))*#ARROWDIST*camera\zoom+Cos(Radian(#off+\angle))*#ARROWDIST*camera\zoom)),floor(tmod+try+SpriteWidth(airship_sprite_id)/2+(-Cos(Radian(#off+\angle)))*#ARROWDIST*camera\zoom+Sin(Radian(#off+\angle))*#ARROWDIST*camera\zoom))
    EndWith
  Next x
 ; camera\tx = sprs(1)\x
 ; camera\ty = sprs(1)\y
EndProcedure

Procedure app_update()
  Protected x.i,i.i,j.i, multiplier.i
  Protected ddist.f = camera\zoom*8
  Protected dx.f, dy.f, trx.f,try.f, tmod.f
  Delay(#MAINLOOP_DELAY)
  Repeat : Until Not WindowEvent()
  ClearScreen(0)
  ExamineKeyboard()
  ExamineMouse()
  controls_update()  
  draw_gridmap()  
  draw_ships()
  sub_Draw_UI()
  FlipBuffers()
EndProcedure
;-MAIN PROGRAM PROCEDURE
Procedure main()
  app_start()
  Repeat
    app_update()
  Until KeyboardPushed(#PB_Key_Escape)
  petskii::destroy()
  End
EndProcedure

;-MAIN PROGRAM
main()

DataSection
grasspng:
Data.a $89,$50,$4E,$47,$0D,$0A,$1A,$0A,$00,$00,$00,$0D,$49,$48,$44,$52,$00,$00,$00,$50,$00,$00,$00,$10,$08,$06,$00,$00,$00,$81,$49,$F8,$C1,$00,$00,$01
Data.a $85,$69,$43,$43,$50,$49,$43,$43,$20,$70,$72,$6F,$66,$69,$6C,$65,$00,$00,$28,$91,$7D,$91,$3D,$48,$C3,$40,$1C,$C5,$5F,$53,$4B,$45,$2A,$0E,$ED,$20
Data.a $22,$18,$B0,$3A,$59,$10,$15,$71,$94,$2A,$16,$C1,$42,$69,$2B,$B4,$EA,$60,$72,$E9,$87,$D0,$A4,$21,$49,$71,$71,$14,$5C,$0B,$0E,$7E,$2C,$56,$1D,$5C
Data.a $9C,$75,$75,$70,$15,$04,$C1,$0F,$10,$27,$47,$27,$45,$17,$29,$F1,$7F,$49,$A1,$45,$8C,$07,$C7,$FD,$78,$77,$EF,$71,$F7,$0E,$10,$1A,$15,$A6,$9A,$5D
Data.a $E3,$80,$AA,$59,$46,$3A,$11,$17,$73,$F9,$15,$31,$F8,$8A,$20,$C2,$08,$60,$08,$C3,$12,$33,$F5,$64,$66,$21,$0B,$CF,$F1,$75,$0F,$1F,$5F,$EF,$62,$3C
Data.a $CB,$FB,$DC,$9F,$A3,$57,$29,$98,$0C,$F0,$89,$C4,$B3,$4C,$37,$2C,$E2,$75,$E2,$E9,$4D,$4B,$E7,$BC,$4F,$1C,$61,$65,$49,$21,$3E,$27,$1E,$33,$E8,$82
Data.a $C4,$8F,$5C,$97,$5D,$7E,$E3,$5C,$72,$58,$E0,$99,$11,$23,$9B,$9E,$23,$8E,$10,$8B,$A5,$0E,$96,$3B,$98,$95,$0D,$95,$78,$8A,$38,$AA,$A8,$1A,$E5,$0B
Data.a $39,$97,$15,$CE,$5B,$9C,$D5,$4A,$8D,$B5,$EE,$C9,$5F,$18,$2A,$68,$CB,$19,$AE,$D3,$1C,$44,$02,$8B,$48,$22,$05,$11,$32,$6A,$D8,$40,$05,$16,$62,$B4
Data.a $6A,$A4,$98,$48,$D3,$7E,$DC,$C3,$3F,$E0,$F8,$53,$E4,$92,$C9,$B5,$01,$46,$8E,$79,$54,$A1,$42,$72,$FC,$E0,$7F,$F0,$BB,$5B,$B3,$38,$39,$E1,$26,$85
Data.a $E2,$40,$E0,$C5,$B6,$3F,$46,$80,$E0,$2E,$D0,$AC,$DB,$F6,$F7,$B1,$6D,$37,$4F,$00,$FF,$33,$70,$A5,$B5,$FD,$D5,$06,$30,$F3,$49,$7A,$BD,$AD,$45,$8F
Data.a $80,$BE,$6D,$E0,$E2,$BA,$AD,$C9,$7B,$C0,$E5,$0E,$D0,$FF,$A4,$4B,$86,$E4,$48,$7E,$9A,$42,$B1,$08,$BC,$9F,$D1,$37,$E5,$81,$F0,$2D,$D0,$B3,$EA,$F6
Data.a $D6,$DA,$C7,$E9,$03,$90,$A5,$AE,$96,$6E,$80,$83,$43,$60,$B4,$44,$D9,$6B,$1E,$EF,$EE,$EE,$EC,$ED,$DF,$33,$AD,$FE,$7E,$00,$7C,$89,$72,$AB,$1A,$50
Data.a $E7,$4E,$00,$00,$00,$06,$62,$4B,$47,$44,$00,$93,$00,$67,$00,$4D,$2A,$10,$06,$37,$00,$00,$00,$09,$70,$48,$59,$73,$00,$00,$0B,$13,$00,$00,$0B,$13
Data.a $01,$00,$9A,$9C,$18,$00,$00,$00,$07,$74,$49,$4D,$45,$07,$E4,$07,$13,$06,$02,$1A,$7A,$54,$30,$1F,$00,$00,$00,$19,$74,$45,$58,$74,$43,$6F,$6D,$6D
Data.a $65,$6E,$74,$00,$43,$72,$65,$61,$74,$65,$64,$20,$77,$69,$74,$68,$20,$47,$49,$4D,$50,$57,$81,$0E,$17,$00,$00,$00,$BB,$49,$44,$41,$54,$58,$C3,$63
Data.a $F4,$DB,$B3,$F3,$3F,$03,$05,$A0,$54,$6A,$1E,$25,$DA,$19,$DE,$FD,$FD,$4B,$91,$7E,$33,$26,$7B,$86,$AF,$EF,$5F,$C3,$F9,$DC,$82,$A2,$0C,$0C,$0C,$0C
Data.a $28,$62,$C8,$E2,$C8,$72,$DC,$82,$A2,$58,$F5,$92,$02,$98,$18,$86,$01,$E0,$16,$14,$85,$63,$6C,$72,$E4,$8A,$11,$02,$5F,$DF,$BF,$1E,$1E,$01,$88,$2B
Data.a $50,$89,$0D,$30,$72,$02,$6F,$58,$A5,$40,$62,$02,$91,$56,$60,$58,$07,$20,$AD,$03,$99,$5B,$50,$74,$34,$00,$29,$05,$2C,$A3,$41,$40,$1E,$80,$D5,$DE
Data.a $4C,$A3,$01,$F1,$1A,$A3,$C9,$43,$6C,$E0,$8D,$A6,$40,$32,$CB,$40,$E4,$B6,$E6,$68,$19,$48,$61,$16,$1E,$2D,$03,$29,$4C,$B9,$A3,$29,$70,$B4,$1D,$38
Data.a $1A,$80,$54,$29,$8B,$06,$42,$FF,$B0,$A9,$44,$70,$05,$02,$BE,$C0,$41,$96,$23,$27,$10,$87,$5D,$25,$82,$3C,$44,$45,$AC,$5A,$52,$F4,$E0,$AA,$44,$00
Data.a $0C,$38,$49,$A7,$A3,$33,$11,$6F,$00,$00,$00,$00,$49,$45,$4E,$44,$AE,$42,$60,$82
EndDataSection

DataSection
deadgrasspng:
Data.a $89,$50,$4E,$47,$0D,$0A,$1A,$0A,$00,$00,$00,$0D,$49,$48,$44,$52,$00,$00,$00,$30,$00,$00,$00,$20,$08,$06,$00,$00,$00,$54,$D4,$FB,$1C,$00,$00,$01
Data.a $85,$69,$43,$43,$50,$49,$43,$43,$20,$70,$72,$6F,$66,$69,$6C,$65,$00,$00,$28,$91,$7D,$91,$3D,$48,$C3,$40,$18,$86,$DF,$A6,$4A,$45,$2A,$0E,$16,$14
Data.a $71,$08,$58,$5D,$B4,$20,$2A,$E2,$28,$55,$2C,$82,$85,$D2,$56,$68,$D5,$C1,$E4,$D2,$3F,$68,$D2,$90,$A4,$B8,$38,$0A,$AE,$05,$07,$7F,$16,$AB,$0E,$2E
Data.a $CE,$BA,$3A,$B8,$0A,$82,$E0,$0F,$88,$93,$A3,$93,$A2,$8B,$94,$F8,$5D,$52,$68,$11,$E3,$1D,$C7,$3D,$BC,$F7,$BD,$2F,$77,$DF,$01,$42,$BD,$CC,$54,$B3
Data.a $63,$02,$50,$35,$CB,$48,$C6,$A2,$62,$26,$BB,$2A,$06,$5E,$11,$44,$3F,$CD,$31,$0C,$4B,$CC,$D4,$E3,$A9,$C5,$34,$3C,$C7,$D7,$3D,$7C,$7C,$BF,$8B,$F0
Data.a $2C,$EF,$BA,$3F,$47,$8F,$92,$33,$19,$E0,$13,$89,$E7,$98,$6E,$58,$C4,$1B,$C4,$33,$9B,$96,$CE,$79,$9F,$38,$C4,$8A,$92,$42,$7C,$4E,$3C,$6E,$D0,$05
Data.a $89,$1F,$B9,$2E,$BB,$FC,$C6,$B9,$E0,$B0,$C0,$33,$43,$46,$3A,$39,$4F,$1C,$22,$16,$0B,$6D,$2C,$B7,$31,$2B,$1A,$2A,$F1,$34,$71,$58,$51,$35,$CA,$17
Data.a $32,$2E,$2B,$9C,$B7,$38,$AB,$E5,$2A,$6B,$DE,$93,$BF,$30,$98,$D3,$56,$52,$5C,$A7,$35,$84,$18,$96,$10,$47,$02,$22,$64,$54,$51,$42,$19,$16,$22,$B4
Data.a $6B,$A4,$98,$48,$D2,$79,$D4,$C3,$3F,$E8,$F8,$13,$E4,$92,$C9,$55,$02,$23,$C7,$02,$2A,$50,$21,$39,$7E,$F0,$3F,$F8,$DD,$5B,$33,$3F,$35,$E9,$26,$05
Data.a $A3,$40,$E7,$8B,$6D,$7F,$8C,$00,$81,$5D,$A0,$51,$B3,$ED,$EF,$63,$DB,$6E,$9C,$00,$FE,$67,$E0,$4A,$6B,$F9,$2B,$75,$60,$F6,$93,$F4,$5A,$4B,$0B,$1F
Data.a $01,$BD,$DB,$C0,$C5,$75,$4B,$93,$F7,$80,$CB,$1D,$60,$E0,$49,$97,$0C,$C9,$91,$FC,$B4,$84,$7C,$1E,$78,$3F,$A3,$6F,$CA,$02,$7D,$B7,$40,$F7,$9A,$DB
Data.a $B7,$E6,$39,$4E,$1F,$80,$34,$F5,$6A,$F9,$06,$38,$38,$04,$46,$0B,$94,$BD,$EE,$F1,$EE,$AE,$F6,$BE,$FD,$5B,$D3,$EC,$DF,$0F,$DE,$34,$72,$D2,$94,$1E
Data.a $82,$6D,$00,$00,$00,$06,$62,$4B,$47,$44,$00,$E7,$00,$D5,$00,$93,$81,$F3,$95,$95,$00,$00,$00,$09,$70,$48,$59,$73,$00,$00,$0B,$13,$00,$00,$0B,$13
Data.a $01,$00,$9A,$9C,$18,$00,$00,$00,$07,$74,$49,$4D,$45,$07,$E4,$0C,$18,$01,$31,$37,$6E,$7E,$A9,$CF,$00,$00,$00,$19,$74,$45,$58,$74,$43,$6F,$6D,$6D
Data.a $65,$6E,$74,$00,$43,$72,$65,$61,$74,$65,$64,$20,$77,$69,$74,$68,$20,$47,$49,$4D,$50,$57,$81,$0E,$17,$00,$00,$01,$6C,$49,$44,$41,$54,$58,$C3,$ED
Data.a $97,$CD,$6A,$83,$40,$14,$85,$BF,$16,$91,$41,$74,$61,$98,$6C,$5C,$84,$AC,$F2,$92,$79,$AC,$42,$9F,$A4,$AB,$AC,$D2,$D2,$66,$53,$69,$16,$11,$11,$11
Data.a $DA,$8D,$77,$08,$1A,$FF,$D0,$29,$A4,$9D,$BB,$12,$9D,$39,$73,$CE,$9C,$C3,$8C,$F7,$E1,$F9,$69,$FF,$CD,$1D,$D7,$23,$77,$5E,$4E,$C0,$9F,$14,$B0,$59
Data.a $EF,$D8,$AC,$77,$00,$14,$79,$49,$91,$97,$AD,$F7,$4B,$CD,$B3,$22,$E0,$ED,$F3,$60,$16,$56,$81,$6F,$9E,$AF,$BF,$0D,$CD,$03,$50,$81,$3F,$38,$CF,$5B
Data.a $9A,$BC,$EC,$5A,$5E,$65,$00,$E8,$38,$21,$E5,$44,$5E,$65,$A4,$E7,$D3,$28,$F1,$3A,$4E,$50,$81,$8F,$8E,$13,$83,$23,$B8,$B2,$21,$D6,$1C,$90,$05,$DE
Data.a $3F,$8E,$00,$86,$F4,$18,$F2,$52,$CD,$39,$82,$D5,$24,$6F,$C5,$81,$6B,$CB,$A7,$90,$EE,$13,$D3,$17,$A5,$C5,$1D,$38,$BC,$BE,$98,$E8,$2C,$55,$82,$25
Data.a $D8,$D6,$23,$34,$36,$EF,$53,$5C,$C8,$AB,$EC,$66,$84,$AC,$9C,$42,$4B,$92,$1F,$C2,$74,$17,$99,$13,$F0,$DF,$05,$78,$A1,$E7,$3B,$07,$9C,$00,$27,$C0
Data.a $09,$68,$D7,$2A,$DE,$B2,$8A,$B7,$00,$64,$55,$49,$56,$95,$AD,$F7,$73,$C6,$5B,$17,$F0,$75,$3E,$1A,$02,$72,$D2,$09,$11,$F9,$D6,$35,$1E,$20,$F4,$FC
Data.a $DE,$F1,$D6,$7E,$A7,$65,$07,$01,$54,$DD,$8C,$A8,$48,$C3,$25,$25,$AF,$32,$8A,$4B,$DA,$2B,$5A,$45,$9A,$D0,$F3,$51,$91,$36,$CD,$8C,$E0,$DD,$3A,$F2
Data.a $AD,$38,$20,$0B,$C9,$0F,$98,$90,$EE,$23,$6F,$3A,$BA,$C6,$58,$C1,$E8,$BA,$AF,$3C,$6B,$F9,$AF,$77,$74,$0C,$E9,$3E,$31,$43,$51,$B2,$DA,$D4,$AB,$48
Data.a $CF,$EF,$2F,$6A,$8C,$5F,$6B,$EA,$C5,$EE,$A1,$BC,$4F,$71,$81,$A8,$3B,$42,$D6,$4E,$A1,$25,$C8,$8F,$C1,$72,$17,$99,$13,$30,$B3,$7E,$00,$3E,$54,$C7
Data.a $DB,$58,$06,$50,$88,$00,$00,$00,$00,$49,$45,$4E,$44,$AE,$42,$60,$82
EndDataSection

DataSection
treespng:
Data.a $89,$50,$4E,$47,$0D,$0A,$1A,$0A,$00,$00,$00,$0D,$49,$48,$44,$52,$00,$00,$00,$40,$00,$00,$00,$10,$08,$06,$00,$00,$00,$A6,$E7,$79,$29,$00,$00,$01
Data.a $85,$69,$43,$43,$50,$49,$43,$43,$20,$70,$72,$6F,$66,$69,$6C,$65,$00,$00,$28,$91,$7D,$91,$3D,$48,$C3,$40,$1C,$C5,$5F,$53,$4B,$45,$2A,$0E,$ED,$20
Data.a $22,$18,$B0,$3A,$59,$10,$15,$71,$94,$2A,$16,$C1,$42,$69,$2B,$B4,$EA,$60,$72,$E9,$87,$D0,$A4,$21,$49,$71,$71,$14,$5C,$0B,$0E,$7E,$2C,$56,$1D,$5C
Data.a $9C,$75,$75,$70,$15,$04,$C1,$0F,$10,$27,$47,$27,$45,$17,$29,$F1,$7F,$49,$A1,$45,$8C,$07,$C7,$FD,$78,$77,$EF,$71,$F7,$0E,$10,$1A,$15,$A6,$9A,$5D
Data.a $E3,$80,$AA,$59,$46,$3A,$11,$17,$73,$F9,$15,$31,$F8,$8A,$20,$C2,$08,$60,$08,$C3,$12,$33,$F5,$64,$66,$21,$0B,$CF,$F1,$75,$0F,$1F,$5F,$EF,$62,$3C
Data.a $CB,$FB,$DC,$9F,$A3,$57,$29,$98,$0C,$F0,$89,$C4,$B3,$4C,$37,$2C,$E2,$75,$E2,$E9,$4D,$4B,$E7,$BC,$4F,$1C,$61,$65,$49,$21,$3E,$27,$1E,$33,$E8,$82
Data.a $C4,$8F,$5C,$97,$5D,$7E,$E3,$5C,$72,$58,$E0,$99,$11,$23,$9B,$9E,$23,$8E,$10,$8B,$A5,$0E,$96,$3B,$98,$95,$0D,$95,$78,$8A,$38,$AA,$A8,$1A,$E5,$0B
Data.a $39,$97,$15,$CE,$5B,$9C,$D5,$4A,$8D,$B5,$EE,$C9,$5F,$18,$2A,$68,$CB,$19,$AE,$D3,$1C,$44,$02,$8B,$48,$22,$05,$11,$32,$6A,$D8,$40,$05,$16,$62,$B4
Data.a $6A,$A4,$98,$48,$D3,$7E,$DC,$C3,$3F,$E0,$F8,$53,$E4,$92,$C9,$B5,$01,$46,$8E,$79,$54,$A1,$42,$72,$FC,$E0,$7F,$F0,$BB,$5B,$B3,$38,$39,$E1,$26,$85
Data.a $E2,$40,$E0,$C5,$B6,$3F,$46,$80,$E0,$2E,$D0,$AC,$DB,$F6,$F7,$B1,$6D,$37,$4F,$00,$FF,$33,$70,$A5,$B5,$FD,$D5,$06,$30,$F3,$49,$7A,$BD,$AD,$45,$8F
Data.a $80,$BE,$6D,$E0,$E2,$BA,$AD,$C9,$7B,$C0,$E5,$0E,$D0,$FF,$A4,$4B,$86,$E4,$48,$7E,$9A,$42,$B1,$08,$BC,$9F,$D1,$37,$E5,$81,$F0,$2D,$D0,$B3,$EA,$F6
Data.a $D6,$DA,$C7,$E9,$03,$90,$A5,$AE,$96,$6E,$80,$83,$43,$60,$B4,$44,$D9,$6B,$1E,$EF,$EE,$EE,$EC,$ED,$DF,$33,$AD,$FE,$7E,$00,$7C,$89,$72,$AB,$1A,$50
Data.a $E7,$4E,$00,$00,$00,$06,$62,$4B,$47,$44,$00,$93,$00,$67,$00,$4D,$2A,$10,$06,$37,$00,$00,$00,$09,$70,$48,$59,$73,$00,$00,$0B,$13,$00,$00,$0B,$13
Data.a $01,$00,$9A,$9C,$18,$00,$00,$00,$07,$74,$49,$4D,$45,$07,$E4,$07,$13,$09,$14,$05,$E0,$98,$CF,$00,$00,$00,$00,$19,$74,$45,$58,$74,$43,$6F,$6D,$6D
Data.a $65,$6E,$74,$00,$43,$72,$65,$61,$74,$65,$64,$20,$77,$69,$74,$68,$20,$47,$49,$4D,$50,$57,$81,$0E,$17,$00,$00,$03,$72,$49,$44,$41,$54,$58,$C3,$D5
Data.a $56,$4B,$48,$1B,$51,$14,$3D,$E3,$67,$2F,$52,$9D,$C4,$45,$DB,$58,$6C,$17,$B5,$50,$1B,$63,$DA,$45,$C5,$85,$52,$1B,$14,$4B,$84,$A9,$A5,$69,$A4,$0A
Data.a $45,$C4,$A5,$88,$64,$13,$BA,$09,$22,$71,$55,$11,$37,$B1,$68,$53,$2A,$81,$16,$4A,$C4,$0A,$7E,$28,$B8,$8A,$51,$52,$DA,$A2,$A2,$A0,$B6,$A2,$E6,$83
Data.a $A2,$28,$6E,$34,$79,$5D,$24,$33,$9D,$97,$BC,$19,$93,$5A,$29,$3D,$30,$CC,$FB,$DC,$F3,$EE,$DC,$73,$EF,$7B,$F3,$38,$9C,$13,$01,$97,$E5,$5C,$FC,$B2
Data.a $56,$37,$73,$9C,$E7,$79,$02,$00,$A1,$50,$88,$4B,$C7,$FF,$DA,$49,$04,$00,$50,$9C,$5B,$C0,$6C,$B3,$E6,$00,$20,$07,$17,$80,$5A,$DB,$24,$91,$F7,$27
Data.a $1C,$35,$DC,$59,$1C,$97,$AB,$16,$00,$D0,$DA,$3A,$01,$9E,$E7,$C9,$D8,$7C,$13,$00,$A0,$AE,$7C,$94,$38,$1C,$65,$9C,$38,$27,$B7,$13,$B1,$76,$12,$81
Data.a $D9,$5A,$0A,$8D,$CE,$2D,$F9,$0D,$AE,$5B,$38,$79,$1F,$00,$06,$5E,$DE,$E6,$CC,$D6,$52,$00,$C0,$87,$91,$EF,$28,$CE,$2D,$F8,$7B,$02,$7C,$CE,$D9,$07
Data.a $00,$F4,$74,$F9,$A5,$8F,$97,$04,$29,$1F,$25,$DD,$BD,$06,$AE,$EA,$34,$4F,$B2,$AB,$3A,$CD,$A3,$82,$7F,$F0,$BC,$2C,$9E,$79,$5B,$80,$E2,$8F,$CD,$37
Data.a $A1,$AE,$7C,$94,$2C,$EC,$B4,$70,$2E,$40,$B2,$73,$25,$89,$A0,$D1,$B9,$25,$9E,$3F,$1A,$83,$46,$E7,$26,$76,$9F,$00,$43,$76,$96,$34,$D6,$6E,$F4,$10
Data.a $B3,$B5,$94,$4A,$86,$24,$80,$D3,$D6,$98,$51,$C0,$9D,$8E,$F7,$54,$F0,$95,$56,$23,$4C,$9A,$FE,$94,$E0,$E5,$41,$A0,$D7,$C0,$55,$5A,$8D,$71,$CE,$88
Data.a $8F,$12,$21,$1D,$18,$EF,$6A,$99,$E3,$ED,$F6,$2F,$C4,$EE,$13,$A4,$BE,$21,$3B,$0B,$F2,$E0,$E5,$63,$1A,$9D,$9B,$04,$D7,$2D,$1C,$25,$80,$D3,$D6,$88
Data.a $CA,$F2,$22,$14,$95,$E4,$63,$7B,$75,$0F,$45,$25,$F9,$00,$80,$ED,$D5,$3D,$00,$A0,$FA,$A2,$8D,$D3,$D6,$48,$89,$90,$0E,$EE,$DC,$2B,$52,$9D,$D7,$6B
Data.a $87,$14,$05,$D4,$6B,$87,$C8,$C2,$4E,$8B,$EA,$56,$F2,$47,$63,$19,$57,$AE,$24,$91,$18,$A4,$F8,$4E,$6E,$2B,$D9,$88,$30,$69,$FA,$A9,$2C,$24,$C3,$EE
Data.a $13,$20,$DC,$FF,$48,$70,$41,$D8,$08,$C7,$B3,$2C,$CF,$BA,$3F,$1A,$A3,$9E,$8D,$30,$A4,$2A,$48,$11,$40,$09,$AC,$60,$33,$CD,$42,$3A,$99,$D1,$6B,$87
Data.a $88,$DD,$27,$50,$B6,$62,$DB,$1F,$8D,$C1,$EE,$13,$A0,$D7,$0E,$11,$D6,$81,$6B,$F7,$09,$B8,$5A,$08,$AA,$DC,$C5,$B7,$5C,$14,$B9,$4D,$CA,$19,$70,$1E
Data.a $F4,$74,$F9,$49,$B3,$57,$38,$33,$E0,$66,$AF,$00,$93,$A6,$9F,$8C,$07,$3B,$D2,$2E,$E5,$4C,$CA,$FA,$4F,$B6,$00,$53,$00,$7D,$F5,$20,$A5,$F4,$C2,$54
Data.a $1B,$87,$0B,$84,$CD,$16,$A0,$04,$54,$42,$B3,$57,$60,$9E,$05,$1B,$61,$A4,$64,$78,$23,$0C,$A0,$30,$06,$96,$9D,$AA,$00,$FA,$EA,$41,$E2,$1F,$78,$0C
Data.a $4D,$61,$FC,$A2,$10,$0C,$47,$A0,$AF,$1E,$24,$0B,$53,$6D,$9C,$FC,$80,$54,$DA,$87,$AC,$32,$53,$72,$AE,$C4,$67,$AD,$A3,$C2,$E7,$86,$EB,$3D,$A4,$D9
Data.a $2B,$A4,$D8,$B0,$38,$C3,$F5,$1E,$00,$E0,$54,$CF,$00,$31,$F8,$E4,$76,$BA,$87,$11,$EB,$C9,$84,$CF,$5A,$47,$09,$13,$8E,$9A,$8C,$2B,$2E,$B8,$6E,$81
Data.a $AA,$00,$C1,$70,$84,$D9,$56,$01,$97,$50,$56,$15,$C9,$EA,$FF,$2B,$7E,$64,$79,$17,$5F,$97,$F7,$E8,$2D,$20,$2F,$EF,$83,$C3,$43,$1C,$1C,$1E,$2A,$2E
Data.a $24,$DE,$0F,$44,$74,$F7,$1A,$D0,$D3,$E5,$E7,$86,$EB,$3D,$04,$00,$DE,$76,$56,$50,$F3,$4F,$9D,$73,$D2,$87,$8E,$07,$3B,$52,$D6,$B3,$3C,$BB,$02,$F7
Data.a $9B,$1F,$69,$F1,$A7,$67,$4C,$D8,$5F,$0A,$62,$71,$E9,$F7,$37,$B4,$3D,$B9,$8C,$C1,$77,$3F,$D3,$E2,$7F,$FB,$F4,$90,$7D,$0F,$60,$05,$C6,$9A,$63,$D9
Data.a $AC,$2C,$EE,$C2,$33,$DB,$20,$65,$87,$2F,$B8,$44,$3D,$A2,$73,$CF,$6C,$03,$8E,$56,$37,$71,$B4,$BA,$89,$95,$C5,$5D,$6A,$8D,$E9,$19,$D3,$99,$FC,$84
Data.a $0D,$13,$89,$C0,$54,$F9,$C9,$C1,$4B,$15,$20,$BF,$D1,$F1,$3C,$CF,$74,$50,$61,$7E,$A5,$E8,$FC,$C5,$F5,$6B,$C0,$EC,$31,$26,$1C,$35,$A8,$B5,$4D,$2A
Data.a $EF,$D5,$D9,$63,$9A,$93,$40,$9F,$73,$0E,$7D,$89,$2C,$29,$F9,$0F,$85,$42,$28,$BD,$F9,$9A,$39,$F7,$E8,$D6,$0D,$6C,$05,$4E,$CF,$F4,$BF,$15,$38,$A5
Data.a $38,$4A,$BF,$C1,$F3,$FE,$F2,$FE,$2B,$FE,$2F,$86,$32,$BB,$EA,$DC,$7F,$AC,$90,$00,$00,$00,$00,$49,$45,$4E,$44,$AE,$42,$60,$82
EndDataSection

DataSection
music_start:
Data.a $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$1A,$10,$00,$00,$02,$00,$01,$00,$0A,$00,$00,$00,$31,$51,$02,$00,$53,$43,$52,$4D,$40,$06,$7D
Data.a $B0,$10,$FC,$00,$14,$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$FF,$0A,$00,$0F,$00
Data.a $00,$00,$1D,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$28,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$80
Data.a $80,$80,$80,$80,$80,$80,$80,$01,$74,$72,$69,$61,$6E,$67,$6C,$65,$5F,$38,$5F,$36,$00,$27,$00,$40,$00,$00,$00,$00,$00,$00,$00,$40,$00,$00,$00,$40,$00,$00,$01,$56,$41,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
Data.a $00,$00,$00,$00,$74,$72,$69,$61,$6E,$67,$6C,$65,$5F,$38,$5F,$36,$34,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$53,$43,$52,$53,$D7,$00,$A0,$40,$01,$01,$10,$00,$20,$42,$01,$00,$A0,$43,$01
Data.a $12,$33,$00,$00,$A0,$43,$01,$12,$33,$00,$20,$45,$00,$00,$20,$47,$01,$00,$00,$20,$47,$01,$00,$20,$4A,$01,$00,$20,$45,$01,$00,$20,$FF,$01,$00,$20,$43,$01,$00,$20,$42,$01,$00,$20,$40,$01,$00,$00,$20,$40,$01
Data.a $00,$20,$42,$01,$00,$20,$43,$01,$00,$00,$20,$43,$01,$00,$20,$45,$00,$00,$20,$47,$01,$00,$00,$20,$47,$01,$00,$20,$4A,$01,$00,$20,$50,$01,$00,$20,$FF,$01,$00,$20,$4A,$01,$00,$20,$52,$01,$00,$20,$50,$01,$00
Data.a $00,$20,$50,$01,$00,$20,$52,$01,$00,$20,$53,$01,$00,$00,$20,$52,$01,$00,$00,$20,$50,$01,$00,$20,$FF,$01,$00,$20,$4A,$01,$00,$00,$20,$48,$01,$00,$00,$20,$47,$01,$00,$00,$20,$45,$01,$00,$00,$00,$20,$FF,$01
Data.a $00,$20,$FF,$01,$00,$20,$FF,$01,$00,$20,$43,$00,$00,$20,$47,$01,$00,$20,$45,$01,$00,$00,$20,$FF,$01,$00,$20,$FF,$01,$00,$00,$20,$43,$01,$00,$20,$42,$00,$00,$A0,$40,$01,$01,$14,$00,$00,$00,$00,$00,$00,$00
Data.a $00,$00,$00,$00,$00,$9F,$00,$20,$44,$01,$00,$20,$47,$01,$00,$20,$49,$01,$00,$20,$44,$01,$00,$20,$47,$01,$00,$20,$49,$01,$00,$00,$00,$00,$00,$00,$00,$20,$44,$00,$00,$20,$47,$00,$00,$20,$49,$00,$00,$20,$44
Data.a $00,$00,$20,$47,$00,$00,$20,$49,$00,$00,$00,$00,$20,$44,$00,$00,$20,$47,$00,$00,$20,$44,$00,$00,$20,$49,$00,$00,$20,$47,$00,$00,$20,$52,$00,$00,$00,$00,$20,$40,$00,$00,$20,$40,$00,$00,$20,$40,$00,$00,$00
Data.a $20,$40,$00,$00,$00,$20,$40,$00,$00,$00,$20,$40,$00,$00,$00,$20,$45,$00,$00,$00,$00,$00,$20,$50,$00,$00,$00,$00,$00,$20,$47,$00,$00,$00,$20,$45,$00,$00,$00,$20,$44,$00,$00,$00,$20,$42,$00,$00,$00,$20,$50
Data.a $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$80,$88,$91,$97,$A0,$A8,$B0,$B7,$BF,$C7,$D0,$D6,$DF,$E7,$EF,$F6,$FE,$F6,$EF,$E7,$DF,$D6,$D0,$C7,$BF,$B7,$B0,$A8,$A0,$97,$91,$88,$80,$78,$6F,$69,$60,$58,$50
Data.a $47,$41,$39,$30,$28,$20,$19,$11,$08,$00,$08,$11,$19,$20,$28,$30,$39,$41,$47,$50,$58,$60,$69,$6F,$78
music_end:
EndDataSection
Last edited by miso on Sun Mar 30, 2025 8:01 pm, edited 2 times in total.
User avatar
idle
Always Here
Always Here
Posts: 5834
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Maths problem with basic camera

Post by idle »

that's very cool. 8)
Joubarbe
Enthusiast
Enthusiast
Posts: 701
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Re: Maths problem with basic camera

Post by Joubarbe »

Sorry to reopen this, but I don't understand why is every movement (camera or sprites) is "smooth" in your first code:

Code: Select all

multiplier.i = (2*camera\zoom)
If multiplier<1 : multiplier = 1 : EndIf  :  If multiplier>20 : multiplier = 20 : EndIf

camera\tx + (MouseDeltaX()/(multiplier*2))
camera\ty + (MouseDeltaY()/(multiplier*2))

; [...]

camera\x = camera\x*0.9+camera\tx*0.1
camera\y = camera\y*0.9+camera\ty*0.1
camera\zoom = camera\zoom*0.95+camera\tzoom*0.05
I think this part of the code is the core. I think you get the "smooth" effect (like if you had a camera acceleration value) by multiplying the current x by 0.9 and the target pos by 0.1, but I don't understand this, nor the "multiplier * 2" part. If you could just give a few comments on this part of the code, I would greatly appreciate it!
miso
Enthusiast
Enthusiast
Posts: 406
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Maths problem with basic camera

Post by miso »

No problem. It's a simple (fast) nonlinear interpolation widely used in games. You correctly selected the parts that do that.
Variable \tx isn't really descriptive, it means "target x coordinate" in my codes.

Code: Select all

currentx = currentx*0.9 + targetx*0.1
will result a smooth movement that slows down as currentx and targetx gets closer.

Regarding the mousedelta part, I think it was too fast if it was not divided. The multiplier would change the mouse sensitivity.

Heres another code that is short and clean (not prototype) and mainly about this interpolated sprite movement:
viewtopic.php?p=634737#p634737
Last edited by miso on Wed Jul 02, 2025 1:54 pm, edited 3 times in total.
Fred
Administrator
Administrator
Posts: 18150
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Maths problem with basic camera

Post by Fred »

I missed this code, very nice indeed @miso ! To have smoother sprite move, may be I can change the x,y in DisplaySprite() from int to float, so you can place a sprite between a pixel
miso
Enthusiast
Enthusiast
Posts: 406
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Maths problem with basic camera

Post by miso »

Thanks, Fred!

Floats would be nice indeed ;) (I currently ceil/floor the tile coordinates to match the sides, but this way its pixel perfect at least)
Joubarbe
Enthusiast
Enthusiast
Posts: 701
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Re: Maths problem with basic camera

Post by Joubarbe »

Thank you! I won't say I totally understand, but I'm going to do some research about this nonlinear interpolation you're talking about. Hopefully my project won't demand much more maths than that! What I used to do for every animation was to use the ease functions and have intermediary variables like acceleration.
miso
Enthusiast
Enthusiast
Posts: 406
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Maths problem with basic camera

Post by miso »

"Easing" the name of those, there are many. Not every one is recommended for games, but most can be "cheated" for faster versions.

Code: Select all

	Procedure.f smooth(x.f,targetx.f)
		ProcedureReturn((0.9*x.f)+(0.1*targetx.f))
	EndProcedure  
I'm not that good at explaining things, but these people are: (27 mins long video)
https://www.youtube.com/watch?v=mr5xkf6zSzk
Joubarbe
Enthusiast
Enthusiast
Posts: 701
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Re: Maths problem with basic camera

Post by Joubarbe »

👍
miso
Enthusiast
Enthusiast
Posts: 406
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Maths problem with basic camera

Post by miso »

I think I have a good description:

You have a sprite, and have a \x \y as position coordinates. You always draw the sprites there, and do not manipulate the values directly.
You have a \targetx and \targety as coordinates of a point. You want to move the sprite toward this position. You only change the target coordinates.

With every iteration of your main loop, you change \x \y to move toward the target, but take only a flat 10% of the distance.
That is done with that current*09 + target*01 multiplication as a rule, and this will be the new current. You apply the rule with every iteration of the main loop once.

In the next iteration of the main loop the distance between current and target will be shorter, so that 10% will be also shorter and so the next movement
will be also shorter. This results in an easing. Theres no speed really here, the speed is based on the distance of the target and current values with this method.
Joubarbe
Enthusiast
Enthusiast
Posts: 701
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Re: Maths problem with basic camera

Post by Joubarbe »

miso wrote: Thu Jul 03, 2025 6:28 am I think I have a good description:

You have a sprite, and have a \x \y as position coordinates. You always draw the sprites there, and do not manipulate the values directly.
You have a \targetx and \targety as coordinates of a point. You want to move the sprite toward this position. You only change the target coordinates.

With every iteration of your main loop, you change \x \y to move toward the target, but take only a flat 10% of the distance.
That is done with that current*09 + target*01 multiplication as a rule, and this will be the new current. You apply the rule with every iteration of the main loop once.

In the next iteration of the main loop the distance between current and target will be shorter, so that 10% will be also shorter and so the next movement
will be also shorter. This results in an easing. Theres no speed really here, the speed is based on the distance of the target and current values with this method.
Funny you write this at the exact moment when I think I finally understand. I did a few experiments to understand that; but also realised that my goal cannot work with linear interpolation, because what I actually want is to move the object from A to B at the same speed. With linear interpolation, the object is faster when the distance is greater.

For a lack of better of code, I have that:

Code: Select all

    If \position\x = \destination\x And \position\y = \destination\y : ProcedureReturn : EndIf
    
    \position\x + \speed * Cos(\angle) * delta
    \position\y + \speed * Sin(\angle) * delta
    
    If (\destination\x - \position\x) * (\destination\x - \position\x) + (\destination\y - \position\y) * (\destination\y - \position\y) < 1.0
      \position\x = \destination\x
      \position\y = \destination\y
    EndIf
I should probably calculate Cos() and Sin() before, as I want things to be very performant. The second part is ugly, but if I don't do that, it will keep moving forever.

That being said, the interpolation of the camera really gives it a cool effect!

EDIT: I don't really understand the following line either:

Code: Select all

tmod = SpriteWidth(airship_sprite_id)/-2+SpriteWidth(arrowsprite_ID)*0.75
If I set tmod to 0, it seems there's no difference.
miso
Enthusiast
Enthusiast
Posts: 406
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Maths problem with basic camera

Post by miso »

Its an offset for the arrowsprite to put it a little bit to the right and down compared to the middle of the boxsprite. Seemed better that way. If you change *0.75 to *1.75, the transformation will be more visible. Though not necessary.

(Also the sprite creation method in that code is not 6.21 ready because of the changes in the new version. It has some visual artifacts)
Post Reply