Image Buttons with MaxGUI

This time a little tutorial on how to use images as buttons in BlitzMax with MaxGUI module.

For beginners the most important thing is to understand the event loop.

The image buttons are made with panels that have background graphics. The source below clarifies the rest.

In order to try the code, download the following images:

demobg

Button1

Button2

Button1sel

Button2sel

 

 

Save the images to the same folder where you save the code below. In order to get the code working with images, name the violet background picture as “demobg.png” and the blue “Button” labeled images as “button1.png” and “button2.png” and the rest “Button” labeled images as “button1sel.png” and “button2sel.png”.

The code uses gadget sensitivity to change the button images when touched with the mouse.

Import MaxGui.Drivers
Import MaxGUI.XPManifest

Strict

Global background:TPixmap=LoadPixmap("demobg.png")

Global gfxButton1:TPixmap = LoadPixmap("button1.png")
Global gfxButton2:TPixmap = LoadPixmap("button2.png")

Global gfxButton1Sel:TPixmap = LoadPixmap("button1sel.png")
Global gfxButton2Sel:TPixmap = LoadPixmap("button2sel.png")

Global window:TGadget = CreateWindow("Image Buttons Demo",40,40,304,228,Null,WINDOW_TITLEBAR|WINDOW_CLIENTCOORDS|WINDOW_CENTER)
Global panel:TGadget

panel=CreatePanel(0,0,ClientWidth(window),ClientHeight(window),window)
SetPanelPixmap(panel,background)


Local pnlButton1:TGadget = CreatePanel(98,40,107,47,panel,PANEL_ACTIVE,"PanelButton1")
Local pnlButton2:TGadget = CreatePanel(98,100,107,47,panel,PANEL_ACTIVE,"PanelButton2")

Local lblButtonPressed:TGadget = CreateLabel("",20,20,100,34,panel)

SetPanelPixmap(pnlButton1, gfxButton1)
SetPanelPixmap(pnlButton2, gfxButton2)

SetGadgetSensitivity(pnlButton1,EVENT_MOUSEENTER|EVENT_MOUSELEAVE)
SetGadgetSensitivity(pnlButton2,EVENT_MOUSEENTER|EVENT_MOUSELEAVE)

Repeat

	WaitEvent()

	Select EventID()
	
		Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE
			End
		
		Case EVENT_MOUSEENTER
			Select EventSource()
				Case pnlButton1
					SetPanelPixmap(pnlButton1, gfxButton1Sel)
					SetGadgetText lblButtonPressed,""

				Case pnlButton2
					SetPanelPixmap(pnlButton2, gfxButton2Sel)
					SetGadgetText lblButtonPressed,""

			End Select
		
		Case EVENT_MOUSELEAVE
			Select EventSource()
				Case pnlButton1
					SetPanelPixmap(pnlButton1,gfxButton1)
				Case pnlButton2
					SetPanelPixmap(pnlButton2,gfxButton2)
			End Select
			
		Case EVENT_MOUSEUP              'checking for a mouseup event
			Select EventSource()    'where does it come from
				Case pnlButton1
					SetGadgetText lblButtonPressed,"Button 1 pressed."
					
				Case pnlButton2
					SetGadgetText lblButtonPressed,"Button 2 pressed."
					
			End Select
			
	EndSelect

Forever

Feel free to use this code.

Using C and DLLs in BlitzMax

BlitzMax apps can be made faster by using C. Also using DLLs in BlitzMax is possible, but that isn’t documented in BlitzMax’s documentation at all.

First, an example of using C code in BlitzMax. As an example we generate the Mandlebrot set using C code to determine does the point belong to the set (see my article on my personal blog on generating the Mandelbrot set, whole example code is in BlitzMax).

To compile the example below, you need to have MinGW configured to BlitzMax.

We start with the C code (save it as mandelbrot.c):

int mandelbrot(double dr, double di, double minR, double minI, int x, int y, int maxIter);

int mandelbrot(double dr, double di, double minR, double minI, int x, int y, int maxIter) {

    int iterations = 0;

    double cr,ci,zr,zi,zr_temp,zi_temp;

    cr = minR + x * dr;
    ci = minI + y * di;
    zr = 0.0;   
    zi = 0.0;
    zr_temp = 0.0;
    zi_temp = 0.0;

 while (iterations < maxIter) {

        zr_temp = zr * zr - zi * zi + cr;
       
        zi_temp = 2.0 * zr * zi + ci;
        
        zr = zr_temp;
        zi = zi_temp;       

        iterations++;

        if (zr * zr + zi * zi > 4.0) return iterations;
    
 }

    return 0;
}

