Eilen koodailin tommosta esimerkkiä jossa kuvat copyboxataan pääkuvaan. Kuten Jonez mainitsi voi isot kuvat olla haasteellisia. Omalla koneella huomasin että makeimage ei toimi kuville joiden kokoluokka on noin 10000x10000px veikkaisin että jokin hieman pienempi kahden potenssi olisi aika turvallinen valinta, tyyliin 1024x1024 ja isot kuvat hajoitettaisiin pienempiin paloihin. Parhaimmillaan sain kolmelle kerrokselle varattua 300x350 32x32 tilekoolla varustetun kuvan eli kolme kappaletta 9600x11200 kuvia tämän jälkeen kokoa tai kerroksia kasvattamalla vain makeimage erroria pukkasi.
Tässä vielä esimerkkikoodi "kartasta" johon piirrellään joka frame 100 uutta tileä ja kerroksia on 15. Hiirellä voi liikuttaa kerroksia toisistaan eroon.
Code: Select all
SCREEN 1024,768
//muutama kirjaston vaatima globaali muuttuja
Dim ScreenImages(255) As integer
Global ScreenEmptyImage, ScreenImageCount, ScreenImageLimit, ImageScreenInitialized
Global gScaledImage
gScaledImage = MakeImage(1, 1)
SAFEEXIT OFF
// tästä voi säätää kokoa
Const LAYERS = 15
Const TILE_W = 32
Const TILE_H = 32
SW = ScreenWidth() / TILE_W - 2
SH = ScreenHeight() / TILE_H - 2
//alustetaan kuvakirjasto
InitializeImageScreenLibrary()
//luodaan kuvaruutu
map = MakeImageScreen(SW,SH,TILE_W,TILE_H,LAYERS)
img = MakeImage(TILE_W,TILE_H)
DrawToImage img
Color 0,0,0
Box 0,0,TILE_W,TILE_H
DrawToScreen
//viedään kuva kuvataulukkoon
AddScreenImage(img)
//luodaan kuvat etukäteen
For i=0 To 100
img = MakeImage(TILE_W,TILE_H)
DrawToImage img
Color Rnd(60,230),Rnd(60,230),Rnd(60,230)
Box 0,0,TILE_W,TILE_H
DrawToScreen
//viedään kuva kuvataulukkoon
AddScreenImage(img)
Next i
updateGoingOn = True
Repeat
If KeyHit(cbkeyreturn) Then updateGoingOn = Not updateGoingOn
If (updateGoingOn) Then
// päivitetään joka frame karttaan 100 uutta tileä
For i=0 To 100
l = Rand(LAYERS)
x = Rand(SW)
y = Rand(SH)
imageIndex = Rand(ScreenImageCount)
If (Rand(5) > 0) Then imageIndex = 0
ImageScreenPut(map,x,y,imageIndex,l)
Next i
ImageScreenUpdate(map)
EndIf
mx# = MouseWX()*0.1
my# = -MouseWY()*0.07
ImageScreenDraw(map,TILE_W,TILE_H,mx#,my#)
SetWindow "FPS: "+FPS()
DrawScreen
Until EscapeKey()
//tyhjennetään muisti turhasta tauhkasta
DeleteImageScreen(map)
DeleteScreenImages()
End
Const BYTE_SIZE = 4
//offset of data in memoryblocks
Const MEMBLOCK_OFFSET_ScreenImageLayers = 0
Const MEMBLOCK_OFFSET_ScreenTextureWidth = 4
Const MEMBLOCK_OFFSET_ScreenTextureHeight = 8
Const MEMBLOCK_OFFSET_ScreenWidth = 12
Const MEMBLOCK_OFFSET_ScreenHeight = 16
Const MEMBLOCK_OFFSET_ScreenLayerAmount = 20
Const MEMBLOCK_OFFSET_ScreenBufferType = 24
Const MEMBLOCK_OFFSET_ScreenBuffer = 25
Const MEMBLOCK_OFFSET_ScreenRenderScaleFactor = 29
Const MEMBLOCK_SIZE_Screen = 33
Const MEMBLOCK_OFFSET_LayerBaseImage = 0
CONST MEMBLOCK_OFFSET_LayerScaledImage = 4
Const MEMBLOCK_OFFSET_LayerNewImageCount = 8
Const MEMBLOCK_OFFSET_LayerNewImageList = 12
Const MEMBLOCK_OFFSET_LayerNewImageListSize = 16
Const MEMBLOCK_SIZE_Layer = 20
Const MEMBLOCK_OFFSET_ImageIndex = 0
Const MEMBLOCK_OFFSET_ImageX = 4
Const MEMBLOCK_OFFSET_ImageY = 8
Const MEMBLOCK_SIZE_Image = 12
Const LIST_INCREASE_SIZE = 20
Const BUFFERTYPE_MEMBLOCK = 1
Const BUFFERTYPE_STREAMFILE = 2
Function InitializeImageScreenLibrary(limit=255)
ScreenEmptyImage = MakeImage(10,10)
ScreenImageLimit = limit
ReDim ScreenImages(limit) As integer
ScreenImageCount = 0
ImageScreenInitialized=1
End Function
Function MakeImageScreen(width=16, height=16, imageW=32, imageH=32, layerAmount=10)
mem = MakeMEMBlock(MEMBLOCK_SIZE_Screen)
width = Max(width, 1)
height = Max(height, 1)
PokeInt mem,MEMBLOCK_OFFSET_ScreenTextureWidth, imageW
PokeInt mem,MEMBLOCK_OFFSET_ScreenTextureHeight, imageH
PokeInt mem,MEMBLOCK_OFFSET_ScreenWidth, width
PokeInt mem,MEMBLOCK_OFFSET_ScreenHeight, height
PokeInt mem,MEMBLOCK_OFFSET_ScreenLayerAmount, layerAmount
PokeFloat mem, MEMBLOCK_OFFSET_ScreenRenderScaleFactor, 1.0
//use buffer only if it's small enough
if (width * height * layerAmount < 100000) Then
PokeByte mem,MEMBLOCK_OFFSET_ScreenBufferType, BUFFERTYPE_MEMBLOCK
else
PokeByte mem,MEMBLOCK_OFFSET_ScreenBufferType, BUFFERTYPE_STREAMFILE
endif
ClearImageScreen(mem)
Return mem
End Function
//Deletes Image Screen
Function DeleteImageScreen(mem)
if (mem and MEMBlockSize(mem) = MEMBLOCK_SIZE_Screen) Then
layerObjects = Peekint(mem,MEMBLOCK_OFFSET_ScreenImageLayers)
layerAmount = PeekInt(mem,MEMBLOCK_OFFSET_ScreenLayerAmount)
// delete previous layer images and memblocks if present
if (layerObjects) then
for iterator=0 to MemBlocksize(layerObjects)-1 step BYTE_SIZE
layer = PeekInt(layerObjects, iterator)
if (layer) Then
layerImage = PeekInt(layer,MEMBLOCK_OFFSET_LayerBaseImage)
if (layerImage) then DeleteImage layerImage
changeList = PeekInt(layer,MEMBLOCK_OFFSET_LayerNewImageList)
if (changeList) then
DeleteMEMBlock changeList
endif
DeleteMEMBlock layer
Endif
Next iterator
DeleteMEMBlock layerObjects
EndIf
bufferType = PeekByte(mem,MEMBLOCK_OFFSET_ScreenBufferType)
if (bufferType = BUFFERTYPE_MEMBLOCK) then
screenBuffer = PeekInt(mem,MEMBLOCK_OFFSET_ScreenBuffer)
// remove screen buffer
if (screenBuffer) then DeleteMEMBlock screenBuffer
endif
DeleteMEMBlock mem
EndIf
End Function
//Clears all ImageScreen layerObjects
function ClearImageScreen(mem)
If mem Then
If MEMBlockSize(mem) = MEMBLOCK_SIZE_Screen Then
width = PeekInt(mem,MEMBLOCK_OFFSET_ScreenWidth)
height = PeekInt(mem,MEMBLOCK_OFFSET_ScreenHeight)
layerAmount = PeekInt(mem,MEMBLOCK_OFFSET_ScreenLayerAmount)
bufferType = PeekByte(mem,MEMBLOCK_OFFSET_ScreenBufferType)
if (bufferType = BUFFERTYPE_MEMBLOCK) then
screenBuffer = PeekInt(mem,MEMBLOCK_OFFSET_ScreenBuffer)
// remove screen buffer
If (screenBuffer) then DeleteMEMBlock screenBuffer
// init screen buffer
PokeInt mem,MEMBLOCK_OFFSET_ScreenBuffer, MakeMEMBlock(width * height * layerAmount * BYTE_SIZE)
endif
// init new memblocks and images for layerObjects
ImageScreenInitLayers(mem)
endif
endif
end function
//(Re)creates ImageScreen layerObjects
Function ImageScreenInitLayers(mem)
If ImageScreenInitialized=0 Then MakeError "You must call ImageScreenInitialize() before calling other ImageScreen functions!"
if (mem and MEMBlockSize(mem) = MEMBLOCK_SIZE_Screen) Then
previousLayers = Peekint(mem,MEMBLOCK_OFFSET_ScreenImageLayers)
layerAmount = PeekInt(mem,MEMBLOCK_OFFSET_ScreenLayerAmount)
// delete previous layer images and memblocks if present
if (previousLayers) then
for iterator=0 to MemBlocksize(previousLayers)-1 step BYTE_SIZE
layer = PeekInt(previousLayers, iterator)
if (layer) Then
layerImage = PeekInt(layer,MEMBLOCK_OFFSET_LayerBaseImage)
if (layerImage) then DeleteImage layerImage
changeList = peekint(layer,MEMBLOCK_OFFSET_LayerNewImageList)
if (changeList) Then
DeleteMEMBlock changeList
endif
DeleteMEMBlock layer
Endif
next iterator
DeleteMEMBlock previousLayers
EndIf
width = PeekInt(mem,MEMBLOCK_OFFSET_ScreenWidth)
height = PeekInt(mem,MEMBLOCK_OFFSET_ScreenHeight)
//create new layerObjects
layerObjects = MakeMemblock(BYTE_SIZE * layerAmount)
textureWidth = PeekInt(mem,MEMBLOCK_OFFSET_ScreenTextureWidth)
textureHeight = PeekInt(mem,MEMBLOCK_OFFSET_ScreenTextureHeight)
for iterator=0 to layerAmount-1
layer = MakeMemBlock(MEMBLOCK_SIZE_Layer)
PokeInt layer, MEMBLOCK_OFFSET_LayerBaseImage, MakeImage(width * textureWidth, height * textureHeight)
PokeInt layer, MEMBLOCK_OFFSET_LayerScaledImage, MakeImage(1,1)
PokeInt layer, MEMBLOCK_OFFSET_LayerNewImageCount, 0
changeListSize = LIST_INCREASE_SIZE * MEMBLOCK_SIZE_Image
PokeInt layer, MEMBLOCK_OFFSET_LayerNewImageListSize, changeListSize
PokeInt layer, MEMBLOCK_OFFSET_LayerNewImageList, MakeMEMBlock(changeListSize)
PokeInt layerObjects, iterator * BYTE_SIZE, layer
next iterator
PokeInt mem, MEMBLOCK_OFFSET_ScreenImageLayers, layerObjects
Endif
End function
//Sets value to ImageScreen
Function ImageScreenPut(mem, x, y, imageIndex=0, layer=0, fillLayer=0, fillAllLayers=0)
If (mem And layer > -1 and imageIndex >= 0 and imageIndex < ScreenImageCount) Then
If MEMBlockSize(mem) = MEMBLOCK_SIZE_Screen Then
width = PeekInt(mem,MEMBLOCK_OFFSET_ScreenWidth)
height = PeekInt(mem,MEMBLOCK_OFFSET_ScreenHeight)
layerAmount = PeekInt(mem,MEMBLOCK_OFFSET_ScreenLayerAmount)
layerObjects = PeekInt(mem,MEMBLOCK_OFFSET_ScreenImageLayers)
bufferType = PeekByte(mem,MEMBLOCK_OFFSET_ScreenBufferType)
if (bufferType = BUFFERTYPE_MEMBLOCK) then screenBuffer = PeekInt(mem,MEMBLOCK_OFFSET_ScreenBuffer)
//put value to only one cell
If (fillLayer=0 And layerObjects <> 0 ) Then
//check that coordinates are inside of screen and layer exists
If ( x => 0)( x < width )( y => 0)( y < height )( layer < layerAmount) Then
//start at last layer if clearing all layerObjects
if (fillAllLayers=1) Then layerIndex = layerAmount-1 Else layerIndex = layer
// loop through all layerObjects
while (layerIndex >= 0)
// if buffer is used check old value
If (bufferType = BUFFERTYPE_MEMBLOCK) then
// get old value
oldValue = PeekInt (screenBuffer,(x + y * width + layerIndex * width * height) * BYTE_SIZE)
writeValue = (oldValue <> imageIndex )
Else
writeValue = true
EndIf
If (writeValue) then
//set buffer value to imageIndex
if (bufferType = BUFFERTYPE_MEMBLOCK) then PokeInt screenBuffer,(x + y * width + layerIndex * width * height) * BYTE_SIZE, imageIndex
layerObject = Peekint(layerObjects, layerIndex * BYTE_SIZE)
if (layerObject <> 0) Then
layerChangeList = PeekInt(layerObject, MEMBLOCK_OFFSET_LayerNewImageList)
if (layerChangeList <> 0) Then
layerChangedAmount = PeekInt(layerObject, MEMBLOCK_OFFSET_LayerNewImageCount)
changeListSize = PeekInt(layerObject, MEMBLOCK_OFFSET_LayerNewImageListSize)
//changelist is too small, increase size
if ( changeListSize < (layerChangedAmount+1) * MEMBLOCK_SIZE_Image) then
newSize = (layerChangedAmount + LIST_INCREASE_SIZE) * MEMBLOCK_SIZE_Image
ResizeMEMBlock layerChangeList, newSize
//resize can alter pointer so save
pokeint layerObject, MEMBLOCK_OFFSET_LayerNewImageList, layerChangeList
//store new size
PokeInt layerObject, MEMBLOCK_OFFSET_LayerNewImageListSize, newSize
endif
// Add value to changelist
PokeInt layerChangeList, layerChangedAmount * MEMBLOCK_SIZE_Image + MEMBLOCK_OFFSET_ImageIndex, imageIndex
PokeInt layerChangeList, layerChangedAmount * MEMBLOCK_SIZE_Image + MEMBLOCK_OFFSET_ImageX, x
PokeInt layerChangeList, layerChangedAmount * MEMBLOCK_SIZE_Image + MEMBLOCK_OFFSET_ImageY, y
//increase changelist counter
PokeInt layerObject, MEMBLOCK_OFFSET_LayerNewImageCount, layerChangedAmount + 1
endif
Endif
EndIf
//break out if not going to clear all layerObjects
if (fillAllLayers=0) Then exit
wend
EndIf
// fill this layer
ElseIf fillLayer=1 And fillAllLayers=0 Then
// layer exists
If (layer < layerAmount) Then
layerObject = Peekint(layerObjects, layer * BYTE_SIZE)
layerChangeList = PeekInt(layerObject, MEMBLOCK_OFFSET_LayerNewImageList)
layerChangedAmount = PeekInt(layerObject, MEMBLOCK_OFFSET_LayerNewImageCount)
changeListSize = PeekInt(layerObject, MEMBLOCK_OFFSET_LayerNewImageListSize)
//loop through layer
For x=0 To width - 1
For y=0 To height - 1
// if buffer is used check old value
if (bufferType = BUFFERTYPE_MEMBLOCK) then
// get old value
oldValue = PeekInt (screenBuffer,(x + y * width + layer * width * height) * BYTE_SIZE)
writeValue = (oldValue <> imageIndex )
else
writeValue = true
endif
if (writeValue) then
//set buffer value to imageIndex
if (bufferType = BUFFERTYPE_MEMBLOCK) then PokeInt screenBuffer,(x + y * width + layer * width * height) * BYTE_SIZE, imageIndex
//changelist is too small, increase size
if ( changeListSize < (layerChangedAmount+1) * MEMBLOCK_SIZE_Image) then
newSize = (layerChangedAmount + LIST_INCREASE_SIZE) * MEMBLOCK_SIZE_Image
ResizeMEMBlock layerChangeList, newSize
//resize can alter pointer so save
pokeint layerObject, MEMBLOCK_OFFSET_LayerNewImageList, layerChangeList
//store new size
PokeInt layerObject, MEMBLOCK_OFFSET_LayerNewImageListSize, newSize
endif
// Add value to changelist
PokeInt layerChangeList, layerChangedAmount * MEMBLOCK_SIZE_Image + MEMBLOCK_OFFSET_ImageIndex, imageIndex
PokeInt layerChangeList, layerChangedAmount * MEMBLOCK_SIZE_Image + MEMBLOCK_OFFSET_ImageX, x
PokeInt layerChangeList, layerChangedAmount * MEMBLOCK_SIZE_Image + MEMBLOCK_OFFSET_ImageY, y
//increase changelist counter
PokeInt layerObject, MEMBLOCK_OFFSET_LayerNewImageCount, layerChangedAmount + 1
EndIf
Next y
Next x
EndIf
// clear all -- this is expensive call, avoid if possible
ElseIf fillLayer=1 And fillAllLayers=1 Then
ClearImageScreen(mem)
EndIf
EndIf
EndIf
End Function
//Applies ImageScreen Changes
Function ImageScreenUpdate(mem)
If mem Then
If MEMBlockSize(mem) = MEMBLOCK_SIZE_Screen Then
width = PeekInt(mem,MEMBLOCK_OFFSET_ScreenWidth)
height = PeekInt(mem,MEMBLOCK_OFFSET_ScreenHeight)
textureWidth = PeekInt(mem,MEMBLOCK_OFFSET_ScreenTextureWidth)
textureHeight = PeekInt(mem,MEMBLOCK_OFFSET_ScreenTextureHeight)
layerAmount = PeekInt(mem,MEMBLOCK_OFFSET_ScreenLayerAmount)
layerObjects = PeekInt(mem, MEMBLOCK_OFFSET_ScreenImageLayers)
scaleFactor# = PeekFloat(mem, MEMBLOCK_OFFSET_ScreenRenderScaleFactor)
if ( layerObjects ) Then
for layerIndex = 0 to layerAmount-1
layerObject = Peekint(layerObjects, layerIndex * BYTE_SIZE)
if (layerObject ) Then
layerImage = PeekInt(layerObject, MEMBLOCK_OFFSET_LayerBaseImage)
if layerImage then
layerChangeList = PeekInt(layerObject, MEMBLOCK_OFFSET_LayerNewImageList)
layerChangedAmount = PeekInt(layerObject, MEMBLOCK_OFFSET_LayerNewImageCount)
changeListSize = PeekInt(layerObject, MEMBLOCK_OFFSET_LayerNewImageListSize)
if (layerChangedAmount > 0 and layerChangeList <> 0) Then
//apply changes to layer
for changeIterator = 0 to layerChangedAmount - 1
value = PeekInt(layerChangeList, changeIterator * MEMBLOCK_SIZE_Image + MEMBLOCK_OFFSET_ImageIndex)
x = PeekInt(layerChangeList, changeIterator * MEMBLOCK_SIZE_Image + MEMBLOCK_OFFSET_ImageX)
y = PeekInt(layerChangeList, changeIterator * MEMBLOCK_SIZE_Image + MEMBLOCK_OFFSET_ImageY)
If value >= 0 and value < ScreenImageCount Then
CopyBox 0,0,textureWidth,textureHeight,x*textureWidth,y*textureHeight,Image(ScreenImages(value)),Image(layerImage)
Else
Drawtoimage layerImage
Color 0,0,0
Box x*textureWidth,y*textureHeight,textureWidth,textureHeight
DrawToScreen
EndIf
next changeIterator
if (scaleFactor# <> 1.0) then
fLayerIndex# = -scaleFactor#^float( layerIndex)
scaledImage = PeekInt(layerObject, MEMBLOCK_OFFSET_LayerScaledImage)
scaledImage = ScaleImage(layerImage, scaledImage, float(textureWidth*width)*fLayerIndex#, float(height*textureHeight)*fLayerIndex#)
pokeint layerObject, MEMBLOCK_OFFSET_LayerScaledImage, scaledImage
endif
suggestedSize = (layerChangedAmount * 2 ) * MEMBLOCK_SIZE_Image
if (changeListSize > suggestedSize) then
resizememblock layerChangeList, suggestedSize
pokeint layerObject, MEMBLOCK_OFFSET_LayerNewImageList, layerChangeList
pokeint layerObject, MEMBLOCK_OFFSET_LayerNewImageListSize, suggestedSize
endif
//reset changed amount to zero
PokeInt layerObject, MEMBLOCK_OFFSET_LayerNewImageCount, 0
Endif
EndIf
EndIf
next layerIndex
Endif
EndIf
EndIf
End Function
Function ImageScreenDraw(mem,imageScreenX#=0.0,imageScreenY#=0.0,layerOffsetX#=0.0, layerOffsetY#=0.0)
If mem Then
If MEMBlockSize(mem) = MEMBLOCK_SIZE_Screen Then
layerAmount = PeekInt(mem,MEMBLOCK_OFFSET_ScreenLayerAmount)
layerObjects = PeekInt(mem, MEMBLOCK_OFFSET_ScreenImageLayers)
scaleFactor# = PeekFloat(mem,MEMBLOCK_OFFSET_ScreenRenderScaleFactor)
width = PeekInt(mem,MEMBLOCK_OFFSET_ScreenWidth)
height = PeekInt(mem,MEMBLOCK_OFFSET_ScreenHeight)
textureWidth = PeekInt(mem,MEMBLOCK_OFFSET_ScreenTextureWidth)
textureHeight = PeekInt(mem,MEMBLOCK_OFFSET_ScreenTextureHeight)
for layerIndex = 0 to layerAmount-1
layerObject = Peekint(layerObjects, layerIndex * BYTE_SIZE)
layerImage = PeekInt(layerObject, MEMBLOCK_OFFSET_LayerBaseImage)
scaledImage = PeekInt(layerObject, MEMBLOCK_OFFSET_LayerScaledImage)
if (scaleFactor# <> 1.0 ) then
fLayerIndex# = scaleFactor#^float(layerIndex)
w# = float(textureWidth*width)
widthDiff# = w#/2.0 - w#*fLayerIndex#/2.0
h# = float(textureHeight*height)
heightDiff# = h#/2.0 - h#*fLayerIndex#/2.0
DrawImage scaledImage, imageScreenX+layerOffsetX#*float(layerIndex)+widthDiff#, imageScreenY+layerOffsetY#*float(layerIndex)+heightDiff#
else
fLayerIndex# = float(layerIndex)
DrawImage layerImage, imageScreenX+layerOffsetX#*fLayerIndex#, imageScreenY+layerOffsetY#*fLayerIndex#
endif
next layerIndex
EndIf
EndIf
End Function
//Adds image to Screen images and returns index of image
Function AddScreenImage(img)
If (img) Then
If (ScreenImageCount >= ScreenImageLimit) Then
ClearArray OFF
ScreenImageLimit = ScreenImageLimit + LIST_INCREASE_SIZE
ReDim ScreenImages(ScreenImageLimit) As integer
EndIf
ScreenImages(ScreenImageCount) = img
ScreenImageCount = ScreenImageCount + 1
Else
MakeError "Image is not valid to add into ImageScreen"
EndIf
imgIndex = ScreenImageCount - 1
Return imgIndex
End Function
Function DeleteScreenImages()
If ImageScreenInitialized=0 Then MakeError "You must call ImageScreenInitialize() before calling other ImageScreen functions!"
For iterator = 0 To ScreenImageLimit
If ScreenImages(ScreenImageLimit) Then DeleteImage ScreenImages(iterator)
Next iterator
End Function
Function ScaleImage(_image, _scaled, _width, _height)
//By: Marcoder
//Modification: Little optimization handling with ImageWidth() And ImageHeight().
If _width <= 0 Or _height <= 0 Then Return _scaled
DeleteImage _scaled
_scaled = MakeImage(_width, _height)
_image_width = ImageWidth(_image)
_image_height= ImageHeight(_image)
// Tehdään temppikuva johon skaalataan ensin vain leveys
lTempImage = MakeImage(_width, ImageHeight(_image))
DrawToImage lTempImage
For x = 0 To _width - 1
sx# = Float(_image_width) / Float(_width) * Float(x)
DrawImageBox _image, x, 0, sx, 0, 1, _image_height, OFF,OFF
Next x
lTempImage_width = ImageWidth(lTempImage)
DrawToScreen
// Skaalataan myös pystysuunnassa
DrawToImage _scaled
For y = 0 To _height - 1
sy# = Float(_image_height) / Float(_height) * Float(y)
DrawImageBox lTempImage, 0, y, 0, sy, lTempImage_width, 1, OFF,OFF
Next y
DrawToScreen
DeleteImage lTempImage
Return _scaled
End Function