Falcon 4.0 Forum, Falcon 4 Home, Falcon 4 Campaign, Falcon 4 Cockpits, Falcon 4 Database, Falcon 4 File Formats, Falcon 4 SRTM Terrain, Falcon 4 Terrain, Falcon 4 Textures, Falcon 4 Tools
Falcon 4 Theater NSIS Installer by PMC
The NSIS installer is quite nice as its free to download and very light weight, its script based so you can tweak the installer to do pretty much anything you want. Sure the script at first looks pretty intimidating, but dont let that scare you, we have the wiki to help you out.
Here in PMC Tactical we use NSIS installer to build our theater installers, also FreeFalcon/RedViper is using this method for their installation. Its very nice freeware open source program.
The scripting is relatively easy for a non-coder to figure out, but is still powerful and flexible. It has a strong user community and good open-source support. It also is “portable” in that there is a version which can run from almost any PC on USB memory stick.
First you should setup your theater directories in preparations for the NSIS to build the installer. It doesn't really matter what you call the source directory as you can configure it on the script, but we call it here Theater_src_THEATERNAME where the theatername of course is like Europe, DesertStorm or Vietnam in our case.
In the “root” theater source dir you got two directories called, Theaters and Utilities. We chose to use the Utilities dir which is included in the default RedViper installation to store its utils/tools. And naturally the Theaters dir is the one which we use to suit PMC Theater Directory Structure which so far everyone (except Naldo) has agreed to use.
In the utilities dir you place the utils, these are lstupdate.exe, LxNormalFix.exe, SeasonSwitcher.exe and Htti.exe filenames.
So in short, you have directory of
Theater_src_DesertStorm\Theaters\DesertStorm\
Which would be your root directory for the ODS theater (later in this doc as we refer to root, this is the dir), in this root directory you have the art, campaign, objects and terrdata directories. Also there is theater selection TDF, TGA files and any readme files you wish the users to see (in our case, its the EULA.txt and version.txt).
Art directory is for the user interface files. Our base system includes the art\resource\ directory which contains two UI files, these are campmap and select which in our experience are universal for all F4 versions. As you need to include the individual UI files for different F4 versions in the art-AF, art-OF and art-RV directories, the main art\ dir is where you place the resource dir.
As seen here
art\resource\ art\art-AF\ art\art-OF\ art\art-RV\
When we examine the individual directories more we'll find these following subdirs.
art-AF\
art\art-AF\campaign\ art\art-AF\main\ art\art-AF\resource\
Notice how art-OF\ requires yet another “art” subdir to work.
art-OF\
art\art-OF\art\main\ art\art-OF\art\resource\
art-RV\
art\art-RV\main\ art\art-RV\resource\
You should refer to our user interface namespace for details how to edit Falcon 4 UI.
Campaign dir includes the common files used for all campaigns, as well the individual campaign directory files required for all possible campaigns. The sub directories in main campaign dir are as follows.
Campaign subdirs for our DesertStorm theater
campaign\common\ campaign\common-AF\ campaign\common-OF\ campaign\common-RV\ campaign\desertstorm1\ campaign\desertstorm2\
When we look closer, we find that the common\ directory contains these following files: instant.cam, kneemap.gif, te_new.tac, desertstorm.idx/.wch, desertstorm.pak and desertstorm.thr. These are the files that are common/same for all the campaign directories we are creating.
In the common-AF\, common-OF\ and common-RV\ dirs we have files for each specific F4 version, in this case strings.idx/.wch files.
Finally in the desertstorm1\ and desertstorm2\ dirs we have the specific files required for each campaign, these are usually save0.cam, save0.tri and save1/2 also.
You should refer to our campaign namespace for details how to edit Falcon 4 campaigns.
To install new objects, objects and including new skins to your theater, you need to create **objects* subdir into the root. In the objects dir create AF, OF and RV sub directories. In these subdirs you place the edited database files.
As seen here
objects\AF\FALCON4.WLD objects\OF\FALCON4.WLD objects\RV\FALCON4.WLD
In this case the falcon4.wld file is the edited loadouts for aircrafts.
You should refer to our database namespace for details how to edit Falcon 4 database.
Terrdata directory is where the terrain\ and texture\ sub directories are located.
As you can see
terrdata\terrain\ terrdata\texture\
Of course if your theater uses only default korean tiles, you dont need texture\ subdir.
In the terrain\ sub dir you find theater.L2/.O2, theater.map and theater.mea files, rest of the theater files are created with the terrain rebuilder util.
In the texture\ sub dir (if you need it) you find fartiles.pal, texture.bin and texture.zip files.
Here is the latest release PMC theater script, its from Vietnam theater.
!define TNAME "Vietnam" !define FRIENDLYNAME "PMC Vietnam Theater Installer" !define APP "VietnamInstaller" ;for some reason, this has to be #.#.#.# but I usually change the name after I build the exe !define VER "0.0.0.9" ; these establish some things about the installer the most important one to me is the outfile Name "${FRIENDLYNAME}" ; outfile is the name of the installer. Unless otherwise set, it will be the same directory as where the script is OutFile "PMC_${TNAME}_Theater_v${VER}.exe" Caption "${FRIENDLYNAME}" ; these VI definitions are what is displayed if you hover the mouse over the icon VIProductVersion "${VER}" VIAddVersionKey ProductName "${FRIENDLYNAME}" VIAddVersionKey Comments "Installs the ${TNAME} theater." VIAddVersionKey LegalCopyright "PMC Tactical" VIAddVersionKey FileDescription "${FRIENDLYNAME}" VIAddVersionKey FileVersion "${VER}" VIAddVersionKey ProductVersion "${VER}" VIAddVersionKey InternalName "${FRIENDLYNAME}" ;=== Runtime Switches ; the CRC check is something I use on bigger installers to make sure everything checks out. CRCCheck On ; this makes it more efficient AutoCloseWindow True ; this is something I use to make sure it uses the LZMA compression, which I believe is the best SetCompressor lzma ; branding text is just something that's displayed at the bottom of the installer BrandingText "https://www.pmctactical.org" ;=== Includes - this will include the necessary dlls and functions that I use in the installer ; MUI 1.67 compatible ------ !include "MUI.nsh" !include "Registry.nsh" !include "WinMessages.nsh" !include "TextFunc.nsh" !include "Sections.nsh" ; MUI Settings - the MUI is the Modern UI for NSIS, this section defines its parameters (there are alot more that I don't use) !define MUI_ABORTWARNING !define MUI_INSTALLCOLORS /windows ; Welcome page - this is the first page of the installer (I also have a snippet for a splashscreen, but we'll keep this simple) ;!define MUI_WELCOMEFINISHPAGE_BITMAP "@@:\FF4Installers\leftgraphic.bmp" ; using the variables means we don't have to remember to change all these when we use the template for another theater !define MUI_WELCOMEPAGE_TITLE "${FRIENDLYNAME} ${VER} Setup Wizard" !define MUI_WELCOMEPAGE_TEXT "Setup will install ${FRIENDLYNAME} ${VER} into your Falcon installation." !insertmacro MUI_PAGE_WELCOME !define MUI_LICENSEPAGE_RADIOBUTTONS !insertmacro MUI_PAGE_LICENSE "Theater_src_${TNAME}\Theaters\${TNAME}\EULA.txt" ; Instfiles page !define MUI_FINISHPAGE_NOAUTOCLOSE !insertmacro MUI_PAGE_INSTFILES ; Finish page - this is the last page people see !define MUI_FINISHPAGE_TITLE "${FRIENDLYNAME} ${VER} Installation completed." !define MUI_FINISHPAGE_TEXT "Click 'Finish' to close this wizard." !insertmacro MUI_PAGE_FINISH ; Language files !insertmacro MUI_LANGUAGE "English" ; MUI end ------ ; now we're ready for the actual installer! Section "Installer" SEC01 ; F4registry check - if no F4 registry, it kicks to the end - the $0 is a variable that holds the -1 (not found) or 0 (found) ; we can also start to determine which install we have ${registry::KeyExists} "HKLM\Software\MicroProse\Falcon\4.0" $0 ${registry::KeyExists} "HKLM\Software\Lead Pursuit\Battlefield Operations\Falcon" $1 ; IntCmp compares the integer in $0 with our number (0) and if it is =, it goes to label "F4Exists" IntCmp $0 0 F4Exists IntCmp $1 0 AFInstall ; this copies the string to $9 - I'm using that as an error label StrCpy $9 "No appropriate registry found." Goto Error F4Exists: ; this determines if there's an AF reg entry, and if so, it only advances 1 line, if not, it goes to F4Install IntCmp $1 0 0 F4Version ; at this point, we need to determine if the person wants to install over "original" F4 or RV Messagebox::show MB_DEFBUTTON3|MB_TOPMOST "" "" "Select where you want the theater installed." "OF/RV" "AF" IDCANCEL ; this places the response 1, 2, or 3, into $0 Pop $0 IntCmp $0 3 Finish IntCmp $0 2 AFInstall F4Version: ; now we know they want OF/RV so we need to differentiate - I'm only going to look for RV, if it isn't RV, I'm going to assume OF for now ; this will also validate the install a bit ; this reads the specified registry value into $0 ReadRegStr $0 HKLM "Software\MicroProse\Falcon\4.0" "basedir" ; if the file exists, go to next line (don't skip a line) if it doesn't, go to label "NoFileFound" IfFileExists $0\theater.lst 0 NoFileFound IfFileExists $0\terrdata\objects\KoreaObj.Dxl RVFound IfFileExists $0\terrdata\objects\KoreaObj.lod OFFound NoFileFound NoFileFound: StrCpy $9 "No F4 install found." Goto Error ; I want to set up a variable to differentiate OF and RV RVFound: ; we'll use this for the lstupdate variable StrCpy $8 "F4" StrCpy $7 "RV" Goto F4Install OFFound: StrCpy $8 "F4" StrCpy $7 "OF" Goto F4Install AFInstall: ; get the AF base directory into a variable ReadRegStr $0 HKLM "Software\Lead Pursuit\Battlefield Operations\Falcon" "basedir" ; sets the right campaign directory StrCpy $1 "$0\campaign\korea" ; campaing\save string StrCpy $2 "$0\Utilities\LxNormalFix.exe $$LP @${TNAME} @$0\Theaters\${TNAME}\terrdata" ; lxnormalfix string StrCpy $8 "AF" Goto CreateDirs F4Install: ReadRegStr $0 HKLM "Software\MicroProse\Falcon\4.0" "basedir" StrCpy $1 "$0\campaign\save" StrCpy $2 "$0\Utilities\LxNormalFix.exe @${TNAME} @$0\Theaters\${TNAME}\terrdata" CreateDirs: SetOutPath $0 CreateDirectory "$0\Theaters\${TNAME}\campaign\vietnam1\" CreateDirectory "$0\Theaters\${TNAME}\campaign\vietnam2\" CreateDirectory "$0\Theaters\${TNAME}\terrdata\weather\" CreateDirectory "$0\Theaters\${TNAME}\objects\" ; new intelligent campaing copy files list CopyFiles /filesonly "$1\*.pri" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$1\*.txt" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$1\*.b" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$1\*.db" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$1\*.ia" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$1\*.dfs" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$1\*.dat" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$1\*.gbd" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$1\*.lst" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$1\default.*" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$1\strings.*" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$1\atc.ini" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$1\falcon4.aii" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$1\falcon4.rt" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$1\falcon4.tt" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$1\validac.*" "$0\Theaters\${TNAME}\campaign\vietnam1\" ; another campaign dir CopyFiles /filesonly "$0\Theaters\${TNAME}\campaign\vietnam1\*.*" "$0\Theaters\${TNAME}\campaign\vietnam2\" ; database objects (same dir for all versions) ; this needs to be recursively because RV has koreaobj subdir. CopyFiles "$0\terrdata\objects\*.*" "$0\Theaters\${TNAME}\objects\" CopyFiles "$0\terrdata\korea\weather\*.*" "$0\Theaters\${TNAME}\terrdata\weather\" ; unpack the theater files ; this is the subdir in the developer's PC that has the files for AF File /r "Theater_src_${TNAME}\*.*" ; common campaign dirs CopyFiles /filesonly "$0\Theaters\${TNAME}\campaign\common\*.*" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles /filesonly "$0\Theaters\${TNAME}\campaign\common\*.*" "$0\Theaters\${TNAME}\campaign\vietnam2\" ; beginning of falcon version DATABASE & UI ; database copy StrCmp $7 "OF" DataBaseOF StrCmp $7 "RV" DataBaseRV ; UI AF CopyFiles "$0\Theaters\${TNAME}\art\art-AF\*.*" "$0\Theaters\${TNAME}\art\art\" ; database AF CopyFiles "$0\Theaters\${TNAME}\objects\AF\*.*" "$0\Theaters\${TNAME}\objects\" CopyFiles "$0\Theaters\${TNAME}\campaign\common-AF\*.*" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles "$0\Theaters\${TNAME}\campaign\common-AF\*.*" "$0\Theaters\${TNAME}\campaign\vietnam2\" goto EndOfDataBaseCopy DataBaseOF: ; UI OF ; copy only one \art\ as we have the art1024 dir there too, heh hmm. CopyFiles "$0\Theaters\${TNAME}\art\art-OF\*.*" "$0\Theaters\${TNAME}\art\" ; database OF CopyFiles "$0\Theaters\${TNAME}\objects\OF\*.*" "$0\Theaters\${TNAME}\objects\" CopyFiles "$0\Theaters\${TNAME}\campaign\common-OF\*.*" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles "$0\Theaters\${TNAME}\campaign\common-OF\*.*" "$0\Theaters\${TNAME}\campaign\vietnam2\" goto EndOfDataBaseCopy DataBaseRV: ; UI RV CopyFiles "$0\Theaters\${TNAME}\art\art-RV\*.*" "$0\Theaters\${TNAME}\art\art\" ; database RV CopyFiles "$0\Theaters\${TNAME}\objects\RV\*.*" "$0\Theaters\${TNAME}\objects\" CopyFiles "$0\Theaters\${TNAME}\campaign\common-RV\*.*" "$0\Theaters\${TNAME}\campaign\vietnam1\" CopyFiles "$0\Theaters\${TNAME}\campaign\common-RV\*.*" "$0\Theaters\${TNAME}\campaign\vietnam2\" EndOfDataBaseCopy: RMDir /r "$0\Theaters\${TNAME}\objects\AF\" RMDir /r "$0\Theaters\${TNAME}\objects\RV\" RMDir /r "$0\Theaters\${TNAME}\objects\OF\" RMDir /r "$0\Theaters\${TNAME}\art\art-AF\" RMDir /r "$0\Theaters\${TNAME}\art\art-RV\" RMDir /r "$0\Theaters\${TNAME}\art\art-OF\" RMDir /r "$0\Theaters\${TNAME}\campaign\common-AF\" RMDir /r "$0\Theaters\${TNAME}\campaign\common-OF\" RMDir /r "$0\Theaters\${TNAME}\campaign\common-RV\" RMDir /r "$0\Theaters\${TNAME}\campaign\common\" ; end of falcon version DATABASE & UI StrCmp $8 "F4" F4curTheater TheaterAdmin StrCpy $9 "Unknown error before curTheater: $8." Goto Error F4curTheater: ; set current theater to new theater ; this reads the specified registry value into $2 for use later ReadRegStr $3 HKLM "Software\MicroProse\Falcon\4.0" "curTheater" ${registry::Write} "hklm\SOFTWARE\MicroProse\Falcon\4.0" "curTheater" "${TNAME}" "REG_SZ" $R0 ; if it is an OF install, skip straight to theater admin otherwise, do RV stuff StrCmp $7 "OF" TheaterAdmin ; this will be the area where we do stuff that it doesn't really matter which install it is TheaterAdmin: SetOutPath $0 ExecWait "$0\Utilities\lstupdate.exe $8 +Theaters\${TNAME}\${TNAME}1.tdf" ExecWait "$0\Utilities\lstupdate.exe $8 +Theaters\${TNAME}\${TNAME}2.tdf" ExecWait '$0\Utilities\SPTinstall.exe -auto "$0\Theaters\${TNAME}\terrdata"' ExecWait "$0\Utilities\LxNormalFix.exe $2" ; just compress textures if F4 then finish StrCmp $8 "AF" Finish ExecWait "$0\Utilities\SeasonSwitcher.exe -0" MessageBox MB_YESNO "Do you want to make the new theater the current one?" IDYES Finish IDNO OldReg OldReg: ${registry::Write} "hklm\SOFTWARE\MicroProse\Falcon\4.0" "curTheater" "$3" "REG_SZ" $R0 Goto Finish Error: Messagebox MB_OK $9 Finish: SectionEnd
Sorry for the long code, but thats the whole script we used to build Vietnam theater installer.
Check out our offical PMC Tactical Forum NSIS installer topic.
Homepage of NSIS.