Next the BlitzMax code that uses the C code:

Import "mandelbrot.c"

' tell the compiler that there is an external function
Extern
	Function mandelbrot:Int(dr:Double,di:Double,minR:Double,minI:Double,x:Int,y:Int,maxIter:Int)
End Extern

Const maxIter:Int = 40

Graphics 640,480

Local minR:Double = -2.25, maxR:Double = 0.75
Local minI:Double = -1.5, maxI:Double = 1.5

Local dr:Double, di:Double

Local w:Double, h:Double, sW:Double, diff:Double
Local shade:Int

w = maxR - minR
h = maxI - minI
sW = h * (640.0) / (480.0)
diff = sW - w

minR = minR - diff / 2
maxR = maxR + diff / 2

dr = (maxR - minR) / 640
di = (maxI - minI) / 480

For Local y:Int = 0 To 480 - 1
	For Local x:Int = 0 To 640 - 1
		shade = mandelbrot(dr,di,minR,minI,x,y,MAXITER)
		shade = 255 - Double(MAXITER - shade) / MAXITER * 255.0
		SetColor 0,0,shade
		Plot x,y
	Next
Next

Flip
WaitKey
End

Compile and run the code and you’ll see a blue shaded Mandelbrot set that should look like following:

mandelbrot

In the next part of this post we’ll create a DLL in C and call it from BlitzMax.

I’m still mostly using Visual C++ 2008.

The steps to create a DLL:

  • Start Visual C++ and start a new project
  • Select WIN32 console application, name it (in our example Mandelbrot) and press OK
  • Then click ”Next” and select DLL

You’ll get a pre-generated code for a DLL.

The C code for our DLL is following (Mandelbrot.cpp in Visual C++):

#include "stdafx.h"	// this for Visual C++

extern "C"{ 
_declspec(dllexport) int mandelbrot(double dr, double di, double minR, double minI, int x, int y, int maxIter); 
} 
int mandelbrot(double dr, double di, double minR, double minI, int x, int y, int maxIter) {

    int iterations = 0;

	double cr,ci,zr,zi,zr_temp,zi_temp;

    cr = minR + x * dr;
    ci = minI + y * di;
    zr = 0.0;   
    zi = 0.0;
    zr_temp = 0.0;
    zi_temp = 0.0;

	while (iterations < maxIter) {

        zr_temp = zr * zr - zi * zi + cr;
       
        zi_temp = 2.0 * zr * zi + ci;
        
        zr = zr_temp;
        zi = zi_temp;       

        iterations++;

        if (zr * zr + zi * zi > 4.0) return iterations;
    
	}

    return 0;
}

The BlitzMax code using the DLL is as follows:

Extern "win32"
	Function FreeLibrary(hLibrary:Int)
End Extern

Global mandelbrot:Int(dr:Double,di:Double,minR:Double,minI:Double,x:Int,y:Int,MAXITER:Int)"Win32"

Global lib = LoadLibraryA("Mandelbrot.dll")

If lib Then
	mandelbrot = GetProcAddress(lib, "mandelbrot")
Else
	Notify "DLL-file not found!"
	End
EndIf

Global x:Int, y:Int
Const MAXITER:Int = 40

Graphics 640,480

Global minR:Double = -2.25, maxR:Double = 0.75
Global minI:Double = -1.5, maxI:Double = 1.5

Global dr:Double, di:Double

Global w:Double, h:Double, sW:Double, diff:Double
Global shade:Int

w = maxR - minR
h = maxI - minI
sW = h * (640.0) / (480.0)
diff = sW - w

minR = minR - diff / 2
maxR = maxR + diff / 2

dr = (maxR - minR) / 640
di = (maxI - minI) / 480

For y = 0 To 480 - 1
	For x = 0 To 640 - 1
		shade = getShade()
		shade = 255 - Double(MAXITER - shade) / MAXITER * 255.0
		SetColor 0,0,shade
		Plot x,y
	Next
Next

Flip
WaitKey
FreeLibrary(lib)	' free the resources
End

Function getShade:Int()
	Return mandelbrot(dr,di,minR,minI,x,y,MAXITER)
EndFunction

The DLL function is called from a BlitzMax function, because otherwise one would get a EXCEPTION_STACK_OVERFLOW.

