Create a terrain

Everything related to 3D programming
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 303
Joined: Sun Aug 29, 2021 4:34 am

Re: Create a terrain

Post by Distorted Pixel »

Thank you for your examples, I will take a look at all of them after work today.

I just have one question for this post for now. What colors are required for height maps to be used in PB? Shades of red, gray scale, black white and gray or multicolors?
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
User avatar
Caronte3D
Addict
Addict
Posts: 1361
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: Create a terrain

Post by Caronte3D »

If do you use the procedure miso posted, then the red channel is used for elevation:

Code: Select all

ColorValue = Red(Color)
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 303
Joined: Sun Aug 29, 2021 4:34 am

Re: Create a terrain

Post by Distorted Pixel »

Caronte3D wrote: Wed Apr 09, 2025 2:32 pm If do you use the procedure miso posted, then the red channel is used for elevation:

Code: Select all

ColorValue = Red(Color)
Ok, thank you.
Is the most common height map type used for PB gray scale?
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
miso
Enthusiast
Enthusiast
Posts: 466
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Create a terrain

Post by miso »

Grayscale is the most common due to it's clean visibility when viewed/edited with an external paint software used by the artists, even if only 1 channel is used. But that's not exclusive, the channels can be used to various things. ( and it does not need to be an image at all, its just convenient. )
User avatar
minimy
Enthusiast
Enthusiast
Posts: 616
Joined: Mon Jul 08, 2013 8:43 pm
Location: off world

Re: Create a terrain

Post by minimy »

Can use some thing like this to convert color to grayscale.
(R+G+B)/3 this can result in error division by cero if color is black. With this no errors (R+G+B)*0.333333
With a function can convert your color image to grayscale. Use c=Point(x,y) and (Red(c)+Green(c)+Blue(c))*0.333333 to convert the pixel color in grayscale.
If translation=Error: reply="Sorry, Im Spanish": Endif
miso
Enthusiast
Enthusiast
Posts: 466
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Create a terrain

Post by miso »

Fun fact, on images the color channel weights to grayscale are not equal.
The NTSC formula is this:

0.299 * Red + 0.587 * Green + 0.114 * Blue.
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 303
Joined: Sun Aug 29, 2021 4:34 am

Re: Create a terrain

Post by Distorted Pixel »

minimy wrote: Mon Apr 07, 2025 12:20 am Hello, as said miso, is a mix of things. When i begin 3D with PB had many problems with meshes and software. Now im working with 6 programs free to use:
Blender for modelling, animation and convert 3D formats.
DelEd is nice for low poly and easy textured of the object,. Create levels or zones for games is easy. This is good is you want prerenderized lights and shadows. (search as deled 3d)
Fragmotion good for model animation,
Gimp for 2D textures, icons, graphs, sprites.
Audacity to edit and convert audio.
ShotCut if need edit any clip of video.
All are free and more or less friendly to use.
You can use 3Dmax, Rhino, Maya or others, save in dae and import with the other 3.
Some times use Cinema or lightwave, because i got good level (in job), but is not free and expensive.

This was my first terrain build with plain mesh, i hope this can help you in your game.
Use a png image in gray color, wher white is the most top and black is bottom.

change line 304, this e= creaTerreno(0,0,0, 180,180, 1,1, 3000, "test.png",suelo_mate)
test.png with your image.

Ahhh, sorry comments and names are in spanish :mrgreen:

Code: Select all

Global.s  home= GetPathPart(ProgramFilename())

UsePNGImageDecoder()
UseJPEGImageDecoder()

#CameraSpeed= 1
Global.f KeyX,KeyY
Global.b sal
Global.i camara, suelo, cubo_enti

