Tutorial Load & save your characters

Wingnut

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,282
Let's start with some code!

Here's an easy example how to load and save your characters and background graphics using code.
It's handy to have for a lot of things, feel free to use and learn from if you find it useful!

A quick guide for the example:
The example will first draw some squares that represents your graphics that you carefully loaded (or created programatically like we did here). Now you want to save it.

It wll be automatically saved as soon as you start the example and it has drawn everything in place.
Check the console to confirm that. After this you would want to press the left mouse-button to
trigger a load to happen. That's basically it.

You will probably didn't even notice any blinking while loading it back. You can use this for any kind of complex graphics.
I'm sorry about the fact that the example is a bit dry but life gets in the way and all that.

Methods
Load method will load anything that was saved with the save method (it saves a header with size information).
Save method takes any image that you already created and give it as a parameter, and saves it correctly, ready to be used with the load method.

This example will also will also how you how you can use SetRenderTarget to draw to images and how switch between images and the main canvas.

You don't have to have one canvas for each image in other words. The cost for switching is zero.

example.cxs
Cerberus:
Strict
Import imports

Function Main:Int()
    New Game()
    Return 0
End

Class Game Extends App

    Field call : Functions
    Field canvas:Canvas,mode:Int = 1 ' 0 = LOAD, 1 = SAVE
    Field sprite:Image

    Method OnCreate:Int()
        canvas=New Canvas ; SetSwapInterval 1 ; SetUpdateRate 0
        call = New Functions()
  
        ' Create main character
        sprite = New Image(256,256,0,0,0)
        canvas.SetRenderTarget sprite                        ' Set canvas to point to 3dsprite's canvas.
        canvas.Clear 0,0,0,0
        canvas.SetColor 1,0,1,1 ; canvas.DrawRect 0,0,256,256    ' Purple blerb, to show the full area.
        canvas.SetColor 0,0,1,1 ; canvas.DrawRect 0,0,50,50    ' Blue blerb, to have something interesting to check against.
        canvas.Flush
  
        canvas.SetRenderTarget Null                        ' Set canvas to point to main canvas.
        Return 0
    End
  
    Method OnRender:Int()
        canvas.Clear 1,0,0                                 ' Make background red to make the 3dsprite's position visible.
        If sprite Then canvas.SetColor 1,1,1 ; canvas.DrawImage sprite,10,10 
        If mode = 1 Then call.saveimage(sprite,"cerberus://data", canvas) ; mode = 3 ; Print "Press left Mousebutton to load everything back"
        If mode = 0 Then sprite = call.loaddimage("cerberus://data", canvas) ; mode = 3 ; Print "Done!"
        If MouseDown(0) And mode = 3 Then mode = 0
 
         canvas.Flush
        Return 0
    End

End

imports.cxs
Cerberus:
Import mojo2
Import brl.databuffer
Import brl.filestream
Import functions

functions.cxs
Cerberus:
Strict
Import imports

Class Functions

    Method saveimage:Int(image:Image,path:String, canvas:Canvas)
 
        canvas.SetRenderTarget image
            Local data:Int,pos:Int = 0,file:=FileStream.Open(path + "/3dsprite.raw","w")
            Local w:Int = canvas.Width,h:Int = canvas.Height

        Local pixels:DataBuffer = New DataBuffer((w * h) * 4)
        file.WriteInt w ; file.WriteInt h ; pos = pos + 8
        canvas.ReadPixels 0,0,w,h,pixels     
  
        For Local y:Int = 0 Until h
                For Local x:Int = 0 Until w
                   data = pixels.PeekInt( (x*4) + (y*w*4) ) ; file.WriteInt data ; pos = pos + 4
                Next
         Next
  
        file.Close
        Print "Saved, length = " + String(pos) ' Above will show 256x256x4 (262144 bytes) + sizeheader (8 bytes) 
        canvas.SetRenderTarget Null
            Return 0
    End
 
    Method loaddimage:Image(path:String,canvas:Canvas)
 
        Local file:=FileStream.Open( path + "/3dsprite.raw","r" )
        Local pos:Int = 0
        Local w:Int = file.ReadInt(),h:Int = file.ReadInt() ; pos = pos + 8
        Local image : Image =New Image(w,h,0,0,0)
  
        canvas.SetRenderTarget image ;     canvas.Clear 0,0,0,0
        Local data:Int,rgba:Int[],dump:FileStream,x:Int = 0,y:Int = 0 ; rgba = rgba.Resize((w * h) *4)
  
        While Not file.Eof()
            Local c:Int[4] ; data = file.ReadInt() ; c = ColorToRgba(data)     
            canvas.SetColor c[0]/255.0,c[1]/255.0,c[2]/255.0,c[3]/255.0 ; canvas.DrawRect x,y,1,1
            pos = pos + 4 ; x = x + 1 ; If x >= w Then x = 0 ; y = y + 1
        Wend
  
        file.Close
        Print "Loaded, length = " + String(pos)
        canvas.Flush ; canvas.SetRenderTarget Null
        Return image
    End
  
    Function ColorToRgba:Int[](value:Int)
            Local v:Int = value,resp:Int[] ; resp = resp.Resize(4) ' Create an array of 4 integers
            resp[0] = v & 255
            v = v Shr 8 ; resp[1] = v & 255
            v = v Shr 8 ; resp[2] = v & 255
            v = v Shr 8 ;  resp[3] = v & 255
            Return resp
    End
 
End


Cerberus file system in general

You see paths used in the code above, and this is the key of course to get more flexibility.

I will cover how macOS behaves with Cerberus here. There are similiar paths for iOS, Android and Windows that you can use.

On macOS platform you can use the paths below to save your files inside the actual .app file.
This will open up like a zip file or folder when you right click it. The other platforms will behave differently.

The main paths you can use are :

"cerberus://data"
"cerberus://internal"
"cerberus://external"

Look at the included image 3 to understand what location each of these paths refer to inside the .app file.
So on a macOS system, this is bascially just different subfolders inside the executable .app file itself. They will stay there.

Note that it seems like you can skip the protocol ("cerberus://) most of the times except when using web (like http:// or https://).
But don't quote me on this. I'll mention it here as you probably have seen alot of paths that does not use them.

------------------------------------------------------------------------------------------------------------------------

Files on the Operating Systems

What If you want to save outside the .app file itself?
You have a lot of possibilities here as well.
On macOS for instance If you want to save a file on the desktop you can use this:

'/Users/yourusernamegoeshere/Desktop"

This will place your files on your desk for easy access.

This was just a quick guide how to deal with files in Cerberus, I hope you enjoyed!
 

Attachments

  • 3dchar.zip
    4 KB · Views: 25
  • 1.png
    1.png
    88.4 KB · Views: 17
  • 2.png
    2.png
    44.2 KB · Views: 17
  • 3.png
    3.png
    45.2 KB · Views: 21
  • 4.png
    4.png
    59.4 KB · Views: 18
Last edited:
Top Bottom