When the DLL is called from a function the memory allocated for the DLL-call is local; after returning from the function all the memory allocated for the function call is freed.

As always, this information is free. You may use the codes above in your projects as you wish.

What if BlitzMax full screen application freezes on exit

With Windows 7 BlitzMax full screen applications worked just fine on my system, but after upgrading to Windows 10 I ran into problems: The app started normally, execution of the app was ok, but sometimes when exiting the app, the application freezed. This problem is probably system related problem; on some systems this problem may not exist, but on some systems there is this problem.

(updated)

It seems that the best solution for best compatibility is to let the user select between full screen and windowed mode. The problem really is Windows 10 related.

I first thought that setting the graphics driver in BlitzMax would help, but eventually the full screen apps freezed on exit… I also tried to set the the graphics driver to D3D11Max2DDriver (DirectX 11) since my system supports it, but that didn’t help either.

Nostalgia: Missile Attack

Again, some nostalgia. I remember, that it was late 80s, when I had a game called “Missile Attack” for Amiga. It was shareware game priced at $5.

Many years ago I made just for fun my own implementation of this classic game in Blitz3D. For curiosity, if my memory serves me right, in Terminator II young John Connor is playing this kind of game in one part of the movie.

In this blog post is shortened version of my Missile Attack game. The code is quite messy. I hope there are not any horrible bugs in this old game. This is the first time the game sees the daylight.

Copy paste the code to Blitz3D and start playing, it’s really quite fun, though quite pointless. 🙂 No external files are needed.

ma_ingame

AppTitle "Missile Attack"
HidePointer

Graphics 640,480,32,2

SeedRnd MilliSecs()


fntArial20 = LoadFont("Arial",20)
fntCourier20 = LoadFont("courier",20,True)


SeedRnd MilliSecs()

Type missile
	Field x#,y#
	Field dx#,dy#
	Field origX#, origY#
	Field r,g,b
	Field ovalM
End Type

Type ammoCircle
	Field frame
	Field x,y
	Field hit
End Type


Type energyBar
	Field r#
	Field dr#
	Field g#
	Field dg#
	Field b#
	Field hit	
End Type

Type yellowFlash
	Field hit
End Type

gfxAim = CreateImage(25,25)
SetBuffer ImageBuffer(gfxAim)
Line 0,13,25,13
Line 13,0,13,25


gfxAmmo = CreateImage(72,72,72)


For q = 0 To 71							
	SetBuffer ImageBuffer (gfxAmmo,q)

	Origin ox#,oy#
	Color 0,0,255
	Oval 72/2,72/2,r#,r#,0

	ox# = ox# - 0.5
	oy# = oy# - 0.5
	r# = r# + 1


Next

gfxOval = CreateImage(15,15)
SetBuffer ImageBuffer(gfxOval)
Origin 0,0
Oval 0,0,15,15,0

SetBuffer BackBuffer()

.start
FlushKeys


For mssl.missile = Each missile
	Delete mssl
Next
		
For ammo.ammoCircle = Each ammoCircle
	Delete ammo
Next

For yc.yellowFlash = Each yellowFlash
	Delete yc
Next
		
For eb.energyBar = Each energyBar
	Delete eb
Next

eb.energyBar = New energyBar

divisor = 48

yellowFlashes = 0	; nr of yellow flashes

energyBarLen = 72
yellow = 0

maxMissiles = 0

r# = 1

orig# = 50
ox# = 0
oy# = 0


nr_of_missiles = 0
gameover = False
printInstr = False
printStr = False

extraEarned = False
print_fullDestr = True
big = False

SetBuffer BackBuffer()

Repeat
	Cls

	If KeyHit(1) Then	
		End
	EndIf	

			
	Color 255,0,0
	SetFont fntCourier20
	Text (640 - StringWidth("Missile Attack")) / 2,40,"Missile Attack"
			
	SetFont fntArial20
	Color 200,80,180
	Text (640 - StringWidth("Use mouse to shoot the missiles")) / 2, 100, "Use mouse to shoot the missiles"
	Text (640 - StringWidth("Space for full destruction")) / 2, 140, "Space for full destruction"
	
	Color 0,255,0
	Text (640 - StringWidth("Press Return to begin"))/2,380,"Press Return To begin"
	
	Color 255,0,255
	Text (640 - StringWidth("Public Domain"))/2,420,"Public Domain"

	Flip
		
Until KeyHit(28)	; Return starts the game



FlushKeys
Cls
destr = 0	; full destructions


SetBuffer BackBuffer()

