diff --git a/build/resources/0ad.appdata.xml b/build/resources/0ad.appdata.xml
index 24606a1f79..affae80e13 100644
--- a/build/resources/0ad.appdata.xml
+++ b/build/resources/0ad.appdata.xml
@@ -76,4 +76,7 @@
none
none
+
+ application/x-pyromod+zip
+
diff --git a/build/resources/0ad.desktop b/build/resources/0ad.desktop
index 5527af1de8..2764d19b43 100644
--- a/build/resources/0ad.desktop
+++ b/build/resources/0ad.desktop
@@ -4,6 +4,7 @@ Name=0 A.D.
Exec=0ad
Icon=0ad
Terminal=false
+MimeType=application/x-pyromod+zip;
Type=Application
Categories=Game;StrategyGame;
Comment=A real-time strategy game of ancient warfare
diff --git a/build/resources/pyrogenesis.xml b/build/resources/pyrogenesis.xml
new file mode 100644
index 0000000000..12bb0ea6a5
--- /dev/null
+++ b/build/resources/pyrogenesis.xml
@@ -0,0 +1,10 @@
+
+
+
+ Pyrogenesis Modfile
+
+
+
+
+
+
diff --git a/source/tools/LICENSE.txt b/source/tools/LICENSE.txt
index ddde70f355..7ef9927979 100644
--- a/source/tools/LICENSE.txt
+++ b/source/tools/LICENSE.txt
@@ -9,29 +9,30 @@ in particular, let us know and we can try to clarify it.
GPL version 2 (or later) - see license_gpl-2.0.txt
autolog
- MIT
+ MIT
cmpgraph
MIT
dist
MIT
+ zlib/libpng (FileAssociation.nsh)
entdocs
MIT
entgraph
MIT
- libjpeg (jpeg.dll)
- libpng (png.dll)
- zlib (z.dll)
+ libjpeg (jpeg.dll)
+ libpng (png.dll)
+ zlib (z.dll)
entity
MIT
fontbuilder2
MIT
- unspecified (FontLoader.py)
+ unspecified (FontLoader.py)
IBM CPL (Packer.py)
i18n
diff --git a/source/tools/dist/0ad.nsi b/source/tools/dist/0ad.nsi
index 29d03c5a79..573da67906 100644
--- a/source/tools/dist/0ad.nsi
+++ b/source/tools/dist/0ad.nsi
@@ -6,8 +6,9 @@
!include "MUI2.nsh"
!include "LogicLib.nsh"
-
- ; Control whether to include source code (and component selection screen)
+ !include "FileAssociation.nsh"
+
+ ;Control whether to include source code (and component selection screen)
!define INCLUDE_SOURCE 0
;--------------------------------
@@ -115,7 +116,7 @@ Section "!Game and data files" GameSection
!if INCLUDE_SOURCE
File /r /x "public" /x "mod" /x "dev.cfg" "${CHECKOUTPATH}\binaries"
!else
- ; Exclude debug DLLs and related files
+ ;Exclude debug DLLs and related files
File /r /x "public" /x "mod" /x "dev.cfg" /x "*_d.dll" /x "enetd.dll" /x "FColladaD.dll" /x "gloox-1.0d.dll" /x "glooxwrapper_dbg.*" /x "libcurld.dll" /x "libpng16d.dll" /x "miniupnpcd.dll" /x "mozjs*-ps-debug.*" /x "msvc*d.dll" /x "zlib1d.dll" "${CHECKOUTPATH}\binaries"
!endif
@@ -159,6 +160,9 @@ Section "!Game and data files" GameSection
!insertmacro MUI_STARTMENU_WRITE_END
+ ;Register .pyromod file association
+ ${registerExtension} "$INSTDIR\binaries\system\pyrogenesis.exe" ".pyromod" "Pyrogenesis mod"
+
SectionEnd
!if INCLUDE_SOURCE
@@ -245,6 +249,9 @@ Section "Uninstall"
DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\0 A.D."
DeleteRegKey /ifempty SHCTX "Software\0 A.D."
+ ;Unregister .pyromod file association
+ ${unregisterExtension} ".pyromod" "Pyrogenesis mod"
+
SectionEnd
;--------------------------------
diff --git a/source/tools/dist/FileAssociation.nsh b/source/tools/dist/FileAssociation.nsh
new file mode 100644
index 0000000000..71a9162efc
--- /dev/null
+++ b/source/tools/dist/FileAssociation.nsh
@@ -0,0 +1,190 @@
+/*
+_____________________________________________________________________________
+
+ File Association
+_____________________________________________________________________________
+
+ Based on code taken from http://nsis.sourceforge.net/File_Association
+
+ Usage in script:
+ 1. !include "FileAssociation.nsh"
+ 2. [Section|Function]
+ ${FileAssociationFunction} "Param1" "Param2" "..." $var
+ [SectionEnd|FunctionEnd]
+
+ FileAssociationFunction=[RegisterExtension|UnRegisterExtension]
+
+_____________________________________________________________________________
+
+ ${RegisterExtension} "[executable]" "[extension]" "[description]"
+
+"[executable]" ; executable which opens the file format
+ ;
+"[extension]" ; extension, which represents the file format to open
+ ;
+"[description]" ; description for the extension. This will be display in Windows Explorer.
+ ;
+
+
+ ${UnRegisterExtension} "[extension]" "[description]"
+
+"[extension]" ; extension, which represents the file format to open
+ ;
+"[description]" ; description for the extension. This will be display in Windows Explorer.
+ ;
+
+_____________________________________________________________________________
+
+ Macros
+_____________________________________________________________________________
+
+ Change log window verbosity (default: 3=no script)
+
+ Example:
+ !include "FileAssociation.nsh"
+ !insertmacro RegisterExtension
+ ${FileAssociation_VERBOSE} 4 # all verbosity
+ !insertmacro UnRegisterExtension
+ ${FileAssociation_VERBOSE} 3 # no script
+*/
+
+
+!ifndef FileAssociation_INCLUDED
+!define FileAssociation_INCLUDED
+
+!include Util.nsh
+
+!verbose push
+!verbose 3
+!ifndef _FileAssociation_VERBOSE
+ !define _FileAssociation_VERBOSE 3
+!endif
+!verbose ${_FileAssociation_VERBOSE}
+!define FileAssociation_VERBOSE `!insertmacro FileAssociation_VERBOSE`
+!verbose pop
+
+!macro FileAssociation_VERBOSE _VERBOSE
+ !verbose push
+ !verbose 3
+ !undef _FileAssociation_VERBOSE
+ !define _FileAssociation_VERBOSE ${_VERBOSE}
+ !verbose pop
+!macroend
+
+
+
+!macro RegisterExtensionCall _EXECUTABLE _EXTENSION _DESCRIPTION
+ !verbose push
+ !verbose ${_FileAssociation_VERBOSE}
+ Push `${_DESCRIPTION}`
+ Push `${_EXTENSION}`
+ Push `${_EXECUTABLE}`
+ ${CallArtificialFunction} RegisterExtension_
+ !verbose pop
+!macroend
+
+!macro UnRegisterExtensionCall _EXTENSION _DESCRIPTION
+ !verbose push
+ !verbose ${_FileAssociation_VERBOSE}
+ Push `${_EXTENSION}`
+ Push `${_DESCRIPTION}`
+ ${CallArtificialFunction} UnRegisterExtension_
+ !verbose pop
+!macroend
+
+
+
+!define RegisterExtension `!insertmacro RegisterExtensionCall`
+!define un.RegisterExtension `!insertmacro RegisterExtensionCall`
+
+!macro RegisterExtension
+!macroend
+
+!macro un.RegisterExtension
+!macroend
+
+!macro RegisterExtension_
+ !verbose push
+ !verbose ${_FileAssociation_VERBOSE}
+
+ Exch $R2 ;exe
+ Exch
+ Exch $R1 ;ext
+ Exch
+ Exch 2
+ Exch $R0 ;desc
+ Exch 2
+ Push $0
+ Push $1
+
+ ReadRegStr $1 HKCR $R1 "" ; read current file association
+ StrCmp "$1" "" NoBackup ; is it empty
+ StrCmp "$1" "$R0" NoBackup ; is it our own
+ WriteRegStr HKCR $R1 "backup_val" "$1" ; backup current value
+NoBackup:
+ WriteRegStr HKCR $R1 "" "$R0" ; set our file association
+
+ ReadRegStr $0 HKCR $R0 ""
+ StrCmp $0 "" 0 Skip
+ WriteRegStr HKCR "$R0" "" "$R0"
+ WriteRegStr HKCR "$R0\shell" "" "open"
+ WriteRegStr HKCR "$R0\DefaultIcon" "" "$R2,0"
+Skip:
+ WriteRegStr HKCR "$R0\shell\open\command" "" '"$R2" "%1"'
+ WriteRegStr HKCR "$R0\shell\edit" "" "Edit $R0"
+ WriteRegStr HKCR "$R0\shell\edit\command" "" '"$R2" "%1"'
+
+ Pop $1
+ Pop $0
+ Pop $R2
+ Pop $R1
+ Pop $R0
+
+ !verbose pop
+!macroend
+
+
+
+!define UnRegisterExtension `!insertmacro UnRegisterExtensionCall`
+!define un.UnRegisterExtension `!insertmacro UnRegisterExtensionCall`
+
+!macro UnRegisterExtension
+!macroend
+
+!macro un.UnRegisterExtension
+!macroend
+
+!macro UnRegisterExtension_
+ !verbose push
+ !verbose ${_FileAssociation_VERBOSE}
+
+ Exch $R1 ;desc
+ Exch
+ Exch $R0 ;ext
+ Exch
+ Push $0
+ Push $1
+
+ ReadRegStr $1 HKCR $R0 ""
+ StrCmp $1 $R1 0 NoOwn ; only do this if we own it
+ ReadRegStr $1 HKCR $R0 "backup_val"
+ StrCmp $1 "" 0 Restore ; if backup="" then delete the whole key
+ DeleteRegKey HKCR $R0
+ Goto NoOwn
+
+Restore:
+ WriteRegStr HKCR $R0 "" $1
+ DeleteRegValue HKCR $R0 "backup_val"
+ DeleteRegKey HKCR $R1 ;Delete key with association name settings
+
+NoOwn:
+
+ Pop $1
+ Pop $0
+ Pop $R1
+ Pop $R0
+
+ !verbose pop
+!macroend
+
+!endif # !FileAssociation_INCLUDED