#AddResource
#AddResource Filename$
 
Parameters:

    Filename$ = The filename (and path) of the file to be included in program resource buffer
Returns: NONE
 

     #AddResource is a compile time directive. It works much like the #include directive with one exception, #AddResource is explicitly for embedding binary data, text / image media and even DLL files into your program. The binding process occurs at compile time, this means whenever the compiler locates a #AddResource statement (followed by a filename), it will load the file into it's internal resource buffer. Depending upon the compile mode (compile and run or compile to exe), PlayBASIC will manage the resource data for you. So when we compile to EXE it bundles up the resource data into our final program.

      The ability to bind media into our programs exe has a number of uses, from helping prevent people tampering with your programs media / data, through to cleaning up our final distribution package and potentially speeding up loading. It's important to understand that as of July 2013, PlayBASIC doesn't encrypt or compress the bound data for you. So highly skilled individuals would be able to extract the information if they really tried. You can prevent this by applying your own encryption algorithms to the resource data prior to including it. One typical approach, would be to write a program that reads your game/apps original data into memory, where it applies some form of encryption/alterations to the data, then saves a copy of the file out either into project folder or a second folder. Never ever, allow it to save over the original file ! In your PlayBASIC program you would include the decryption code that will convert the modified resource back into it's original state. The data can then be loaded as normal.

      PlayBASIC treats the resource buffer as an internal file buffer. When we bind a file using #AddResource, PlayBASIC uses the filename and path as the internal 'name' of this resource. To access any bound resource, we need the filename that it was originally bound with. It works like this, so we can internally remap media loading commands from disc to load the resource from memory rather than disc.


Example:

  
  // Tell PlayBASIC compiler to load this file into it's internal
  // resource buffer at compile time.
  #AddResource "Media/GameLogo.png"
  
  // Load the file as normal once the program is running
  LoadImage "Media/GameLogo.png"1
  


      So in this mock up, we've some code that binds a media resource into an exe during compile time, in this case the pretend file "GameLogo.png". When the program is executed, the LoadImage statement internally checks if the file your loading can be found in the programs resource buffer in memory. If it is, it will automatically load the image from memory resource for you. So for the most part we don't have to change how we load media in our programs. We just bind the resources we want to be internal and that's it. If you wanted to apply some form of decryption algorithm (assuming the bound resource was previously encrypted) to the resource then you'd call your decrypt routine prior to the loading the media.







FACTS:


      * Some Image Resources bound to your EXE via #AddResource can be directly loaded from memory via LoadIMage (and it's variant) commands. (PBI, BMP,TGA & PNG)

      * Some Font Resources bound to your EXE using the #AddResource directive can be directly loaded from memory via LoadFont commands. (CRF only)

      * Linked DLL files (via linkDLL) bound to your EXE using the #AddResource directive or through the LinkDLL, are loaded directly memory.

      * Sounds + Music can't be bound or loaded from memory as of PlayBASIC V1.64O July 2013




Mini Tutorial #1: - Loading Media From Resource


      In this first example we're going to look at how PlayBASIC can load resource Image + Font media directly from memory. The example doesn't include the media, if it did we'll assume the programmer as created a sub-folder within their projects folder called "MEDIA", which contains required files.

      To bind media into our executable we use the #AddResource directive followed by the relative (or absolute path) and filename of the file. Since the command is resolved at compile time (during compilation), the filename has to be literal string/constant, you can't use a string variable/array/type as those data structures only exist at runtime. The binding process simply loads the file into your programs resource buffer. Once it's there the program can access them as will.

      In this example we're going to bind some resources and then load the Image + Fonts files from the resource buffer. Since the PlayBASIC V1.64O (July2013), the media loading commands now check if the file you requested to load is in resource buffer in memory first. So the loading such resources is transparent to the users program.

  
  // These directives imports the file data into memory/exe at compile time
  // The data is saved with your EXE, so you don't have to include these external files
  #AddResource "Media/Arial36.crf"
  #AddResource "Media/uwlogo.png"
  
  
  // The load font statement checks if this file is actually a
  // bound (in memory) resource, if so, it loads it from memory
  Arial36=LoadNewFont("Media/Arial36.crf",1)
  SetFont Arial36
  Print "This Font was loaded as a resource"
  
  
  // The load image statement checks if this file is actually
  // a bound (in memory) resource, if so, it loads it from memory
  logo=LoadNewImage("Media/uwlogo.png",1)
  DrawImage Logo,200,300,true
  Print logo
  
  
  Sync
  WaitKey
  


