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 <stdio.h>
#include <stdlib.h>
#include <math.h>

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 make an installer

How to make an installer with NSIS

Code updated to work on Windows 10 properly.

Many people may have a finished product but lacking an installer for the product. There are lots of installer creating software, but some of them are very expensive. NSIS is a free installer scripting system from Nullsoft. I used to use it in my products. In this blog I present my example script that gets beginners started.

At first NSIS may seem complicated, but fortunately it has many macros, that make creating an installer an easy task. The picture below shows one page of the built example script presented at the end of this blog post.

NSIS-example

Now, let’s get on with NSIS.

An NSIS installer has one ore more pages. The pages are created with macros in the script (in our example).

Furthermore, every script is build up with sections. Each section except the uninstaller section is shown in the ”Choose Components” page as shown in the picture above.

In our example script we are using the modern user interface, MUI in short. First there’s defined some constants, that make life easier later in the script and make the script easily re-usable. The example script installs for all users. The line

SetShellVarContext all

means all the users. And in the registry key registration HKLM is related to all users.

Enough, let’s see the commented example script (name it as myscript.nsi or something):

; We are using the Modern User Interface
!include "MUI2.nsh"

; Put you own information here
!define MUI_PRODUCT "Your Product"
!define MUI_VERSION "1.00"
!define MUI_PUBLISHER "Your Company"

; The name of the installer
Name "${MUI_PRODUCT}"

; The filename of the installer
OutFile "${MUI_PRODUCT} installer.exe"

RequestExecutionLevel admin

; The directory where the files will be installed
; The installer let's the user change this
InstallDir "$PROGRAMFILES${MUI_PRODUCT}"

; Registry key for the install dir
InstallDirRegKey HKLM "Software${MUI_PRODUCT}" ""

;Interface Settings
!define MUI_ABORTWARNING 

; Installer pages
!insertmacro MUI_PAGE_WELCOME

; The path on line below is relative to nsi-file you have created
!insertmacro MUI_PAGE_LICENSE "docLicense.rtf"
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_RUN
!define MUI_FINISHPAGE_RUN_FUNCTION LaunchApplication
!insertmacro MUI_PAGE_FINISH

; Uninstaller pages
!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH

; Language 
!insertmacro MUI_LANGUAGE "English"
 
Section "${MUI_PRODUCT} (required)" SecProduct

  ; Read only section
  ; This section can't be unchecked from the interface
  SectionIn RO
 
  SetOutPath "$INSTDIR" ; files will be installed here

  
  ; Recursively add all the files from "publish" directory
  ; The path of the "publish" is relative to the path
  ; of the nsi-file you have created
  File /r "publish*.*"
  
  ; The following creates the uninstaller
  WriteUninstaller "$INSTDIRUninstall.exe"

  ; Registry key for the installed product
  WriteRegStr HKLM "Software${MUI_PRODUCT}" "$INSTDIR" ""

SectionEnd

Section "Start Menu Shortcuts" secStartMenuShortcuts

  ; Install for the current user
  SetShellVarContext all

  CreateDirectory "$SMPROGRAMS${MUI_PRODUCT}"
  CreateShortCut "$SMPROGRAMS${MUI_PRODUCT}${MUI_PRODUCT}.lnk" "$INSTDIR${MUI_PRODUCT}.exe"
  CreateShortCut "$SMPROGRAMS${MUI_PRODUCT}Uninstall.lnk" "$INSTDIRUninstall.exe"

SectionEnd

Section "Desktop shortcut" secDesktopShortcut

  SetShellVarContext all

  CreateShortCut "$DESKTOP${MUI_PRODUCT}.lnk" "$INSTDIR${MUI_PRODUCT}.exe"

SectionEnd

; Descriptions for installing
  LangString DESC_SecProduct ${LANG_ENGLISH} "${MUI_PRODUCT} files and uninstaller"
  LangString DESC_SecStartMenuShortcuts ${LANG_ENGLISH} "Creates Start Menu Folder"
  LangString DESC_SecDesktopShortcut ${LANG_ENGLISH} "Creates desktop icon"

; Put the descriptions
  !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
    !insertmacro MUI_DESCRIPTION_TEXT ${SecProduct} $(DESC_SecProduct)
    !insertmacro MUI_DESCRIPTION_TEXT ${SecStartMenuShortcuts} $(DESC_SecStartMenuShortcuts)
    !insertmacro MUI_DESCRIPTION_TEXT ${SecDesktopShortcut} $(DESC_SecDesktopShortcut)
  !insertmacro MUI_FUNCTION_DESCRIPTION_END
  
Section "Uninstall"
  
  SetShellVarContext all

  ; Delete files and directories
  ; An unempty directory cannot be deleted

  Delete "$INSTDIR*.*"
  RMDir "$INSTDIR"
  
  Delete "$SMPROGRAMS${MUI_PRODUCT}*.*"
  RMDir "$SMPROGRAMS${MUI_PRODUCT}"
 
  Delete "$DESKTOP${MUI_PRODUCT}.lnk"

  ; If the reg key has no subkeys,
  ; it will be deleted
  DeleteRegKey /ifempty HKLM "Software${MUI_PRODUCT}"
  DeleteRegKey /ifempty HKLM "SoftwareMicrosoftWindowsCurrentVersionUninstall${MUI_PRODUCT}"

SectionEnd

Function .onInstSuccess

  ; Registry key information for the Control Add/Remove Programs of Windows
  WriteRegStr HKLM "SoftwareMicrosoftWindowsCurrentVersionUninstall${MUI_PRODUCT}" "DisplayName" "${MUI_PRODUCT}"
  WriteRegStr HKLM "SoftwareMicrosoftWindowsCurrentVersionUninstall${MUI_PRODUCT}" "InstallLocation" "$INSTDIR"

  WriteRegStr HKLM "SoftwareMicrosoftWindowsCurrentVersionUninstall${MUI_PRODUCT}" "Publisher" "${MUI_PUBLISHER}"
  WriteRegStr HKLM "SoftwareMicrosoftWindowsCurrentVersionUninstall${MUI_PRODUCT}" "RegOwner" "${MUI_PUBLISHER}"
  WriteRegStr HKLM "SoftwareMicrosoftWindowsCurrentVersionUninstall${MUI_PRODUCT}" "DisplayVersion" "${MUI_VERSION}"
  
  WriteRegStr HKLM "SoftwareMicrosoftWindowsCurrentVersionUninstall${MUI_PRODUCT}" "UninstallString" "$INSTDIRUninstall.exe"

FunctionEnd

; Function to launch the application,
; when the installing is finished
Function LaunchApplication
  ; If needed, change the filename
  ExecShell "" "$INSTDIR${MUI_PRODUCT}.exe"
FunctionEnd

Other environment variables that often are needed, when creating an installer are $APPDATA and $DOCUMENTS for the %AppData% folder and Documents folder respectively.

Links:

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("%sn",appdata);

}