[bb] CLE - Cower Landscape Editor by N [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:42

Previous topic - Next topic

BlitzBot

Title : CLE - Cower Landscape Editor
Author : N
Posted : 1+ years ago

Description : This was my counter-action to FLE becoming closed-source and for-profit.  It was a relatively complete editor that used the what I believe was called F-UI.  Unfortunately, I no longer have F-UI or Blitz3D.. or much else in that area, so you may be out of luck if you're hoping to use the old UI.  However, I did include a means of replacing the UI rather easily, so it shouldn't be too much trouble to adapt to your own needs.

This uses the old 'tried and true' vertex alpha stuff that .. you get the idea.  

To get right to where the GUI is implemented and read the basic documentation, search for #gui-key in the code.  I tried to support both 2D and 3D GUIs, as it was obviously not possible for me to expect others to have the same assets as I did.


Code :
Code (blitzbasic) Select
;#Region INPUT GLOBALS
;; Set these globals inside your CLEUpdateGUI* function- either 2D or 3D, but they have to be set in order for CLE to work properly

Global PaintMode%  = 0 ;; The paint mode (0 for texture painting, 1 for raising terrain, 2 for lowering terrain, 3 for smoothing terrain)
Global BrushSize% = 0 ;; The size of the brush
Global BrushSpeed# = .1 ;; The speed of the brush
Global BrushLayer% = 0 ;; The current layer to be painted on
Global MXS#,MYS#,MZS#,MX#,MY#,MZ# ;; Mouse X/Y/Z speed and mouse X/Y/Z position
Global MD1%,MD2%,MD3% ;; Mouse button down
Global Camera% ;; Camera used for moving around the terrain
Global WindowWidth% ;; Window width
Global WindowHeight% ;; Window height
Global EndEditor% = 0 ;; Close the editor
;#End Region

Include "CLE_GUI.bb"

;#Region TERRAIN SYSTEM
Type CLETexture
Field Path$
Field Flags%
Field Blend%
Field SX#
Field SY#
Field Texture%
Field Index
End Type

Global Terra = CreateStack() ;; Terrain meshes- uses AnimaStack
Global TexStack = CreateStack() ;; Textures
Global LayerTex = CreateStack() ;; Layer textures
Global TerrainRoot = 0 ;; The first layer of the terrain mesh
Dim OptimArray(0) ;; Used in optimization of the terrain mesh on load

;#Region CREATE TERRAIN [ SEGMENTS ]
Function t_CreateTerrain(Segments=32,Layers=1)
ClearTerrain() ;; Precaution against creating more than one terrain that isn't optimized

For i = 0 To Layers-1
om = mesh
mesh = CreateSegQuad(Segments,0,0)
PushObject Terra,mesh
If i > 0
EntityFX mesh,2+32
EntityParent mesh,om,0
Else
EntityFX mesh,2
EndIf
TranslateEntity mesh,0,.00036*i,0
PushObject LayerTex,CreateStack()
Next

EntityPickMode GetObject(Terra,0),2

RaiseLayer 0,0,512,2

TerrainRoot = GetObject(Terra,0)
Return TerrainRoot
End Function
;#End Region

;#Region HEIGHTMAP
;#Region APPLY HEIGHT MAP [ MAP [ SCALE ] ]
Function ApplyHeightmap(Map$,Scale#=1.0)
If Objects(Terra) = 0 Then Return 0
Segments = Sqr(CountVertices(GetSurface(GetObject(Terra,i),1)))

tm = LoadImage(Map$)

If tm = 0 Then DebugLog( "ERROR:: Heightmap '"+Map$+"' does not exist" ) Return 0

w = ImageWidth(tm)
h = ImageHeight(tm)

buffer = ImageBuffer(tm)

LockBuffer(buffer)

For ix# = 0 To Segments-1
For iz# = 0 To Segments - 1
x = (ix / segments) * w
z = (iz / segments) * h
v = ix + iz * segments

r# = (Float(((ReadPixelFast(x,z,buffer) Shr 16) And 255) - 128) / 255) * Scale

For i = 0 To Objects(Terra)-1
s = GetSurface(GetObject(Terra,i),1)
VertexCoords(s,v,VertexX(s,v),r,VertexZ(s,v))
Next
Next
Next

For i = 0 To Objects(Terra)-1
UpdateNormals GetObject(Terra,i)
Next

UnlockBuffer(buffer)
FreeImage tm
Return 1
End Function
;#End Region

;#Region EXPORT HEIGHTMAP [ PATH ]
Function ExportHeightmap(Path$)
If Objects(Terra) = 0 Then Return 0

Mesh = GetObject(Terra,0)
s = GetSurface(Mesh,1)

segments = Sqr(CountVertices(s))

image = CreateImage(segments,segments)

b = ImageBuffer(image)
LockBuffer(b)

Local minx#=10000,miny#=-10000,minz#

For i = 0 To CountVertices(s)-1
v# = VertexY(s,i)
If v < minx Then minx = v
If v > miny Then miny = v
Next

minz = miny-minx

For i = 0 To CountVertices(s)-1
x = i Mod segments
y = (i - x)/segments
l# = ((VertexY(s,i)-minx)/minz)*255
WritePixelFast x,y,255 Shl 24 Or l Shl 16 Or l Shl 8 Or l,b
Next
UnlockBuffer(b)
SaveImage(image,Path$)
FreeImage image
Return 1
End Function
;#End Region
;#End Region

;#Region CLEAR TERRAIN
Function ClearTerrain()
While Objects(Terra) > 0
FreeEntity PopObject(Terra)
Wend
While Objects(LayerTex) > 0
FreeStack PopObject(LayerTex)
Wend
End Function
;#End Region

;#Region CLM FORMAT

;#Region CONSTANTS
;; The CLM (Cower Landscape Mesh) plays off the file structure of Gile[s]'s, the (damn cool) lightmapper, scene files

Const CLM_HEADER = $1000 ;;  Header- one string and a float
Const CLM_AUTHOR = $1001 ;;  Author of the file being saved

Const CLM_TEXTURES = $3001 ;;  Opening of the texture list
Const CLM_TEXTURE = $3002 ;;  Opening of a texture
Const CLM_TEXTUREPATH = $3003 ;;  Sets the path from which the texture will be loaded from
Const CLM_TEXTUREFLAGS = $3004 ;;  Sets the flags the texture is loaded with
Const CLM_LOADTEXTURE = $3005 ;;  Tells the importer to load the texture at this point because it has sufficient data to do so
Const CLM_TEXTUREBLEND = $3006 ;;  Sets the blend mode of the texture
Const CLM_TEXTURESCALE = $3007 ;;  Sets the scale of the texture

Const CLM_LAYERS = $2000 ;;  Opening of the layers, one byte and one int
Const CLM_LAYER = $2001 ;;  Opening of a CLE layer, one byte
Const CLM_LAYERFORMAT = $2002 ;;  1- Alpha
Const CLM_LAYERDATA = $2003 ;;  N Bytes; refer to CLM_MESHFORMAT
Const CLM_HEIGHTDATA = $2004 ;;  The heightmap information- two floats to set delta and minimum y and all bytes to determine height afterwards
Const CLM_LAYERTEXTURES = $2005 ;;  The textures applied to the layer
Const CLM_HEIGHTFORMAT = $2006 ;;  The format in which the heightmap data is stored
;#End Region

;#Region EXPORT CLM
Function ExportCLM(Name$)
If Objects(Terra) = 0 Then Return
F = WriteFile(Name$+".clm")
If F = 0 Then DebugLog "Failed to open "+Name$+".clm for writing, check file properties"+Chr(10)+FileType(Name$+".clm")+ " " + FileSize(Name$+".clm") Return 0

Local Paths$[7]

WriteInt F,CLM_HEADER
WriteInt F,12
WriteString F,"CLMesh_"
WriteFloat F,0.6

WriteInt F,CLM_TEXTURES
WriteInt F,0

For i = 0 To Objects(TexStack)-1
t.CLETexture = Object.CLETexture(GetObject(TexStack,i))
WriteInt F,CLM_TEXTURE
WriteInt F,0

WriteInt F,CLM_TEXTUREPATH
WriteInt F,Len(tPath)+1
WriteString F,tPath

WriteInt F,CLM_FLAGS
WriteInt F,2
WriteShort F,tFlags

WriteInt F,CLM_TEXTUREBLEND
WriteInt F,1
WriteByte F,tBlend

WriteInt F,CLM_TEXTURESCALE
WriteInt F,8
WriteFloat F,tSX
WriteFloat F,tSY

WriteInt F,CLM_LOADTEXTURE
WriteInt F,0
Next

WriteInt F,CLM_LAYERS
WriteInt F,5
WriteByte F,Objects(Terra)
WriteInt F,Sqr(CountVertices(GetSurface(GetObject(Terra,0),1)))

For i = 0 To Objects(Terra)-1
s = GetSurface(GetObject(Terra,i),1)
Bytes = CountVertices(s)

WriteInt F,CLM_LAYER
WriteInt F,1
WriteByte F,i

WriteInt F,CLM_LAYERFORMAT
WriteInt F,1
WriteByte F,1

WriteInt F,CLM_LAYERDATA
WriteInt F,Bytes

For n = 0 To Bytes-1
WriteByte F,VertexAlpha(s,n)*255
Next

WriteInt F,CLM_LAYERTEXTURES
WriteInt F,2+Objects(GetObject(LayerTex,i))*2
st = GetObject(LayerTex,i)
WriteShort F,Objects(st)
For n = 0 To Objects(st)-1
WriteShort F,GetObject(st,n)
Next
Next

minx# = -1000
miny# = 1000

WriteInt F,CLM_HEIGHTFORMAT
WriteInt F,1
WriteByte F,2

WriteInt F,CLM_HEIGHTDATA
s = GetSurface(GetObject(Terra,0),1)
WriteInt F,CountVertices(s)*4
; For n = 0 To CountVertices(s)-1
; y# = VertexY(s,n)
; If y < miny Then miny = y
; If y > minx Then minx = y
; Next
;
; d# = minx - miny
;
; WriteFloat F,d
; WriteFloat F,miny

For n = 0 To CountVertices(s)-1
WriteFloat F,VertexY(s,n)
Next

Return 1
End Function
;#End Region

;#Region IMPORT CLM
;; Setting the optimize flag to 1/True will make the loaded mesh unuseable in the editor, but it can drastically reduce the polygon count of terrain
Function ImportCLM(Name$,Optimize=0)
Local F = ReadFile(Name$+".clm")
If F = 0 Then DebugLog "Failed to open "+Name$+".clm for reading, check file properties"+Chr(10)+FileType(Name$+".clm")+ " " + FileSize(Name$+".clm") Return 0

tex = -1


ClearTerrain()
While Not Eof(F)
Class = ReadInt(F)
Size = ReadInt(F)
Position = FilePos(F)
Select Class
Case CLM_HEADER
Header$ = ReadString(F)
Version# = ReadFloat(F)

Case CLM_AUTHOR
Author = ReadString(F)

Case CLM_TEXTURES

Case CLM_TEXTURE
tex = -1
sx# = 1
sy# = 1
blend = 5

Case CLM_TEXTUREPATH
path$ = ReadString(F)

Case CLM_TEXTUREFLAGS
flags = ReadShort(F)

Case CLM_TEXTUREBLEND
blend = ReadByte(F)
If tex >= 0 Then
t_TextureBlend tex,blend
EndIf

Case CLM_TEXTURESCALE
sx# = ReadFloat(F)
sy# = ReadFloat(F)
If tex >= 0 Then
t_ScaleTexture tex,sx,sy
EndIf

Case CLM_LOADTEXTURE
tex = t_LoadTexture(path$,flags,sx,sy,blend)

Case CLM_LAYERS
Layers = ReadByte(F)
Segments = ReadInt(F)
Terrain = t_CreateTerrain(Segments,Layers)

Case CLM_LAYER
Layer = ReadByte(F)

Case CLM_LAYERFORMAT
Format = ReadByte(F)
If (Format And 1) = 1 Then Alpha = 1

Case CLM_LAYERDATA
Vertices = Segments*Segments-1
s = GetSurface(GetObject(Terra,Layer),1)
For i = 0 To Vertices
a# = Float(ReadByte(F))/255
VertexColor s,i,VertexRed(s,i),VertexGreen(s,i),VertexBlue(s,i),a
Next
UpdateNormals(GetObject(Terra,Layer))

Case CLM_LAYERTEXTURES
textures = ReadShort(F)
For i = 1 To textures
index = ReadShort(F)
t_ApplyTexture Layer,index
Next

Case CLM_HEIGHTFORMAT
hmf = ReadByte(F)

Case CLM_HEIGHTDATA
If (hmf And 2) = 2 Then
For i = 0 To CountVertices(GetSurface(GetObject(Terra,0),1))-1
h# = ReadFloat(F)
For n = 0 To Objects(Terra)-1
s = GetSurface(GetObject(Terra,n),1)
VertexCoords s,i,VertexX(s,i),h,VertexZ(s,i)
Next
Next
Else
delta# = ReadFloat(F)
my# = ReadFloat(F)
For i = 0 To Segments*Segments-1
h# = Float(ReadByte(F))/255
For n = 0 To Objects(Terra)-1
s = GetSurface(GetObject(Terra,n),1)
VertexCoords s,i,VertexX(s,i),my+h*delta,VertexZ(s,i)
Next
Next
EndIf

For n = 0 To Objects(Terra)-1
UpdateNormals(GetObject(Terra,n))
Next

Default
SeekFile(F,Position+Size)
End Select
Wend

If Optimize Then
told = Terrain
Dim OptimArray(CountTriangles(GetSurface(GetObject(Terra,0),1))-1)

root = 0

For i = 0 To Objects(Terra)-1
s = GetSurface(GetObject(Terra,i),1)
m2 = M
M = CreateMesh()
If m2 <> 0 Then EntityParent m2,M
ss = CreateSurface(M)
TranslateEntity M,0,.0015*i,0

If i = 0 Then
root = M
Else
EntityFX M,2+32
EndIf

For v = 0 To CountVertices(s)-1
AddVertex ss,VertexX(s,v),VertexY(s,v),VertexZ(s,v),VertexU(s,v),VertexV(s,v)
VertexNormal ss,v,VertexNX(s,v),VertexNY(s,v),VertexNZ(s,v)
VertexColor ss,v,VertexRed(s,v),VertexGreen(s,v),VertexBlue(s,v),VertexAlpha(s,v)
Next

For t = 0 To CountTriangles(s)-1
If OptimArray(t) = 0 And M <> root Then
a# = 0
For n = 0 To 2
a# = a# + VertexAlpha(s,TriangleVertex(s,t,n))
Next
If a = 3 Then OptimArray(t) = 1
If a > 0 Then AddTriangle ss,TriangleVertex(s,t,0),TriangleVertex(s,t,1),TriangleVertex(s,t,2)
ElseIf root = M Then
AddTriangle ss,TriangleVertex(s,t,0),TriangleVertex(s,t,1),TriangleVertex(s,t,2)
EndIf
Next
Next

Dim OptimArray(0)

ClearTerrain()
Terrain = root
EndIf

Return Terrain
End Function
;#End Region
;#End Region

;#Region LAYER CONTROL
;#Region RAISE LAYER [ INDEX [ LAYER [ SIZE ] ] ]
Function RaiseLayer(Index,Layer,Size%=1,Speed#=.01,Mode=0)
If Objects(Terra) = 0 Then Return
If Index < 0 Then Return 0
Segments = Sqr(CountVertices(GetSurface(GetObject(Terra,0),1)))

x = Index Mod Segments
Y = (Index-ix)/Segments

ssize# = Sqr(Size*Size+Size*Size)

fD# = Sqr(Size*Size+Size*Size)

For ix = -Floor(fD) To Floor(fD)
For iy = -Floor(fD) To Floor(fD)
vx = x + ix
vy = y + iy

vertex = vx + vy * segments
vl = vertex - 1
vr = vertex + 1
va = vertex - segments
vb = vertex + segments

If vx > -1 And vx < segments And vy > -1 And vy < segments Then

If Size > 0 Then
d# = Min(1.0-(Sqr(ix*ix+iy*iy)/fD),0)
Else
d# = 1
EndIf

For i = 1-Max(Min(Mode,0),1) To Objects(Terra)-1
s = GetSurface(GetObject(Terra,i),1)
If Mode = 0 Then
a# = VertexAlpha(s,vertex)

If i <> Layer Then
a# = Min(a# -Speed*d,0)
Else
a# = Max(a# +Speed*d,1)
EndIf

VertexColor s,vertex,VertexRed(s,vertex),VertexGreen(s,vertex),VertexBlue(s,vertex),a#
ElseIf Mode = 1
VertexCoords s,vertex,VertexX(s,vertex),VertexY(s,vertex)+(Speed*d)*.5,VertexZ(s,Vertex)
ElseIf Mode = 2
VertexCoords s,vertex,VertexX(s,vertex),VertexY(s,vertex)-(Speed*d)*.5,VertexZ(s,Vertex)
ElseIf Mode = 3
div = 1
zy# = VertexY(s,vertex)

For ly = -4 To 4
For lx = -4 To 4
vl = vertex +ly*segments +lx
If SameRow(vl,vertex+ly*segments,segments) And vl > -1 And vl < CountVertices(s)
div = div + 1
zy = zy + VertexY(s,vl)
EndIf
Next
Next

If div > 0 Then
zy# = zy# / div
dy# = zy# - VertexY(s,vertex)
ny# = VertexY(s,vertex) + (dy * Speed);*d ;; I decided not to make this one affected by radial falloff.  you can uncomment the *d if you want it to.
VertexCoords s,vertex,VertexX(s,vertex),ny#,VertexZ(s,Vertex)
EndIf
EndIf
Next
EndIf
Next
Next

If Mode > 0 Then
For i = 0 To Objects(Terra)-1
UpdateNormals(GetObject(Terra,i))
Next
EndIf
End Function
;#End Region

;#Region APPLY TEXTURE [ LAYER [ TEXTURE ] ] ]
Function t_ApplyTexture(Layer, Texture)
If Objects(Terra) = 0 Then Return
If Layer < 0 Or Layer >= Objects(Terra) Then Return 0
Index = Objects(GetObject(LayerTex,Layer))
i.CLETexture = Object.CLETexture(GetObject(TexStack,Texture))
If i = Null Then Return 0
EntityTexture GetObject(Terra,Layer),iTexture,0,Index
PushObject GetObject(LayerTex,Layer),iIndex
End Function
;#End Region

;#Region GENERATE
Function GenerateTerrain(Rock=1, Sand=2,Normal#=.35)
If Objects(Terra) = 0 Then Return
rs = GetSurface(GetObject(Terra,Rock),1)
For i = 0 To CountVertices(rs)-1
y# = Abs(VertexNY(rs,i))
If y =<  Normal Then
a# = y / (Normal/2)
VertexColor rs,i,VertexRed(rs,i),VertexGreen(rs,i),VertexBlue(rs,i),a
Else
VertexColor rs,i,VertexRed(rs,i),VertexGreen(rs,i),VertexBlue(rs,i),0
EndIf
Next

If Sand < 0 Then Return

ss = GetSurface(GetObject(Terra,Sand),1)
segments = Sqr(CountVertices(ss))
For i = 0 To CountVertices(ss)-1
l = 0
a = i
d = i
k=0
For n = 1 To 6
a = i- Segments*n
d = i+ Segments*n

If a > -1 Then
If VertexAlpha(rs,a) = 0 Then l = l + 1
Else
k = k + 1
EndIf

If d < CountVertices(ss)
If VertexAlpha(rs,d) = 0 Then l = l + 1
Else
k = k + 1
EndIf
Next

If VertexAlpha(rs,i) = 0 Then l = l + 1

a = i
d = i

If l = 13-k Then

; VertexColor ss,i,VertexRed(ss,i),VertexGreen(ss,i),VertexBlue(ss,i),VertexAlpha(ss,i)+.5

For n = 1 To 6

a = i- Segments*n
d = i+ Segments*n

If a > -1 Then
VertexColor ss,a,VertexRed(ss,a),VertexGreen(ss,a),VertexBlue(ss,a),VertexAlpha(ss,a)+(Float(6-n)/6)*.05
EndIf

If d < CountVertices(ss)
VertexColor ss,d,VertexRed(ss,d),VertexGreen(ss,d),VertexBlue(ss,d),VertexAlpha(ss,d)+(Float(6-n)/6)*.05
EndIf

Next
EndIf
Next
End Function
;#End Region

;#Region ADD LAYER
;; Adds another layer on top of all the others
Function AddLayer()
If Objects(Terra) = 0 Then Return
b = CreateBrush()
root = GetObject(Terra,0)
m = CopyMesh(root)

TranslateEntity m,0,.00036,0

PaintEntity m,b
FreeBrush b
EntityFX m,2+32
s = GetSurface(m,1)
For i = 0 To CountVertices(s)-1
VertexColor s,i,255,255,255,0
Next
EntityParent m,GetObject(Terra,Objects(Terra)-1),0
PushObject Terra,m
PushObject LayerTex,CreateStack()
End Function
;#End Region

;#Region REMOVE LAYER
;; Removes the top-most layer from the terrain, you have to be careful with this 'cause you may accidentally lose work if calling it at the wrong time
Function RemoveLayer()
If Objects(Terra) = 0 Then Return
Layer = Objects(Terra)-1
If Layer = 0 Then Return 0
FreeEntity PopObject(Terra)
For i = Layer To Objects(Terra)-1
TranslateEntity GetObject(Terra,i),0,-.0015,0
Next
FreeStack PopObject(LayerTex)
Return 1
End Function
;#End Region

;#Region RESET LAYER
Function ResetLayer(Layer)
If Layer < 0 Or Layer > Objects(Terra)-1 Then Return 0
b = CreateBrush()
If Layer > 0 Then
BrushFX b,2+32
Else
BrushFX b,2
EndIf
PaintEntity GetObject(Terra,Layer),b
FreeBrush b
End Function
;#End Region

;#Region TEXTURE
Function t_LoadTexture(Path$,Flags%,SX#=1,SY#=1,Blend=5)
For i.CLETexture = Each CLETexture
If Lower(iPath$) = Lower(Path$) Then Return iIndex
Next
i.CLETexture = New CLETexture
iTexture = LoadTexture(Path$,Flags%)
tex = iTexture
iPath = Path
iFlags = Flags
ScaleTexture tex,SX,SY
iSX = SX
iSY = SY
iBlend = Blend
TextureBlend tex,Blend
iIndex = Objects(TexStack)
PushObject TexStack,Handle(i)
Return iIndex
End Function

Function t_TextureBlend(ind,blend)
i.CLETexture = Object.CLETexture(GetObject(TexStack,ind))
iBlend = blend
TextureBlend iTexture,blend
End Function

Function t_ScaleTexture(ind,sx#,sy#)
i.CLETexture = Object.CLETexture(GetObject(TexStack,ind))
isx = sx : isy = sy
ScaleTexture i exture,sx,sy
End Function
;#End Region
;#End Region
;#End Region

CLEInit()

;#Region SKY
; Sky = MakeSkyBox("sky")
;#End Region

;#Region LIGHTING
AmbientLight 128,128,128
l = CreateLight(1)
PositionEntity(l,25,75,25)
LightRange(l,150)
LightColor l,150,150,150
;#End Region

Repeat
CLEUpdateGUI3D()

;#Region CAMERA
rts# = rts * .85
pts# = pts * .85
sts# = sts * .75
fts# = fts * .75
If MouseDown(2) And (Not CLEMouseInGUI()) Then
MoveMouse WindowWidth/2,WindowHeight/2
pts = pts + MYS*.25
rts = rts - MXS*.25
TurnEntity Camera,pts,rts,0
RotateEntity Camera,EntityPitch(Camera),EntityYaw(Camera),0
sts = sts + (KeyDown(32)-KeyDown(30))*.03
fts = fts + (KeyDown(17)-KeyDown(31))*.03
MoveEntity Camera,sts,0,fts
EndIf
;#End Region

;#Region SKY
; PositionEntity Sky,EntityX(Camera,1),EntityY(Camera,1),EntityZ(Camera,1)
;#End Region

;#Region TERRAIN
If Objects(Terra) > 0 Then
If Not CLEMouseInGUI()
pick = CameraPick( Camera,MX,MY )
If pick = GetObject(Terra,0) And MouseDown(1) Then RaiseLayer(PickedVertex(),BrushLayer,BrushSize,BrushSpeed,PaintMode)
EndIf
EndIf
;#End Region

;#Region SYSTEM
UpdateWorld
RenderWorld

CLEUpdateGUI2D()

Flip False
;#End Region
Until EndEditor = 1
ClearWorld()
EndGraphics()
End()

;#Region CREATE SEG QUAD [ SEGMENTS [ SEGMENTED [ CENTERED ] ] ]
Function CreateSegQuad(Segments=16,Segmented=0,Centered=0)
sx = 0
sz = 0
st = Segments-1

m = CreateMesh()
s = CreateSurface(m)

If Segmented = 0 Then
For x# = sx To st
For z# = sz To st
vertex = CountVertices(s)
AddVertex s, x, 0, z, x / Segments, z / Segments
; VertexNormal s,vertex,0,1,0
Next
Next

For ix = 0 To st-1
For iz = 0 To st-1
v1 = (iz) * Segments + (ix)
v2 = (iz) * Segments + (ix+1)
v3 = (iz+1) * Segments + (ix+1)
v4 = (iz+1) * Segments + (ix)
AddTriangle s,v1,v2,v3
AddTriangle s,v3,v4,v1
Next
Next
Else
For x# = sx To st
For z# = sz To st
vertex = CountVertices(s)
AddVertex s,x,0,z,0,0
AddVertex s,x+1,0,z,1,0
AddVertex s,x+1,0,z+1,1,1
AddVertex s,x,0,z+1,0,1
AddTriangle s,vertex,vertex+1,vertex+2
AddTriangle s,vertex+2,vertex+3,vertex

For i = 0 To 3
; VertexNormal s,vertex+i,0,1,0
Next
Next
Next
EndIf

ScaleMesh m,1.0/Segments,1,1.0/Segments

Return m
End Function
;#End Region

;#Region MATH
Function Min#(x#,y#)   ; Returns x if x > y, else y
If x < y Then Return y
Return x
End Function

Function Max#(x#,y#)   ; Returns x if x < y, else y
If x > y Then Return y
Return x
End Function

Function SameRow(x,z,width)
y = x
x = x Mod width
y = y - x
z = (z - (z Mod width))/width
If y/width <> z Then Return 0
Return 1
End Function
;#End Region

;#Region MESH
Function PickedVertex()
s = PickedSurface()
If s = 0 Then Return -1

x# = PickedX()
y# = PickedY()
z# = PickedZ()

piv = CreatePivot()
PositionEntity piv,x,y,z

d# = -1

piv2 = CreatePivot()

t = PickedTriangle()

Local d2#[2]
Local v2%[2]

For i = 0 To 2
v = TriangleVertex(s,t,i)
TFormPoint VertexX(s,v),VertexY(s,v),VertexZ(s,v),PickedEntity(),0
PositionEntity piv2,TFormedX(),TFormedY(),TFormedZ()

d2[i] = EntityDistance(piv,piv2)
v2[i] = v
Next

FreeEntity piv2
FreeEntity piv

If d2[0] < d2[1] And d2[0] < d2[2] Then
Return v2[0]
ElseIf d2[1] < d2[0] And d2[1] < d2[2] Then
Return v2[1]
Else
Return v2[0]
EndIf
End Function
;#End Region

;#Region COLOR
Const RALPHA = 24 ;Return Alpha when using RColor
Const RRED = 16 ;Return Red when using RColor
Const RGREEN = 8 ;Return Green when using RColor
Const RBLUE = 0 ;Return Blue when using RColor

Function IntColor(R,G,B,A=255)
Return A Shl 24 Or R Shl 16 Or G Shl 8 Or B Shl 0
End Function

Function RColor%(c%,d%)
Return c Shr d And 255 Shl 0
End Function
;#End Region

;#Region SKY [ PATH ]
;; AGore's nice sky box code
;; Taken from Samples/AGore/BirdDemo
;; I'm not sure what license this is under, so it is not under the license the rest of this source is [NOTE: this is probably pub. domain now]
Function MakeSkyBox( file$ )

m=CreateMesh()
;front face
b=LoadBrush( file$+"_FR.bmp",49 )
s=CreateSurface( m,b )
AddVertex s,-1,+1,-1,0,0:AddVertex s,+1,+1,-1,1,0
AddVertex s,+1.5,-1,-1.5,1,1:AddVertex s,-1.5,-1,-1.5,0,1
AddTriangle s,0,1,2:AddTriangle s,0,2,3
FreeBrush b
;right face
b=LoadBrush( file$+"_LF.bmp",49 )
s=CreateSurface( m,b )
AddVertex s,+1,+1,-1,0,0:AddVertex s,+1,+1,+1,1,0
AddVertex s,+1.5,-1,+1.5,1,1:AddVertex s,+1.5,-1,-1.5,0,1
AddTriangle s,0,1,2:AddTriangle s,0,2,3
FreeBrush b
;back face
b=LoadBrush( file$+"_BK.bmp",49 )
s=CreateSurface( m,b )
AddVertex s,+1,+1,+1,0,0:AddVertex s,-1,+1,+1,1,0
AddVertex s,-1.5,-1,+1.5,1,1:AddVertex s,+1.5,-1,+1.5,0,1
AddTriangle s,0,1,2:AddTriangle s,0,2,3
FreeBrush b
;left face
b=LoadBrush( file$+"_RT.bmp",49 )
s=CreateSurface( m,b )
AddVertex s,-1,+1,+1,0,0:AddVertex s,-1,+1,-1,1,0
AddVertex s,-1.5,-1,-1.5,1,1:AddVertex s,-1.5,-1,+1.5,0,1
AddTriangle s,0,1,2:AddTriangle s,0,2,3
FreeBrush b
;top face
b=LoadBrush( file$+"_UP.bmp",49 )
s=CreateSurface( m,b )
AddVertex s,-1,+1,+1,0,1:AddVertex s,+1,+1,+1,0,0
AddVertex s,+1,+1,-1,1,0:AddVertex s,-1,+1,-1,1,1
AddTriangle s,0,1,2:AddTriangle s,0,2,3
FreeBrush b
;bottom face - this bit was added by me.  'cause i wanted a bottom face.  WHAT!?  YOU DON'T SEE IT BUT I NEED IT THERE ANYWAY!
b=LoadBrush( file$+"_BT.bmp",49 )
s=CreateSurface( m,b )
AddVertex s,-1.5,-1,+1.5,0,1:AddVertex s,+1.5,-1,+1.5,0,0
AddVertex s,+1.5,-1,-1.5,1,0:AddVertex s,-1.5,-1,-1.5,1,1
AddTriangle s,0,1,2:AddTriangle s,0,2,3
FreeBrush b

ScaleEntity m,20,20,20
FlipMesh m
EntityFX m,1+16+8
EntityOrder m,100
Return m

End Function
;#End Region

;#Region TEXTS [ X [ Y [ T$ [ CX [ CY ] ] ] ] ]
Function Texts(X,Y,T$,CX=0,CY=0)
Color 0,0,0
Text X-1,Y-1,T$,CX,CY
Text X+1,Y-1,T$,CX,CY
Text X+1,Y+1,T$,CX,CY
Text X-1,Y+1,T$,CX,CY
Text X,Y-1,T$,CX,CY
Text X,Y+1,T$,CX,CY
Text X-1,Y,T$,CX,CY
Text X+1,Y,T$,CX,CY
Color 255,255,255
Text X,Y,T$,CX,CY
End Function
;#End Region


;#Region PUSH/POP DATA
Global PoppedValue$
Global PoppedClass%

Type Stack
Field F.StackObj
Field L.StackObj
Field Objects
End Type

Type StackObj
Field Parent.Stack
Field N.StackObj
Field P.StackObj
Field Value$
Field Class%
End Type

Function CreateStack()
Local s.Stack
s.Stack = New Stack
Return Handle(s)
End Function

Function PushObject(Stack,Value$,Class%=0,ToFront=0)
Local s.Stack,i.StackObj
s.Stack = Object.Stack(Stack)
sObjects = sObjects + 1
i.StackObj = New StackObj
iValue = Value
iClass = Class
iParent = s
If ToFront = 0 Then
If sF = Null And sL = Null Then
sF = i
sL = sF
Else
iP = sL
sLN = i
sL = i
EndIf
Else
If sF = Null And sL = Null Then
sF = i
sL = sF
Else
iN = sF
sFP = i
sF = i
EndIf
EndIf
End Function

Function PopObject$(Stack,FromFront=0,RemoveData=1)
Local s.Stack,i.StackObj,v$
s.Stack = Object.Stack(Stack)
If RemoveData > 0 Then sObjects = sObjects - 1
If FromFront = 0 Then
i.StackObj = sL
If RemoveData > 0 Then
sL = iP
If SL <> Null Then sLN = Null
EndIf
Else
i.StackObj = sF
If RemoveData > 0 Then
sF = iN
If SF <> Null Then sFP = Null
EndIf
EndIf

If sL = Null Then sL = sF
If sF = Null Then sF = sL

PoppedClass = iClass
PoppedValue = iValue
v$ = iValue
If RemoveData > 0 Then Delete i
Return V
End Function

Function Objects(Stack)
Local s.Stack
s.Stack = Object.Stack(Stack)
Return sObjects
End Function

Function GetObject$(Stack,Index,RemoveData = 0,Reverse=0)
Local s.Stack,i.StackObj,n
s.Stack = Object.Stack(Stack)
i.StackObj = sF

If Reverse Then Index = (sObjects-1)-Index

Repeat
If i = Null Then
Return False
ElseIf n = Index Then
PoppedValue  = iValue
PoppedClass = iClass

If RemoveData Then
If iP <> Null Then iPN = iN
If iN <> Null Then iNP = iP
sObjects = sObjects - 1
Delete i
EndIf

Return PoppedValue
EndIf

i = iN
n = n + 1
Forever
End Function

Function InsertObject(Stack,Index,Value$="",Class%=0)
Local s.Stack,i.StackObj,o.StackObj,ne.StackObj,pr.StackObj,n
s.Stack = Object.Stack(Stack)

i.StackObj = sF
o.StackObj = New StackObj
oValue$ = Value
oClass% = Class
oParent = s

Repeat
If iN = Null Or n = Index Then
ne.StackObj = iN
pr.StackObj = iP

If ne <> Null Then neP =  o
If pr <> Null Then prN = o

If ne = Null Then sL = o
If pr = Null Then sF = o

oN = ne
oP = pr

Return True
EndIf

i = iN
n = n + 1
Forever
End Function

Function FreeStack(Stack)
Local s.Stack,i.StackObj
s.Stack = Object.Stack(Stack)

Delete s
For i.StackObj = Each StackObj
If iParent = Null Then Delete i
Next
End Function
;#End Region


;;;;;;;;;;;;;; THIS IS WHERE THE GUI BEGINS ;;;;;;;;;;;;;;;;;;;
; #gui-key

; If you intend to replace the GUI, be aware of the functions
; marked as required.  You will have to implement those, either
; the 3D set or the 2D set.


;; This is the old GUI, probably doesn't work with any version of F-UI that does
;; not include my vast array of changes (now lost to time)
Include "FUI/F-UI.bb"

Type CLEGUI
Field Window
Field View
Field BrushParmsSize
Field BrushParmsSpeed
Field BrushModeGroup
Field BrushParmsModePaint
Field BrushParmsModeRaise
Field BrushParmsModeLower
Field BrushParmsModeSmooth
Field LayerList
Field ControlTab
Field BrushPage
Field LayerStack

Field mnCLMNew
Field mnCLMSave
Field mnCLMLoad

Field mnCreateWindow
Field mnCreateSegments

Field mnApplyHMap
Field mnExportHMap

Field mnQuit

Field cmLayer
Field cmLayerAdd
Field cmLayerRmv
Field cmLayerReset

Field TexPage
Field TexList
Field BtnApplyTexture
Field ScaleSpinner
Field BlendGroup
Field BlendRadioAlp
Field BlendRadioMul
Field BlendRadioAdd
Field BlendRadioMod

Field cmTexture
Field cmTextureLoad
Field tlStack
Field selTex

Field nterraWin
Field spnSegments
Field lblAmnt
Field btnOK
Field btnCancel

Field hmpCancel
Field hmpOK
Field hmpWin
Field hmpSize
Field pathText
Field opnPath
End Type

Type TextureBlock
Field Node
Field Index
Field Path$
Field Name$
End Type

Global GUI.CLEGUI

;; This function is REQUIRED
;; Use this function to intialize graphics mode, create the camera, set texture filters, etc.
Function CLEInit()
FUI_LoadResolution("CLE.cfg")
WINDOW_RESIZE_METHOD = 0
FUI_Initialise(800,600,32,2,0,1,"CLE",".72b") ;; That bit about '.72b' is just bullshit, ignore it
GUI = New CLEGUI
GUIWindow = FUI_Window(0,0,192+12,GraphicsHeight(),"Control Panel",0,1+2,2)
; GUIWindow = FUI_Window(0,0,GraphicsWidth(),GraphicsHeight(),"Control Panel",0,1+2,2)
; v.View = Object.View(GUIView)
GUI lStack = CreateStack()
FUI_LockWindow(GUIWindow)
GUIControlTab = FUI_Tab(GUIWindow,6,128,192,GraphicsHeight()-128-52)
GUIBrushPage = FUI_TabPage(GUIControlTab,"Brush")
GUITexPage = FUI_TabPage(GUIControlTab,"Textures")
GUILayerList = FUI_ListBox(GUIWindow,6,6,192,128-12,0,1)

FUI_Label(GUIBrushPage,6,6,"Brush Size")
GUIBrushParmsSize = FUI_Slider(GUIBrushPage,6,6+16*1+32*0,192-24,16,0,25,BrushSize,12,DIR_HORIZONTAL)

FUI_Label(GUIBrushPage,6,6+16*1+32*1,"Brush Speed")
GUIBrushParmsSpeed = FUI_Slider(GUIBrushPage,6,6+16*2+32*1,192-24,16,0.01,.5,BrushSpeed,12,DIR_HORIZONTAL)

GUIBrushModeGroup = FUI_GroupBox(GUIBrushPage,6,116,192-36,12+78+8,"Brush Mode")
GUIBrushParmsModePaint = FUI_Radio(GUIBrushModeGroup,6,6,"Paint",1,0)
GUIBrushParmsModeRaise = FUI_Radio(GUIBrushModeGroup,6,6+18,"Raise",0,0)
GUIBrushParmsModeLower = FUI_Radio(GUIBrushModeGroup,6,6+36,"Lower",0,0)
GUIBrushParmsModeSmooth = FUI_Radio(GUIBrushModeGroup,6,6+36+18,"Smooth",0,0)

GUITexList = FUI_ListBox(GUITexPage,6,6,192-12,128-12,0,1)
GUIBtnApplyTexture = FUI_Button(GUITexPage,6,128,192-12,24,"Apply Texture")
FUI_Label(GUITexPage,6,128+24+10,"Scale")
GUIScaleSpinner = FUI_Spinner(GUITexPage, (192-12)/2-48, 128+24+6, 48+(192-12)/2, 24, 0, 20, 1.0, 0.01, DTYPE_FLOAT)
GUIBlendGroup = FUI_GroupBox(GUITexPage,6,128+48+12,192-12,22*4+4,"Blend Mode")
GUIBlendRadioAlp = FUI_Radio(GUIBlendGroup,2,1+19*0,"Alpha",1,1)
GUIBlendRadioMul = FUI_Radio(GUIBlendGroup,2,1+19*1,"Multiply",0,1)
GUIBlendRadioAdd = FUI_Radio(GUIBlendGroup,2,1+19*2,"Add",0,1)
GUIBlendRadioMod = FUI_Radio(GUIBlendGroup,2,1+19*3,"Modulate 2X",0,1)

file=FUI_MenuTitle(GUIWindow,"File")
GUImnCLMNew = FUI_MenuItem(file,"New")
GUImnCLMLoad = FUI_MenuItem(file,"Load")
GUImnCLMSave = FUI_MenuItem(file,"Save")
FUI_MenuBar(file)
GUImnApplyHMap = FUI_MenuItem(file,"Load Heightmap")
GUImnExportHMap = FUI_MenuItem(file,"Save Heightmap")
FUI_MenuBar(file)
GUImnQuit = FUI_MenuItem(file,"Quit")

GUIcmLayer = FUI_ContextMenu()
GUIcmLayerAdd = FUI_ContextMenuItem(GUIcmLayer,"Add Layer")
GUIcmLayerRmv = FUI_ContextMenuItem(GUIcmLayer,"Remove Layer")
FUI_ContextMenuBar(GUIcmLayer)
GUIcmLayerReset = FUI_ContextMenuItem(GUIcmLayer,"Reset Textures")

GUIcmTexture = FUI_ContextMenu()
GUIcmTextureLoad = FUI_ContextMenuItem(GUIcmTexture,"Load Texture")

GUI
terraWin = FUI_Window( appW/2-101, appH/2-50, 202, 100, "New Terrain", "", 1 )
GUIspnSegments = FUI_Spinner( GUI
terraWin, 120, 8, 70, 20, 0.0, 128.0, 64.0, 1.0, DTYPE_INTEGER, "" )
GUIlblAmnt = FUI_Label( GUI
terraWin, 14, 12, "Amount of Segments" )
GUItnOK = FUI_Button( GUI
terraWin, 26, 42, 70, 20, "OK" )
GUItnCancel = FUI_Button( GUI
terraWin, 110, 42, 70, 20, "Cancel" )
FUI_HideGadget(GUI
terraWin)

hmpWin = FUI_Window( appW/2-267/2, appH/2-55, 267, 128, "Load Heightmap", "", 1 )
FUI_Label( hmpWin, 10, 42, "Scale" )
hmpSize = FUI_Spinner( hmpWin, 46, 40, 92, 20, -100.0, 100.0, 1.0, .01, DTYPE_FLOAT, "" )
FUI_Label( hmpWin, 10, 16, "Path" )
pathText = FUI_TextBox( hmpWin, 46, 12, 200, 22, 0 )
opnPath = FUI_Button( hmpWin, 245, 12, 16, 22, "..." )
hmpOK = FUI_Button( hmpWin, 30, 74, 70, 20, "OK" )
hmpCancel = FUI_Button( hmpWin, 112, 74, 70, 20, "Cancel" )
FUI_ModalWindow(hmpWin,0)

GUIhmpWin = hmpWin
GUIpathText = pathText
GUIopnPath = opnPath
GUIhmpSize = hmpSize
GUIhmpOK = hmpOK
GUIhmpCancel = hmpCancel

FUI_HideGadget(GUIhmpWin)

Camera = appCam
CameraRange Camera,.01,5000
CameraFogMode Camera,1
CameraFogColor Camera,220,250,252
CameraFogRange Camera,35,150
CameraClsColor Camera,192,200,240

PositionEntity Camera,0,50,0

GUILayerStack = CreateStack()

TextureFilter "",1+8

FUI_SetGadgetAlpha(GUIWindow,.8,1)
FUI_SetGadgetAlpha(GUI
terraWin,.8,1)
FUI_SetGadgetAlpha(GUIhmpWin,.8,1)

WindowWidth = appW
WindowHeight = appH
GUIselTex = -1
End Function

;; This function is REQUIRED
;; If you are not using a 2D GUI then leave its contents blank, but you MUST have it defined
Function CLEUpdateGUI2D()
End Function

;; This function is REQUIRED
;; If you are not using a 3D GUI then leave its contents blank, but you MUST have it defined
Function CLEUpdateGUI3D()

If Objects(Terra) > 0 Then
FUI_EnableGadget(GUIcmLayerRmv)
FUI_EnableGadget(GUIcmLayerAdd)
FUI_EnableGadget(GUIcmLayerReset)
Else
FUI_DisableGadget(GUIcmLayerRmv)
FUI_DisableGadget(GUIcmLayerAdd)
FUI_DisableGadget(GUIcmLayerReset)
EndIf

If FUI_OverGadget(GUILayerList) And appMB2 Then
FUI_OpenContextMenu(GUIcmLayer)
ElseIf FUI_OverGadget(GUITexList) And appMB2 Then
FUI_OpenContextMenu(GUIcmTexture)
EndIf

; CameraClsMode Camera,1,1

FUI_Update()

; CameraClsMode Camera,0,0

If Terra <> 0 Then
While Objects(GUILayerStack) <> Objects(Terra)
If Objects(Terra) > Objects(GUILayerStack) Then
PushObject GUILayerStack,FUI_ListBoxItem(GUILayerList,"Layer "+(Objects(GUILayerStack)+1))
Else
FUI_DeleteGadget(PopObject(GUILayerStack))
EndIf
Wend
EndIf

MX = appMX
MY = appMY
MZ = appMZ
MXS = appMXS
MYS = appMYS
MZS = appMZS
MD1 = appMB1
MD2 = appMB2
MD3 = appMB3
appcurrentFile = "burnInHellMemoryAccessViolation"

If GUIselTex = -1 Then
FUI_DisableGadget(GUIBtnApplyTexture)
; FUI_DisableGadget(GUIBlendGroup)
FUI_DisableGadget(GUIScaleSpinner)
FUI_DisableGadget(GUIBlendRadioAlp)
FUI_DisableGadget(GUIBlendRadioMul)
FUI_DisableGadget(GUIBlendRadioAdd)
FUI_DisableGadget(GUIBlendRadioMod)
Else
FUI_EnableGadget(GUIBtnApplyTexture)
; FUI_EnableGadget(GUIBlendGroup)
FUI_EnableGadget(GUIScaleSpinner)
FUI_EnableGadget(GUIBlendRadioAlp)
FUI_EnableGadget(GUIBlendRadioMul)
FUI_EnableGadget(GUIBlendRadioAdd)
FUI_EnableGadget(GUIBlendRadioMod)
EndIf

For i = 0 To Objects(TexStack)-1
d.CLETexture = Object.CLETexture(GetObject(TexStack,i))
Found = 0

p$ = dPath
For n = 1 To Len(p)
If Left(Right(p,n),1) = "" Or Left(Right(p,n),1) = "/" Then
p$ = Trim(Right(p,n-1))
Exit
EndIf
Next

For t.TextureBlock = Each TextureBlock
If Lower(p) = Lower(tName) Then
Found = 1
Exit
EndIf
Next

If Found = 0 Then
image = LoadImage(dPath)
If image = 0 Then
ResizeImage image,16,16
t.TextureBlock = New TextureBlock
tNode = FUI_ListBoxItem(GUITexList,p$,image)
tName = p
tPath = dPath
FreeImage Image
PushObject GUI lStack,Handle(t)
EndIf
EndIf
Next


; f.ListBox = Object.ListBox(GUITexList)
;
; For i = 0 To Objects(GUI lStack)-1
; t.TextureBlock = Object.TextureBlock(GetObject(GUI lStack,i))
; If foverItem = Null
; FUI_HideGadget tImageBox
; Else
; If Handle(foverItem) = tNode
; FUI_ShowGadget tImageBox
; Else
; FUI_HideGadget tImageBox
; EndIf
; EndIf
; Next

For e.Event = Each Event
Select eEventID
Case GUIcmLayerRmv
RemoveLayer()

Case GUIcmLayerAdd
AddLayer()

Case GUIcmLayerReset
ResetLayer(BrushLayer)

Case GUIBrushParmsSize
BrushSize = eEventData

Case GUIBrushParmsSpeed
BrushSpeed = eEventData

Case GUIBrushParmsModePaint
PaintMode = 0

Case GUIBrushParmsModeRaise
PaintMode = 1

Case GUIBrushParmsModeLower
PaintMode = 2

Case GUIBrushParmsModeSmooth
PaintMode = 3

Case GUIScaleSpinner
t_ScaleTexture GUIselTex,eEventData,eEventData

Case GUIBlendRadioAlp
t_TextureBlend GUIselTex,1

Case GUIBlendRadioMul
t_TextureBlend GUIselTex,2

Case GUIBlendRadioAdd
t_TextureBlend GUIselTex,3

Case GUIBlendRadioMod
t_TextureBlend GUIselTex,5

Case GUIBtnApplyTexture
t_ApplyTexture BrushLayer,GUIselTex

Case GUImnCLMSave
FUI_SaveDialog("Save landscape..","","Cower Landscape Mesh (*.clm)|*.clm|All files (*.*)|*.*")
path$ = Replace( Lower(appcurrentFile),".clm","" )
ExportCLM(path$)

Case GUImnCLMLoad
FUI_OpenDialog("Load landscape..","","Cower Landscape Mesh (*.clm)|*.clm|All files (*.*)|*.*")
path$ = appcurrentFile
While Objects(GUILayerStack)
FUI_DeleteGadget(PopObject(GUILayerStack))
Wend
If FileType(path$) = 1 Then
path$ = Replace( Lower(appcurrentFile),".clm","" )
ter = ImportCLM(path$)
ScaleEntity ter,50,50,50
EndIf

Case GUImnCLMNew
While Objects(GUILayerStack)
FUI_DeleteGadget(PopObject(GUILayerStack))
Wend
FUI_ModalWindow(GUIWindow,0)
FUI_ShowGadget(GUI
terraWin)
FUI_ModalWindow(GUI
terraWin,1)
Delete e
Repeat
FUI_Update()

For k.Event = Each Event
Select kEventID
Case GUItnOK
Segments = FUI_SendMessageI(GUIspnSegments,M_GETVALUE)
ter = t_CreateTerrain(Segments,1)
If ter <> 0 Then ScaleEntity ter,50,50,50
quitLoop = 1
Case GUItnCancel
quitLoop = 1
End Select
Delete k
Next

RenderWorld
Flip 0
Until quitLoop = 1
FUI_HideGadget(GUI
terraWin)
FUI_ModalWindow(GUI
terraWin,0)
FUI_ModalWindow(GUIWindow,1)

Case GUImnApplyHMap
Delete e
FUI_ModalWindow(GUIWindow,0)
FUI_SendMessage(GUIpathText,M_SETTEXT,"")
FUI_SendMessage(GUIhmpSize,M_SETVALUE,1.0)
FUI_ShowGadget(GUIhmpWin)
FUI_ModalWindow(GUIhmpWin,1)
size# = 1.0
path$ = ""
Repeat
FUI_Update()

For k.Event = Each Event
Select kEventID
Case GUIhmpSize
size# = kEventData
Case GUIhmpOK
If FileType(path$) = 1 Then
ApplyHeightmap(path$,size#)
EndIf
quitLoop = 1
Case GUIhmpCancel
quitLoop = 1
Case GUIopnPath
FUI_OpenDialog("Load heightmap..","","PNG (*.png)|*.png|Bitmap (*.bmp)|*.bmp|Targa (*.tga)|*.tga|JPG (*.jpg)|*.jpg|All files (*.*)|*.*")
path$ = appcurrentFile
FUI_SendMessage GUIpathText,M_SETTEXT,path$
Case GUIpathText
path$ = kEventData
End Select
Delete k
Next

RenderWorld
Flip 0
Until quitLoop = 1
FUI_ModalWindow(GUIhmpWin,0)
FUI_HideGadget(GUIhmpWin)
FUI_ModalWindow(GUIWindow,1)

Case GUImnExportHMap
FUI_SaveDialog("Save landscape..","","Bitmap (*.bmp)|*.bmp|All files (*.*)|*.*")
path$ = appcurrentFile
ExportHeightmap(path$)

Case GUImnQuit
q = FUI_CustomMessageBox("Are you sure you want to quit?","Quit",MB_YESNO)
If q = IDYES Then
Delete GUI
EndEditor = 1
Exit
EndIf

Case GUIcmTextureLoad
FUI_OpenDialog("Load texture..","","PNG (*.png)|*.png|Bitmap (*.bmp)|*.bmp|Targa (*.tga)|*.tga|JPG (*.jpg)|*.jpg|All files (*.*)|*.*")
path$ = appcurrentFile
If FileType(path$) = 1 Then
tex = t_LoadTexture(Path$,1+8,1.0,1.0,5)
For n = 1 To Len(path$)
If Left(Right(path$,n),1) = "" Or Left(Right(path$,n),1) = "/" Then
name$ = Trim(Right(path$,n-1))
Exit
EndIf
Next

t.TextureBlock = New TextureBlock
image = LoadImage(path)
ResizeImage image,16,16
tNode = FUI_ListBoxItem(GUITexList,name$,image)
tName = name
tIndex = tex
tPath = path$
FreeImage image
PushObject GUI lStack,Handle(t)
EndIf

Default
For i = 0 To Objects(GUILayerStack)-1
If Int(GetObject(GUILayerStack,i)) = Int(eEventID) Then
BrushLayer = i
Exit
EndIf
Next

For i = 0 To Objects(GUI lStack)-1
t.TextureBlock = Object.TextureBlock(GetObject(GUI lStack,i))
If tNode = eEventID Then
GUIselTex = tIndex
d.CLETexture = Object.CLETexture(GetObject(TexStack,i))
FUI_SendMessage GUIScaleSpinner,M_SETVALUE,dSX
Select dBlend
Case 1
FUI_SendMessage GUIBlendRadioAlp,M_SETCHECKED,1
FUI_SendMessage GUIBlendRadioMul,M_SETCHECKED,0
FUI_SendMessage GUIBlendRadioAdd,M_SETCHECKED,0
FUI_SendMessage GUIBlendRadioMod,M_SETCHECKED,0
Case 2
FUI_SendMessage GUIBlendRadioAlp,M_SETCHECKED,0
FUI_SendMessage GUIBlendRadioMul,M_SETCHECKED,1
FUI_SendMessage GUIBlendRadioAdd,M_SETCHECKED,0
FUI_SendMessage GUIBlendRadioMod,M_SETCHECKED,0
Case 3
FUI_SendMessage GUIBlendRadioAlp,M_SETCHECKED,0
FUI_SendMessage GUIBlendRadioMul,M_SETCHECKED,0
FUI_SendMessage GUIBlendRadioAdd,M_SETCHECKED,1
FUI_SendMessage GUIBlendRadioMod,M_SETCHECKED,0
Case 5
FUI_SendMessage GUIBlendRadioAlp,M_SETCHECKED,0
FUI_SendMessage GUIBlendRadioMul,M_SETCHECKED,0
FUI_SendMessage GUIBlendRadioAdd,M_SETCHECKED,0
FUI_SendMessage GUIBlendRadioMod,M_SETCHECKED,1
End Select
Exit
EndIf
Next
End Select
Next

Delete Each Event
End Function

;; This function is REQUIRED
;; This function should return whether or not the mouse is over/inside of the
;; GUI area (the area you don't want to have the camera rotate/move when mouse
;; 2 is pressed).
Function CLEMouseInGUI()
If GUI = Null Then Return -1
Return (FUI_OverGadget(GUIWindow))
End Function


Comments :


markcw(Posted 1+ years ago)

 Thanks Noel.