-
Notifications
You must be signed in to change notification settings - Fork 23
_MEM
The _MEM variable type can be used when working with memory blocks. It has no variable Variable Types suffix.
-
The _MEM type contains the following read-only elements where name is the _MEM variable name:
-
Memory DOT values are actually part of the built in memory variable Variable Types in QB64. The following TYPE is built in:
TYPE memory_type
OFFSET AS _OFFSET 'start location of block(changes with byte position)
SIZE AS _OFFSET 'size of block remaining at offset(changes with position)
TYPE AS LONG 'type description of variable used(never changes)
ELEMENTSIZE AS _OFFSET 'byte size of values inside the block(never changes)
IMAGE AS LONG 'the image handle used when _MEMIMAGE(handle) is used
SOUND AS LONG 'the sound handle used when _MEMSOUND(handle) is used
END TYPE
The above TYPE is for clarification purposes only. It doesn't need to be pasted in a program to use _MEM.
IMPORTANT NOTE: As of Build 20170802/57 onward, mem.TYPE has been changed to be an _OFFSET, just as mem.SIZE and mem.ELEMENTSIZE.
- 0 = UDT (TYPE) or memory created by _MEMNEW
- 1 = 1 bit ELEMENT.SIZE=1 * Only used along with specific types (currently integers or floats)
- 2 = 2 bit. ELEMENT.SIZE=2
- 4 = 4 bit. ELEMENT.SIZE=4
- 8 = 8 bit. ELEMENT.SIZE=8
- 16 = 16 bit. ELEMENT.SIZE=16
- 32 = 32 bit. ELEMENT.SIZE=32
- 64 = 64 bit. ELEMENT.SIZE=64
- 128 = 128 bit. ELEMENT.SIZE=128
- 256 = 256 bit. ELEMENT.SIZE=256
- 512(+ bit*) = integer types only(ie. whole numbers)
- 1024(+ bit*) = floating point types only(ie. numbers that can have a decimal point)
- 2048 = STRING type only
- 4096(+ 512 + bit*) = _UNSIGNED integer type only
- 8192 = _MEM type only
- 16384(+ 512 + bit*)= _OFFSET type only
Note: If a future integer, float or other type doesn't have a size that is 1,2,4,8,16,32,64,128 or 256 it won't have a size-bit set.
-
1 = Integer types such as _BYTE, INTEGER, LONG, _INTEGER64 or _OFFSET
-
2 = _UNSIGNED variable types. Value must be added to the variable type value.(2 cannot be used by itself)
-
8 = STRING
-
Note: _OFFSET values cannot be cast to other variable Variable Typess reliably. _MEM is a reserved custom variable Variable Types.
-
_MEM (function) cannot reference variable length STRING variable values. String values must be designated as a fixed-LEN string.
Demonstration of .IMAGE to determine an image's dimensions, .TYPE to verify the type and _MEMEXISTS to check image has not been freed
SCREEN _NEWIMAGE(500, 500, 32)
i = _LOADIMAGE("qb64_trans.png", 32)
_PUTIMAGE (0, 0), i
DIM m AS _MEM
m = _MEMIMAGE(i)
'try uncommenting the following line and see what happens
'_MEMFREE m
t = m.TYPE
IF t AND 2048 THEN
PRINT "this is/was an image"
IF _MEMEXISTS(m) THEN 'check if memory m is still available
PRINT t AND 7; "bytes per pixel"
PRINT "image handle "; m.IMAGE
PRINT "image width"; _WIDTH(m.IMAGE)
PRINT "image height"; _HEIGHT(m.IMAGE)
ELSE PRINT "Memory already freed!"
END IF
END IF
Converts the current _DEST SCREEN 13 image memory altered by PSET to a STRING value. SCREEN 13 only.
SCREEN 13
PSET (0, 0), ASC("H") 'top left corner of screen
PSET (1, 0), ASC("E")
PSET (2, 0), ASC("L")
PSET (3, 0), ASC("L")
PSET (4, 0), ASC("O")
DIM m AS _MEM
m = _MEMIMAGE(0) 'copy the screen memory to m
x1$ = _MEMGET(m, m.OFFSET, STRING * 5) 'get at block start position
LOCATE 2, 1:PRINT LEN(x1$) 'prints 5 bytes as size is STRING * 5
PRINT x1$ 'prints HELLO as ASCII character values
PRINT m.OFFSET; m.SIZE; m.ELEMENTSIZE
_MEMFREE m
5
HELLO
5448320 6400 1
Explanation: When a numerical _BYTE value is converted to a STRING, each byte is converted to an ASCII character. The QB64 IDE will capitalize _MEM dot values.
m.SIZE = 320 * 200 = 6400 bytes
m.ELEMENTSIZE = 1 byte
Using _MEM to convert _OFFSET to _INTEGER64.
DIM x AS INTEGER
DIM m AS _MEM
m = _MEM(x)
PRINT m.OFFSET
PRINT ConvertOffset(m.OFFSET)
FUNCTION ConvertOffset&& (value AS _OFFSET)
$CHECKING:OFF
DIM m AS _MEM 'Define a memblock
m = _MEM(value) 'Point it to use value
$IF 64BIT THEN
'On 64 bit OSes, an OFFSET is 8 bytes in size. We can put it directly into an Integer64
_MEMGET m, m.OFFSET, ConvertOffset&& 'Get the contents of the memblock and put the values there directly into ConvertOffset&&
$ELSE
'However, on 32 bit OSes, an OFFSET is only 4 bytes. We need to put it into a LONG variable first
_MEMGET m, m.OFFSET, temp& 'Like this
ConvertOffset&& = temp& 'And then assign that long value to ConvertOffset&&
$END IF
_MEMFREE m 'Free the memblock
$CHECKING:ON
END FUNCTION
Explanation: The above will print two numbers which should match. These numbers will vary, as they're representations of where X is stored in memory, and that position is going to vary every time the program is run. What it should illustrate, however, is a way to convert _OFFSET to _INTEGER64 values, which can sometimes be useful when trying to run calculations involving mem.SIZE, mem.TYPE, or mem.ELEMENTSIZE.