Global.f normal.Vector3

  Procedure   CalculateTriangleNormal(x1.f, y1.f, z1.f, x2.f, y2.f, z2.f, x3.f, y3.f, z3.f)
    ; Calcula los vectores AB y AC
    Protected.f ABx, ABy, ABz, ACx, ACy, ACz
    ABx = x2 - x1
    ABy = y2 - y1
    ABz = z2 - z1
    ACx = x3 - x1
    ACy = y3 - y1
    ACz = z3 - z1
    ; Calcula el producto cruz de AB y AC
    normal\x = ABy * ACz - ABz * ACy
    normal\y = ABz * ACx - ABx * ACz
    normal\z = ABx * ACy - ABy * ACx
    ; Normaliza el vector resultante
    Protected.f length
    length = Sqr(normal\x * normal\x + normal\y * normal\y + normal\z * normal\z)
    If length <> 0
      normal\x = normal\x / length
      normal\y = normal\y / length
      normal\z = normal\z / length
    EndIf
  EndProcedure
  Procedure   CalculateNormalVector4(x1.f, y1.f, z1.f, x2.f, y2.f, z2.f, x3.f, y3.f, z3.f, x4.f, y4.f, z4.f)
    ; Calcula las normales de los dos triángulos formados por los vértices
    Protected.f n1.Vector3, n2.Vector3
    CalculateTriangleNormal(x1, y1, z1, x2, y2, z2, x3, y3, z3)
    n1\x= normal\x
    n1\y= normal\y
    n1\z= normal\z
    
    CalculateTriangleNormal(x1, y1, z1, x3, y3, z3, x4, y4, z4)
    n2\x= normal\x
    n2\y= normal\y
    n2\z= normal\z
    ; Promedia las normales de los triángulos para obtener la normal del plano
    Protected.f NormalX, NormalY, NormalZ
    normal\x = (n1\x + n2\x) / 2
    normal\y = (n1\y + n2\y) / 2
    normal\z = (n1\z + n2\z) / 2
  EndProcedure

  Procedure   spr2DText(spr, txt.s, font, ink.l=$ff00ff00)
    Protected n,y=2,tl= CountString(txt,#CR$)
    Protected tx.s
    StartDrawing(SpriteOutput(spr))
    DrawingMode(#PB_2DDrawing_AlphaChannel)
      Box(0,0,OutputWidth(),OutputHeight(),$00000000)
    DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Transparent)
      Box(0,0,OutputWidth(),OutputHeight(),$aa000000)
      DrawingFont(FontID(font))
      For n=1 To tl+1
        tx= StringField(txt,n,#CR$)
        DrawText(5,y,tx,ink)
        y+16
      Next n
      DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Outlined)
      Box(0,0,OutputWidth(),OutputHeight(),ink)
    StopDrawing()
  EndProcedure
  Procedure   iniDX(title.s="dx", width=800,height=600, AA=#PB_AntialiasingMode_None, fps.b=50, shadowmode= #PB_Shadow_Modulative, shadowres=4096, param=#PB_Window_ScreenCentered|#PB_Window_SystemMenu, sincro= #PB_Screen_NoSynchronization)
    InitEngine3D()
      InitSprite()
      InitKeyboard()
      InitMouse()
      AntialiasingMode(AA)
      OpenWindow(0, 0, 0, width, height, title, param)
        SetWindowColor(0,$444444)
      OpenWindowedScreen(WindowID(0), 0, 0, (width * DesktopResolutionX()), (height * DesktopResolutionY()),0,0,0, sincro  )
      Protected.b s= 100
      WorldShadows(#PB_Shadow_Modulative, -1, RGB(s,s,s))
      If fps>-1
        SetFrameRate(fps)
      EndIf
  EndProcedure
  
  Procedure   eventosWindows()
    Repeat
      event= WindowEvent()
      Select event
        Case #PB_Event_Gadget
          EventGadget=  EventGadget()
          EventType=    EventType()
          
        Case #PB_Event_CloseWindow
          sal= 1
      EndSelect
    Until event= 0
  EndProcedure
  Procedure   eventos3D(camara.i=0, speed=1, mousespeed.d=0.05)
    Protected.f KeyX,KeyY
    Protected.b factor= 1
    If ExamineKeyboard()
      ;{
      If KeyboardReleased(#PB_Key_F1)
        CameraRenderMode(camara, #PB_Camera_Wireframe)
      EndIf
      If KeyboardReleased(#PB_Key_F2)
        CameraRenderMode(camara, #PB_Camera_Textured)
      EndIf
      If KeyboardReleased(#PB_Key_F3)
        WorldDebug(#PB_World_DebugNone)
      EndIf
      If KeyboardReleased(#PB_Key_F4)
        WorldDebug(#PB_World_DebugEntity)
      EndIf
      
      If KeyboardReleased(#PB_Key_Pad9)
        Debug "OK"
      EndIf
      
      If KeyboardPushed(#PB_Key_Escape)
        sal=1
      EndIf
      
      If KeyboardPushed(#PB_Key_Left)
        KeyX = -#CameraSpeed / speed
      ElseIf KeyboardPushed(#PB_Key_Right)
        KeyX = #CameraSpeed / speed
      Else
        KeyX = 0
      EndIf
      
      If KeyboardPushed(#PB_Key_Up)
        KeyY = -#CameraSpeed / speed
      ElseIf KeyboardPushed(#PB_Key_Down)
        KeyY = #CameraSpeed / speed
      Else
        KeyY = 0
      EndIf
      ;}
      
      If KeyboardPushed(#PB_Key_A)
        KeyX = -#CameraSpeed / speed
      ElseIf KeyboardPushed(#PB_Key_D)
        KeyX = #CameraSpeed / speed
      Else
        KeyX = 0
      EndIf
      
      If KeyboardPushed(#PB_Key_W)
        KeyY = -#CameraSpeed / speed
      ElseIf KeyboardPushed(#PB_Key_S)
        KeyY = #CameraSpeed / speed
      Else
        KeyY = 0
      EndIf
    EndIf
    
    If ExamineMouse()
      MouseX = -MouseDeltaX() * #CameraSpeed * mousespeed; * 0.05
      MouseY = -MouseDeltaY() * #CameraSpeed * mousespeed; * 0.05
      mouseW = MouseWheel()
      KeyY + (MouseW * #CameraSpeed)
    EndIf
    
    RotateCamera(camara, MouseY, MouseX, 0, #PB_Relative)
    MoveCamera  (camara, KeyX*factor, 0, KeyY*factor)
  EndProcedure
  
  Procedure   creaTerreno(posx.f=0,posy.f=0,posz.f=0, sizex=10,sizez=10, tilesx=1,tilesz=1, altura=50, mapfile.s="sueloC2.png", material=0, color.l=$333333)
    Structure vector5
      x.f
      y.f
      z.f
      u.f
      v.f
      n.i
    EndStructure
    Protected   Dim v.Vector5(sizex,sizez)
    Protected.f Dim n.Vector3(sizex,sizez)
    Protected   xx,zz, n, e
    Protected.f x,z
    Protected.b u,v
    Protected   i
    If LCase(GetExtensionPart(mapfile))="png"
      i= LoadImage(#PB_Any,mapfile)
    Else
      i= Val(mapfile)
    EndIf
    
    ResizeImage(i,sizex+1,sizez+1)
    
    Protected.i mesh= CreateMesh(#PB_Any)
    x= posx -((sizex * tilesx)/2): y=2: z=posz -((sizez * tilesz)/2)
    n=0
    ;altura
    StartDrawing(ImageOutput(i))
    For zz= 0 To sizez
      For xx= 0 To sizex
        px= Point(xx,zz)
        v(xx,zz)\y= ( (((Red(px)+Green(px)+Blue(px)) * (1/255)) * altura)/255 )*-1
      Next xx
    Next zz
    StopDrawing()
    ;normales
    For zz= 0 To sizez-1 Step 2
      For xx= 0 To sizex-1 Step 2
        CalculateNormalVector4( xx,v(xx,zz)\y,zz,
                                xx+1,v(xx+1,zz)\y,zz,
                                xx+1,v(xx+1,zz+1)\y,zz+1,
                                xx,v(xx,zz+1)\y,zz+1)
        n(xx,zz)\x= normal\x
        n(xx,zz)\y= normal\y
        n(xx,zz)\z= normal\z
        
        n(xx+1,zz)\x= normal\x
        n(xx+1,zz)\y= normal\y
        n(xx+1,zz)\z= normal\z
        
        n(xx+1,zz+1)\x= normal\x
        n(xx+1,zz+1)\y= normal\y
        n(xx+1,zz+1)\z= normal\z
        
        n(xx,zz+1)\x= normal\x
        n(xx,zz+1)\y= normal\y
        n(xx,zz+1)\z= normal\z
      Next xx
    Next zz
    
    ;vertices
    For zz= 0 To sizez
      For xx= 0 To sizex
        v(xx,zz)\x= x+ (xx * tilesx)
        v(xx,zz)\z= z+ (zz * tilesz)
        u=0 : If xx % 2: u=1 :EndIf
        v=0 : If zz % 2: v=1 :EndIf
        v(xx,zz)\u= u
        v(xx,zz)\v= v
        v(xx,zz)\n= n
        MeshVertex(v(xx,zz)\x, v(xx,zz)\y, v(xx,zz)\z, v(xx,zz)\u,v(xx,zz)\v, color, n(xx,zz)\x,n(xx,zz)\y,n(xx,zz)\z)
        n+1
      Next xx
    Next zz
    ;caras
    For zz= 0 To sizez-1
      For xx= 0 To sizex-1
        MeshFace( v(xx,zz)\n, v(xx+1,zz)\n, v(xx+1,zz+1)\n, v(xx,zz+1)\n )
      Next xx
    Next zz
    
    FinishMesh(mesh)
    BuildMeshTangents(mesh)
;     FreeStructure(*vector5)
    FreeArray(v())
    FreeArray(n())
    FreeImage(i)
    e= CreateEntity(#PB_Any,MeshID(mesh),MaterialID(material))
    EntityRenderMode(e,#PB_Shadow_None)
    RotateEntity(e,180,0,0,#PB_Absolute)
    ProcedureReturn e
  EndProcedure
  Procedure   eliminaTerreno(enti)
    If IsEntity(enti)
      Protected.i mesh= GetEntityMesh(enti)
      FreeEntity(enti)
      If IsMesh(mesh):FreeMesh(mesh):EndIf
    EndIf
  EndProcedure

  iniDX("Terreno",800,600,#PB_AntialiasingMode_None,500)
  
  ;{ CÁMARA Y LUZ
  AmbientColor($555555)
  luz=          CreateLight(#PB_Any,$aaaaaa,0,100,0,#PB_Light_Directional)
                LightDirection(luz,0.6,-0.4,0.8)
                LightAttenuation(luz,160,0.5)
                SetLightColor(luz,#PB_Light_DiffuseColor,$888888)
                SetLightColor(luz,#PB_Light_SpecularColor,$ffffff)
 
  camara=       CreateCamera(#PB_Any,0,0,100,100)
                MoveCamera(camara,0,50,15)
                CameraRange(camara,0.1,1000)
                CameraLookAt(camara,0,0,0)
  ;}
                
  ;{ HUD
  fnt1= LoadFont(#PB_Any,"Arial",9,#PB_Font_HighQuality)
  spr1= CreateSprite(#PB_Any,100,100,#PB_Sprite_AlphaBlending)    
  ;}  
  
  ;{ MATERIAL
  suelo_tx3D=   CreateTexture(#PB_Any,256,256)
  StartDrawing(TextureOutput(suelo_tx3D))
    Box(0,0,OutputWidth(),OutputHeight(),$0)
    Box(16,16,OutputWidth()-32,OutputHeight()-32,$ffffff)
  StopDrawing()
  
  suelo_mate=   CreateMaterial(#PB_Any,TextureID(suelo_tx3D))
  ;}
  
  e= creaTerreno(0,0,0, 180,180, 1,1, 3000, "test.png",suelo_mate)
  EntityRenderMode(e, #PB_Shadow_None)
                
  Repeat
    eventosWindows()
    eventos3D(camara, 4, 0.05)
    
    
    ElapsedTime = RenderWorld()
    
    If KeyboardReleased(#PB_Key_E)
      eliminaTerreno(e)
      e= creaTerreno(0,0,0, 180,180, 4,4, 3000, "test2.png",suelo_mate)
;       Debug "E"
    EndIf
    ;{ HUD
    a= cubo_enti
    txt.s=  "FPS: "+Str( Engine3DStatus(#PB_Engine3D_CurrentFPS) )+#CR$
    spr2DText(spr1,txt, fnt1, $ff00ffff )
    DisplayTransparentSprite(spr1, 10, 10)
    ;}
    
    FlipBuffers()
    
  Until sal=1
  
I ran the above code with my image and I got the folowing message:

The debugged executable quit unexpectedly
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 303
Joined: Sun Aug 29, 2021 4:34 am

Re: Create a terrain

Post by Distorted Pixel »

miso wrote: Tue Apr 08, 2025 12:11 pm This procedure is not from me, and I'm ashamed, but could not find the original post/author. (definietly from the pb forums, but not sure from which one)
This generates a mesh from a heightmap image.

Code: Select all

Procedure TG_GenerateTerrain(TilesX, TilesZ, TerrainHeight, TerrainSizeX, TerrainSizeZ, TextureRepeatU, TextureRepeatV, HeightMapHandle)
  ;(max 16 bit, 65,536 vertices)
  If TilesX <= 0 : ProcedureReturn #False : EndIf
  If TilesZ <= 0 : ProcedureReturn #False : EndIf
  If TerrainSizeX <= 0 : ProcedureReturn #False : EndIf
  If TerrainSizeZ <= 0 : ProcedureReturn #False : EndIf
  If TextureRepeatU <= 0 : ProcedureReturn #False : EndIf
  If TextureRepeatV <= 0 : ProcedureReturn #False : EndIf
  If IsImage(HeightMapHandle) = 0 : ProcedureReturn #False : EndIf
  Protected.i TotalVertices
  TotalVertices = (TilesX + 1) * (TilesZ + 1)
  If TotalVertices > 65536 : ProcedureReturn #False : EndIf
  ;# Generating Vertex Data
  Dim Vertices.d(TotalVertices, 2)
  Protected.d TileSizeX, TileSizeZ
  TileSizeX = TerrainSizeX / TilesX
  TileSizeZ = TerrainSizeZ / TilesZ
  
  Protected.d TileLocX, TileLocY, TileLocZ
  TileLocX = (TerrainSizeX * 0.5) * -1
  TileLocZ = (TerrainSizeZ * 0.5) * -1
  
  StartDrawing(ImageOutput(HeightMapHandle))
    Protected.i ImgWidth, ImgHeight
    ImgWidth  = ImageWidth (HeightMapHandle) - 1
    ImgHeight = ImageHeight(HeightMapHandle) - 1
    
    Protected.d ImgXRatio, ImgZRatio
    ImgXRatio = ImgWidth  / TerrainSizeX
    ImgZRatio = ImgHeight / TerrainSizeZ
    
    Protected.d HeightRatio
    HeightRatio = TerrainHeight / 255
    
    Protected.i PixelX, PixelY, VCTR, CTRX, CTRZ, Color, ColorValue
    
    For CTRZ = 0 To TilesZ
      For CTRX = 0 To TilesX
        PixelX = ((TerrainSizeX * 0.5) + TileLocX) * ImgXRatio
        PixelY = ((TerrainSizeZ * 0.5) + TileLocZ) * ImgZRatio
        Color = Point(PixelX, PixelY)
        ColorValue = Red(Color)
        TileLocY = ColorValue * HeightRatio
        Vertices(VCTR, 0) = TileLocX
        Vertices(VCTR, 1) = TileLocY
        Vertices(VCTR, 2) = TileLocZ
        TileLocX = TileLocX + TileSizeX
        VCTR + 1
      Next
      TileLocX = (TerrainSizeX * 0.5) * -1
      TileLocZ = TileLocZ + TileSizeZ
    Next
  StopDrawing()
  
  ;# Generating Face Data
  Protected.i TotalFaces
  TotalFaces = (TilesX * TilesZ) * 2
  Dim Faces(TotalFaces, 2)
  Protected.i FCTR, FaceCTR
  
  For CTRZ = 0 To TilesZ - 1
    For CTRX = 0 To TilesX - 1
      Faces(FCTR, 0) = FaceCTR
      Faces(FCTR, 1) = FaceCTR + 1 + TilesX
      Faces(FCTR, 2) = FaceCTR + 1
      Faces(FCTR + 1, 0) = FaceCTR + 1
      Faces(FCTR + 1, 1) = FaceCTR + 1 + TilesX
      Faces(FCTR + 1, 2) = FaceCTR + 2 + TilesX
      FCTR + 2
      FaceCTR + 1
    Next
    FaceCTR + 1
  Next
  
  ;# Now we can create our terrain
  Protected.i UCounter
  Protected.d U, V, Uoffset, Voffset

  Uoffset = TextureRepeatU * (1 / TilesX)
  Voffset = TextureRepeatV * (1 / TilesZ)
  Protected handle.i
  Handle = CreateMesh(#PB_Any, #PB_Mesh_TriangleList, #PB_Mesh_Static)
  Protected ctr.i
    For CTR = 0 To TotalVertices -1
      MeshVertexPosition(Vertices(CTR, 0), Vertices(CTR, 1), Vertices(CTR, 2))
      MeshVertexNormal(0, 0, 0)
      MeshVertexTextureCoordinate(U, V)
      U = U + Uoffset
      UCounter + 1
      If UCounter > TilesX
        UCounter = 0
        U = 0
        V = V + Voffset
      EndIf
    Next

    For CTR = 0 To TotalFaces
      MeshFace(Faces(CTR, 0), Faces(CTR, 1), Faces(CTR, 2))
    Next
  FinishMesh(#True)
  NormalizeMesh(Handle)
  FreeArray(Vertices())
  FreeArray(Faces())
  ProcedureReturn Handle
EndProcedure
In the above code I can't figure out where to put my height map information such as the image name. I thought it was the first line, but after a second look at the code, am I suppose to implement it into my code?

Also, not pertaining to the above code and that this isn't the place to get Deled help, but I exported a test object to .mesh and .material formats for an object and texture, but all it exported with the Orge exporter plugin was some .png file that looks black and the .material file.
Last edited by Distorted Pixel on Wed Apr 09, 2025 11:03 pm, edited 4 times in total.
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
miso
Enthusiast
Enthusiast
Posts: 466
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Create a terrain

Post by miso »

This needs an image already loaded in pb. But this is just the procedure that creates a terrain, example usage will be down there.
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 303
Joined: Sun Aug 29, 2021 4:34 am

Re: Create a terrain

Post by Distorted Pixel »

miso wrote: Wed Apr 09, 2025 10:57 pm This needs an image already loaded in pb. But this is just the procedure that creates a terrain, example usage will be down there.
LOL, I'm assuming that both snippets are suppose to be added to my code because now that I looked again at both snippets there is no OpenWindow or OpenWindow3D statements. I will get something working eventually, but I know that learning takes time. I will fool around with both examples for a while with my code and post back at some point about results
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
miso
Enthusiast
Enthusiast
Posts: 466
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Create a terrain

Post by miso »

Uhm, the code Minimy posted is standalone. It does not work because of the shadow commands in it, I assume. I have a procedure, it does not run as standalone of course. I extracted it, so it can be placed into your program at once. After that, there is 2 examples of mine, that is also standalone. Should run. If not, your pb version might be different. (my example uses 2 textures and a skybox from the pb folder) If does not work, try to run it with the latest beta, or 6.20 full.
(I used to locate the textures in those versions in windows)
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 303
Joined: Sun Aug 29, 2021 4:34 am

Re: Create a terrain

Post by Distorted Pixel »

miso wrote: Wed Apr 09, 2025 11:22 pm Uhm, the code Minimy posted is standalone. It does not work because of the shadow commands in it, I assume. I have a procedure, it does not run as standalone of course. I extracted it, so it can be placed into your program at once. After that, there is 2 examples of mine, that is also standalone. Should run. If not, your pb version might be different. (my example uses 2 textures and a skybox from the pb folder) If does not work, try to run it with the latest beta, or 6.20 full.
(I used to locate the textures in those versions in windows)
I have yet to download the latest 6.21 beta 4 and install it. I am currently still running 6.21 beta 3. I will play around with all the examples here for a while. I will post back after I try for a while tonight or tomorrow some time. Thank you
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
miso
Enthusiast
Enthusiast
Posts: 466
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Create a terrain

Post by miso »

Do they run? The examples.
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 303
Joined: Sun Aug 29, 2021 4:34 am

Re: Create a terrain

Post by Distorted Pixel »

miso wrote: Wed Apr 09, 2025 11:37 pm Do they run? The examples.
I have not tested them since my last post. Currently spending time with the family. I will test them in a couple of hours
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 303
Joined: Sun Aug 29, 2021 4:34 am

Re: Create a terrain

Post by Distorted Pixel »

minimy wrote: Mon Apr 07, 2025 12:20 am

Code: Select all

Global.s  home= GetPathPart(ProgramFilename())

UsePNGImageDecoder()
UseJPEGImageDecoder()

#CameraSpeed= 1
Global.f KeyX,KeyY
Global.b sal
Global.i camara, suelo, cubo_enti

Global.f normal.Vector3

  Procedure   CalculateTriangleNormal(x1.f, y1.f, z1.f, x2.f, y2.f, z2.f, x3.f, y3.f, z3.f)
    ; Calcula los vectores AB y AC
    Protected.f ABx, ABy, ABz, ACx, ACy, ACz
    ABx = x2 - x1
    ABy = y2 - y1
    ABz = z2 - z1
    ACx = x3 - x1
    ACy = y3 - y1
    ACz = z3 - z1
    ; Calcula el producto cruz de AB y AC
    normal\x = ABy * ACz - ABz * ACy
    normal\y = ABz * ACx - ABx * ACz
    normal\z = ABx * ACy - ABy * ACx
    ; Normaliza el vector resultante
    Protected.f length
    length = Sqr(normal\x * normal\x + normal\y * normal\y + normal\z * normal\z)
    If length <> 0
      normal\x = normal\x / length
      normal\y = normal\y / length
      normal\z = normal\z / length
    EndIf
  EndProcedure
  Procedure   CalculateNormalVector4(x1.f, y1.f, z1.f, x2.f, y2.f, z2.f, x3.f, y3.f, z3.f, x4.f, y4.f, z4.f)
    ; Calcula las normales de los dos triángulos formados por los vértices
    Protected.f n1.Vector3, n2.Vector3
    CalculateTriangleNormal(x1, y1, z1, x2, y2, z2, x3, y3, z3)
    n1\x= normal\x
    n1\y= normal\y
    n1\z= normal\z
    
    CalculateTriangleNormal(x1, y1, z1, x3, y3, z3, x4, y4, z4)
    n2\x= normal\x
    n2\y= normal\y
    n2\z= normal\z
    ; Promedia las normales de los triángulos para obtener la normal del plano
    Protected.f NormalX, NormalY, NormalZ
    normal\x = (n1\x + n2\x) / 2
    normal\y = (n1\y + n2\y) / 2
    normal\z = (n1\z + n2\z) / 2
  EndProcedure

  Procedure   spr2DText(spr, txt.s, font, ink.l=$ff00ff00)
    Protected n,y=2,tl= CountString(txt,#CR$)
    Protected tx.s
    StartDrawing(SpriteOutput(spr))
    DrawingMode(#PB_2DDrawing_AlphaChannel)
      Box(0,0,OutputWidth(),OutputHeight(),$00000000)
    DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Transparent)
      Box(0,0,OutputWidth(),OutputHeight(),$aa000000)
      DrawingFont(FontID(font))
      For n=1 To tl+1
        tx= StringField(txt,n,#CR$)
        DrawText(5,y,tx,ink)
        y+16
      Next n
      DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Outlined)
      Box(0,0,OutputWidth(),OutputHeight(),ink)
    StopDrawing()
  EndProcedure
  Procedure   iniDX(title.s="dx", width=800,height=600, AA=#PB_AntialiasingMode_None, fps.b=50, shadowmode= #PB_Shadow_Modulative, shadowres=4096, param=#PB_Window_ScreenCentered|#PB_Window_SystemMenu, sincro= #PB_Screen_NoSynchronization)
    InitEngine3D()
      InitSprite()
      InitKeyboard()
      InitMouse()
      AntialiasingMode(AA)
      OpenWindow(0, 0, 0, width, height, title, param)
        SetWindowColor(0,$444444)
      OpenWindowedScreen(WindowID(0), 0, 0, (width * DesktopResolutionX()), (height * DesktopResolutionY()),0,0,0, sincro  )
      Protected.b s= 100
      WorldShadows(#PB_Shadow_Modulative, -1, RGB(s,s,s))
      If fps>-1
        SetFrameRate(fps)
      EndIf
  EndProcedure
  
  Procedure   eventosWindows()
    Repeat
      event= WindowEvent()
      Select event
        Case #PB_Event_Gadget
          EventGadget=  EventGadget()
          EventType=    EventType()
          
        Case #PB_Event_CloseWindow
          sal= 1
      EndSelect
    Until event= 0
  EndProcedure
  Procedure   eventos3D(camara.i=0, speed=1, mousespeed.d=0.05)
    Protected.f KeyX,KeyY
    Protected.b factor= 1
    If ExamineKeyboard()
      ;{
      If KeyboardReleased(#PB_Key_F1)
        CameraRenderMode(camara, #PB_Camera_Wireframe)
      EndIf
      If KeyboardReleased(#PB_Key_F2)
        CameraRenderMode(camara, #PB_Camera_Textured)
      EndIf
      If KeyboardReleased(#PB_Key_F3)
        WorldDebug(#PB_World_DebugNone)
      EndIf
      If KeyboardReleased(#PB_Key_F4)
        WorldDebug(#PB_World_DebugEntity)
      EndIf
      
      If KeyboardReleased(#PB_Key_Pad9)
        Debug "OK"
      EndIf
      
      If KeyboardPushed(#PB_Key_Escape)
        sal=1
      EndIf
      
      If KeyboardPushed(#PB_Key_Left)
        KeyX = -#CameraSpeed / speed
      ElseIf KeyboardPushed(#PB_Key_Right)
        KeyX = #CameraSpeed / speed
      Else
        KeyX = 0
      EndIf
      
      If KeyboardPushed(#PB_Key_Up)
        KeyY = -#CameraSpeed / speed
      ElseIf KeyboardPushed(#PB_Key_Down)
        KeyY = #CameraSpeed / speed
      Else
        KeyY = 0
      EndIf
      ;}
      
      If KeyboardPushed(#PB_Key_A)
        KeyX = -#CameraSpeed / speed
      ElseIf KeyboardPushed(#PB_Key_D)
        KeyX = #CameraSpeed / speed
      Else
        KeyX = 0
      EndIf
      
      If KeyboardPushed(#PB_Key_W)
        KeyY = -#CameraSpeed / speed
      ElseIf KeyboardPushed(#PB_Key_S)
        KeyY = #CameraSpeed / speed
      Else
        KeyY = 0
      EndIf
    EndIf
    
    If ExamineMouse()
      MouseX = -MouseDeltaX() * #CameraSpeed * mousespeed; * 0.05
      MouseY = -MouseDeltaY() * #CameraSpeed * mousespeed; * 0.05
      mouseW = MouseWheel()
      KeyY + (MouseW * #CameraSpeed)
    EndIf
    
    RotateCamera(camara, MouseY, MouseX, 0, #PB_Relative)
    MoveCamera  (camara, KeyX*factor, 0, KeyY*factor)
  EndProcedure
  
  Procedure   creaTerreno(posx.f=0,posy.f=0,posz.f=0, sizex=10,sizez=10, tilesx=1,tilesz=1, altura=50, mapfile.s="sueloC2.png", material=0, color.l=$333333)
    Structure vector5
      x.f
      y.f
      z.f
      u.f
      v.f
      n.i
    EndStructure
    Protected   Dim v.Vector5(sizex,sizez)
    Protected.f Dim n.Vector3(sizex,sizez)
    Protected   xx,zz, n, e
    Protected.f x,z
    Protected.b u,v
    Protected   i
    If LCase(GetExtensionPart(mapfile))="png"
      i= LoadImage(#PB_Any,mapfile)
    Else
      i= Val(mapfile)
    EndIf
    
    ResizeImage(i,sizex+1,sizez+1)
    
    Protected.i mesh= CreateMesh(#PB_Any)
    x= posx -((sizex * tilesx)/2): y=2: z=posz -((sizez * tilesz)/2)
    n=0
    ;altura
    StartDrawing(ImageOutput(i))
    For zz= 0 To sizez
      For xx= 0 To sizex
        px= Point(xx,zz)
        v(xx,zz)\y= ( (((Red(px)+Green(px)+Blue(px)) * (1/255)) * altura)/255 )*-1
      Next xx
    Next zz
    StopDrawing()
    ;normales
    For zz= 0 To sizez-1 Step 2
      For xx= 0 To sizex-1 Step 2
        CalculateNormalVector4( xx,v(xx,zz)\y,zz,
                                xx+1,v(xx+1,zz)\y,zz,
                                xx+1,v(xx+1,zz+1)\y,zz+1,
                                xx,v(xx,zz+1)\y,zz+1)
        n(xx,zz)\x= normal\x
        n(xx,zz)\y= normal\y
        n(xx,zz)\z= normal\z
        
        n(xx+1,zz)\x= normal\x
        n(xx+1,zz)\y= normal\y
        n(xx+1,zz)\z= normal\z
        
        n(xx+1,zz+1)\x= normal\x
        n(xx+1,zz+1)\y= normal\y
        n(xx+1,zz+1)\z= normal\z
        
        n(xx,zz+1)\x= normal\x
        n(xx,zz+1)\y= normal\y
        n(xx,zz+1)\z= normal\z
      Next xx
    Next zz
    
    ;vertices
    For zz= 0 To sizez
      For xx= 0 To sizex
        v(xx,zz)\x= x+ (xx * tilesx)
        v(xx,zz)\z= z+ (zz * tilesz)
        u=0 : If xx % 2: u=1 :EndIf
        v=0 : If zz % 2: v=1 :EndIf
        v(xx,zz)\u= u
        v(xx,zz)\v= v
        v(xx,zz)\n= n
        MeshVertex(v(xx,zz)\x, v(xx,zz)\y, v(xx,zz)\z, v(xx,zz)\u,v(xx,zz)\v, color, n(xx,zz)\x,n(xx,zz)\y,n(xx,zz)\z)
        n+1
      Next xx
    Next zz
    ;caras
    For zz= 0 To sizez-1
      For xx= 0 To sizex-1
        MeshFace( v(xx,zz)\n, v(xx+1,zz)\n, v(xx+1,zz+1)\n, v(xx,zz+1)\n )
      Next xx
    Next zz
    
    FinishMesh(mesh)
    BuildMeshTangents(mesh)
;     FreeStructure(*vector5)
    FreeArray(v())
    FreeArray(n())
    FreeImage(i)
    e= CreateEntity(#PB_Any,MeshID(mesh),MaterialID(material))
    EntityRenderMode(e,#PB_Shadow_None)
    RotateEntity(e,180,0,0,#PB_Absolute)
    ProcedureReturn e
  EndProcedure
  Procedure   eliminaTerreno(enti)
    If IsEntity(enti)
      Protected.i mesh= GetEntityMesh(enti)
      FreeEntity(enti)
      If IsMesh(mesh):FreeMesh(mesh):EndIf
    EndIf
  EndProcedure

  iniDX("Terreno",800,600,#PB_AntialiasingMode_None,500)
  
  ;{ CÁMARA Y LUZ
  AmbientColor($555555)
  luz=          CreateLight(#PB_Any,$aaaaaa,0,100,0,#PB_Light_Directional)
                LightDirection(luz,0.6,-0.4,0.8)
                LightAttenuation(luz,160,0.5)
                SetLightColor(luz,#PB_Light_DiffuseColor,$888888)
                SetLightColor(luz,#PB_Light_SpecularColor,$ffffff)
 
  camara=       CreateCamera(#PB_Any,0,0,100,100)
                MoveCamera(camara,0,50,15)
                CameraRange(camara,0.1,1000)
                CameraLookAt(camara,0,0,0)
  ;}
                
  ;{ HUD
  fnt1= LoadFont(#PB_Any,"Arial",9,#PB_Font_HighQuality)
  spr1= CreateSprite(#PB_Any,100,100,#PB_Sprite_AlphaBlending)    
  ;}  
  
  ;{ MATERIAL
  suelo_tx3D=   CreateTexture(#PB_Any,256,256)
  StartDrawing(TextureOutput(suelo_tx3D))
    Box(0,0,OutputWidth(),OutputHeight(),$0)
    Box(16,16,OutputWidth()-32,OutputHeight()-32,$ffffff)
  StopDrawing()
  
  suelo_mate=   CreateMaterial(#PB_Any,TextureID(suelo_tx3D))
  ;}
  
  e= creaTerreno(0,0,0, 180,180, 1,1, 3000, "test.png",suelo_mate)
  EntityRenderMode(e, #PB_Shadow_None)
                
  Repeat
    eventosWindows()
    eventos3D(camara, 4, 0.05)
    
    
    ElapsedTime = RenderWorld()
    
    If KeyboardReleased(#PB_Key_E)
      eliminaTerreno(e)
      e= creaTerreno(0,0,0, 180,180, 4,4, 3000, "test2.png",suelo_mate)
;       Debug "E"
    EndIf
    ;{ HUD
    a= cubo_enti
    txt.s=  "FPS: "+Str( Engine3DStatus(#PB_Engine3D_CurrentFPS) )+#CR$
    spr2DText(spr1,txt, fnt1, $ff00ffff )
    DisplayTransparentSprite(spr1, 10, 10)
    ;}
    
    FlipBuffers()
    
  Until sal=1
  
minimy's code above will take me some time to figure out how to implement it into my code. So I will take time to work on it.


miso's code has a bit of 1st person character movement below works as is and I will fool around with it also to learn.
miso wrote: Tue Apr 08, 2025 12:35 pm

Code: Select all

EnableExplicit
;-CONSTANTS
#MAINDESKTOP_H        = 0
#MAINWINDOW_H         = 0
#MAINWINDOW_NAME      = "Test Application"
#MAINWINDOW_FLAGS     = #PB_Window_BorderLess
#MAINWINDOW_RESIZE    = 1
#MAINWINDOW_TOPOFFSET = 0
#SCREEN_FLAGS         = #PB_Screen_WaitSynchronization
#SCREEN_FRAMERATE     = 60
#AUTOSTRETCH_ON       = 1
#AUTOSTRETCH_OFF      = 0
#MAINLOOP_DELAY       = 1

#WATERLEVEL = 300




Declare TG_GenerateTerrain(TilesX, TilesZ, TerrainHeight, TerrainSizeX, TerrainSizeZ, TextureRepeatU, TextureRepeatV, HeightMapHandle)
;-AUXILIARY PROCEDURES
 Procedure.f LERP(a.f,b.f,t.f)
   ProcedureReturn(((1.0-t.f)*a) + (b*t))
   ;ProcedureReturn(a + t*(b-a))
 EndProcedure
   
 ;invertált lineáris interpoláció
 Procedure.f INVLERP(a.f,b.f,v.f)
   If a=b : ProcedureReturn(1) : EndIf
   ProcedureReturn((v-a) / (b-a))
 EndProcedure
   
 Procedure.f remap(iMin.f,iMAX.f, oMin.f, oMax.f, v.f)  
   Define t.f
   t.f = INVLERP(iMin,iMAX,v)
   ProcedureReturn(LERP(oMin,oMax,t))
 EndProcedure

Procedure sub_checks()
EndProcedure

;-PROCEDURES
Procedure app_start()
  sub_checks()
  UsePNGImageDecoder()
  UseJPEGImageDecoder()
  ExamineDesktops()
  InitEngine3D()
  InitSprite()
  InitKeyboard()
  InitMouse()
  OpenWindow(#MAINWINDOW_H,DesktopUnscaledX(DesktopWidth(#MAINDESKTOP_H))*(1-#MAINWINDOW_RESIZE)/2,#MAINWINDOW_TOPOFFSET,DesktopUnscaledX(DesktopWidth(#MAINDESKTOP_H)*#MAINWINDOW_RESIZE),DesktopUnscaledY(DesktopHeight(#MAINDESKTOP_H)*#MAINWINDOW_RESIZE),#MAINWINDOW_NAME,#MAINWINDOW_FLAGS)
  OpenWindowedScreen(WindowID(#MAINWINDOW_H),0,0,WindowWidth(#MAINWINDOW_H),WindowHeight(#MAINWINDOW_H),#AUTOSTRETCH_ON,0,0,#SCREEN_FLAGS)
  SetFrameRate(#SCREEN_FRAMERATE)
  Global playercam.i
  playercam = CreateCamera(#PB_Any,0,0,100,100)
  MoveCamera(playercam,0,#WATERLEVEL+20,0)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures/nvidia", #PB_3DArchive_FileSystem)
  Parse3DScripts()
  Protected.i texture_terdiffuse , image_heightmap, texture_terdetail, material_mainterrain, mesh_mainterrain, entity_mainterrain
  Protected.i watertexture, watermesh, watermaterial, waterentity
    texture_terdiffuse = LoadTexture(#PB_Any,"grass_green-01_diffusespecular.jpg")
    image_heightmap = LoadImage(#PB_Any,#PB_Compiler_Home + "examples/3d/Data/Textures/nvidia/terrain513.png")
    
    CatchImage(1,?detailpng)
    texture_terdetail = CreateTexture(#PB_Any,64,64)
    StartDrawing(TextureOutput(texture_terdetail))
    DrawImage(ImageID(1),0,0,OutputWidth(),OutputHeight())
    StopDrawing()
    FreeImage(1)
    
    material_mainterrain = CreateMaterial(#PB_Any,TextureID(texture_terdiffuse))
    AddMaterialLayer(material_mainterrain,TextureID(texture_terdetail),#PB_Material_AddSigned,0)
    ScaleMaterial(material_mainterrain,0.0005,0.0005,1)
    AmbientColor(RGB(100,100,100))
    mesh_mainterrain = TG_GenerateTerrain(255,255,600,10000,10000,1,1,image_heightmap)
    entity_mainterrain = CreateEntity(#PB_Any,MeshID(mesh_mainterrain),MaterialID(material_mainterrain),0,0,0,1<<1)
    
    CatchImage(1,?waterpng)
    watertexture = CreateTexture(#PB_Any,64,64)
    StartDrawing(TextureOutput(watertexture))
    DrawImage(ImageID(1),0,0,OutputWidth(),OutputHeight())
    StopDrawing()
    FreeImage(1)
    
    watermesh=CreatePlane(#PB_Any,10000,10000,1,1,1,1)
    watermaterial = CreateMaterial(#PB_Any,TextureID(watertexture))
    AddMaterialLayer(watermaterial,TextureID(watertexture),#PB_Material_Add,0)
    AddMaterialLayer(watermaterial,TextureID(watertexture),#PB_Material_AddSigned,0)
    ScaleMaterial(watermaterial,0.05,0.05,0)
    ScaleMaterial(watermaterial,0.04,0.04,1)
    ScaleMaterial(watermaterial,0.03,0.03,2)
    ScrollMaterial(watermaterial,0.025,0.1,#PB_Material_Animated,0)
    ScrollMaterial(watermaterial,-0.025,-0.1,#PB_Material_Animated,1)
    ScrollMaterial(watermaterial,0.03,-0.2,#PB_Material_Animated,2)
    MaterialCullingMode(watermaterial,#PB_Material_NoCulling)
    waterentity = CreateEntity(#PB_Any,MeshID(watermesh),MaterialID(watermaterial))
    MoveEntity(waterentity,0,300,0)
EndProcedure

Procedure app_update()
  Protected w_event.i, a.i,b.i
  Repeat 
    w_event = WindowEvent() : If w_event = #PB_Event_CloseWindow : End : EndIf
  Until Not w_event
  ExamineKeyboard()
  ExamineMouse()
  RotateCamera(playercam,MouseDeltaY()*-0.1,MouseDeltaX()*-0.1,0,#PB_Relative)
  If MouseButton(#PB_MouseButton_Right)
    MoveCamera(playercam,0,0,-1,#PB_Relative)
  EndIf
  
  If CameraY(playercam)<#WATERLEVEL
    AmbientColor(RGB(0,0,128))
    a = remap(0,#WATERLEVEL,10,128,CameraY(playercam))
    b = remap(0,#WATERLEVEL,100,150,CameraY(playercam))
    Fog(RGB(0,0,a),5,0,b)
  Else
    Fog(RGB(128,128,128),0.1,0,100000)
    AmbientColor(RGB(100,100,100))
  EndIf
  
  RenderWorld()
  FlipBuffers()
  Delay(#MAINLOOP_DELAY)
EndProcedure

;-MAIN PROGRAM PROCEDURE
Procedure main()
  app_start()
  Repeat
    app_update()
  Until KeyboardPushed(#PB_Key_Escape)
EndProcedure

Procedure TG_GenerateTerrain(TilesX, TilesZ, TerrainHeight, TerrainSizeX, TerrainSizeZ, TextureRepeatU, TextureRepeatV, HeightMapHandle)
  ;(max 16 bit, 65,536 vertices)
  If TilesX <= 0 : ProcedureReturn #False : EndIf
  If TilesZ <= 0 : ProcedureReturn #False : EndIf
  If TerrainSizeX <= 0 : ProcedureReturn #False : EndIf
  If TerrainSizeZ <= 0 : ProcedureReturn #False : EndIf
  If TextureRepeatU <= 0 : ProcedureReturn #False : EndIf
  If TextureRepeatV <= 0 : ProcedureReturn #False : EndIf
  If IsImage(HeightMapHandle) = 0 : ProcedureReturn #False : EndIf
  Protected.i TotalVertices
  TotalVertices = (TilesX + 1) * (TilesZ + 1)
  If TotalVertices > 65536 : ProcedureReturn #False : EndIf
  ;# Generating Vertex Data
  Dim Vertices.d(TotalVertices, 2)
  Protected.d TileSizeX, TileSizeZ
  TileSizeX = TerrainSizeX / TilesX
  TileSizeZ = TerrainSizeZ / TilesZ
  
  Protected.d TileLocX, TileLocY, TileLocZ
  TileLocX = (TerrainSizeX * 0.5) * -1
  TileLocZ = (TerrainSizeZ * 0.5) * -1
  
  StartDrawing(ImageOutput(HeightMapHandle))
    Protected.i ImgWidth, ImgHeight
    ImgWidth  = ImageWidth (HeightMapHandle) - 1
    ImgHeight = ImageHeight(HeightMapHandle) - 1
    
    Protected.d ImgXRatio, ImgZRatio
    ImgXRatio = ImgWidth  / TerrainSizeX
    ImgZRatio = ImgHeight / TerrainSizeZ
    
    Protected.d HeightRatio
    HeightRatio = TerrainHeight / 255
    
    Protected.i PixelX, PixelY, VCTR, CTRX, CTRZ, Color, ColorValue
    
    For CTRZ = 0 To TilesZ
      For CTRX = 0 To TilesX
        PixelX = ((TerrainSizeX * 0.5) + TileLocX) * ImgXRatio
        PixelY = ((TerrainSizeZ * 0.5) + TileLocZ) * ImgZRatio
        Color = Point(PixelX, PixelY)
        ColorValue = Red(Color)
        TileLocY = ColorValue * HeightRatio
        Vertices(VCTR, 0) = TileLocX
        Vertices(VCTR, 1) = TileLocY
        Vertices(VCTR, 2) = TileLocZ
        TileLocX = TileLocX + TileSizeX
        VCTR + 1
      Next
      TileLocX = (TerrainSizeX * 0.5) * -1
      TileLocZ = TileLocZ + TileSizeZ
    Next
  StopDrawing()
  
  ;# Generating Face Data
  Protected.i TotalFaces
  TotalFaces = (TilesX * TilesZ) * 2
  Dim Faces(TotalFaces, 2)
  Protected.i FCTR, FaceCTR
  
  For CTRZ = 0 To TilesZ - 1
    For CTRX = 0 To TilesX - 1
      Faces(FCTR, 0) = FaceCTR
      Faces(FCTR, 1) = FaceCTR + 1 + TilesX
      Faces(FCTR, 2) = FaceCTR + 1
      Faces(FCTR + 1, 0) = FaceCTR + 1
      Faces(FCTR + 1, 1) = FaceCTR + 1 + TilesX
      Faces(FCTR + 1, 2) = FaceCTR + 2 + TilesX
      FCTR + 2
      FaceCTR + 1
    Next
    FaceCTR + 1
  Next
  
  ;# Now we can create our terrain
  Protected.i UCounter
  Protected.d U, V, Uoffset, Voffset

  Uoffset = TextureRepeatU * (1 / TilesX)
  Voffset = TextureRepeatV * (1 / TilesZ)
  Protected handle.i
  Handle = CreateMesh(#PB_Any, #PB_Mesh_TriangleList, #PB_Mesh_Static)
  Protected ctr.i
    For CTR = 0 To TotalVertices -1
      MeshVertexPosition(Vertices(CTR, 0), Vertices(CTR, 1), Vertices(CTR, 2))
      MeshVertexNormal(0, 0, 0)
      MeshVertexTextureCoordinate(U, V)
      U = U + Uoffset
      UCounter + 1
      If UCounter > TilesX
        UCounter = 0
        U = 0
        V = V + Voffset
      EndIf
    Next

    For CTR = 0 To TotalFaces
      MeshFace(Faces(CTR, 0), Faces(CTR, 1), Faces(CTR, 2))
    Next
  FinishMesh(#True)
  NormalizeMesh(Handle)
  FreeArray(Vertices())
  FreeArray(Faces())
  ProcedureReturn Handle
EndProcedure

;-MAIN PROGRAM
main()


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

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

No one cares how much you know until they know how much you care
Post Reply