blueFrame = False
bigBangs = 3
amountMissiles = Rand(5,8)
nr_of_missiles = 0

print_bigShot = False

divisor = 48

yellowFlashes = 0
energyBarLen = 72
yellow = 0

maxMissiles = 0

r# = 1

orig# = 50
ox# = 0
oy# = 0

gameover = False
extraEarned = False
print_fullDestr = True
big = False

firstBigShot = True
yellowFlashesInfo = False

While Not gameover = True

	Cls
	
	If KeyHit(1) Then Goto start
	
	mx = MouseX()
	my = MouseY()
	
	DrawImage gfxAim,mx,my

	While nr_of_missiles < amountMissiles
	
		mssl.missile = New missile
		mssl\origX# = Rand(100,580)
		mssl\x# = Rand(50,100)
		mssl\origY# = 31
		mssl\x# = mssl\origX# + Rand(-5,5)
		mssl\y# = 32
		mssl\dx# = Rnd(-2,2)
		mssl\dy# = Rnd(0,2)
	
		mssl\r = Rand(50,255)
		mssl\g = Rand(50,255)
		mssl\b = Rand(50,255)

		mssl\ovalM = Rand(5,15)

		nr_of_missiles = nr_of_missiles + 1
		
	Wend

	If MouseHit(1) Then
		ammo.ammoCircle = New ammoCircle
		ammo\x = mx - 24
		ammo\y = my - 24
		ammo\frame = 1
		ammo\hit = 0 
	EndIf

	Origin 0,0

	Color 0,0,255
	If bigBangs > 0 And bigBangs < 4 Then
		For i = 1 To bigBangs
			Oval 565 + i * 15,460,10,10,1
		Next
	EndIf

	For ammo.ammoCircle = Each ammoCircle
		ammo\frame = ammo\frame + 2
		
		If ammo\frame >= divisor Then
			Delete ammo
		Else
			If nr_of_missiles > 0 Then
			
				DrawImage gfxAmmo,ammo\x,ammo\y,ammo\frame

				For mssl.missile = Each missile
					If ImageRectCollide (gfxAmmo,ammo\x,ammo\y,ammo\frame, mssl\x ,mssl\y ,5,5)					
						Delete mssl
						ammo\hit = ammo\hit + 1
						nr_of_missiles = nr_of_missiles - 1
					EndIf
				Next
			EndIf	
		EndIf
	Next


	If print_bigShot = True Then

		Color 0,0,255

		If MilliSecs() - 2500 < timer_bigShot Then
			Text 270,200,"Big shot earned!"
		Else
			print_bigShot = False
		EndIf
				
		
	EndIf
		

	
	For ammo.ammoCircle = Each ammoCircle 
		maxMissiles = ammo\hit

		If ammo\hit >= 2 Then
			divisor = 72
			
			If firstBigShot = True Then
			
				firstBigShot = False
				print_bigShot = True
				timer_bigShot = MilliSecs()
				
				yellowFlashes = 0 
			EndIf
						
			big = True
		EndIf
			
		
		; If nr of missiles = 0, player get all 3 full destruction balls
		If nr_of_missiles = 0 Then

			timer_all = MilliSecs()
			print_fullDestr = True
	
			first_bigShot = True
			timer_bigShot = MilliSecs()
			
			blueTimer = MilliSecs()
			blueFrame = True
			
			bigBangs = 3
			
			destr = destr + 1
			
			For mssl.missile = Each missile
				Delete mssl
			Next
			
			For ammo.ammoCircle = Each ammoCircle
				Delete ammo
			Next


			For yc.yellowFlash = Each yellowFlash
				Delete yc
			Next
		
			For eb.energyBar = Each energyBar
				Delete eb
			Next
			nr_of_missiles = 0

			divisor = 72
			big = True
			Exit
			
		EndIf
						
	Next
	

	If print_fullDestr = True Then
		If MilliSecs() - timer_all < 2500 Then
			Text 270,220,"Full destruction!"
		EndIf
		If MilliSecs() - timer_all > 2500 Then print_fullDestr = False
	EndIf
	
	
	If gameover = True Then
			
		For mssl.missile = Each missile
			Delete mssl
		Next
		
		For ammo.ammoCircle = Each ammoCircle
			Delete ammo
		Next

		For yc.yellowFlash = Each yellowFlash
			Delete yc
		Next
		
		For eb.energyBar = Each energyBar
			Delete eb
		Next

		Goto gameEnd
	EndIf

	; BigBang
	If KeyHit(57) Then
		
		If bigBangs > 0 Then
			blueTimer = MilliSecs()
			blueFrame = True
			bigBangs = bigBangs - 1
			amountMissiles = 1
			nr_of_missiles = 0
			
		Else
			bigBangs = 0
			blueFrame = False
		EndIf
	EndIf

	Color 0,255,0
	Line 0,450,639,450
	Line 0,30,639,30
	

	For mssl.missile = Each missile
		If mssl\x# <= 0 Or mssl\x# >= 639 Then
			Delete mssl
			nr_of_missiles = nr_of_missiles - 1
			
			ec.yellowFlash = New yellowFlash
			ec\hit = True
			
			yellowFrame = True
			yellowTimer = MilliSecs()
						
			yellowFlashes = yellowFlashes + 1
						
		EndIf
	Next


	; If 20 missiles have gone to side of the screen.
	; return the normal size shot
	If yellowFlashesInfo = False And yellowFlashes > 20 And big = True Then	
		divisor = 48
		yellowFlashesDelay = MilliSecs()
		yellowFlashesInfo = True
		yellowFlashes = 0
	EndIf
	
	If yellowFlashesInfo = True Then
		If big = True Then print_bigShot = True	;
		If MilliSecs() - 2500 < yellowFlashesDelay Then
			firstBigShot = True
			Color 255,0,0
			Text 270,185,"Big shot lost!"
		Else
			yellowFlashesInfo = False
			big = False
			firstBigShot = True
		EndIf
	EndIf


	For mssl.missile = Each missile
		mssl\x# = mssl\x# + mssl\dx#
		mssl\y# = mssl\y# + mssl\dy#

		Color 255,255,255
		Line mssl\origX#, 31, mssl\x#, mssl\y#

		Color mssl\r,mssl\g,mssl\b	
		Oval mssl\x#-mssl\ovalM/2,mssl\y#-mssl\ovalM/2,mssl\OvalM,mssl\ovalM,1		
				
		If mssl\y# >=450 Then
			gameover = True
		EndIf
	Next
			
	
	If gameover = False Then
	
		eb.energyBar = New energyBar
		eb\r# = 255
		eb\dr# = 255 / 72
		eb\g# = 0
		eb\dg# = 255 / 72
		eb\b# = 0
		eb\hit = 0
		
		yellow = 0
		For ec.yellowFlash = Each yellowFlash
			If ec\hit = True Then
				yellow = yellow + 1
				Delete ec
			EndIf
		Next
		
		energyBarLen = energyBarLen - yellow
		
		If energyBarLen <= 0 Then
			gameOver = True
			Goto gameEnd
		EndIf
		
		For i = 1 To energyBarLen
		
			eb\r# = eb\r# - eb\dr#
			eb\g# = eb\g# + eb\dg#

			Color eb\r#,eb\g#,eb\b#
	
			Line i + 263 ,460,i + 263,470

		Next
		yellow = 0
	EndIf
	
	If gameover = True Then
	
		For mssl.missile = Each missile
			Delete mssl
		Next
		
		For ammo.ammoCircle = Each ammoCircle
			Delete ammo
		Next

		For yc.yellowFlash = Each yellowFlash
			Delete yc
		Next
		
		For eb.energyBar = Each energyBar
			Delete eb
		Next

	EndIf		

	If yellowFrame = True Then
		Color 255,255,0
		Rect 0,31,640,419,1
		If MilliSecs() < yellowTimer + 2000 Then yellowFrame = False		
	EndIf

	If blueFrame = True Then
		Color 0,0,255
		Rect 0,31,640,420,1
		
		For mssl.missile = Each missile
			nr_of_missiles = nr_of_missiles - 1
			
			Delete mssl
		Next

		For ammo.ammoCircle = Each ammoCircle
			Delete ammo
		Next

		nr_of_missiles = 0
		amountMissiles = Rand(5,8)
				
		If MilliSecs() < blueTimer + 2000 Then
			blueFrame = False
			nr_of_missiles = 0
		EndIf
	
	EndIf

	Flip	