(Example only: This is not cut'n'paste friendly code)

The program would output someting like this (if we had the media files)







Mini Tutorial #1b: - #AddResource is a compile time directive


      In the example above, the code reads in order (top -> down), meaning that it looks like when we execute the program, the program will run the #AddResource commands and then the load and display commands. So a new programmer could easily be fooled into thinking #AddResource is a command in the same way as LoadImage and such are.

      It's important to understand that #AddResource is a compile time directive. When the compiler scans your program code and encounters a directive operation, it performs that operations there and then. In the case of #AddResource the compiler loads the file we want into memory. Since directives are processed at compile time and not run time (they don't exist at run time), we can place our #AddResource statements anywhere we like.

      We can demonstrate this simply moving the #AddResource after the Load statements.


  
  // The load font statement checks if this file is actually a
  // bound (in memory) resource, if so, it loads it from memory
  Arial36=LoadNewFont("Media/Arial36.crf",1)
  SetFont Arial36
  Print "This Font was loaded as a resource"
  
  
  // The load image statement checks if this file is actually
  // a bound (in memory) resource, if so, it loads it from memory
  logo=LoadNewImage("Media/uwlogo.png",1)
  DrawImage Logo,200,300,true
  Print logo
  
  
  Sync
  WaitKey
  
  // These directives imports the file data into memory/exe at compile time
  // The data is saved with your EXE, so you don't have to include these external files
  #AddResource "Media/Arial36.crf"
  #AddResource "Media/uwlogo.png"
  
  


(Example only: This is not cut'n'paste friendly code)

So if we ran this, we'd get the same result.









Mini Tutorial #2: - Accessing a bound resource


      So far we've looked at the automated media loading support, but what if you want to the bind some other type of data, like a text file or some custom data ? Well, binding process is the same, the only change is that now the programmer has to manually load the media. To do that we use the FindResourceIndex, GetResourcePtr and GetResourceSize functions. The process is first we locate our resources media index, then if found we get the address and size of this chunk of memory. Beyond that we can use the PeekByte,PeekWord,PeekInt,PeekString etc etc functions to read what this data is.

      For our example, let's say we have a text file called HelloWorld.txt stored in a sub folder called MEDIA again. The text file contains the following text.

  
  Hello World
  Hello World
  Hello World
  Hello World
  Bye Bye
  



      To load this from a resource buffer we first need to ask PlayBASIC what resource buffer this file is stored in. To do this we use the FindResourceIndex() function with the full name/ path of the original file. The function returns the INDEX of the resource in the resource buffer. If the resource wasn't found, the returned indexed will be -1. Once we have the INDEX, we can query the address and size of this buffer using the GetResourcePtr and GetResourceSize functions. PlayBASIC doesn't


For our example, let's say we have a text file called HelloWorld.txt stored in a sub folder called MEDIA again. The text file contains the following text.

  
  
  #AddResource "Media/Hello-World.txt"
  
  // Search for a bound resource
  Index=findresourceindex("Media/Hello-World.txt")
  
  // If the resource was found it's index will be 0 or higher
  If Index>-1
     
     // Display information about this resource
     Print "Resource Found"
     
     Address     =getresourceptr(Index)
     Size          =getresourcesize(Index)
     
     Print "Address In Memory:"+Str$(Address)
     Print "Size:"+Str$(Size)
     
     // Since we know this is text resource
     // here's we'll copy it to a string
     // using peekstring
     s$=PeekString(Address,Size)
     
     
     // New we'll split this string into an array to display it
     Dim Rows$(0)
     
     // remove any ASC chr 13 from the string
     s$=Replace$(s$,Chr$(13),"")
     
     // split the string on the ASC II chr 10
     RowCount=SplitToArray(s$,Chr$(10),Rows$())
     
     // Display the rows of this text file
     For lp =0 To RowCount-1
        Print Rows$(lp)
     Next
     
  EndIf
  
  Sync
  WaitKey
  
  


(Example only: This is not cut'n'paste friendly code)

So if we ran this, we'd get the same result.







More Reading:


      The best resource for low level details about PlayBASIC head over to the PlayBASIC forums, make sure you sign up as guests only have very limited access !





 
Related Info: #include | Data | FindResourceIndex | GetResourcePtr | GetResourceSize :
 


(c) Copyright 2002 - 2024 - Kevin Picone - PlayBASIC.com