Wend

.gameEnd
endTimer = MilliSecs()

Repeat
	If MilliSecs() > endTimer + 10000 Then Exit
	Color 200,100,100
	Text (640 - StringWidth("Game Over")) / 2, 200, "Game Over"
	Flip
Until KeyHit(1) Or KeyHit(28) Or KeyHit(57)

Goto start
End

Instructions for playing:

  • Use mouse to shoot the missiles
  • Space bar for full destruction
  • When at least 2 missiles are shot with one shot. the player is rewarded by bigger shot
  • If a missile goes to the side of the screen, player’s energy decreases
  • If missile touches the line at the bottom of the window, the game ends
  • If the player clears the screen by firing, the player is rewarded by giving 3 full destruction balls

The code isn’t really commented, sorry!

How to capture a screenshot from BlitzMax 2D fullscreen game

It’s of course possible to capture a screenshot from BlitzMax fullscreen game with video capture programs such Fraps. It can be also done with the in the BlitzMax code of the game. Here’s my little code to do it:

SuperStrict

HideMouse

Const JPEG_QUALITY:Int = 90

Graphics 640,480,32,1

Local screenpixmap:TPixmap = CreatePixmap(640,480,PF_RGBA8888)

While Not KeyHit(KEY_ESCAPE)
   Cls

   DrawOval (640 - 32) / 2, (480 - 32) / 2, 32, 32

   If KeyHit(KEY_C) Then
      screenpixmap = GrabPixmap(0,0,640,480)
      SavePixmapJPeg (screenpixamp,"filename.jpg",JPEG_QUALITY)	
   EndIf
 
   Flip
	
Wend
End

One must define a Pixmap to which the screen’s content is grabbed. When the contents are grabbed the pixmap is saved as JPEG picture by name “filename.jpg”.

In this example program the screenshot is taken when key c is pressed and saved as jpeg-file.

Hex 2 Dec

In many programming languages there is built-in command or function to convert a decimal value to a hex value. But at least in BlitzMax there isn’t a command or function to convert a hex value to a dec value. In this post I present my little function to convert a hex value to dec value in BlitzMax and in C.

The BlitzMax function:

First, put somewhere in the beginning of your program line

Const hexes:String = "0123456789ABCDEF"

The function itself:

Function hex2dec:Int(hexvalue:String)

  Local i:Byte, val10:Int, index:Byte, length:Int
  Local char:String

  length = Len(hexvalue)

  For i = 1 To length

    char = Mid$(hexvalue,i,1)
    index = Instr(hexes,char) - 1
    val10 = val10 + (16 ^ (length - i)) * index

  Next

  Return val10

EndFunction

The C version is a complete program that uses its functions:

#include 
#include 
#include 

int hex2dec(char*);
int indexOfchar(char);

const char hexes[] = "0123456789ABCDEF";

void main (void) {

  char hex[8+1];

  printf("Hex number: ");
  scanf("%s",&hex[0]);
  printf("%s is %d in dec.n",&hex[0],hex2dec(&hex[0]));
}

int hex2dec(char *hex) {
  int i, index, val10, length;
  char chr;

  val10 = 0;

  length = strlen(hex);

  for (i = 0; i < length; i++) {
    chr = hex[i];
    index = indexOfchar(chr);
    val10 = val10 + pow(16,(length - i - 1)) * index;
}
  return val10;
}

int indexOfchar(char chr) {

  int i;

  for (i = 0; i < 16; i++) {
    if (hexes[i] == chr) return i;
  }
}

Be careful with the C version: It doesn’t check if the input is correct. As you can see from the code the letters in the hex number should be given in capital letters. Feel free to use and improve these codes!

How to retrieve the %AppData% folder

AppData folder is used to store data like hiscores, config, etc. of a game (or app). The AppData folder is a special folder that’s location is related to Windows version one is using. This is why AppData folder must be retrieved with the aid of the system.

In Blitz3D retrieving the AppData folder is as simple as this:

AppDataFolder$ = GetEnv$(”AppData”)

In BlitzMax retrieving the AppData folder isn’t this straight forward. The easiest way to get the location of this special folder is to use external module, BAH.Volumes. Once this module is installed for BlitzMax and imported in the beginning of the code, retrieving the AppData folder is as easy as this:

AppDataFolder = GetUserAppDir()

Above is assumed that the variable AppDataFolder is defined as String.

In order to install external modules to BlitzMax, MinGW must be installed and configured for BlitzMax. The BlitzMax product page has a link to forum topic that explains how to set up MinGW for BlitzMax.

Link: BAH.Volumes (from Google Code)

Update!

With good old ANSI C the %AppData% folder can be retrieved as follows:

#include <stdio.h>
#include <stdlib.h>

void main(void) {

	char *appdata;
	appdata = getenv("AppData");
	printf("%s\n",appdata);

}