]> de.git.xonotic.org Git - voretournament/voretournament.git/commitdiff
Update fteqcc source
authorMirceaKitsune <sonichedgehog_hyperblast00@yahoo.com>
Sun, 18 Mar 2012 20:39:29 +0000 (22:39 +0200)
committerMirceaKitsune <sonichedgehog_hyperblast00@yahoo.com>
Sun, 18 Mar 2012 20:39:29 +0000 (22:39 +0200)
26 files changed:
misc/source/fteqcc-src/Makefile
misc/source/fteqcc-src/comprout.c
misc/source/fteqcc-src/dotnet2008/qcc.sln [new file with mode: 0644]
misc/source/fteqcc-src/dotnet2008/qcc.vcproj [new file with mode: 0644]
misc/source/fteqcc-src/dotnet2010/qcc.sln [new file with mode: 0644]
misc/source/fteqcc-src/dotnet2010/qcc.vcxproj [new file with mode: 0644]
misc/source/fteqcc-src/execloop.h
misc/source/fteqcc-src/gui.h
misc/source/fteqcc-src/initlib.c
misc/source/fteqcc-src/pr_comp.h
misc/source/fteqcc-src/pr_edict.c
misc/source/fteqcc-src/pr_exec.c
misc/source/fteqcc-src/pr_multi.c
misc/source/fteqcc-src/pr_x86.c
misc/source/fteqcc-src/progsint.h
misc/source/fteqcc-src/progslib.h
misc/source/fteqcc-src/qcc.dsp [deleted file]
misc/source/fteqcc-src/qcc.h
misc/source/fteqcc-src/qcc_cmdlib.c
misc/source/fteqcc-src/qcc_pr_comp.c
misc/source/fteqcc-src/qcc_pr_lex.c
misc/source/fteqcc-src/qccgui.c
misc/source/fteqcc-src/qccmain.c
misc/source/fteqcc-src/qcdecomp.c
misc/source/fteqcc-src/vc6/qcc.dsp [new file with mode: 0644]
misc/source/fteqcc-src/vc6/qcc.dsw [new file with mode: 0644]

index 40a721c6474c1d19182f4927701512c69a55b4ec..786d22e32dbc41ba53eacb86c67459496d5d643c 100644 (file)
@@ -6,7 +6,8 @@ WIN32GUI_OBJS=qccgui.o qccguistuff.o
 TUI_OBJS=qcctui.o
 LIB_OBJS=
 
-CC=gcc -Wall
+CC?=gcc
+CFLAGS?=-Wall
 
 all: qcc
 
index 2a2f96156d57a0892c88bbf5b88f55499fe09ebc..a2a7a3bd80340b9f1b722c280a88214b2329c383 100644 (file)
@@ -61,7 +61,7 @@ pbool PreCompile(void)
 
        qccClearHunk();
        strcpy(qcc_gamedir, "");
-       qcchunk = malloc(qcchunksize=256*1024*1024);
+       qcchunk = malloc(qcchunksize=128*1024*1024);
        while(!qcchunk && qcchunksize > 8*1024*1024)
        {
                qcchunksize /= 2;
diff --git a/misc/source/fteqcc-src/dotnet2008/qcc.sln b/misc/source/fteqcc-src/dotnet2008/qcc.sln
new file mode 100644 (file)
index 0000000..a50d9b3
--- /dev/null
@@ -0,0 +1,26 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 10.00\r
+# Visual Studio 2008\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qcc", "qcc.vcproj", "{B9F10DBD-C3E7-4312-B357-0FEFB360979A}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Win32 = Debug|Win32\r
+               GUIDebug|Win32 = GUIDebug|Win32\r
+               GUIRelease|Win32 = GUIRelease|Win32\r
+               Release|Win32 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.Debug|Win32.Build.0 = Debug|Win32\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.GUIDebug|Win32.ActiveCfg = GUIDebug|Win32\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.GUIDebug|Win32.Build.0 = GUIDebug|Win32\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.GUIRelease|Win32.ActiveCfg = GUIRelease|Win32\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.GUIRelease|Win32.Build.0 = GUIRelease|Win32\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.Release|Win32.ActiveCfg = Release|Win32\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.Release|Win32.Build.0 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/misc/source/fteqcc-src/dotnet2008/qcc.vcproj b/misc/source/fteqcc-src/dotnet2008/qcc.vcproj
new file mode 100644 (file)
index 0000000..040d9ea
--- /dev/null
@@ -0,0 +1,814 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="9.00"\r
+       Name="qcc"\r
+       ProjectGUID="{B9F10DBD-C3E7-4312-B357-0FEFB360979A}"\r
+       TargetFrameworkVersion="0"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\Debug"\r
+                       IntermediateDirectory=".\Debug"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\Debug/qcc.tlb"\r
+                               HeaderFileName=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="1"\r
+                               PrecompiledHeaderFile=".\Debug/qcc.pch"\r
+                               AssemblerListingLocation=".\Debug/"\r
+                               ObjectFile=".\Debug/"\r
+                               ProgramDataBaseFileName=".\Debug/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                               DebugInformationFormat="4"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="2057"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="../../libs/zlib.lib odbc32.lib odbccp32.lib"\r
+                               OutputFile="../../fteqcc_dbg.exe"\r
+                               LinkIncremental="2"\r
+                               SuppressStartupBanner="true"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile=".\Debug/fteqcc_dbg.pdb"\r
+                               SubSystem="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                               SuppressStartupBanner="true"\r
+                               OutputFile=".\Debug/qcc.bsc"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="GUIDebug|Win32"\r
+                       OutputDirectory=".\qcc___Win32_GUIDebug"\r
+                       IntermediateDirectory=".\qcc___Win32_GUIDebug"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\qcc___Win32_GUIDebug/qcc.tlb"\r
+                               HeaderFileName=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="1"\r
+                               PrecompiledHeaderFile=".\qcc___Win32_GUIDebug/qcc.pch"\r
+                               AssemblerListingLocation=".\qcc___Win32_GUIDebug/"\r
+                               ObjectFile=".\qcc___Win32_GUIDebug/"\r
+                               ProgramDataBaseFileName=".\qcc___Win32_GUIDebug/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                               DebugInformationFormat="4"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="2057"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="../../libs/zlib.lib odbc32.lib odbccp32.lib comctl32.lib"\r
+                               OutputFile="..\..\fteqcc.exe"\r
+                               LinkIncremental="2"\r
+                               SuppressStartupBanner="true"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile=".\qcc___Win32_GUIDebug/fteqcc.pdb"\r
+                               SubSystem="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                               SuppressStartupBanner="true"\r
+                               OutputFile=".\qcc___Win32_GUIDebug/qcc.bsc"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="GUIRelease|Win32"\r
+                       OutputDirectory=".\qcc___Win32_GUIRelease0"\r
+                       IntermediateDirectory=".\qcc___Win32_GUIRelease0"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\qcc___Win32_GUIRelease0/qcc.tlb"\r
+                               HeaderFileName=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               StringPooling="true"\r
+                               RuntimeLibrary="0"\r
+                               EnableFunctionLevelLinking="true"\r
+                               PrecompiledHeaderFile=".\qcc___Win32_GUIRelease0/qcc.pch"\r
+                               AssemblerListingLocation=".\qcc___Win32_GUIRelease0/"\r
+                               ObjectFile=".\qcc___Win32_GUIRelease0/"\r
+                               ProgramDataBaseFileName=".\qcc___Win32_GUIRelease0/"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="2057"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="../../libs/zlib.lib odbc32.lib odbccp32.lib comctl32.lib"\r
+                               OutputFile="../../fteqccgui.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="true"\r
+                               ProgramDatabaseFile=".\qcc___Win32_GUIRelease0/fteqccgui.pdb"\r
+                               SubSystem="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                               SuppressStartupBanner="true"\r
+                               OutputFile=".\qcc___Win32_GUIRelease0/qcc.bsc"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\Release"\r
+                       IntermediateDirectory=".\Release"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               TypeLibraryName=".\Release/qcc.tlb"\r
+                               HeaderFileName=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               StringPooling="true"\r
+                               RuntimeLibrary="0"\r
+                               EnableFunctionLevelLinking="true"\r
+                               PrecompiledHeaderFile=".\Release/qcc.pch"\r
+                               AssemblerListingLocation=".\Release/"\r
+                               ObjectFile=".\Release/"\r
+                               ProgramDataBaseFileName=".\Release/"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="2057"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="../../libs/zlib.lib odbc32.lib odbccp32.lib"\r
+                               OutputFile="../../fteqcc.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="true"\r
+                               ProgramDatabaseFile=".\Release/fteqcc.pdb"\r
+                               SubSystem="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                               SuppressStartupBanner="true"\r
+                               OutputFile=".\Release/qcc.bsc"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+                       >\r
+                       <File\r
+                               RelativePath="..\Comprout.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIDebug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIRelease|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\hash.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIDebug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIRelease|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\qcc_cmdlib.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIDebug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIRelease|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\qcc_gtk.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIDebug|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIRelease|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\qcc_pr_comp.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIDebug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIRelease|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\qcc_pr_lex.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIDebug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIRelease|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\qccgui.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIDebug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIRelease|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\qccguistuff.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIDebug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIRelease|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\QccMain.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIDebug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIRelease|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\qcctui.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIDebug|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIRelease|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\qcd_main.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIDebug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="GUIRelease|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl"\r
+                       >\r
+                       <File\r
+                               RelativePath="..\gui.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\pr_comp.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\qcc.h"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+                       >\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/misc/source/fteqcc-src/dotnet2010/qcc.sln b/misc/source/fteqcc-src/dotnet2010/qcc.sln
new file mode 100644 (file)
index 0000000..4d85f4a
--- /dev/null
@@ -0,0 +1,26 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 11.00\r
+# Visual Studio 2010\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qcc", "qcc.vcxproj", "{B9F10DBD-C3E7-4312-B357-0FEFB360979A}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Win32 = Debug|Win32\r
+               GUIDebug|Win32 = GUIDebug|Win32\r
+               GUIRelease|Win32 = GUIRelease|Win32\r
+               Release|Win32 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.Debug|Win32.Build.0 = Debug|Win32\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.GUIDebug|Win32.ActiveCfg = GUIDebug|Win32\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.GUIDebug|Win32.Build.0 = GUIDebug|Win32\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.GUIRelease|Win32.ActiveCfg = GUIRelease|Win32\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.GUIRelease|Win32.Build.0 = GUIRelease|Win32\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.Release|Win32.ActiveCfg = Release|Win32\r
+               {B9F10DBD-C3E7-4312-B357-0FEFB360979A}.Release|Win32.Build.0 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/misc/source/fteqcc-src/dotnet2010/qcc.vcxproj b/misc/source/fteqcc-src/dotnet2010/qcc.vcxproj
new file mode 100644 (file)
index 0000000..abcd564
--- /dev/null
@@ -0,0 +1,343 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="GUIDebug|Win32">\r
+      <Configuration>GUIDebug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="GUIRelease|Win32">\r
+      <Configuration>GUIRelease</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{B9F10DBD-C3E7-4312-B357-0FEFB360979A}</ProjectGuid>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <UseOfMfc>false</UseOfMfc>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup>\r
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">.\qcc___Win32_GUIDebug\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">.\qcc___Win32_GUIDebug\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">true</LinkIncremental>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">.\qcc___Win32_GUIRelease0\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">.\qcc___Win32_GUIRelease0\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">false</LinkIncremental>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'" />\r
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <Midl>\r
+      <TypeLibraryName>.\Debug/qcc.tlb</TypeLibraryName>\r
+      <HeaderFileName>\r
+      </HeaderFileName>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MinimalRebuild>true</MinimalRebuild>\r
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+      <PrecompiledHeaderOutputFile>.\Debug/qcc.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>.\Debug/</AssemblerListingLocation>\r
+      <ObjectFileName>.\Debug/</ObjectFileName>\r
+      <ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>\r
+      <BrowseInformation>true</BrowseInformation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <Culture>0x0809</Culture>\r
+    </ResourceCompile>\r
+    <Link>\r
+      <AdditionalDependencies>../../libs/zlib.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>../../fteqcc_dbg.exe</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>.\Debug/fteqcc_dbg.pdb</ProgramDatabaseFile>\r
+      <SubSystem>Console</SubSystem>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+    <Bscmake>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <OutputFile>.\Debug/qcc.bsc</OutputFile>\r
+    </Bscmake>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">\r
+    <Midl>\r
+      <TypeLibraryName>.\qcc___Win32_GUIDebug/qcc.tlb</TypeLibraryName>\r
+      <HeaderFileName>\r
+      </HeaderFileName>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <MinimalRebuild>true</MinimalRebuild>\r
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+      <PrecompiledHeaderOutputFile>.\qcc___Win32_GUIDebug/qcc.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>.\qcc___Win32_GUIDebug/</AssemblerListingLocation>\r
+      <ObjectFileName>.\qcc___Win32_GUIDebug/</ObjectFileName>\r
+      <ProgramDataBaseFileName>.\qcc___Win32_GUIDebug/</ProgramDataBaseFileName>\r
+      <BrowseInformation>true</BrowseInformation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <Culture>0x0809</Culture>\r
+    </ResourceCompile>\r
+    <Link>\r
+      <AdditionalDependencies>../../libs/zlib.lib;odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>..\..\fteqcc.exe</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <ProgramDatabaseFile>.\qcc___Win32_GUIDebug/fteqcc.pdb</ProgramDatabaseFile>\r
+      <SubSystem>Windows</SubSystem>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+    <Bscmake>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <OutputFile>.\qcc___Win32_GUIDebug/qcc.bsc</OutputFile>\r
+    </Bscmake>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">\r
+    <Midl>\r
+      <TypeLibraryName>.\qcc___Win32_GUIRelease0/qcc.tlb</TypeLibraryName>\r
+      <HeaderFileName>\r
+      </HeaderFileName>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeaderOutputFile>.\qcc___Win32_GUIRelease0/qcc.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>.\qcc___Win32_GUIRelease0/</AssemblerListingLocation>\r
+      <ObjectFileName>.\qcc___Win32_GUIRelease0/</ObjectFileName>\r
+      <ProgramDataBaseFileName>.\qcc___Win32_GUIRelease0/</ProgramDataBaseFileName>\r
+      <BrowseInformation>true</BrowseInformation>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <Culture>0x0809</Culture>\r
+    </ResourceCompile>\r
+    <Link>\r
+      <AdditionalDependencies>../../libs/zlib.lib;odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>../../fteqccgui.exe</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <ProgramDatabaseFile>.\qcc___Win32_GUIRelease0/fteqccgui.pdb</ProgramDatabaseFile>\r
+      <SubSystem>Windows</SubSystem>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+    <Bscmake>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <OutputFile>.\qcc___Win32_GUIRelease0/qcc.bsc</OutputFile>\r
+    </Bscmake>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <Midl>\r
+      <TypeLibraryName>.\Release/qcc.tlb</TypeLibraryName>\r
+      <HeaderFileName>\r
+      </HeaderFileName>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <PrecompiledHeaderOutputFile>.\Release/qcc.pch</PrecompiledHeaderOutputFile>\r
+      <AssemblerListingLocation>.\Release/</AssemblerListingLocation>\r
+      <ObjectFileName>.\Release/</ObjectFileName>\r
+      <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+    </ClCompile>\r
+    <ResourceCompile>\r
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <Culture>0x0809</Culture>\r
+    </ResourceCompile>\r
+    <Link>\r
+      <AdditionalDependencies>../../libs/zlib.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>../../fteqcc.exe</OutputFile>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <ProgramDatabaseFile>.\Release/fteqcc.pdb</ProgramDatabaseFile>\r
+      <SubSystem>Console</SubSystem>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+      <DataExecutionPrevention>\r
+      </DataExecutionPrevention>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+    </Link>\r
+    <Bscmake>\r
+      <SuppressStartupBanner>true</SuppressStartupBanner>\r
+      <OutputFile>.\Release/qcc.bsc</OutputFile>\r
+    </Bscmake>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\Comprout.c">\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+    </ClCompile>\r
+    <ClCompile Include="..\hash.c">\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+    </ClCompile>\r
+    <ClCompile Include="..\qcc_cmdlib.c">\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+    </ClCompile>\r
+    <ClCompile Include="..\qcc_gtk.c">\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">true</ExcludedFromBuild>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">true</ExcludedFromBuild>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+    </ClCompile>\r
+    <ClCompile Include="..\qcc_pr_comp.c">\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+    </ClCompile>\r
+    <ClCompile Include="..\qcc_pr_lex.c">\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+    </ClCompile>\r
+    <ClCompile Include="..\qccgui.c">\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+    </ClCompile>\r
+    <ClCompile Include="..\qccguistuff.c">\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+    </ClCompile>\r
+    <ClCompile Include="..\QccMain.c">\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+    </ClCompile>\r
+    <ClCompile Include="..\qcctui.c">\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">true</ExcludedFromBuild>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">true</ExcludedFromBuild>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+    </ClCompile>\r
+    <ClCompile Include="..\qcd_main.c">\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIDebug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='GUIRelease|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="..\gui.h" />\r
+    <ClInclude Include="..\pr_comp.h" />\r
+    <ClInclude Include="..\qcc.h" />\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
index 08d0ce9fd55a4bde5e18ccf80efbf902856bb080..f6aa4eb5db809a400362fa37f059e71f7adffd5b 100644 (file)
 #error Bad cont size
 #endif
 
+#ifdef DEBUGABLE
+#define OPCODE (st->op & ~0x8000)
+#else
+#define OPCODE (st->op)
+#endif
+
 #define ENGINEPOINTER(p) ((char*)(p) - progfuncs->stringtable)
 #define QCPOINTER(p) (eval_t *)(p->_int+progfuncs->stringtable)
 #define QCPOINTERM(p) (eval_t *)((p)+progfuncs->stringtable)
@@ -49,11 +55,10 @@ cont:       //last statement may have been a breakpoint
        st = pr_statements + s;
 
 reeval:
-       switch (st->op & ~0x8000)
 #else
        st++;
-       switch (st->op)
 #endif
+       switch (OPCODE)
        {
        case OP_ADD_F:
                OPC->_float = OPA->_float + OPB->_float;
@@ -292,7 +297,7 @@ reeval:
                if ((unsigned int)OPB->_int >= addressableused)
                {
                        pr_xstatement = st-pr_statements;
-                       PR_RunError (progfuncs, "bad pointer write in %s", progfuncs->stringtable + pr_xfunction->s_name);
+                       PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
                }
                ptr = QCPOINTER(OPB);
                ptr->_float = (float)OPA->_int;
@@ -301,38 +306,45 @@ reeval:
                if ((unsigned int)OPB->_int >= addressableused)
                {
                        pr_xstatement = st-pr_statements;
-                       PR_RunError (progfuncs, "bad pointer write in %s", progfuncs->stringtable + pr_xfunction->s_name);
+                       PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
                }
                ptr = QCPOINTER(OPB);
                ptr->_int = (int)OPA->_float;
                break;
        case OP_STOREP_I:
+       case OP_GSTOREP_I:
                if ((unsigned int)OPB->_int >= addressableused)
                {
                        pr_xstatement = st-pr_statements;
-                       PR_RunError (progfuncs, "bad pointer write in %s", progfuncs->stringtable + pr_xfunction->s_name);
+                       PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
                }
                ptr = QCPOINTER(OPB);
                ptr->_int = OPA->_int;
                break;
        case OP_STOREP_F:
+       case OP_GSTOREP_F:
        case OP_STOREP_ENT:
+       case OP_GSTOREP_ENT:
        case OP_STOREP_FLD:             // integers
+       case OP_GSTOREP_FLD:
        case OP_STOREP_S:
+       case OP_GSTOREP_S:
        case OP_STOREP_FNC:             // pointers
+       case OP_GSTOREP_FNC:
                if ((unsigned int)OPB->_int >= addressableused)
                {
                        pr_xstatement = st-pr_statements;
-                       PR_RunError (progfuncs, "bad pointer write in %s", progfuncs->stringtable + pr_xfunction->s_name);
+                       PR_RunError (progfuncs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(progfuncs, pr_xfunction->s_name), OPB->_int, addressableused);
                }
                ptr = QCPOINTER(OPB);
                ptr->_int = OPA->_int;
                break;
        case OP_STOREP_V:
+       case OP_GSTOREP_V:
                if ((unsigned int)OPB->_int >= addressableused)
                {
                        pr_xstatement = st-pr_statements;
-                       PR_RunError (progfuncs, "bad pointer write in %s", progfuncs->stringtable + pr_xfunction->s_name);
+                       PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
                }
                ptr = QCPOINTER(OPB);
                ptr->_vector[0] = OPA->_vector[0];
@@ -344,7 +356,7 @@ reeval:
                if ((unsigned int)OPB->_int >= addressableused)
                {
                        pr_xstatement = st-pr_statements;
-                       PR_RunError (progfuncs, "bad pointer write in %s", progfuncs->stringtable + pr_xfunction->s_name);
+                       PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
                }
                ptr = QCPOINTER(OPB);
                *(unsigned char *)ptr = (char)OPA->_float;
@@ -353,7 +365,7 @@ reeval:
        case OP_MULSTORE_F: // f *= f
                OPB->_float *= OPA->_float;
                break;
-       case OP_MULSTORE_V: // v *= f
+       case OP_MULSTORE_VF: // v *= f
                OPB->_vector[0] *= OPA->_float;
                OPB->_vector[1] *= OPA->_float;
                OPB->_vector[2] *= OPA->_float;
@@ -362,12 +374,17 @@ reeval:
                if ((unsigned int)OPB->_int >= addressableused)
                {
                        pr_xstatement = st-pr_statements;
-                       PR_RunError (progfuncs, "bad pointer write in %s", progfuncs->stringtable + pr_xfunction->s_name);
+                       PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
                }
                ptr = QCPOINTER(OPB);
                OPC->_float = (ptr->_float *= OPA->_float);
                break;
-       case OP_MULSTOREP_V: // e.v *= f
+       case OP_MULSTOREP_VF: // e.v *= f
+               if ((unsigned int)OPB->_int >= addressableused)
+               {
+                       pr_xstatement = st-pr_statements;
+                       PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
+               }
                ptr = QCPOINTER(OPB);
                OPC->_vector[0] = (ptr->_vector[0] *= OPA->_float);
                OPC->_vector[0] = (ptr->_vector[1] *= OPA->_float);
@@ -378,6 +395,11 @@ reeval:
                OPB->_float /= OPA->_float;
                break;
        case OP_DIVSTOREP_F: // e.f /= f
+               if ((unsigned int)OPB->_int >= addressableused)
+               {
+                       pr_xstatement = st-pr_statements;
+                       PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
+               }
                ptr = QCPOINTER(OPB);
                OPC->_float = (ptr->_float /= OPA->_float);
                break;
@@ -391,10 +413,20 @@ reeval:
                OPB->_vector[2] += OPA->_vector[2];
                break;
        case OP_ADDSTOREP_F: // e.f += f
+               if ((unsigned int)OPB->_int >= addressableused)
+               {
+                       pr_xstatement = st-pr_statements;
+                       PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
+               }
                ptr = QCPOINTER(OPB);
                OPC->_float = (ptr->_float += OPA->_float);
                break;
        case OP_ADDSTOREP_V: // e.v += v
+               if ((unsigned int)OPB->_int >= addressableused)
+               {
+                       pr_xstatement = st-pr_statements;
+                       PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
+               }
                ptr = QCPOINTER(OPB);
                OPC->_vector[0] = (ptr->_vector[0] += OPA->_vector[0]);
                OPC->_vector[1] = (ptr->_vector[1] += OPA->_vector[1]);
@@ -410,10 +442,20 @@ reeval:
                OPB->_vector[2] -= OPA->_vector[2];
                break;
        case OP_SUBSTOREP_F: // e.f -= f
+               if ((unsigned int)OPB->_int >= addressableused)
+               {
+                       pr_xstatement = st-pr_statements;
+                       PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
+               }
                ptr = QCPOINTER(OPB);
                OPC->_float = (ptr->_float -= OPA->_float);
                break;
        case OP_SUBSTOREP_V: // e.v -= v
+               if ((unsigned int)OPB->_int >= addressableused)
+               {
+                       pr_xstatement = st-pr_statements;
+                       PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
+               }
                ptr = QCPOINTER(OPB);
                OPC->_vector[0] = (ptr->_vector[0] -= OPA->_vector[0]);
                OPC->_vector[1] = (ptr->_vector[1] -= OPA->_vector[1]);
@@ -427,7 +469,7 @@ reeval:
                {
 #ifndef DEBUGABLE
                        pr_trace++;
-                       printf("OP_ADDRESS references invalid entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
+                       printf("OP_ADDRESS references invalid entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
                        st--;
                        goto cont;
 #else
@@ -444,7 +486,7 @@ reeval:
 #ifndef DEBUGABLE
                        //boot it over to the debugger
                        pr_trace++;
-                       printf("assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
+                       printf("assignment to read-only entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
                        st--;
                        goto cont;
 #else
@@ -453,7 +495,7 @@ reeval:
                                fdef_t *f;
                                d16 = ED_GlobalAtOfs16(progfuncs, st->a);
                                f = ED_FieldAtOfs(progfuncs, OPB->_int + progfuncs->fieldadjust);
-                               PR_RunError (progfuncs, "assignment to read-only entity in %s (%s.%s)", PR_StringToNative(progfuncs, pr_xfunction->s_name), PR_StringToNative(progfuncs, d16->s_name), f?f->name:NULL);
+                               printf ("assignment to read-only entity in %s (%s.%s)\n", PR_StringToNative(progfuncs, pr_xfunction->s_name), d16?PR_StringToNative(progfuncs, d16->s_name):NULL, f?f->name:NULL);
                        }
 #endif
                }
@@ -462,7 +504,7 @@ reeval:
 //             if (ed->isfree)
 //             {
 //                     pr_xstatement = st-pr_statements;
-//                     PR_RunError (progfuncs, "assignment to free entitiy in %s", progfuncs->stringtable + pr_xfunction->s_name);
+//                     PR_RunError (progfuncs, "assignment to free entitiy in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
 //             }
                OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust));
                break;
@@ -475,7 +517,7 @@ reeval:
        case OP_LOAD_S:
        case OP_LOAD_FNC:
                if ((unsigned)OPA->edict >= (unsigned)maxedicts)
-                       PR_RunError (progfuncs, "OP_LOAD references invalid entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
+                       PR_RunError (progfuncs, "OP_LOAD references invalid entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
                ed = PROG_TO_EDICT(progfuncs, OPA->edict);
 #ifdef PARANOID
                NUM_FOR_EDICT(ed);              // make sure it's in range
@@ -486,7 +528,7 @@ reeval:
 
        case OP_LOAD_V:
                if ((unsigned)OPA->edict >= (unsigned)maxedicts)
-                       PR_RunError (progfuncs, "OP_LOAD_V references invalid entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
+                       PR_RunError (progfuncs, "OP_LOAD_V references invalid entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
                ed = PROG_TO_EDICT(progfuncs, OPA->edict);
 #ifdef PARANOID
                NUM_FOR_EDICT(ed);              // make sure it's in range
@@ -567,15 +609,14 @@ reeval:
                RUNAWAYCHECK();
                pr_xstatement = st-pr_statements;
 
-
-               if (st->op > OP_CALL8)
-                       pr_argc = st->op - (OP_CALL1H-1);
+               if (OPCODE > OP_CALL8)
+                       pr_argc = OPCODE - (OP_CALL1H-1);
                else
-                       pr_argc = st->op - OP_CALL0;
+                       pr_argc = OPCODE - OP_CALL0;
                fnum = OPA->function;
                if ((fnum & ~0xff000000)==0)
                {
-                       PR_RunError(progfuncs, "NULL function from qc (%s).\n", progfuncs->stringtable + pr_xfunction->s_name);
+                       PR_RunError(progfuncs, "NULL function from qc (%s).\n", PR_StringToNative(progfuncs, pr_xfunction->s_name));
 #ifndef DEBUGABLE
                        goto cont;
 #endif
@@ -588,24 +629,24 @@ reeval:
                progfuncs->save_ents(progfuncs, buffer, &size, 0);
 }*/
 
-
-               p=pr_typecurrent;
+               {
+               int callerprogs=pr_typecurrent;
 //about to switch. needs caching.
 
                //if it's an external call, switch now (before any function pointers are used)
-               PR_MoveParms(progfuncs, (fnum & 0xff000000)>>24, p);
+               PR_MoveParms(progfuncs, (fnum & 0xff000000)>>24, callerprogs);
                PR_SwitchProgs(progfuncs, (fnum & 0xff000000)>>24);
 
                newf = &pr_functions[fnum & ~0xff000000];
 
                if (newf->first_statement < 0)
                {       // negative statements are built in functions
-
-if (pr_typecurrent != 0)
-{
-       PR_MoveParms(progfuncs, 0, pr_typecurrent);
-       PR_SwitchProgs(progfuncs, 0);
-}
+                       /*calling a builtin in another progs may affect that other progs' globals instead, is the theory anyway, so args and stuff need to move over*/
+                       if (pr_typecurrent != 0)
+                       {
+                               PR_MoveParms(progfuncs, 0, pr_typecurrent);
+                               PR_SwitchProgs(progfuncs, 0);
+                       }
                        i = -newf->first_statement;
 //                     p = pr_typecurrent;
                        progfuncs->lastcalledbuiltinnumber = i;
@@ -633,9 +674,9 @@ if (pr_typecurrent != 0)
                                else
                                        current_progstate->builtins [i] (progfuncs, (struct globalvars_s *)current_progstate->globals);
                        }
-                       PR_MoveParms(progfuncs, p, pr_typecurrent);
+                       PR_MoveParms(progfuncs, callerprogs, pr_typecurrent);
 //                     memcpy(&pr_progstate[p].globals[OFS_RETURN], &current_progstate->globals[OFS_RETURN], sizeof(vec3_t));
-                       PR_SwitchProgs(progfuncs, (progsnum_t)p);
+                       PR_SwitchProgs(progfuncs, (progsnum_t)callerprogs);
 
 //#ifndef DEBUGABLE    //decide weather non debugger wants to start debugging.
                        s = st-pr_statements;
@@ -645,8 +686,9 @@ if (pr_typecurrent != 0)
                }
 //             PR_MoveParms((OPA->function & 0xff000000)>>24, pr_typecurrent);
 //             PR_SwitchProgs((OPA->function & 0xff000000)>>24);
-               s = PR_EnterFunction (progfuncs, newf, p);
+               s = PR_EnterFunction (progfuncs, newf, callerprogs);
                st = &pr_statements[s];
+               }
                
                goto restart;
 //             break;
@@ -743,7 +785,7 @@ if (pr_typecurrent != 0)
 
        //array/structure reading/writing.
        case OP_GLOBALADDRESS:
-               OPC->_int = ENGINEPOINTER(&OPA->_int + OPB->_int);
+               OPC->_int = ENGINEPOINTER(&OPA->_int + OPB->_int); /*pointer arithmatic*/
                break;
        case OP_POINTER_ADD:    //pointer to 32 bit (remember to *3 for vectors)
                OPC->_int = OPA->_int + OPB->_int*4;
@@ -755,7 +797,7 @@ if (pr_typecurrent != 0)
        case OP_LOADA_ENT:
        case OP_LOADA_S:
        case OP_LOADA_FNC:
-               ptr = (eval_t *)(&OPA->_int + OPB->_int);
+               ptr = (eval_t *)(&OPA->_int + OPB->_int); /*pointer arithmatic*/
                OPC->_int = ptr->_int;
                break;
 
@@ -775,7 +817,20 @@ if (pr_typecurrent != 0)
                OPC->_int = OPA->_int - OPB->_int;
                break;
        case OP_LOADP_C:        //load character from a string
-               ptr = QCPOINTERM(OPA->_int + (int)OPB->_float);
+               i = (unsigned int)OPA->_int + (unsigned int)OPB->_float;
+               if ((unsigned int)i >= addressableused)
+               {
+                       i = (unsigned int)OPB->_float;
+                       ptr = (eval_t*)PR_StringToNative(progfuncs, OPA->_int);
+                       if ((size_t)i > strlen((char*)ptr))
+                       {
+                               pr_xstatement = st-pr_statements;
+                               PR_RunError (progfuncs, "bad pointer read in %s (%i bytes into %s)", PR_StringToNative(progfuncs, pr_xfunction->s_name), i, ptr);
+                       }
+                       ptr = (eval_t*)((char*)ptr + i);
+               }
+               else 
+                       ptr = QCPOINTERM(i);
                OPC->_float = *(unsigned char *)ptr;
                break;
        case OP_LOADP_I:
@@ -784,12 +839,24 @@ if (pr_typecurrent != 0)
        case OP_LOADP_ENT:
        case OP_LOADP_S:
        case OP_LOADP_FNC:
-               ptr = QCPOINTERM(OPA->_int + OPB->_int);
+               i = OPA->_int + OPB->_int*4;
+               if ((unsigned int)i >= addressableused)
+               {
+                       pr_xstatement = st-pr_statements;
+                       PR_RunError (progfuncs, "bad pointer read in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
+               }
+               ptr = QCPOINTERM(OPA->_int + OPB->_int*4);
                OPC->_int = ptr->_int;
                break;
 
        case OP_LOADP_V:
-               ptr = QCPOINTERM(OPA->_int + OPB->_int);
+               i = OPA->_int + OPB->_int*4;
+               if ((unsigned int)i >= addressableused)
+               {
+                       pr_xstatement = st-pr_statements;
+                       PR_RunError (progfuncs, "bad pointer read in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
+               }
+               ptr = QCPOINTERM(i);
                OPC->_vector[0] = ptr->_vector[0];
                OPC->_vector[1] = ptr->_vector[1];
                OPC->_vector[2] = ptr->_vector[2];
@@ -813,7 +880,7 @@ if (pr_typecurrent != 0)
                i = (int)OPB->_float;
                if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
                {
-                       PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
+                       PR_RunError(progfuncs, "array index out of bounds: %s[%d] (max %d)", PR_GlobalStringNoContents(progfuncs, st->a), i, ((eval_t *)&glob[st->a-1])->_int);
                }
                t = (eval_t *)&pr_globals[(uofs)st->a + i];
                OPC->_int = t->_int;
@@ -847,6 +914,11 @@ if (pr_typecurrent != 0)
                OPB->_float = (float)((int)OPB->_float | (int)OPA->_float);
                break;
        case OP_BITSETP: // .b (+) a
+               if ((unsigned int)OPB->_int >= addressableused)
+               {
+                       pr_xstatement = st-pr_statements;
+                       PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
+               }
                ptr = QCPOINTER(OPB);
                ptr->_float = (float)((int)ptr->_float | (int)OPA->_float);
                break;
@@ -854,49 +926,54 @@ if (pr_typecurrent != 0)
                OPB->_float = (float)((int)OPB->_float & ~((int)OPA->_float));
                break;
        case OP_BITCLRP: // .b (-) a
+               if ((unsigned int)OPB->_int >= addressableused)
+               {
+                       pr_xstatement = st-pr_statements;
+                       PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
+               }
                ptr = QCPOINTER(OPB);
                ptr->_float = (float)((int)ptr->_float & ~((int)OPA->_float));
                break;
 
        case OP_RAND0:
-               G_FLOAT(OFS_RETURN) = (rand()&0x7fff)/((float)0x7fff);
+               OPC->_float = (rand()&0x7fff)/((float)0x7fff);
                break;
        case OP_RAND1:
-               G_FLOAT(OFS_RETURN) = (rand()&0x7fff)/((float)0x7fff)*OPA->_float;
+               OPC->_float = (rand()&0x7fff)/((float)0x7fff)*OPA->_float;
                break;
        case OP_RAND2:
                if(OPA->_float < OPB->_float)
                {
-                       G_FLOAT(OFS_RETURN) = OPA->_float+((rand()&0x7fff)/((float)0x7fff)
+                       OPC->_float = OPA->_float+((rand()&0x7fff)/((float)0x7fff)
                                *(OPB->_float-OPA->_float));
                }
                else
                {
-                       G_FLOAT(OFS_RETURN) = OPB->_float+((rand()&0x7fff)/((float)0x7fff)
+                       OPC->_float = OPB->_float+((rand()&0x7fff)/((float)0x7fff)
                                *(OPA->_float-OPB->_float));
                }
                break;
        case OP_RANDV0:
-               G_FLOAT(OFS_RETURN+0) = (rand()&0x7fff)/((float)0x7fff);
-               G_FLOAT(OFS_RETURN+1) = (rand()&0x7fff)/((float)0x7fff);
-               G_FLOAT(OFS_RETURN+2) = (rand()&0x7fff)/((float)0x7fff);
+               OPC->_vector[0] = (rand()&0x7fff)/((float)0x7fff);
+               OPC->_vector[1] = (rand()&0x7fff)/((float)0x7fff);
+               OPC->_vector[2] = (rand()&0x7fff)/((float)0x7fff);
                break;
        case OP_RANDV1:
-               G_FLOAT(OFS_RETURN+0) = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[0];
-               G_FLOAT(OFS_RETURN+1) = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[1];
-               G_FLOAT(OFS_RETURN+2) = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[2];
+               OPC->_vector[0] = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[0];
+               OPC->_vector[1] = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[1];
+               OPC->_vector[2] = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[2];
                break;
        case OP_RANDV2:
                for(i = 0; i < 3; i++)
                {
                        if(OPA->_vector[i] < OPB->_vector[i])
                        {
-                               G_FLOAT(OFS_RETURN+i) = OPA->_vector[i]+((rand()&0x7fff)/((float)0x7fff)
+                               OPC->_vector[i] = OPA->_vector[i]+((rand()&0x7fff)/((float)0x7fff)
                                        *(OPB->_vector[i]-OPA->_vector[i]));
                        }
                        else
                        {
-                               G_FLOAT(OFS_RETURN+i) = OPB->_vector[i]+(rand()*(1.0f/RAND_MAX)
+                               OPC->_vector[i] = OPB->_vector[i]+(rand()*(1.0f/RAND_MAX)
                                        *(OPA->_vector[i]-OPB->_vector[i]));
                        }
                }
@@ -909,7 +986,7 @@ if (pr_typecurrent != 0)
        case OP_SWITCH_E:
        case OP_SWITCH_FNC:
                swtch = OPA;
-               swtchtype = st->op;
+               swtchtype = OPCODE;
                RUNAWAYCHECK();
                st += (sofs)st->b - 1;  // offset the st++
                break;
@@ -1050,13 +1127,6 @@ if (pr_typecurrent != 0)
                OPC->_int = (OPA->_float != OPB->_int);
                break;
 
-       case OP_GSTOREP_I:
-       case OP_GSTOREP_F:
-       case OP_GSTOREP_ENT:
-       case OP_GSTOREP_FLD:            // integers
-       case OP_GSTOREP_S:
-       case OP_GSTOREP_FNC:            // pointers
-       case OP_GSTOREP_V:
        case OP_GADDRESS:
        case OP_GLOAD_I:
        case OP_GLOAD_F:
@@ -1072,7 +1142,7 @@ if (pr_typecurrent != 0)
                if ((unsigned int)OPA->_int < (unsigned int)st->c || (unsigned int)OPA->_int >= (unsigned int)st->b)
                {
                        pr_xstatement = st-pr_statements;
-                       PR_RunError(progfuncs, "Progs boundcheck failed. Value is %i.", OPA->_int);
+                       PR_RunError(progfuncs, "Progs boundcheck failed. Value is %i. Must be between %u and %u", OPA->_int, st->c, st->b);
                }
                break;
 /*     case OP_PUSH:
@@ -1100,7 +1170,7 @@ if (pr_typecurrent != 0)
                {
                        pr_xstatement = s = st-pr_statements;
 
-                       printf("Break point hit in %s.\n", pr_xfunction->s_name+progfuncs->stringtable);
+                       printf("Break point hit in %s.\n", PR_StringToNative(progfuncs, pr_xfunction->s_name));
                        if (pr_trace<1)
                                pr_trace=1;     //this is what it's for
 
@@ -1124,6 +1194,7 @@ if (pr_typecurrent != 0)
 #undef dstatement_t
 #undef sofs
 #undef uofs
+#undef OPCODE
 
 #undef ENGINEPOINTER
 #undef QCPOINTER
index 66ad9c56cfdd869933785a1ff6753689d320419d..341aedb409bf8b31f940bb1a72133dc5d37a2294 100644 (file)
@@ -4,9 +4,9 @@ void EditFile(char *name, int line);
 void GUI_SetDefaultOpts(void);
 int GUI_BuildParms(char *args, char **argv);
 
-unsigned char *QCC_ReadFile (char *fname, void *buffer, int len);
-int QCC_FileSize (char *fname);
-pbool QCC_WriteFile (char *name, void *data, int len);
+unsigned char *QCC_ReadFile (const char *fname, void *buffer, int len);
+int QCC_FileSize (const char *fname);
+pbool QCC_WriteFile (const char *name, void *data, int len);
 void GUI_DialogPrint(char *title, char *text);
 
 extern char parameters[16384];
index 8ee0f99a2cef5f18de5767ae943304be93178766..e630395a4f155eed9e9464e2e31725d49f7da63c 100644 (file)
@@ -41,6 +41,38 @@ void PRHunkFree(progfuncs_t *progfuncs, int mark)
        return;
 }
 
+/*if we ran out of memory, the vm can allocate a new block, but doing so requires fixing up all sorts of pointers*/
+void PRAddressableRelocate(progfuncs_t *progfuncs, char *oldb, char *newb, int oldlen)
+{
+       unsigned int i;
+       edictrun_t *e;
+       for (i=0 ; i<maxedicts; i++)
+       {
+               e = (edictrun_t *)(prinst->edicttable[i]);
+               if (e && (char*)e->fields >= oldb && (char*)e->fields < oldb+oldlen)
+                       e->fields = ((char*)e->fields - oldb) + newb;
+       }
+
+       if (progfuncs->stringtable >= oldb && progfuncs->stringtable < oldb+oldlen)
+               progfuncs->stringtable = (progfuncs->stringtable - oldb) + newb;
+
+       for (i=0; i < maxprogs; i++)
+       {
+               if ((char*)prinst->progstate[i].globals >= oldb && (char*)prinst->progstate[i].globals < oldb+oldlen)
+                       prinst->progstate[i].globals = (float*)(((char*)prinst->progstate[i].globals - oldb) + newb);
+               if (prinst->progstate[i].strings >= oldb && prinst->progstate[i].strings < oldb+oldlen)
+                       prinst->progstate[i].strings = (prinst->progstate[i].strings - oldb) + newb;
+       }
+
+       for (i = 0; i < numfields; i++)
+       {
+               if (field[i].name >= oldb && field[i].name < oldb+oldlen)
+                       field[i].name = (field[i].name - oldb) + newb;
+       }
+
+       externs->addressablerelocated(progfuncs, oldb, newb, oldlen);
+}
+
 //for 64bit systems. :)
 //addressable memory is memory available to the vm itself for writing.
 //once allocated, it cannot be freed for the lifetime of the VM.
@@ -48,7 +80,46 @@ void *PRAddressableAlloc(progfuncs_t *progfuncs, int ammount)
 {
        ammount = (ammount + 4)&~3;     //round up to 4
        if (addressableused + ammount > addressablesize)
-               Sys_Error("Not enough addressable memory for progs VM");
+       {
+               /*only do this if the caller states that it can cope with addressable-block relocations/resizes*/
+               if (externs->addressablerelocated)
+               {
+#ifdef _WIN32
+                       char *newblock;
+               #if 0//def _DEBUG
+                       int oldtot = addressablesize;
+               #endif
+                       int newsize = (addressableused + ammount + 4096) & ~(4096-1);
+                       newblock = VirtualAlloc (NULL, addressablesize, MEM_RESERVE, PAGE_NOACCESS);
+                       if (newblock)
+                       {
+                               VirtualAlloc (newblock, addressableused, MEM_COMMIT, PAGE_READWRITE);
+                               memcpy(newblock, addressablehunk, addressableused);
+               #if 0//def _DEBUG
+                               VirtualAlloc (addressablehunk, oldtot, MEM_RESERVE, PAGE_NOACCESS);
+               #else
+                               VirtualFree (addressablehunk, 0, MEM_RELEASE);
+               #endif
+                               PRAddressableRelocate(progfuncs, addressablehunk, newblock, addressableused);
+                               addressablehunk = newblock;
+                               addressablesize = newsize;
+                       }
+#else
+                       char *newblock;
+                       int newsize = (addressableused + ammount + 1024*1024) & ~(1024*1024-1);
+                       newblock = realloc(newblock, addressablesize);
+                       if (newblock)
+                       {
+                               PRAddressableRelocate(progfuncs, addressablehunk, newblock, addressableused);
+                               addressablehunk = newblock;
+                               addressablesize = newsize;
+                       }
+#endif
+               }
+
+               if (addressableused + ammount > addressablesize)
+                       Sys_Error("Not enough addressable memory for progs VM");
+       }
 
        addressableused += ammount;
 
@@ -69,12 +140,17 @@ void PRAddressableFlush(progfuncs_t *progfuncs, int totalammount)
 //             return;
        }
 
-       if (addressablehunk)
 #ifdef _WIN32
-       VirtualFree(addressablehunk, 0, MEM_RELEASE);   //doesn't this look complicated? :p
-       addressablehunk = VirtualAlloc (NULL, totalammount, MEM_RESERVE, PAGE_NOACCESS);
+       if (addressablehunk && addressablesize != totalammount)
+       {
+               VirtualFree(addressablehunk, 0, MEM_RELEASE);   //doesn't this look complicated? :p
+               addressablehunk = NULL;
+       }
+       if (!addressablehunk)
+               addressablehunk = VirtualAlloc (addressablehunk, totalammount, MEM_RESERVE, PAGE_NOACCESS);
 #else
-       free(addressablehunk);
+       if (addressablehunk)
+               free(addressablehunk);
        addressablehunk = malloc(totalammount); //linux will allocate-on-use anyway, which is handy.
 //     memset(addressablehunk, 0xff, totalammount);
 #endif
@@ -160,7 +236,10 @@ struct globalvars_s *PR_globals (progfuncs_t *progfuncs, progsnum_t pnum)
        if (pnum < 0)
        {
                if (!current_progstate)
-                       return NULL;    //err.. you've not loaded one yet.
+               {
+                       static float fallback[RESERVED_OFS];
+                       return (struct globalvars_s *)fallback; //err.. you've not loaded one yet.
+               }
                return (struct globalvars_s *)current_progstate->globals;
        }
        return (struct globalvars_s *)pr_progstate[pnum].globals;
@@ -426,8 +505,8 @@ string_t PR_StringToProgs                   (progfuncs_t *progfuncs, char *str)
        if (!str)
                return 0;
 
-//     if (str-progfuncs->stringtable < progfuncs->stringtablesize)
-//             return str - progfuncs->stringtable;
+       if (str >= progfuncs->stringtable && str < progfuncs->stringtable + addressableused)
+               return str - progfuncs->stringtable;
 
        for (i = prinst->numallocedstrings-1; i >= 0; i--)
        {
@@ -507,6 +586,8 @@ char *ASMCALL PR_StringToNative                             (progfuncs_t *progfuncs, string_t str)
                        int i = str & ~0x80000000;
                        if (i >= prinst->numallocedstrings)
                        {
+                               printf("invalid string %x\n", str);
+                               PR_StackTrace(progfuncs);
                                pr_trace = 1;
                                return "";
                        }
@@ -514,6 +595,8 @@ char *ASMCALL PR_StringToNative                             (progfuncs_t *progfuncs, string_t str)
                                return prinst->allocedstrings[i];
                        else
                        {
+                               printf("invalid string %x\n", str);
+                               PR_StackTrace(progfuncs);
                                pr_trace = 1;
                                return "";      //urm, was freed...
                        }
@@ -523,6 +606,8 @@ char *ASMCALL PR_StringToNative                             (progfuncs_t *progfuncs, string_t str)
                        int i = str & ~0x40000000;
                        if (i >= prinst->numtempstrings)
                        {
+                               printf("invalid temp string %x\n", str);
+                               PR_StackTrace(progfuncs);
                                pr_trace = 1;
                                return "";
                        }
@@ -530,8 +615,10 @@ char *ASMCALL PR_StringToNative                            (progfuncs_t *progfuncs, string_t str)
                }
        }
 
-       if (str >= progfuncs->stringtablesize)
+       if (str >= addressableused)
        {
+               printf("invalid string offset %x\n", str);
+               PR_StackTrace(progfuncs);
                pr_trace = 1;
                return "";
        }
@@ -571,6 +658,38 @@ string_t PR_AllocTempString                        (progfuncs_t *progfuncs, char *str)
 
        return (string_t)((unsigned int)i | 0x40000000);
 }
+string_t PR_AllocTempStringLen                 (progfuncs_t *progfuncs, char **str, unsigned int len)
+{
+       char **ntable;
+       int newmax;
+       int i;
+
+       if (!str)
+               return 0;
+
+       if (prinst->numtempstrings == prinst->maxtempstrings)
+       {
+               newmax = prinst->maxtempstrings += 1024;
+               prinst->maxtempstrings += 1024;
+               ntable = memalloc(sizeof(char*) * newmax);
+               memcpy(ntable, prinst->tempstrings, sizeof(char*) * prinst->numtempstrings);
+               prinst->maxtempstrings = newmax;
+               if (prinst->tempstrings)
+                       memfree(prinst->tempstrings);
+               prinst->tempstrings = ntable;
+       }
+
+       i = prinst->numtempstrings;
+       if (i == 0x10000000)
+               return 0;
+
+       prinst->numtempstrings++;
+
+       prinst->tempstrings[i] = memalloc(len);
+       *str = prinst->tempstrings[i];
+
+       return (string_t)((unsigned int)i | 0x40000000);
+}
 
 void PR_FreeTemps                      (progfuncs_t *progfuncs, int depth)
 {
@@ -683,7 +802,9 @@ progfuncs_t deffuncs = {
        0,
        PR_QueryField,
        QC_ClearEdict,
-       QC_FindPrefixedGlobals
+       QC_FindPrefixedGlobals,
+       PRAddressableAlloc,
+       PR_AllocTempStringLen
 };
 #undef printf
 
@@ -774,8 +895,8 @@ void CloseProgs(progfuncs_t *inst)
 #endif
 
        if (inst->prinst->allocedstrings)
-                f(inst->prinst->allocedstrings);
-               inst->prinst->allocedstrings = NULL;
+               f(inst->prinst->allocedstrings);
+       inst->prinst->allocedstrings = NULL;
        if (inst->prinst->tempstrings)
                f(inst->prinst->tempstrings);
        inst->prinst->tempstrings = NULL;
index d6c34a96ed70db5eece3d6c3725236dda3361a26..3559086383ba057f2acfaae14c608b7072b4accf 100644 (file)
@@ -112,9 +112,9 @@ enum qcop_e {
        //these following ones are Hexen 2 constants.
        
        OP_MULSTORE_F,
-       OP_MULSTORE_V,
+       OP_MULSTORE_VF,
        OP_MULSTOREP_F,
-       OP_MULSTOREP_V,
+       OP_MULSTOREP_VF,
 
        OP_DIVSTORE_F,  //70
        OP_DIVSTOREP_F,
@@ -260,8 +260,8 @@ enum qcop_e {
 
        //-------------------------------------
        //string manipulation.
-       OP_ADD_SF,      //(char*)c = (char*)a + (float)b
-       OP_SUB_S,       //(float)c = (char*)a - (char*)b
+       OP_ADD_SF,      //(char*)c = (char*)a + (float)b    add_fi->i
+       OP_SUB_S,       //(float)c = (char*)a - (char*)b    sub_ii->f
        OP_STOREP_C,//(float)c = *(char*)b = (float)a
        OP_LOADP_C,     //(float)c = *(char*)
        //-------------------------------------
@@ -304,7 +304,7 @@ enum qcop_e {
        OP_BOUNDCHECK,
 
 //back to ones that we do use.
-       OP_STOREP_P,
+       OP_UNUSED,      //used to be OP_STOREP_P, which is now emulated with OP_STOREP_I, fteqcc nor fte generated it
        OP_PUSH,        //push 4octets onto the local-stack (which is ALWAYS poped on function return). Returns a pointer.
        OP_POP,         //pop those ones that were pushed (don't over do it). Needs assembler.
 
@@ -350,7 +350,13 @@ enum qcop_e {
        OP_SUBSTORE_FI,
        OP_SUBSTOREP_FI,
 
-       OP_NUMOPS                       //246
+       OP_MULSTORE_VI,
+       OP_MULSTOREP_VI,
+
+       OP_LOADA_STRUCT,
+       OP_STOREP_P,
+
+       OP_NUMOPS
 };
 
 #define        MAX_PARMS       8
index a67b36851e358328db2960f22406f15069a86cb2..468aea459c22721514ec4237e5a2c10a1ade410c 100644 (file)
@@ -5,11 +5,6 @@ struct edict_s;
 #include "progsint.h"
 //#include "crc.h"
 
-/*int maxedicts;
-
-evalc_t spawnflagscache;
-*/
-
 #ifdef _WIN32
 //this is windows  all files are written with this endian standard. we do this to try to get a little more speed.
 #define NOENDIAN
@@ -18,30 +13,8 @@ evalc_t spawnflagscache;
 
 vec3_t vec3_origin;
 
-//edictrun_t *sv_edicts;
-//int sv_num_edicts;
-
-//int                          pr_edict_size;  // in bytes
-//int                          pr_max_edict_size;
-
-//unsigned short               pr_crc;
-
 fdef_t *ED_FieldAtOfs (progfuncs_t *progfuncs, unsigned int ofs);
-pbool  ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s, int bits);
-
-
-
-/*
-#define        MAX_FIELD_LEN   64
-#define GEFV_CACHESIZE 5
-
-typedef struct {
-       ddef_t  *pcache;
-       char    field[MAX_FIELD_LEN];
-} gefv_cache;
-
-static gefv_cache      gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}};
-*/
+pbool  ED_ParseEpair (progfuncs_t *progfuncs, int qcptr, unsigned int fldofs, int fldtype, char *s);
 
 /*
 =================
@@ -487,7 +460,7 @@ char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val)
        type &= ~DEF_SAVEGLOBAL;
 #endif
 
-       if (pr_types)
+       if (current_progstate && pr_types)
                type = pr_types[type].type;
 
        switch (type)
@@ -600,8 +573,8 @@ char *PR_UglyValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val)
        type &= ~DEF_SAVEGLOBAL;
 #endif
 
-       if (pr_types)
-               type = pr_types[type].type;
+//     if (pr_types)
+//             type = pr_types[type].type;
 
        switch (type)
        {
@@ -1052,54 +1025,30 @@ Can parse either fields or globals
 returns false if error
 =============
 */
-pbool  ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s, int structtype)
+pbool  ED_ParseEpair (progfuncs_t *progfuncs, int qcptr, unsigned int fldofs, int fldtype, char *s)
 {
        int             i;
        char    string[128];
        fdef_t  *def;
        char    *v, *w;
-       void    *d;
        string_t st;
        dfunction_t     *func;
-
-       int type = 0; // warning about beign used without initializing it
-
-       switch(structtype)
-       {
-       case PST_DEFAULT:
-               d = (void *)((int *)base + ((ddef16_t*)key)->ofs);
-
-               if (pr_types)
-                       type = pr_types[((ddef16_t*)key)->type & ~DEF_SAVEGLOBAL].type;
-               else
-                       type = ((ddef16_t*)key)->type & ~DEF_SAVEGLOBAL;
-               break;
-       case PST_FTE32:
-               d = (void *)((int *)base + ((ddef32_t*)key)->ofs);
-
-               if (pr_types)
-                       type = pr_types[((ddef32_t*)key)->type & ~DEF_SAVEGLOBAL].type;
-               else
-                       type = ((ddef32_t*)key)->type & ~DEF_SAVEGLOBAL;
-               break;
-       default:
-               Sys_Error("Bad struct type in ED_ParseEpair");
-               d = 0;
-       }
+       int type = fldtype & ~DEF_SAVEGLOBAL;
+       qcptr += fldofs*sizeof(int);
 
        switch (type)
        {
        case ev_string:
                st = PR_StringToProgs(progfuncs, ED_NewString (progfuncs, s, 0));
-               *(string_t *)d = st;
+               *(string_t *)(progfuncs->stringtable + qcptr) = st;
                break;
 
        case ev_float:
-               *(float *)d = (float)atof (s);
+               *(float *)(progfuncs->stringtable + qcptr) = (float)atof (s);
                break;
 
        case ev_integer:
-               *(int *)d = atoi (s);
+               *(int *)(progfuncs->stringtable + qcptr) = atoi (s);
                break;
 
        case ev_vector:
@@ -1112,20 +1061,20 @@ pbool   ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s,
                                v++;
                        if (!*v)
                        {
-                               ((float *)d)[i] = (float)atof (w);
+                               ((float *)(progfuncs->stringtable + qcptr))[i] = (float)atof (w);
                                w = v;
                        }
                        else
                        {
                                *v = 0;
-                               ((float *)d)[i] = (float)atof (w);
+                               ((float *)(progfuncs->stringtable + qcptr))[i] = (float)atof (w);
                                w = v = v+1;
                        }
                }
                break;
 
        case ev_entity:
-               *(int *)d = atoi (s);
+               *(int *)(progfuncs->stringtable + qcptr) = atoi (s);
                break;
 
        case ev_field:
@@ -1135,13 +1084,13 @@ pbool   ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s,
                        printf ("Can't find field %s\n", s);
                        return false;
                }
-               *(int *)d = def->ofs;
+               *(int *)(progfuncs->stringtable + qcptr) = def->ofs;
                break;
 
        case ev_function:
                if (s[1]==':'&&s[2]=='\0')
                {
-                       *(func_t *)d = 0;
+                       *(func_t *)(progfuncs->stringtable + qcptr) = 0;
                        return true;
                }
                func = ED_FindFunction (progfuncs, s, &i, -1);
@@ -1150,7 +1099,7 @@ pbool     ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s,
                        printf ("Can't find function %s\n", s);
                        return false;
                }
-               *(func_t *)d = (func - pr_progstate[i].functions) | (i<<24);
+               *(func_t *)(progfuncs->stringtable + qcptr) = (func - pr_progstate[i].functions) | (i<<24);
                break;
 
        default:
@@ -1259,7 +1208,7 @@ char *ED_ParseEdict (progfuncs_t *progfuncs, char *data, edictrun_t *ent)
                }
 
 cont:
-               if (!ED_ParseEpair (progfuncs, ent->fields, (ddefXX_t*)key, qcc_token, PST_FTE32))
+               if (!ED_ParseEpair (progfuncs, (char*)ent->fields - progfuncs->stringtable, key->ofs, key->type, qcc_token))
                {
                        continue;
 //                     Sys_Error ("ED_ParseEdict: parse error on entities");
@@ -1690,6 +1639,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
        eval_t *fulldata;       //this is part of FTE_FULLSPAWNDATA
        char *datastart;
 
+       eval_t *selfvar = NULL;
        eval_t *var;
 
        char filename[128];
@@ -1699,6 +1649,8 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
        ddef16_t *d16;
        ddef32_t *d32;
        func_t CheckSpawn=0;
+       void *oldglobals = NULL;
+       int oldglobalssize = 0;
 
        extern edictrun_t tempedict;
 
@@ -1719,14 +1671,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
        {
                isloadgame = false;
 
-               if (pr_typecurrent>=0)
-                       num = ED_FindGlobalOfs(progfuncs, "__fullspawndata");
-               else
-                       num = 0;
-               if (num)
-                       fulldata = (eval_t *)((int *)pr_globals + num);
-               else
-                       fulldata = NULL;
+               fulldata = PR_FindGlobal(progfuncs, "__fullspawndata", PR_ANY, NULL);
        }
 
        while(1)
@@ -1854,6 +1799,14 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
                                current_progstate->builtins = externs->builtinsfor(num, header_crc);
                                current_progstate->numbuiltins = numbuiltins;
                        }
+
+                       if (num == 0 && oldglobals)
+                       {
+                               if (pr_progstate[0].globals_size == oldglobalssize)
+                                       memcpy(pr_progstate[0].globals, oldglobals, pr_progstate[0].globals_size);
+                               free(oldglobals);
+                               oldglobals = NULL;
+                       }
                }
                else if (!strcmp(qcc_token, "globals"))
                {
@@ -1905,7 +1858,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
                                        else
                                        {
                                                file = QCC_COM_Parse(file);
-                                               ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d16, qcc_token, PST_DEFAULT);
+                                               ED_ParseEpair(progfuncs, (char*)pr_globals - progfuncs->stringtable, d16->ofs, d16->type, qcc_token);
                                        }
                                        break;
                                case PST_QTEST:
@@ -1918,7 +1871,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
                                        else
                                        {
                                                file = QCC_COM_Parse(file);
-                                               ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d32, qcc_token, PST_FTE32);
+                                               ED_ParseEpair(progfuncs, (char*)pr_globals - progfuncs->stringtable, d32->ofs, d32->type, qcc_token);
                                        }
                                        break;
                                default:
@@ -1963,6 +1916,21 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
                                        Sys_Error("Bad key \"%s\" in general block", qcc_token);
                        }
 
+                       if (oldglobals)
+                               free(oldglobals);
+                       oldglobals = NULL;
+                       if (pr_progstate[0].globals_size)
+                       {
+                               oldglobals = malloc(pr_progstate[0].globals_size);
+                               if (oldglobals)
+                               {
+                                       oldglobalssize = pr_progstate[0].globals_size;
+                                       memcpy(oldglobals, pr_progstate[0].globals, oldglobalssize);
+                               }
+                               else
+                                       printf("Unable to alloc %i bytes\n", pr_progstate[0].globals_size);
+                       }
+
                        PRAddressableFlush(progfuncs, -1);
                        resethunk=true;
 
@@ -2004,7 +1972,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
                                                        else
                                                        {
                                                                file = QCC_COM_Parse(file);
-                                                               ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d16, qcc_token, PST_DEFAULT);
+                                                               ED_ParseEpair(progfuncs, (char*)pr_globals - progfuncs->stringtable, d16->ofs, d16->type, qcc_token);
                                                        }
                                                        break;
                                                case PST_QTEST:
@@ -2017,7 +1985,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
                                                        else
                                                        {
                                                                file = QCC_COM_Parse(file);
-                                                               ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d32, qcc_token, PST_FTE32);
+                                                               ED_ParseEpair(progfuncs, (char*)pr_globals - progfuncs->stringtable, d32->ofs, d32->type, qcc_token);
                                                        }
                                                        break;
                                                default:
@@ -2097,8 +2065,6 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
                                }
                                else
                                {
-                                       eval_t *selfvar;
-
                                        //added by request of Mercury.
                                        if (fulldata)   //this is a vital part of HL map support!!!
                                        {       //essentually, it passes the ent's spawn info to the ent.
@@ -2113,8 +2079,10 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
                                                fulldata->string = PR_StringToProgs(progfuncs, spawndata);
                                        }
 
-                                       selfvar = (eval_t *)((int *)pr_globals + ED_FindGlobalOfs(progfuncs, "self"));
-                                       selfvar->edict = EDICT_TO_PROG(progfuncs, ed);
+                                       if (!selfvar)
+                                               selfvar = PR_FindGlobal(progfuncs, "self", PR_ANY, NULL);
+                                       if (selfvar)
+                                               selfvar->edict = EDICT_TO_PROG(progfuncs, ed);
 
                                        //DP_SV_SPAWNFUNC_PREFIX support
                                        eclassname = PR_StringToNative(progfuncs, var->string);
@@ -2164,6 +2132,10 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
                sv_num_edicts = numents;
        }
 
+       if (oldglobals)
+               free(oldglobals);
+       oldglobals = NULL;
+
        if (resethunk)
        {
                return entsize;
@@ -2505,6 +2477,7 @@ retry:
        current_progstate->statements = (void *)((qbyte *)pr_progs + pr_progs->ofs_statements);
 
        glob = pr_globals = (void *)((qbyte *)pr_progs + pr_progs->ofs_globals);
+       current_progstate->globals_size = pr_progs->numglobals*sizeof(*pr_globals);
 
        pr_linenums=NULL;
        pr_types=NULL;
@@ -2929,6 +2902,9 @@ retry:
                        {
                                if (st16[i].op >= OP_CALL1 && st16[i].op <= OP_CALL8)
                                        st16[i].op += OP_CALL1H - OP_CALL1;
+                               if (st16[i].op >= OP_RAND0 && st16[i].op <= OP_RANDV2)
+                                       if (!st16[i].c)
+                                               st16[i].c = OFS_RETURN;
                        }
                }
                break;
@@ -2958,6 +2934,9 @@ retry:
                        {
                                if (pr_statements32[i].op >= OP_CALL1 && pr_statements32[i].op <= OP_CALL8)
                                        pr_statements32[i].op += OP_CALL1H - OP_CALL1;
+                               if (pr_statements32[i].op >= OP_RAND0 && pr_statements32[i].op <= OP_RANDV2)
+                                       if (!pr_statements32[i].c)
+                                               pr_statements32[i].c = OFS_RETURN;
                        }
                }
                break;
@@ -3117,7 +3096,7 @@ retry:
                                d16 = ED_FindGlobal16(progfuncs, s);
                                if (!d16)
                                {
-                                       printf("Progs requires \"%s\" the external function \"%s\", but the definition was stripped", filename, s);
+                                       printf("Progs requires \"%s\" the external function \"%s\", but the definition was stripped\n", filename, s);
                                        PRHunkFree(progfuncs, hmark);
                                        pr_progs=NULL;
                                        return false;
@@ -3125,7 +3104,7 @@ retry:
 
                                ((int *)glob)[d16->ofs] = PR_FindFunc(progfuncs, s, PR_ANY);
                                if (!((int *)glob)[d16->ofs])
-                                       printf("Warning: Runtime-linked function %s was not found in primary progs (loading %s)", s, filename);
+                                       printf("Warning: Runtime-linked function %s could not be found (loading %s)\n", s, filename);
                                /*
                                d2 = ED_FindGlobalOfsFromProgs(progfuncs, s, 0, ev_function);
                                if (!d2)
index 9795603937c8c0cc86b6f0435c36cbe2f98d5521..323c566069bf1dd7e46cb102be90aab5b6daae5f 100644 (file)
@@ -346,6 +346,9 @@ ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, char *name, eval_t **val)
        ddef16_t *def16;
        int i;
 
+       if (pr_typecurrent < 0)
+               return NULL;
+
        switch (pr_progstate[pr_typecurrent].structtype)
        {
        case PST_DEFAULT:
@@ -436,6 +439,7 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key)
        int type;
        ddef32_t fakedef;
        eval_t fakeval;
+       edictrun_t *ed;
 
        assignment = strchr(key, '=');
        if (assignment)
@@ -469,7 +473,7 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key)
                c2 = c+1;
                c = strchr(c2, '.');
                type = type &~DEF_SAVEGLOBAL;
-               if (current_progstate->types)
+               if (current_progstate && current_progstate->types)
                        type = current_progstate->types[type].type;
                if (type != ev_entity)
                        return "'.' without entity";
@@ -478,13 +482,18 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key)
                if (c)*c = '.';
                if (!fdef)
                        return "(Bad string)";
-               val = (eval_t *) (((char *)PROG_TO_EDICT(progfuncs, val->_int)->fields) + fdef->ofs*4);
+               ed = PROG_TO_EDICT(progfuncs, val->_int);
+               if (!ed)
+                       return "(Invalid Entity)";
+               val = (eval_t *) (((char *)ed->fields) + fdef->ofs*4);
                type = fdef->type;
        }
 
        if (assignment)
        {
                assignment++;
+               while(*assignment == ' ')
+                       assignment++;
                switch (type&~DEF_SAVEGLOBAL)
                {
                case ev_string:
@@ -492,7 +501,10 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key)
                        break;
 
                case ev_float:
-                       *(float *)val = (float)atof (assignment);
+                       if (assignment[0] == '0' && (assignment[1] == 'x' || assignment[1] == 'X'))
+                               *(float*)val = strtoul(assignment, NULL, 0);
+                       else
+                               *(float *)val = (float)atof (assignment);
                        break;
 
                case ev_integer:
@@ -849,7 +861,6 @@ void PR_ExecuteCode (progfuncs_t *progfuncs, int s)
        dfunction_t     *newf;
        int             runaway;
        int             i;
-       int p;
        edictrun_t      *ed;
        eval_t  *ptr;
 
@@ -859,9 +870,9 @@ void PR_ExecuteCode (progfuncs_t *progfuncs, int s)
 
        prinst->continuestatement = -1;
 #ifdef QCJIT
-       if (prinst->jit)
+       if (current_progstate->jit)
        {
-               PR_EnterJIT(progfuncs, prinst->jit, s);
+               PR_EnterJIT(progfuncs, current_progstate->jit, s);
                return;
        }
 #endif
@@ -875,7 +886,7 @@ void PR_ExecuteCode (progfuncs_t *progfuncs, int s)
        {                                                                                       \
                pr_xstatement = st-pr_statements;               \
                PR_StackTrace(progfuncs);                               \
-               printf ("runaway loop error");                  \
+               printf ("runaway loop error\n");                \
                while(pr_depth > prinst->exitdepth)             \
                        PR_LeaveFunction(progfuncs);            \
                pr_spushed = 0;                                                 \
index b66b8b5e781cb2411bab3c9cf2d5f0800b310edd..334536ec0e3dcb2e237224580843bd6d2103bc64 100644 (file)
@@ -19,8 +19,16 @@ int maxshares;
 pbool PR_SwitchProgs(progfuncs_t *progfuncs, progsnum_t type)
 {      
        if ((unsigned)type >= maxprogs)
+       {
+               if (type == -1)
+               {
+                       pr_typecurrent = -1;
+                       current_progstate = NULL;
+                       return true;
+               }
                PR_RunError(progfuncs, "QCLIB: Bad prog type - %i", type);
 //             Sys_Error("Bad prog type - %i", type);
+       }
 
        if (pr_progstate[(unsigned)type].progs == NULL) //we havn't loaded it yet, for some reason
                return false;   
@@ -32,38 +40,38 @@ pbool PR_SwitchProgs(progfuncs_t *progfuncs, progsnum_t type)
        return true;
 }
 
-void PR_MoveParms(progfuncs_t *progfuncs, progsnum_t progs1, progsnum_t progs2)        //from 2 to 1
+void PR_MoveParms(progfuncs_t *progfuncs, progsnum_t newpr, progsnum_t oldpr)  //from 2 to 1
 {
        unsigned int a;
-       progstate_t *p1;
-       progstate_t *p2;
+       progstate_t *np;
+       progstate_t *op;
 
-       if (progs1 == progs2)
+       if (newpr == oldpr)
                return; //don't bother coping variables to themselves...
 
-       p1 = &pr_progstate[(int)progs1];
-       p2 = &pr_progstate[(int)progs2];
+       np = &pr_progstate[(int)newpr];
+       op = &pr_progstate[(int)oldpr];
 
-       if ((unsigned)progs1 >= maxprogs || !p1->globals)
-               Sys_Error("QCLIB: Bad prog type - %i", progs1);
-       if ((unsigned)progs2 >= maxprogs || !p2->globals)
-               Sys_Error("QCLIB: Bad prog type - %i", progs2);
+       if ((unsigned)newpr >= maxprogs || !np->globals)
+               PR_RunError(progfuncs, "QCLIB: Bad prog type - %i", newpr);
+       if ((unsigned)oldpr >= maxprogs || !op->globals)
+               return;
 
        //copy parms.
        for (a = 0; a < MAX_PARMS;a++)
        {
-               *(int *)&p1->globals[OFS_PARM0+3*a  ] = *(int *)&p2->globals[OFS_PARM0+3*a  ];
-               *(int *)&p1->globals[OFS_PARM0+3*a+1] = *(int *)&p2->globals[OFS_PARM0+3*a+1];
-               *(int *)&p1->globals[OFS_PARM0+3*a+2] = *(int *)&p2->globals[OFS_PARM0+3*a+2];
+               *(int *)&np->globals[OFS_PARM0+3*a  ] = *(int *)&op->globals[OFS_PARM0+3*a  ];
+               *(int *)&np->globals[OFS_PARM0+3*a+1] = *(int *)&op->globals[OFS_PARM0+3*a+1];
+               *(int *)&np->globals[OFS_PARM0+3*a+2] = *(int *)&op->globals[OFS_PARM0+3*a+2];
        }
-       p1->globals[OFS_RETURN] = p2->globals[OFS_RETURN];
-       p1->globals[OFS_RETURN+1] = p2->globals[OFS_RETURN+1];
-       p1->globals[OFS_RETURN+2] = p2->globals[OFS_RETURN+2];
+       np->globals[OFS_RETURN] = op->globals[OFS_RETURN];
+       np->globals[OFS_RETURN+1] = op->globals[OFS_RETURN+1];
+       np->globals[OFS_RETURN+2] = op->globals[OFS_RETURN+2];
 
        //move the vars defined as shared.
        for (a = 0; a < numshares; a++)//fixme: make offset per progs
        {
-               memmove(&((int *)p1->globals)[shares[a].varofs], &((int *)p2->globals)[shares[a].varofs], shares[a].size*4);
+               memmove(&((int *)np->globals)[shares[a].varofs], &((int *)op->globals)[shares[a].varofs], shares[a].size*4);
 /*             ((int *)p1->globals)[shares[a].varofs] = ((int *)p2->globals)[shares[a].varofs];
                if (shares[a].size > 1)
                {
@@ -94,14 +102,13 @@ progsnum_t PR_LoadProgs(progfuncs_t *progfuncs, char *s, int headercrc, builtin_
                                        progfuncs->numprogs = a+1;
 
 #ifdef QCJIT
-                               prinst->jit = PR_GenerateJit(progfuncs);
+                               current_progstate->jit = PR_GenerateJit(progfuncs);
 #endif
-                               if (oldtype>=0)
+                               if (oldtype != -1)
                                        PR_SwitchProgs(progfuncs, oldtype);
                                return a;       //we could load it. Yay!
                        }
-                       if (oldtype!=-1)
-                               PR_SwitchProgs(progfuncs, oldtype);
+                       PR_SwitchProgs(progfuncs, oldtype);
                        return -1; // loading failed.
                }
        }
@@ -122,6 +129,10 @@ void PR_Clear(progfuncs_t *progfuncs)
        unsigned int a;
        for (a = 0; a < maxprogs; a++)
        {
+#ifdef QCJIT
+               if (pr_progstate[a].jit)
+                       PR_CloseJit(pr_progstate[a].jit);
+#endif
                pr_progstate[a].progs = NULL;
        }
 }
@@ -232,8 +243,15 @@ int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, s
                {
                        if (field[i].type != type)
                        {
-                               printf("Field type mismatch on \"%s\". %i != %i\n", name, field[i].type, type);
-                               continue;
+                               /*Hexen2/DP compat hack: if the new type is a float and the original type is a vector, make the new def alias to the engine's _x field
+                               this 'works around' the unused .vector color field used for rtlight colours vs the .float color used for particle colours (the float initialisers in map files will expand into the x slot safely).
+                               qc/hc can work around this by just using .vector color/color_x instead, which is the same as this hack, but would resolve defs to allow rtlight colours.
+                               */
+                               if (field[i].type != ev_vector || type != ev_float)
+                               {
+                                       printf("Field type mismatch on \"%s\". %i != %i\n", name, field[i].type, type);
+                                       continue;
+                               }
                        }
                        if (!progfuncs->fieldadjust && engineofs>=0)
                                if ((unsigned)engineofs/4 != field[i].ofs)
index 9f217b339ef96f677a873ced7f716f356c1df491..9f1f1acc242708d08f2869b58d55784979b65867 100644 (file)
@@ -42,6 +42,10 @@ optimisations:
 \r
 #ifdef QCJIT\r
 \r
+#ifndef _WIN32\r
+#include <sys/mman.h>\r
+#endif\r
+\r
 static float ta, tb, nullfloat=0;\r
 \r
 struct jitstate\r
@@ -52,6 +56,10 @@ struct jitstate
        unsigned char *code;\r
        unsigned int codesize;\r
        unsigned int jitstatements;\r
+\r
+       float *glob;\r
+       unsigned int cachedglobal;\r
+       unsigned int cachereg;\r
 };\r
 \r
 static void EmitByte(struct jitstate *jit, unsigned char byte)\r
@@ -108,7 +116,11 @@ enum
        REG_ESP,\r
        REG_EBP,\r
        REG_ESI,\r
-       REG_EDI\r
+       REG_EDI,\r
+\r
+       /*I'm not going to list S1 here, as that makes things too awkward*/\r
+       REG_S0,\r
+       REG_NONE\r
 };\r
 #define XOR(sr,dr) EmitByte(0x31);EmitByte(0xc0 | (sr<<3) | dr);\r
 #define CLEARREG(reg) XOR(reg,reg)\r
@@ -118,6 +130,117 @@ enum
 #define STOREI(i, addr) EmitByte(0xc7);EmitByte(0x05); EmitAdr(addr);Emit4Byte(i);\r
 #define SETREGI(val,reg) EmitByte(0xbe);Emit4Byte(val);\r
 \r
+#define ARGREGS(a,b,c) GCache_Load(jit, op[i].a, a, op[i].b, b, op[i].c, c)\r
+#define RESULTREG(r) GCache_Store(jit, op[i].c, r)\r
+\r
+//for the purposes of the cache, 'temp' offsets are only read when they have been written only within the preceeding control block.\r
+//if they were read at any other time, then we must write them out in full.\r
+//this logic applies only to locals of a function.\r
+//#define USECACHE\r
+\r
+static void GCache_Load(struct jitstate *jit, int ao, int ar, int bo, int br, int co, int cr)\r
+{\r
+#if USECACHE\r
+       if (jit->cachedreg != REG_NONE)\r
+       {\r
+               /*something is cached, if its one of the input offsets then can chain the instruction*/\r
+\r
+               if (jit->cachedglobal === ao && ar != REG_NONE)\r
+               {\r
+                       if (jit->cachedreg == ar)\r
+                               ar = REG_NONE;\r
+               }\r
+               if (jit->cachedglobal === bo && br != REG_NONE)\r
+               {\r
+                       if (jit->cachedreg == br)\r
+                               br = REG_NONE;\r
+               }\r
+               if (jit->cachedglobal === co && cr != REG_NONE)\r
+               {\r
+                       if (jit->cachedreg == cr)\r
+                               cr = REG_NONE;\r
+               }\r
+\r
+               if (!istemp(ao))\r
+               {\r
+                       /*purge the old cache*/\r
+                       switch(jit->cachedreg)\r
+                       {\r
+                       case REG_NONE:\r
+                               break;\r
+                       case REG_S0:\r
+                               //fstps glob[C]\r
+                               EmitByte(0xd9);EmitByte(0x1d);EmitAdr(jit->glob + jit->cachedglobal);\r
+                               break;\r
+                       default:\r
+                               STOREREG(jit->cachedreg, jit->glob + jit->cachedglobal);\r
+                               break;\r
+               }\r
+               jit->cachedglobal = -1;\r
+               jit->cachedreg = REG_NONE;\r
+       }\r
+\r
+#endif\r
+       switch(ar)\r
+       {\r
+       case REG_NONE:\r
+               break;\r
+       case REG_S0:\r
+               //flds glob[A]\r
+               EmitByte(0xd9);EmitByte(0x05);EmitAdr(jit->glob + op[i].a);\r
+               break;\r
+       default:\r
+               LOADREG(jit->glob + ao, ar);\r
+               break;\r
+       }\r
+\r
+       switch(br)\r
+       {\r
+       case REG_NONE:\r
+               break;\r
+       case REG_S0:\r
+               //flds glob[A]\r
+               EmitByte(0xd9);EmitByte(0x05);EmitAdr(jit->glob + op[i].b);\r
+               break;\r
+       default:\r
+               LOADREG(jit->glob + bo, br);\r
+               break;\r
+       }\r
+\r
+       switch(cr)\r
+       {\r
+       case REG_NONE:\r
+               break;\r
+       case REG_S0:\r
+               //flds glob[A]\r
+               EmitByte(0xd9);EmitByte(0x05);EmitAdr(jit->glob + op[i].c);\r
+               break;\r
+       default:\r
+               LOADREG(jit->glob + co, cr);\r
+               break;\r
+       }\r
+}\r
+static void GCache_Store(struct jitstate *jit, int ofs, int reg)\r
+{\r
+#if USECACHE\r
+       jit->cachedglobal = ofs;\r
+       jit->cachedreg = reg;\r
+#else\r
+       switch(reg)\r
+       {\r
+       case REG_NONE:\r
+               break;\r
+       case REG_S0:\r
+               //fstps glob[C]\r
+               EmitByte(0xd9);EmitByte(0x1d);EmitAdr(jit->glob + ofs);\r
+               break;\r
+       default:\r
+               STOREREG(reg, jit->glob + ofs);\r
+               break;\r
+       }\r
+#endif\r
+}\r
+\r
 static void *LocalLoc(struct jitstate *jit)\r
 {\r
        return &jit->code[jit->codesize];\r
@@ -204,9 +327,17 @@ int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsn
 \r
 void PR_CloseJit(struct jitstate *jit)\r
 {\r
-       free(jit->statementjumps);\r
-       free(jit->statementoffsets);\r
-       free(jit->code);\r
+       if (jit)\r
+       {\r
+               free(jit->statementjumps);\r
+               free(jit->statementoffsets);\r
+#ifndef _WIN32\r
+               munmap(jit->code, jit->jitstatements * 500);\r
+#else\r
+               free(jit->code);\r
+#endif\r
+               free(jit)\r
+       }\r
 }\r
 \r
 #define EmitByte(v) EmitByte(jit, v)\r
@@ -238,7 +369,11 @@ struct jitstate *PR_GenerateJit(progfuncs_t *progfuncs)
 \r
        jit->statementjumps = malloc(numstatements*12);\r
        jit->statementoffsets = malloc(numstatements*4);\r
+#ifndef _WIN32\r
+       jit->code = mmap(NULL, numstatements*500, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);\r
+#else\r
        jit->code = malloc(numstatements*500);\r
+#endif\r
        if (!jit->code)\r
                return NULL;\r
 \r
@@ -343,6 +478,9 @@ struct jitstate *PR_GenerateJit(progfuncs_t *progfuncs)
                case OP_CALL6:\r
                case OP_CALL7:\r
                case OP_CALL8:\r
+                       //FIXME: the size of this instruction is going to hurt cache performance if every single function call is expanded into this HUGE CHUNK of gibberish!\r
+                       //FIXME: consider the feasability of just calling a C function and just jumping to the address it returns.\r
+\r
                //save the state in place the rest of the engine can cope with\r
                        //movl $i, pr_xstatement\r
                        EmitByte( 0xc7);EmitByte(0x05);EmitAdr(&pr_xstatement);Emit4Byte(i);\r
@@ -705,6 +843,7 @@ struct jitstate *PR_GenerateJit(progfuncs_t *progfuncs)
 \r
                case OP_AND_F:\r
                        //test floats properly, so we don't get confused with -0.0\r
+                       //FIXME: is it feasable to grab the value as an int and test it against 0x7fffffff?\r
 \r
                        //flds  glob[A]\r
                        EmitByte(0xd9); EmitByte(0x05); EmitAdr(glob + op[i].a);\r
@@ -1256,6 +1395,7 @@ LOADREG(glob + op[i].b, REG_EDI);
 \r
        FixupJumps(jit);\r
 \r
+       /* most likely want executable memory calls somewhere else more common */\r
 #ifdef _WIN32\r
        {\r
                DWORD old;\r
@@ -1264,6 +1404,8 @@ LOADREG(glob + op[i].b, REG_EDI);
                //this means that we must maintain read/write protection, or libc will crash us\r
                VirtualProtect(jit->code, jit->codesize, PAGE_EXECUTE_READWRITE, &old);\r
        }\r
+#else\r
+       mprotect(jit->code, jit->codesize, PROT_READ|PROT_EXEC);\r
 #endif\r
 \r
 //     externs->WriteFile("jit.x86", jit->code, jit->codesize);\r
index e0d5cd461d7f84e78d1d46f887959bb52f78063e..795dcb5e06f090b6ba88a53e114dc0f5c11c5a93 100644 (file)
@@ -1,5 +1,7 @@
 #ifdef _WIN32
+       #ifndef _CRT_SECURE_NO_WARNINGS
        #define _CRT_SECURE_NO_WARNINGS
+       #endif
        #define _CRT_NONSTDC_NO_WARNINGS
        #ifndef AVAIL_ZLIB
                #ifdef _MSC_VER
@@ -34,10 +36,6 @@ typedef unsigned char qbyte;
 #define PROGSUSED
 #endif
 
-extern int maxedicts;
-extern int maxprogs;
-extern int hunksize;
-
 #include "progtype.h"
 #include "progslib.h"
 
@@ -188,6 +186,7 @@ typedef struct progstate_s
        void    *statements;
 //     void                    *global_struct;
        float                   *globals;                       // same as pr_global_struct
+       int                             globals_size;   // in bytes
 
        typeinfo_t      *types;
 
@@ -201,6 +200,10 @@ typedef struct progstate_s
        int *linenums;  //debug versions only
 
        progstructtype_t structtype;
+
+#ifdef QCJIT
+       struct jitstate *jit;
+#endif
 } progstate_t;
 
 typedef struct extensionbuiltin_s {
@@ -279,7 +282,7 @@ unsigned int NUM_FOR_EDICT(progfuncs_t *progfuncs, struct edict_s *e);
 #define        GQ_STRING(o) (*(QCC_string_t *)&pr_globals[o])
 #define GQ_STRING2(o) ((char*)*(QCC_string_t *)&pr_globals[o])
 #define        G_FUNCTION(o) (*(func_t *)&pr_globals[o])
-#define G_PROG(o) (*(progsnum_t *)&pr_globals[o])      //simply so it's nice and easy to change...
+#define G_PROG(o) G_FLOAT(o)   //simply so it's nice and easy to change...
 
 #define        RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e))
 
@@ -343,9 +346,6 @@ void PR_SetBuiltins(int type);
 #define vars(type, name, size) type name[size]
 
 typedef struct prinst_s {
-#ifdef QCJIT
-       struct jitstate *jit;
-#endif
        char **tempstrings;
        int maxtempstrings;
        int numtempstrings;
@@ -355,8 +355,8 @@ typedef struct prinst_s {
        int maxallocedstrings;
        int numallocedstrings;
 
-var(progstate_t *, pr_progstate);
-#define pr_progstate prinst->pr_progstate
+var(progstate_t *, progstate);
+#define pr_progstate prinst->progstate
 
 var(progsnum_t, pr_typecurrent);
 #define pr_typecurrent prinst->pr_typecurrent
@@ -481,6 +481,7 @@ pbool CompileFile(progfuncs_t *progfuncs, char *filename);
 struct jitstate;
 struct jitstate *PR_GenerateJit(progfuncs_t *progfuncs);
 void PR_EnterJIT(progfuncs_t *progfuncs, struct jitstate *jitstate, int statement);
+void PR_CloseJit(struct jitstate *jit);
 
 char *QCC_COM_Parse (char *data);
 extern char    qcc_token[1024];
index 1e9b612556091cc78a2e71f20b32a8761ce9d0eb..1160959b3c5cfb782861a735adcf343b64b117ab 100644 (file)
@@ -138,6 +138,10 @@ struct progfuncs_s {
 
        void (*EntClear)                                        (progfuncs_t *progfuncs, struct edict_s *e);
        void (*FindPrefixGlobals)                       (progfuncs_t *progfuncs, char *prefix, void (*found) (progfuncs_t *progfuncs, char *name, union eval_s *val, etype_t type) );
+
+       void *(*AddressableAlloc)                       (progfuncs_t *progfuncs, int ammount); /*returns memory within the qc block, use stringtoprogs to get a usable qc pointer/string*/
+
+       string_t (*AllocTempString)                     (progfuncs_t *prinst, char **str, unsigned int len);
 };
 
 typedef struct progexterns_s {
@@ -179,6 +183,9 @@ typedef struct progexterns_s {
        unsigned int *sv_num_edicts;            //pointer to the engine's edict count.
 
        int (*useeditor) (progfuncs_t *prinst, char *filename, int line, int nump, char **parms);       //called on syntax errors or step-by-step debugging.
+       void (*addressablerelocated) (progfuncs_t *progfuncs, char *oldb, char *newb, int oldlen);      //called when the progs memory was resized. you must fix up all pointers to globals, strings, fields, addressable blocks.
+
+       void *user;     /*contains the owner's world reference in FTE*/
 } progparms_t, progexterns_t;
 
 //FIXMEs
@@ -206,7 +213,7 @@ typedef union eval_s
        func_t                  function;
        int                             _int;
        int                             edict;
-       progsnum_t              prog;   //so it can easily be changed
+       float           prog;   //so it can easily be changed
 } eval_t;
 #endif
 
@@ -252,7 +259,8 @@ typedef union eval_s
 #define PR_FindFunction(pf, name, num)                                         (*pf->FindFunction)                     (pf, name, num)
 #define PR_FindGlobal(pf, name, progs, type)                           (*pf->FindGlobal)                       (pf, name, progs, type)
 #define PR_AddString(pf, ed, len)                                                      (*pf->AddString)                        (pf, ed, len)
-#define PR_Alloc(pf,size)                                                                      (*pf->Tempmem)                          (pf, size)
+#define PR_Alloc(pf,size,whatfor)                                                      (*pf->Tempmem)                          (pf, size, whatfor)
+#define PR_AddressableAlloc(pf,size)                                           (*pf->AddressableAlloc)         (pf, size)
 
 #define PROG_TO_EDICT(pf, ed)                                                          (*pf->ProgsToEdict)                     (pf, ed)
 #define EDICT_TO_PROG(pf, ed)                                                          (*pf->EdictToProgs)                     (pf, (struct edict_s*)ed)
diff --git a/misc/source/fteqcc-src/qcc.dsp b/misc/source/fteqcc-src/qcc.dsp
deleted file mode 100644 (file)
index f5af89c..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-# Microsoft Developer Studio Project File - Name="qcc" - Package Owner=<4>\r
-# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
-# ** DO NOT EDIT **\r
-\r
-# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
-\r
-CFG=qcc - Win32 GUIDebug\r
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
-!MESSAGE use the Export Makefile command and run\r
-!MESSAGE \r
-!MESSAGE NMAKE /f "qcc.mak".\r
-!MESSAGE \r
-!MESSAGE You can specify a configuration when running NMAKE\r
-!MESSAGE by defining the macro CFG on the command line. For example:\r
-!MESSAGE \r
-!MESSAGE NMAKE /f "qcc.mak" CFG="qcc - Win32 GUIDebug"\r
-!MESSAGE \r
-!MESSAGE Possible choices for configuration are:\r
-!MESSAGE \r
-!MESSAGE "qcc - Win32 Release" (based on "Win32 (x86) Console Application")\r
-!MESSAGE "qcc - Win32 Debug" (based on "Win32 (x86) Console Application")\r
-!MESSAGE "qcc - Win32 GUIDebug" (based on "Win32 (x86) Console Application")\r
-!MESSAGE "qcc - Win32 GUIRelease" (based on "Win32 (x86) Console Application")\r
-!MESSAGE \r
-\r
-# Begin Project\r
-# PROP AllowPerConfigDependencies 0\r
-# PROP Scc_ProjName ""\r
-# PROP Scc_LocalPath ""\r
-CPP=cl.exe\r
-RSC=rc.exe\r
-\r
-!IF  "$(CFG)" == "qcc - Win32 Release"\r
-\r
-# PROP BASE Use_MFC 0\r
-# PROP BASE Use_Debug_Libraries 0\r
-# PROP BASE Output_Dir "Release"\r
-# PROP BASE Intermediate_Dir "Release"\r
-# PROP BASE Target_Dir ""\r
-# PROP Use_MFC 0\r
-# PROP Use_Debug_Libraries 0\r
-# PROP Output_Dir "Release"\r
-# PROP Intermediate_Dir "Release"\r
-# PROP Ignore_Export_Lib 0\r
-# PROP Target_Dir ""\r
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
-# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "QCCONLY" /YX /FD /c\r
-# ADD BASE RSC /l 0x809 /d "NDEBUG"\r
-# ADD RSC /l 0x809 /d "NDEBUG"\r
-BSC32=bscmake.exe\r
-# ADD BASE BSC32 /nologo\r
-# ADD BSC32 /nologo\r
-LINK32=link.exe\r
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
-# ADD LINK32 ../libs/zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../../fteqcc.exe"\r
-\r
-!ELSEIF  "$(CFG)" == "qcc - Win32 Debug"\r
-\r
-# PROP BASE Use_MFC 0\r
-# PROP BASE Use_Debug_Libraries 1\r
-# PROP BASE Output_Dir "Debug"\r
-# PROP BASE Intermediate_Dir "Debug"\r
-# PROP BASE Target_Dir ""\r
-# PROP Use_MFC 0\r
-# PROP Use_Debug_Libraries 1\r
-# PROP Output_Dir "Debug"\r
-# PROP Intermediate_Dir "Debug"\r
-# PROP Ignore_Export_Lib 0\r
-# PROP Target_Dir ""\r
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c\r
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "QCCONLY" /FR /YX /FD /GZ /c\r
-# ADD BASE RSC /l 0x809 /d "_DEBUG"\r
-# ADD RSC /l 0x809 /d "_DEBUG"\r
-BSC32=bscmake.exe\r
-# ADD BASE BSC32 /nologo\r
-# ADD BSC32 /nologo\r
-LINK32=link.exe\r
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
-# ADD LINK32 ..\libs\zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../fteqcc_dbg.exe" /pdbtype:sept\r
-\r
-!ELSEIF  "$(CFG)" == "qcc - Win32 GUIDebug"\r
-\r
-# PROP BASE Use_MFC 0\r
-# PROP BASE Use_Debug_Libraries 1\r
-# PROP BASE Output_Dir "qcc___Win32_GUIDebug"\r
-# PROP BASE Intermediate_Dir "qcc___Win32_GUIDebug"\r
-# PROP BASE Ignore_Export_Lib 0\r
-# PROP BASE Target_Dir ""\r
-# PROP Use_MFC 0\r
-# PROP Use_Debug_Libraries 1\r
-# PROP Output_Dir "qcc___Win32_GUIDebug"\r
-# PROP Intermediate_Dir "qcc___Win32_GUIDebug"\r
-# PROP Ignore_Export_Lib 0\r
-# PROP Target_Dir ""\r
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "QCCONLY" /FR /YX /FD /GZ /c\r
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "QCCONLY" /FR /YX /FD /GZ /c\r
-# ADD BASE RSC /l 0x809 /d "_DEBUG"\r
-# ADD RSC /l 0x809 /d "_DEBUG"\r
-BSC32=bscmake.exe\r
-# ADD BASE BSC32 /nologo\r
-# ADD BSC32 /nologo\r
-LINK32=link.exe\r
-# ADD BASE LINK32 ..\libs\zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../../fteqcc.exe" /pdbtype:sept\r
-# ADD LINK32 ..\libs\zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib comdlg32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"..\..\fteqcc.exe" /pdbtype:sept\r
-# SUBTRACT LINK32 /pdb:none\r
-\r
-!ELSEIF  "$(CFG)" == "qcc - Win32 GUIRelease"\r
-\r
-# PROP BASE Use_MFC 0\r
-# PROP BASE Use_Debug_Libraries 0\r
-# PROP BASE Output_Dir "qcc___Win32_GUIRelease0"\r
-# PROP BASE Intermediate_Dir "qcc___Win32_GUIRelease0"\r
-# PROP BASE Ignore_Export_Lib 0\r
-# PROP BASE Target_Dir ""\r
-# PROP Use_MFC 0\r
-# PROP Use_Debug_Libraries 0\r
-# PROP Output_Dir "qcc___Win32_GUIRelease0"\r
-# PROP Intermediate_Dir "qcc___Win32_GUIRelease0"\r
-# PROP Ignore_Export_Lib 0\r
-# PROP Target_Dir ""\r
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "QCCONLY" /YX /FD /c\r
-# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "QCCONLY" /FR /YX /FD /c\r
-# ADD BASE RSC /l 0x809 /d "NDEBUG"\r
-# ADD RSC /l 0x809 /d "NDEBUG"\r
-BSC32=bscmake.exe\r
-# ADD BASE BSC32 /nologo\r
-# ADD BSC32 /nologo\r
-LINK32=link.exe\r
-# ADD BASE LINK32 ../libs/zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../../../fteqcc.exe"\r
-# ADD LINK32 ../libs/zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /machine:I386 /out:"../../fteqccgui.exe"\r
-# SUBTRACT LINK32 /pdb:none\r
-\r
-!ENDIF \r
-\r
-# Begin Target\r
-\r
-# Name "qcc - Win32 Release"\r
-# Name "qcc - Win32 Debug"\r
-# Name "qcc - Win32 GUIDebug"\r
-# Name "qcc - Win32 GUIRelease"\r
-# Begin Group "Source Files"\r
-\r
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
-# Begin Source File\r
-\r
-SOURCE=.\Comprout.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\hash.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\qcc_cmdlib.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\qcc_gtk.c\r
-# PROP Exclude_From_Build 1\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\qcc_pr_comp.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\qcc_pr_lex.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\qccgui.c\r
-\r
-!IF  "$(CFG)" == "qcc - Win32 Release"\r
-\r
-# PROP Exclude_From_Build 1\r
-\r
-!ELSEIF  "$(CFG)" == "qcc - Win32 Debug"\r
-\r
-# PROP Exclude_From_Build 1\r
-\r
-!ELSEIF  "$(CFG)" == "qcc - Win32 GUIDebug"\r
-\r
-!ELSEIF  "$(CFG)" == "qcc - Win32 GUIRelease"\r
-\r
-!ENDIF \r
-\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\qccguistuff.c\r
-\r
-!IF  "$(CFG)" == "qcc - Win32 Release"\r
-\r
-# PROP Exclude_From_Build 1\r
-\r
-!ELSEIF  "$(CFG)" == "qcc - Win32 Debug"\r
-\r
-# PROP Exclude_From_Build 1\r
-\r
-!ELSEIF  "$(CFG)" == "qcc - Win32 GUIDebug"\r
-\r
-!ELSEIF  "$(CFG)" == "qcc - Win32 GUIRelease"\r
-\r
-!ENDIF \r
-\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\QccMain.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\qcctui.c\r
-\r
-!IF  "$(CFG)" == "qcc - Win32 Release"\r
-\r
-!ELSEIF  "$(CFG)" == "qcc - Win32 Debug"\r
-\r
-!ELSEIF  "$(CFG)" == "qcc - Win32 GUIDebug"\r
-\r
-# PROP Exclude_From_Build 1\r
-\r
-!ELSEIF  "$(CFG)" == "qcc - Win32 GUIRelease"\r
-\r
-# PROP Exclude_From_Build 1\r
-\r
-!ENDIF \r
-\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\qcd_main.c\r
-# End Source File\r
-# End Group\r
-# Begin Group "Header Files"\r
-\r
-# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
-# Begin Source File\r
-\r
-SOURCE=.\gui.h\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\pr_comp.h\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\qcc.h\r
-# End Source File\r
-# End Group\r
-# Begin Group "Resource Files"\r
-\r
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
-# End Group\r
-# End Target\r
-# End Project\r
index 5c2cd2ed79ca1e61d54be0ac78bb668665e484b4..1ee2ac62ae77c6e477cfcead9ebae6d22229f312 100644 (file)
@@ -42,7 +42,7 @@ extern float   (*PRLittleFloat) (float l);
 
 #define        MAX_ERRORS              10
 
-#define        MAX_NAME                128             // chars long
+#define        MAX_NAME                256             // chars long
 
 extern unsigned int MAX_REGS;
 
@@ -59,7 +59,7 @@ extern int    MAX_FUNCTIONS;
 #define        MAX_DATA_PATH   64
 
 extern int MAX_CONSTANTS;
-#define MAXCONSTANTLENGTH 64
+#define MAXCONSTANTNAMELENGTH 64
 #define MAXCONSTANTPARAMLENGTH 32
 #define MAXCONSTANTPARAMS 32
 
@@ -281,7 +281,7 @@ extern hashtable_t globalstable, localstable;
 #endif
 
 #ifdef WRITEASM
-FILE *asmfile;
+extern FILE *asmfile;
 #endif
 //=============================================================================
 
@@ -305,6 +305,8 @@ typedef struct QCC_type_s
 
        unsigned int ofs;       //inside a structure.
        unsigned int size;
+       unsigned int arraysize;
+       pbool typedefed;
        char *name;
 } QCC_type_t;
 int typecmp(QCC_type_t *a, QCC_type_t *b);
@@ -330,6 +332,7 @@ typedef struct QCC_def_s
        struct QCC_def_s        *nextlocal;     //provides a chain of local variables for the opt_locals_marshalling optimisation.
        gofs_t          ofs;
        struct QCC_def_s        *scope;         // function the var was defined in, or NULL
+       struct QCC_def_s        *deftail;       // arrays and structs create multiple globaldef objects providing different types at the different parts of the single object (struct), or alternative names (vectors). this allows us to correctly set the const type based upon how its initialised.
        int                     initialized;    // 1 when a declaration included "= immediate"
        int                     constant;               // 1 says we can use the value over and over again
 
@@ -340,10 +343,11 @@ typedef struct QCC_def_s
        int s_line;
 
        int arraysize;
-       pbool shared;
-       pbool saved;
-       pbool isstatic;
-       pbool subscoped_away;
+       pbool shared:1;
+       pbool saved:1;
+       pbool isstatic:1;
+       pbool subscoped_away:1;
+       pbool followptr:1;
 
        temp_t *temp;
 } QCC_def_t;
@@ -371,7 +375,7 @@ typedef union QCC_eval_s
 const extern   unsigned int            type_size[];
 //extern       QCC_def_t       *def_for_type[9];
 
-extern QCC_type_t      *type_void, *type_string, *type_float, *type_vector, *type_entity, *type_field, *type_function, *type_pointer, *type_integer, *type_variant, *type_floatfield;
+extern QCC_type_t      *type_void, *type_string, *type_float, *type_vector, *type_entity, *type_field, *type_function, *type_pointer, *type_floatpointer, *type_intpointer, *type_integer, *type_variant, *type_floatfield;
 
 struct QCC_function_s
 {
@@ -406,7 +410,7 @@ extern      QCC_pr_info_t   pr;
 
 typedef struct
 {
-       char name[MAXCONSTANTLENGTH];
+       char name[MAXCONSTANTNAMELENGTH];
        char *value;
        char params[MAXCONSTANTPARAMS][MAXCONSTANTPARAMLENGTH];
        int numparams;
@@ -440,6 +444,7 @@ extern pbool keyword_break;
 extern pbool keyword_case;
 extern pbool keyword_class;
 extern pbool keyword_const;
+extern pbool keyword_optional;
 extern pbool keyword_continue;
 extern pbool keyword_default;
 extern pbool keyword_do;
@@ -481,6 +486,7 @@ extern pbool flag_fasttrackarrays;
 extern pbool flag_assume_integer;
 extern pbool flag_msvcstyle;
 extern pbool flag_filetimes;
+extern pbool flag_typeexplicit;
 
 extern pbool opt_overlaptemps;
 extern pbool opt_shortenifnots;
@@ -532,8 +538,10 @@ void QCC_PR_PrintStatement (QCC_dstatement_t *s);
 void QCC_PR_Lex (void);
 // reads the next token into pr_token and classifies its type
 
-QCC_type_t *QCC_PR_NewType (char *name, int basictype);
-QCC_type_t *QCC_PR_ParseType (int newtype); extern pbool type_inlinefunction;
+QCC_type_t *QCC_PR_NewType (char *name, int basictype, pbool typedefed);
+QCC_type_t *QCC_PointerTypeTo(QCC_type_t *type);
+QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail);
+extern pbool type_inlinefunction;
 QCC_type_t *QCC_TypeForName(char *name);
 QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype);
 QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype);
@@ -542,6 +550,8 @@ CompilerConstant_t *QCC_PR_DefineName(char *name);
 
 void QCC_RemapOffsets(unsigned int firststatement, unsigned int laststatement, unsigned int min, unsigned int max, unsigned int newmin);
 
+int QCC_PR_IntConstExpr(void);
+
 #ifndef COMMONINLINES
 pbool QCC_PR_CheckImmediate (char *string);
 pbool QCC_PR_CheckToken (char *string);
@@ -551,7 +561,7 @@ pbool QCC_PR_CheckKeyword(int keywordenabled, char *string);
 #endif
 void VARGS QCC_PR_ParseError (int errortype, char *error, ...);
 void VARGS QCC_PR_ParseWarning (int warningtype, char *error, ...);
-void VARGS QCC_PR_Warning (int type, char *file, int line, char *error, ...);
+pbool VARGS QCC_PR_Warning (int type, char *file, int line, char *error, ...);
 void VARGS QCC_PR_Note (int type, char *file, int line, char *error, ...);
 void QCC_PR_ParsePrintDef (int warningtype, QCC_def_t *def);
 void VARGS QCC_PR_ParseErrorPrintDef (int errortype, QCC_def_t *def, char *error, ...);
@@ -614,6 +624,7 @@ enum {
        WARN_SAMENAMEASGLOBAL,
        WARN_CONSTANTCOMPARISON,
        WARN_UNSAFEFUNCTIONRETURNTYPE,
+       WARN_MISSINGOPTIONAL,
 
        ERR_PARSEERRORS,        //caused by qcc_pr_parseerror being called.
 
@@ -846,23 +857,32 @@ extern int numtemps;
 
 typedef char PATHSTRING[MAX_DATA_PATH];
 
-PATHSTRING             *precache_sounds;
-int                    *precache_sounds_block;
-int                    *precache_sounds_used;
-int                    numsounds;
-
-PATHSTRING             *precache_textures;
-int                    *precache_textures_block;
-int                    numtextures;
-
-PATHSTRING             *precache_models;
-int                    *precache_models_block;
-int                    *precache_models_used;
-int                    nummodels;
-
-PATHSTRING             *precache_files;
-int                    *precache_files_block;
-int                    numfiles;
+extern PATHSTRING              *precache_sounds;
+extern int                     *precache_sounds_block;
+extern int                     *precache_sounds_used;
+extern int                     numsounds;
+
+extern PATHSTRING              *precache_textures;
+extern int                     *precache_textures_block;
+extern int                     numtextures;
+
+extern PATHSTRING              *precache_models;
+extern int                     *precache_models_block;
+extern int                     *precache_models_used;
+extern int                     nummodels;
+
+extern PATHSTRING              *precache_files;
+extern int                     *precache_files_block;
+extern int                     numfiles;
+
+typedef struct qcc_includechunk_s {
+       struct qcc_includechunk_s *prev;
+       char *filename;
+       char *currentdatapoint;
+       int currentlinenumber;
+       CompilerConstant_t *cnst;
+} qcc_includechunk_t;
+extern qcc_includechunk_t *currentchunk;
 
 int    QCC_CopyString (char *str);
 
index f93e3e9c19683e8e884803e36543417f135d8eb0..b3c4b6b843e91af03bfc27a4199256cb1d669a99 100644 (file)
 extern jmp_buf qcccompileerror;
 #endif
 
-// I put the following here to resolve "undefined reference to `__imp__vsnprintf'" with MinGW64 ~ Moodles
-#ifdef __MINGW64__
-#ifndef QCCONLY
-       #if (_MSC_VER >= 1400)
-               //with MSVC 8, use MS extensions
-               #define snprintf linuxlike_snprintf_vc8
-               int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ...) LIKEPRINTF(3);
-               #define vsnprintf(a, b, c, d) vsnprintf_s(a, b, _TRUNCATE, c, d)
-       #else
-               //msvc crap
+#ifdef _WIN64
+       #ifdef _SDL
                #define snprintf linuxlike_snprintf
                int VARGS linuxlike_snprintf(char *buffer, int size, const char *format, ...) LIKEPRINTF(3);
                #define vsnprintf linuxlike_vsnprintf
                int VARGS linuxlike_vsnprintf(char *buffer, int size, const char *format, va_list argptr);
+               void *__imp__vsnprintf = vsnprintf;
        #endif
 #endif
-#endif
 
 // set these before calling CheckParm
 int myargc;
@@ -44,7 +36,7 @@ const unsigned int            type_size[12] = {1,     //void
                                                sizeof(func_t)/4,//function
                                                1,  //pointer (its an int index)
                                                1,      //integer
-                                               1,      //fixme: how big should a variant be?
+                                               3,      //fixme: how big should a variant be?
                                                0,      //ev_struct. variable sized.
                                                0       //ev_union. variable sized.
                                                };
index a269987703a6747564f4569afb90c175b73c269e..badefcac4e2ff9b58f8355347db3fab4ee963a72 100644 (file)
@@ -12,9 +12,6 @@ extern char *compilingfile;
 
 int conditional;
 
-extern int dotranslate;
-extern int dotranslate_count;
-
 //standard qcc keywords
 #define keyword_do             1
 #define keyword_return 1
@@ -28,6 +25,7 @@ pbool keyword_asm;
 pbool keyword_break;
 pbool keyword_case;
 pbool keyword_class;
+pbool keyword_optional;
 pbool keyword_const;   //fixme
 pbool keyword_continue;
 pbool keyword_default;
@@ -80,6 +78,7 @@ pbool flag_fasttrackarrays;   //Faster arrays, dynamically detected, activated onl
 pbool flag_msvcstyle;          //MSVC style warnings, so msvc's ide works properly
 pbool flag_assume_integer;     //5 - is that an integer or a float? qcc says float. but we support int too, so maybe we want that instead?
 pbool flag_filetimes;
+pbool flag_typeexplicit;       //no implicit type conversions, you must do the casts yourself.
 
 pbool opt_overlaptemps;                //reduce numpr_globals by reuse of temps. When they are not needed they are freed for reuse. The way this is implemented is better than frikqcc's. (This is the single most important optimisation)
 pbool opt_assignments;         //STORE_F isn't used if an operation wrote to a temp.
@@ -134,7 +133,6 @@ void *(*pHash_GetNext)(hashtable_t *table, const char *name, void *old);
 void *(*pHash_Add)(hashtable_t *table, const char *name, void *data, bucket_t *);
 
 QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int arraysize, unsigned int ofs, int referable, pbool saved);
-QCC_type_t *QCC_PR_NewType (char *name, int basictype);
 QCC_type_t *QCC_PR_FindType (QCC_type_t *type);
 QCC_type_t *QCC_PR_PointerType (QCC_type_t *pointsto);
 QCC_type_t *QCC_PR_FieldType (QCC_type_t *pointsto);
@@ -192,7 +190,7 @@ int num_labels;
 
 QCC_def_t *extra_parms[MAX_EXTRA_PARMS];
 
-#define ASSOC_RIGHT_RESULT ASSOC_RIGHT
+//#define ASSOC_RIGHT_RESULT ASSOC_RIGHT
 
 //========================================
 
@@ -295,9 +293,9 @@ QCC_opcode_t pr_opcodes[] =
 
 //these are hexen2
  {7, "*=", "MULSTORE_F",       6, ASSOC_RIGHT_RESULT,                          &type_float, &type_float, &type_float},
- {7, "*=", "MULSTORE_V",       6, ASSOC_RIGHT_RESULT,                          &type_vector, &type_float, &type_vector},
+ {7, "*=", "MULSTORE_VF",      6, ASSOC_RIGHT_RESULT,                          &type_vector, &type_float, &type_vector},
  {7, "*=", "MULSTOREP_F",      6, ASSOC_RIGHT_RESULT,                          &type_pointer, &type_float, &type_float},
- {7, "*=", "MULSTOREP_V",      6, ASSOC_RIGHT_RESULT,                          &type_pointer, &type_float, &type_vector},
+ {7, "*=", "MULSTOREP_VF",     6, ASSOC_RIGHT_RESULT,                          &type_pointer, &type_float, &type_vector},
 
  {7, "/=", "DIVSTORE_F",       6, ASSOC_RIGHT_RESULT,                          &type_float, &type_float, &type_float},
  {7, "/=", "DIVSTOREP_F",      6, ASSOC_RIGHT_RESULT,                          &type_pointer, &type_float, &type_float},
@@ -358,8 +356,8 @@ QCC_opcode_t pr_opcodes[] =
  {7, "<CALL8H>", "CALL8H",     -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_vector},
 
  {7, "=",      "STORE_I", 6, ASSOC_RIGHT,                              &type_integer, &type_integer, &type_integer},
- {7, "=",      "STORE_IF", 6, ASSOC_RIGHT,                     &type_integer, &type_float, &type_integer},
- {7, "=",      "STORE_FI", 6, ASSOC_RIGHT,                     &type_float, &type_integer, &type_float},
+ {7, "=",      "STORE_IF", 6, ASSOC_RIGHT,                     &type_float, &type_integer, &type_integer},
+ {7, "=",      "STORE_FI", 6, ASSOC_RIGHT,                     &type_integer, &type_float, &type_float},
 
  {7, "+", "ADD_I", 4, ASSOC_LEFT,                              &type_integer, &type_integer, &type_integer},
  {7, "+", "ADD_FI", 4, ASSOC_LEFT,                             &type_float, &type_integer, &type_float},
@@ -400,7 +398,7 @@ QCC_opcode_t pr_opcodes[] =
 
                                                                                //var,          offset                  return
  {7, "<ARRAY>", "GET_POINTER", -1, ASSOC_LEFT, &type_float,            &type_integer, &type_pointer},
- {7, "<ARRAY>", "ARRAY_OFS", -1, ASSOC_LEFT,           &type_pointer,  &type_integer, &type_pointer},
+ {7, "<ARRAY>", "MUL4ADD_I", -1, ASSOC_LEFT,           &type_pointer,  &type_integer, &type_pointer},
 
  {7, "=", "LOADA_F", 6, ASSOC_LEFT,                    &type_float,    &type_integer, &type_float},
  {7, "=", "LOADA_V", 6, ASSOC_LEFT,                    &type_vector,   &type_integer, &type_vector},
@@ -494,9 +492,9 @@ QCC_opcode_t pr_opcodes[] =
 {7, "<>",      "GLOAD_S",              -1, ASSOC_LEFT,                         &type_float,    &type_float,    &type_float},
 {7, "<>",      "GLOAD_FNC",    -1, ASSOC_LEFT,                         &type_float,    &type_float,    &type_float},
 
-{7, "<>",      "BOUNDCHECK",   -1, ASSOC_LEFT,                         &type_float,    &type_float,    &type_float},
+{7, "<>",      "BOUNDCHECK",   -1, ASSOC_LEFT,                         &type_integer,  NULL,   NULL},
 
-{7, "=",       "STOREP_P",             6,      ASSOC_RIGHT,                            &type_pointer,  &type_pointer,  &type_void},
+{7, "<UNUSED>",        "UNUSED",               6,      ASSOC_RIGHT,                            &type_void,     &type_void,     &type_void},
 {7, "<PUSH>",  "PUSH",         -1, ASSOC_RIGHT,                        &type_float,    &type_void,             &type_pointer},
 {7, "<POP>",   "POP",          -1, ASSOC_RIGHT,                        &type_float,    &type_void,             &type_void},
 
@@ -524,23 +522,30 @@ QCC_opcode_t pr_opcodes[] =
  {7, "+=", "ADDSTOREP_I",      6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_integer, &type_integer},
  {7, "-=", "SUBSTOREP_I",      6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_integer, &type_integer},
 
- {7, "*=", "OP_MULSTORE_IF",   6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_float, &type_integer},
- {7, "*=", "OP_MULSTOREP_IF",  6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_float, &type_integer},
- {7, "/=", "OP_DIVSTORE_IF",   6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_float, &type_integer},
- {7, "/=", "OP_DIVSTOREP_IF",  6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_float, &type_integer},
- {7, "+=", "OP_ADDSTORE_IF",   6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_float, &type_integer},
- {7, "+=", "OP_ADDSTOREP_IF",  6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_float, &type_integer},
- {7, "-=", "OP_SUBSTORE_IF",   6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_float, &type_integer},
- {7, "-=", "OP_SUBSTOREP_IF",  6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_float, &type_integer},
-
- {7, "*=", "OP_MULSTORE_FI",   6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_integer, &type_float},
- {7, "*=", "OP_MULSTOREP_FI",  6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_integer, &type_float},
- {7, "/=", "OP_DIVSTORE_FI",   6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_integer, &type_float},
- {7, "/=", "OP_DIVSTOREP_FI",  6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_integer, &type_float},
- {7, "+=", "OP_ADDSTORE_FI",   6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_integer, &type_float},
- {7, "+=", "OP_ADDSTOREP_FI",  6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_integer, &type_float},
- {7, "-=", "OP_SUBSTORE_FI",   6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_integer, &type_float},
- {7, "-=", "OP_SUBSTOREP_FI",  6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_integer, &type_float},
+ {7, "*=", "MULSTORE_IF",      6,      ASSOC_RIGHT_RESULT,             &type_integer, &type_float, &type_float},
+ {7, "*=", "MULSTOREP_IF",     6,      ASSOC_RIGHT_RESULT,             &type_intpointer, &type_float, &type_float},
+ {7, "/=", "DIVSTORE_IF",      6,      ASSOC_RIGHT_RESULT,             &type_integer, &type_float, &type_float},
+ {7, "/=", "DIVSTOREP_IF",     6,      ASSOC_RIGHT_RESULT,             &type_intpointer, &type_float, &type_float},
+ {7, "+=", "ADDSTORE_IF",      6,      ASSOC_RIGHT_RESULT,             &type_integer, &type_float, &type_float},
+ {7, "+=", "ADDSTOREP_IF",     6,      ASSOC_RIGHT_RESULT,             &type_intpointer, &type_float, &type_float},
+ {7, "-=", "SUBSTORE_IF",      6,      ASSOC_RIGHT_RESULT,             &type_integer, &type_float, &type_float},
+ {7, "-=", "SUBSTOREP_IF",     6,      ASSOC_RIGHT_RESULT,             &type_intpointer, &type_float, &type_float},
+
+ {7, "*=", "MULSTORE_FI",      6,      ASSOC_RIGHT_RESULT,             &type_float, &type_integer, &type_float},
+ {7, "*=", "MULSTOREP_FI",     6,      ASSOC_RIGHT_RESULT,             &type_floatpointer, &type_integer, &type_float},
+ {7, "/=", "DIVSTORE_FI",      6,      ASSOC_RIGHT_RESULT,             &type_float, &type_integer, &type_float},
+ {7, "/=", "DIVSTOREP_FI",     6,      ASSOC_RIGHT_RESULT,             &type_floatpointer, &type_integer, &type_float},
+ {7, "+=", "ADDSTORE_FI",      6,      ASSOC_RIGHT_RESULT,             &type_float, &type_integer, &type_float},
+ {7, "+=", "ADDSTOREP_FI",     6,      ASSOC_RIGHT_RESULT,             &type_floatpointer, &type_integer, &type_float},
+ {7, "-=", "SUBSTORE_FI",      6,      ASSOC_RIGHT_RESULT,             &type_float, &type_integer, &type_float},
+ {7, "-=", "SUBSTOREP_FI",     6,      ASSOC_RIGHT_RESULT,             &type_floatpointer, &type_integer, &type_float},
+
+ {7, "*=", "MULSTORE_VI",      6, ASSOC_RIGHT_RESULT,          &type_vector, &type_integer, &type_vector},
+ {7, "*=", "MULSTOREP_VI",     6, ASSOC_RIGHT_RESULT,          &type_pointer, &type_integer, &type_vector},
+
+ {7, "=", "LOADA_STRUCT",      6, ASSOC_LEFT,                          &type_float,    &type_integer, &type_float},
+
+ {7, "=",      "STOREP_P",             6,      ASSOC_RIGHT,                            &type_pointer,  &type_pointer,  &type_pointer},
 
  {0, NULL}
 };
@@ -595,6 +600,7 @@ pbool OpAssignsToB(unsigned int op)
 #undef ASSOC_RIGHT_RESULT
 
 #define        TOP_PRIORITY    7
+#define FUNC_PRIORITY  1
 #define UNARY_PRIORITY 1
 #define        NOT_PRIORITY    5
 //conditional and/or
@@ -657,11 +663,17 @@ QCC_opcode_t *opcodeprioritized[TOP_PRIORITY+1][128] =
                &pr_opcodes[OP_MUL_F],
                &pr_opcodes[OP_MUL_V],
                &pr_opcodes[OP_MUL_FV],
+               &pr_opcodes[OP_MUL_IV],
                &pr_opcodes[OP_MUL_VF],
+               &pr_opcodes[OP_MUL_VI],
                &pr_opcodes[OP_MUL_I],
+               &pr_opcodes[OP_MUL_FI],
+               &pr_opcodes[OP_MUL_IF],
 
                &pr_opcodes[OP_DIV_F],
                &pr_opcodes[OP_DIV_I],
+               &pr_opcodes[OP_DIV_FI],
+               &pr_opcodes[OP_DIV_IF],
                &pr_opcodes[OP_DIV_VF],
 
                &pr_opcodes[OP_BITAND_F],
@@ -734,6 +746,8 @@ QCC_opcode_t *opcodeprioritized[TOP_PRIORITY+1][128] =
 
                NULL
        }, {    //6
+               &pr_opcodes[OP_STOREP_P],
+
                &pr_opcodes[OP_STORE_F],
                &pr_opcodes[OP_STORE_V],
                &pr_opcodes[OP_STORE_S],
@@ -754,7 +768,6 @@ QCC_opcode_t *opcodeprioritized[TOP_PRIORITY+1][128] =
                &pr_opcodes[OP_STOREP_I],
                &pr_opcodes[OP_STOREP_IF],
                &pr_opcodes[OP_STOREP_FI],
-               &pr_opcodes[OP_STOREP_P],
 
                &pr_opcodes[OP_DIVSTORE_F],
                &pr_opcodes[OP_DIVSTORE_I],
@@ -765,12 +778,14 @@ QCC_opcode_t *opcodeprioritized[TOP_PRIORITY+1][128] =
                &pr_opcodes[OP_DIVSTOREP_IF],
                &pr_opcodes[OP_DIVSTOREP_FI],
                &pr_opcodes[OP_MULSTORE_F],
-               &pr_opcodes[OP_MULSTORE_V],
+               &pr_opcodes[OP_MULSTORE_VF],
+               &pr_opcodes[OP_MULSTORE_VI],
                &pr_opcodes[OP_MULSTORE_I],
                &pr_opcodes[OP_MULSTORE_IF],
                &pr_opcodes[OP_MULSTORE_FI],
                &pr_opcodes[OP_MULSTOREP_F],
-               &pr_opcodes[OP_MULSTOREP_V],
+               &pr_opcodes[OP_MULSTOREP_VF],
+               &pr_opcodes[OP_MULSTOREP_VI],
                &pr_opcodes[OP_MULSTOREP_I],
                &pr_opcodes[OP_MULSTOREP_IF],
                &pr_opcodes[OP_MULSTOREP_FI],
@@ -913,7 +928,6 @@ pbool QCC_OPCodeValid(QCC_opcode_t *op)
 
                //stores into a pointer (generated from 'ent.field=XXX')
                case OP_STOREP_I:       //no worse than the other OP_STOREP_X functions
-               case OP_STOREP_P:
                //reads from an entity field
                case OP_LOAD_I:         //no worse than the other OP_LOAD_X functions.
                case OP_LOAD_P:
@@ -1011,9 +1025,9 @@ pbool QCC_OPCodeValid(QCC_opcode_t *op)
                        return false; //DPFIXME: dp's bounds check may give false positives with expected uses.
 
                case OP_MULSTORE_F:
-               case OP_MULSTORE_V:
+               case OP_MULSTORE_VF:
                case OP_MULSTOREP_F:
-               case OP_MULSTOREP_V: // e.v *= f
+               case OP_MULSTOREP_VF: // e.v *= f
                case OP_DIVSTORE_F:
                case OP_DIVSTOREP_F:
                case OP_STORE_IF:
@@ -1097,8 +1111,14 @@ Emits a primitive statement, returning the var it places it's value in
 QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, QCC_dstatement_t **outstatement);
 static int QCC_ShouldConvert(QCC_def_t *var, etype_t wanted)
 {
+       /*no conversion needed*/
+       if (var->type->type == wanted)
+               return 0;
        if (var->type->type == ev_integer && wanted == ev_function)
                return 0;
+       if (var->type->type == ev_integer && wanted == ev_pointer)
+               return 0;
+       /*stuff needs converting*/
        if (var->type->type == ev_pointer && var->type->aux_type)
        {
                if (var->type->aux_type->type == ev_float && wanted == ev_integer)
@@ -1116,10 +1136,12 @@ static int QCC_ShouldConvert(QCC_def_t *var, etype_t wanted)
                        return OP_CONV_ITOF;
        }
 
+       /*impossible*/
        return -1;
 }
-QCC_def_t *QCC_SupplyConversion(QCC_def_t *var, etype_t wanted)
+QCC_def_t *QCC_SupplyConversion(QCC_def_t *var, etype_t wanted, pbool fatal)
 {
+       extern char *basictypenames[];
        int o;
 
        if (pr_classtype && var->type->type == ev_field && wanted != ev_field)
@@ -1127,7 +1149,7 @@ QCC_def_t *QCC_SupplyConversion(QCC_def_t *var, etype_t wanted)
                if (pr_classtype)
                {       //load self.var into a temp
                        QCC_def_t *self;
-                       self = QCC_PR_GetDef(type_entity, "self", NULL, true, 1, false);
+                       self = QCC_PR_GetDef(type_entity, "self", NULL, true, 0, false);
                        switch(wanted)
                        {
                        case ev_float:
@@ -1148,16 +1170,25 @@ QCC_def_t *QCC_SupplyConversion(QCC_def_t *var, etype_t wanted)
 
        o = QCC_ShouldConvert(var, wanted);
 
-       if (o <= 0)     //no conversion
+       if (o == 0) //type already matches
                return var;
-
+       if (flag_typeexplicit)
+               QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, var, "Implicit type mismatch. Needed %s, got %s.", basictypenames[wanted], var->type->name);
+       if (o < 0)
+       {
+               if (fatal)
+                       QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, var, "Implicit type mismatch. Needed %s, got %s.", basictypenames[wanted], var->type->name);
+               else
+                       return var;
+       }
 
        return QCC_PR_Statement(&pr_opcodes[o], var, NULL, NULL);       //conversion return value
 }
-QCC_def_t *QCC_MakeStringDef(char *value);
-QCC_def_t *QCC_MakeFloatDef(float value);
-QCC_def_t *QCC_MakeIntDef(int value);
-QCC_def_t *QCC_MakeVectorDef(float a, float b, float c);
+QCC_def_t *QCC_MakeTranslateStringConst(char *value);
+QCC_def_t *QCC_MakeStringConst(char *value);
+QCC_def_t *QCC_MakeFloatConst(float value);
+QCC_def_t *QCC_MakeIntConst(int value);
+QCC_def_t *QCC_MakeVectorConst(float a, float b, float c);
 
 typedef struct freeoffset_s {
        struct freeoffset_s *next;
@@ -1363,10 +1394,8 @@ static void QCC_FreeTemps(void)
        while(t)
        {
                if (t->used && !pr_error_count) //don't print this after an error jump out.
-               {
-                       QCC_PR_ParseWarning(WARN_DEBUGGING, "Temp was used in %s", pr_scope->name);
-                       t->used = false;
-               }
+                       QCC_PR_ParseWarning(WARN_DEBUGGING, "Internal: temp(ofs %i) was not released in %s. This implies miscompilation.", t->ofs, pr_scope->name);
+               t->used = false;
                t = t->next;
        }
 }
@@ -1399,6 +1428,13 @@ static void QCC_LockTemp(QCC_def_t *d)
        if (d->temp && d->temp->used)
                d->temp->scope = pr_scope;
 }
+static void QCC_ForceLockTempForOffset(int ofs)
+{
+       temp_t *t;
+       for (t = functemps; t; t = t->next)
+               if(t->ofs == ofs /* && t->used */)
+                       t->scope = pr_scope;
+}
 
 static void QCC_RemapLockedTemp(temp_t *t, int firststatement, int laststatement)
 {
@@ -1501,14 +1537,17 @@ static void QCC_fprintfLocals(FILE *f, gofs_t paramstart, gofs_t paramend)
        {
                if (var->ofs >= paramstart && var->ofs < paramend)
                        continue;
-               fprintf(f, "local %s %s; /* at %d */\n", TypeName(var->type), var->name, var->ofs);
+               if (var->arraysize)
+                       fprintf(f, "local %s %s[%i];\n", TypeName(var->type), var->name, var->arraysize);
+               else
+                       fprintf(f, "local %s %s;\n", TypeName(var->type), var->name);
        }
 
        for (t = functemps, i = 0; t; t = t->next, i++)
        {
                if (t->lastfunc == pr_scope)
                {
-                       fprintf(f, "local %s temp_%i; /* at %d */\n", (t->size == 1)?"float":"vector", i, t->ofs);
+                       fprintf(f, "local %s temp_%i;\n", (t->size == 1)?"float":"vector", i);
                }
        }
 }
@@ -1528,9 +1567,9 @@ static const char *QCC_VarAtOffset(unsigned int ofs, unsigned int size)
                if (ofs >= t->ofs && ofs < t->ofs + t->size)
                {
                        if (size < t->size)
-                               sprintf(message, "temp_%i_%c", i, 'x' + (ofs-t->ofs)%3);
+                               sprintf(message, "temp_%i_%c", t->ofs, 'x' + (ofs-t->ofs)%3);
                        else
-                               sprintf(message, "temp_%i", i);
+                               sprintf(message, "temp_%i", t->ofs);
                        return message;
                }
        }
@@ -1615,36 +1654,28 @@ static const char *QCC_VarAtOffset(unsigned int ofs, unsigned int size)
 }
 #endif
 
-QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, QCC_dstatement_t **outstatement)
+QCC_dstatement_t *QCC_PR_SimpleStatement( int op, int var_a, int var_b, int var_c, int force);
+
+QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, QCC_dstatement_t **outstatement)
 {
        QCC_dstatement_t        *statement;
        QCC_def_t                       *var_c=NULL, *temp=NULL;
 
        if (outstatement == (QCC_dstatement_t **)0xffffffff)
                outstatement = NULL;
-       else if (op->priority != -1)
+       else if (op->priority != -1 && op->priority != CONDITION_PRIORITY)
        {
                if (op->associative!=ASSOC_LEFT)
                {
-                       if (op->type_a == &type_pointer)
-                               var_b = QCC_SupplyConversion(var_b, (*op->type_b)->type);
-                       else
-                               var_b = QCC_SupplyConversion(var_b, (*op->type_a)->type);
+                       if (op->type_a != &type_pointer)
+                               var_b = QCC_SupplyConversion(var_b, (*op->type_a)->type, false);
                }
                else
                {
                        if (var_a)
-                               var_a = QCC_SupplyConversion(var_a, (*op->type_a)->type);
+                               var_a = QCC_SupplyConversion(var_a, (*op->type_a)->type, false);
                        if (var_b)
-                               var_b = QCC_SupplyConversion(var_b, (*op->type_b)->type);
-//                     if (op->type_a == &def_pointer)
-//                                     var_a = QCC_SupplyConversion(var_a, (*op->type_b)->type);
-//                             else
-//                                     var_a = QCC_SupplyConversion(var_a, (*op->type_a)->type);
-//                     }
-//                             //can't convert the left componant of an assignment operation
-//                     if (var_b && var_b->type && var_b->type != op->type_b->type)
-//                             var_b = QCC_SupplyConversion(var_b, op->type_b->type->type);
+                               var_b = QCC_SupplyConversion(var_b, (*op->type_b)->type, false);
                }
        }
 
@@ -1677,73 +1708,92 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                                //both are constants
                                switch (op - pr_opcodes)        //improve some of the maths.
                                {
+                               case OP_LOADA_F:
+                               case OP_LOADA_V:
+                               case OP_LOADA_S:
+                               case OP_LOADA_ENT:
+                               case OP_LOADA_FLD:
+                               case OP_LOADA_FNC:
+                               case OP_LOADA_I:
+                                       {
+                                               QCC_def_t *nd;
+                                               nd = (void *)qccHunkAlloc (sizeof(QCC_def_t));
+                                               memset (nd, 0, sizeof(QCC_def_t));
+                                               nd->type = var_a->type;
+                                               nd->ofs = var_a->ofs + G_INT(var_b->ofs);
+                                               nd->temp = var_a->temp;
+                                               nd->constant = true;
+                                               nd->name = var_a->name;
+                                               return nd;
+                                       }
+                                       break;
                                case OP_BITOR_F:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeFloatDef((float)((int)G_FLOAT(var_a->ofs) | (int)G_FLOAT(var_b->ofs)));
+                                       return QCC_MakeFloatConst((float)((int)G_FLOAT(var_a->ofs) | (int)G_FLOAT(var_b->ofs)));
                                case OP_BITAND_F:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeFloatDef((float)((int)G_FLOAT(var_a->ofs) & (int)G_FLOAT(var_b->ofs)));
+                                       return QCC_MakeFloatConst((float)((int)G_FLOAT(var_a->ofs) & (int)G_FLOAT(var_b->ofs)));
                                case OP_MUL_F:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeFloatDef(G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs));
+                                       return QCC_MakeFloatConst(G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs));
                                case OP_DIV_F:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeFloatDef(G_FLOAT(var_a->ofs) / G_FLOAT(var_b->ofs));
+                                       return QCC_MakeFloatConst(G_FLOAT(var_a->ofs) / G_FLOAT(var_b->ofs));
                                case OP_ADD_F:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeFloatDef(G_FLOAT(var_a->ofs) + G_FLOAT(var_b->ofs));
+                                       return QCC_MakeFloatConst(G_FLOAT(var_a->ofs) + G_FLOAT(var_b->ofs));
                                case OP_SUB_F:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeFloatDef(G_FLOAT(var_a->ofs) - G_FLOAT(var_b->ofs));
+                                       return QCC_MakeFloatConst(G_FLOAT(var_a->ofs) - G_FLOAT(var_b->ofs));
 
                                case OP_BITOR_I:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeIntDef(G_INT(var_a->ofs) | G_INT(var_b->ofs));
+                                       return QCC_MakeIntConst(G_INT(var_a->ofs) | G_INT(var_b->ofs));
                                case OP_BITAND_I:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeIntDef(G_INT(var_a->ofs) & G_INT(var_b->ofs));
+                                       return QCC_MakeIntConst(G_INT(var_a->ofs) & G_INT(var_b->ofs));
                                case OP_MUL_I:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeIntDef(G_INT(var_a->ofs) * G_INT(var_b->ofs));
+                                       return QCC_MakeIntConst(G_INT(var_a->ofs) * G_INT(var_b->ofs));
                                case OP_DIV_I:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeIntDef(G_INT(var_a->ofs) / G_INT(var_b->ofs));
+                                       return QCC_MakeIntConst(G_INT(var_a->ofs) / G_INT(var_b->ofs));
                                case OP_ADD_I:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeIntDef(G_INT(var_a->ofs) + G_INT(var_b->ofs));
+                                       return QCC_MakeIntConst(G_INT(var_a->ofs) + G_INT(var_b->ofs));
                                case OP_SUB_I:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeIntDef(G_INT(var_a->ofs) - G_INT(var_b->ofs));
+                                       return QCC_MakeIntConst(G_INT(var_a->ofs) - G_INT(var_b->ofs));
 
                                case OP_AND_F:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeIntDef(G_INT(var_a->ofs) && G_INT(var_b->ofs));
+                                       return QCC_MakeIntConst(G_INT(var_a->ofs) && G_INT(var_b->ofs));
                                case OP_OR_F:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeIntDef(G_INT(var_a->ofs) || G_INT(var_b->ofs));
+                                       return QCC_MakeIntConst(G_INT(var_a->ofs) || G_INT(var_b->ofs));
                                case OP_MUL_V:  //mul_f is actually a dot-product
                                        optres_constantarithmatic++;
-                                       return QCC_MakeFloatDef(        G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+0) +
+                                       return QCC_MakeFloatConst(      G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+0) +
                                                                                                G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+1) +
                                                                                                G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+2));
                                case OP_MUL_FV:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeVectorDef(       G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+0),
+                                       return QCC_MakeVectorConst(     G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+0),
                                                                                                G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+1),
                                                                                                G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+2));
                                case OP_MUL_VF:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeVectorDef(       G_FLOAT(var_a->ofs+0) * G_FLOAT(var_b->ofs),
+                                       return QCC_MakeVectorConst(     G_FLOAT(var_a->ofs+0) * G_FLOAT(var_b->ofs),
                                                                                                G_FLOAT(var_a->ofs+1) * G_FLOAT(var_b->ofs),
                                                                                                G_FLOAT(var_a->ofs+2) * G_FLOAT(var_b->ofs));
                                case OP_ADD_V:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeVectorDef(       G_FLOAT(var_a->ofs+0) + G_FLOAT(var_b->ofs+0),
+                                       return QCC_MakeVectorConst(     G_FLOAT(var_a->ofs+0) + G_FLOAT(var_b->ofs+0),
                                                                                                G_FLOAT(var_a->ofs+1) + G_FLOAT(var_b->ofs+1),
                                                                                                G_FLOAT(var_a->ofs+2) + G_FLOAT(var_b->ofs+2));
                                case OP_SUB_V:
                                        optres_constantarithmatic++;
-                                       return QCC_MakeVectorDef(       G_FLOAT(var_a->ofs+0) - G_FLOAT(var_b->ofs+0),
+                                       return QCC_MakeVectorConst(     G_FLOAT(var_a->ofs+0) - G_FLOAT(var_b->ofs+0),
                                                                                                G_FLOAT(var_a->ofs+1) - G_FLOAT(var_b->ofs+1),
                                                                                                G_FLOAT(var_a->ofs+2) - G_FLOAT(var_b->ofs+2));
                                }
@@ -1753,6 +1803,12 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                                //a is const, b is not
                                switch (op - pr_opcodes)
                                {
+                               case OP_CONV_FTOI:
+                                       optres_constantarithmatic++;
+                                       return QCC_MakeIntConst(G_FLOAT(var_a->ofs));
+                               case OP_CONV_ITOF:
+                                       optres_constantarithmatic++;
+                                       return QCC_MakeFloatConst(G_INT(var_a->ofs));
                                case OP_BITOR_F:
                                case OP_OR_F:
                                case OP_ADD_F:
@@ -1816,6 +1872,25 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                        //b is const, a is not
                        switch (op - pr_opcodes)
                        {
+                       case OP_LOADA_F:
+                       case OP_LOADA_V:
+                       case OP_LOADA_S:
+                       case OP_LOADA_ENT:
+                       case OP_LOADA_FLD:
+                       case OP_LOADA_FNC:
+                       case OP_LOADA_I:
+                               {
+                                       QCC_def_t *nd;
+                                       nd = (void *)qccHunkAlloc (sizeof(QCC_def_t));
+                                       memset (nd, 0, sizeof(QCC_def_t));
+                                       nd->type = var_a->type;
+                                       nd->ofs = var_a->ofs + G_INT(var_b->ofs);
+                                       nd->temp = var_a->temp;
+                                       nd->constant = false;
+                                       nd->name = var_a->name;
+                                       return nd;
+                               }
+                               break;
                        case OP_BITOR_F:
                        case OP_OR_F:
                        case OP_SUB_F:
@@ -1874,7 +1949,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                                        return var_a;
                                }
                        case OP_AND_I:
-                               if (G_INT(var_b->ofs) != 0)
+                               if (G_INT(var_b->ofs) == 0)
                                {
                                        optres_constantarithmatic++;
                                        QCC_UnFreeTemp(var_a);
@@ -1887,6 +1962,14 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
 
        switch (op - pr_opcodes)
        {
+       case OP_LOADA_F:
+       case OP_LOADA_V:
+       case OP_LOADA_S:
+       case OP_LOADA_ENT:
+       case OP_LOADA_FLD:
+       case OP_LOADA_FNC:
+       case OP_LOADA_I:
+               break;
        case OP_AND_F:
                if (var_a->ofs == var_b->ofs)
                        QCC_PR_ParseWarning(WARN_CONSTANTCOMPARISON, "Parameter offsets for && are the same");
@@ -2035,8 +2118,14 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
        {
                switch(op - pr_opcodes)
                {
+               case OP_LOADA_STRUCT:
+                       /*emit this anyway. if it reaches runtime then you messed up.
+                       this is valid only if you do &foo[0]*/
+                       break;
+
+
                case OP_IF_S:
-                       var_c = QCC_PR_GetDef(type_string, "string_null", NULL, true, 1, false);
+                       var_c = QCC_PR_GetDef(type_string, "string_null", NULL, true, 0, false);
                        numstatements--;
                        var_a = QCC_PR_Statement(&pr_opcodes[OP_NE_S], var_a, var_c, NULL);
                        statement = &statements[numstatements];
@@ -2047,7 +2136,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                        break;
 
                case OP_IFNOT_S:
-                       var_c = QCC_PR_GetDef(type_string, "string_null", NULL, true, 1, false);
+                       var_c = QCC_PR_GetDef(type_string, "string_null", NULL, true, 0, false);
                        numstatements--;
                        var_a = QCC_PR_Statement(&pr_opcodes[OP_NE_S], var_a, var_c, NULL);
                        statement = &statements[numstatements];
@@ -2058,7 +2147,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                        break;
 
                case OP_IF_F:
-                       var_c = QCC_MakeFloatDef(0);
+                       var_c = QCC_MakeFloatConst(0);
                        numstatements--;
                        var_a = QCC_PR_Statement(&pr_opcodes[OP_NE_F], var_a, var_c, NULL);
                        statement = &statements[numstatements];
@@ -2069,7 +2158,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                        break;
 
                case OP_IFNOT_F:
-                       var_c = QCC_MakeFloatDef(0);
+                       var_c = QCC_MakeFloatConst(0);
                        numstatements--;
                        var_a = QCC_PR_Statement(&pr_opcodes[OP_NE_F], var_a, var_c, NULL);
                        statement = &statements[numstatements];
@@ -2086,6 +2175,13 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                        var_a = var_c;
                        var_c = var_a;
                        break;
+               case OP_ADDSTORE_I:
+                       op = &pr_opcodes[OP_ADD_I];
+                       var_c = var_b;
+                       var_b = var_a;
+                       var_a = var_c;
+                       var_c = var_a;
+                       break;
                case OP_ADDSTORE_FI:
                        op = &pr_opcodes[OP_ADD_FI];
                        var_c = var_b;
@@ -2183,13 +2279,20 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                        var_c = var_a;
                        break;
 
-               case OP_MULSTORE_V:
+               case OP_MULSTORE_VF:
                        op = &pr_opcodes[OP_MUL_VF];
                        var_c = var_b;
                        var_b = var_a;
                        var_a = var_c;
                        var_c = var_a;
                        break;
+               case OP_MULSTORE_VI:
+                       op = &pr_opcodes[OP_MUL_VI];
+                       var_c = var_b;
+                       var_b = var_a;
+                       var_a = var_c;
+                       var_c = var_a;
+                       break;
 
                case OP_BITSET_I:
                        op = &pr_opcodes[OP_BITOR_I];
@@ -2206,6 +2309,10 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                        var_c = var_a;
                        break;
 
+               case OP_STOREP_P:
+                       op = &pr_opcodes[OP_STOREP_I];
+                       break;
+
                case OP_BITCLR:
                        //b = var, a = bit field.
 
@@ -2236,8 +2343,14 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                case OP_DIVSTOREP_FI:
                case OP_DIVSTOREP_IF:
 
+               case OP_MULSTOREP_VF:
+               case OP_MULSTOREP_VI:
+               case OP_SUBSTOREP_V:
+               case OP_ADDSTOREP_V:
 
                case OP_SUBSTOREP_F:
+               case OP_SUBSTOREP_I:
+               case OP_ADDSTOREP_I:
                case OP_ADDSTOREP_F:
                case OP_MULSTOREP_F:
                case OP_DIVSTOREP_F:
@@ -2251,35 +2364,60 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                        {
                                int st;
                                int need_lock = false;
-                               for (st = numstatements-2; st>=0; st--)
+                               if (var_b->temp)
                                {
-                                       if (statements[st].op == OP_ADDRESS)
-                                               if (statements[st].c == var_b->ofs)
-                                                       break;
+                                       for (st = numstatements-2; st>=0; st--)
+                                       {
+                                               if (statements[st].op == OP_ADDRESS)
+                                                       if (statements[st].c == var_b->ofs)
+                                                               break;
 
-                                       if ((statements[st].op >= OP_CALL0 && statements[st].op <= OP_CALL8) || (statements[st].op >= OP_CALL1H && statements[st].op <= OP_CALL8H))
-                                               need_lock = true;
+                                               if ((statements[st].op >= OP_CALL0 && statements[st].op <= OP_CALL8) || (statements[st].op >= OP_CALL1H && statements[st].op <= OP_CALL8H))
+                                                       need_lock = true;
 
-                                       if (statements[st].c == var_b->ofs)
-                                               QCC_PR_ParseWarning(0, "Temp-reuse may have broken your %s", op->name);
+                                               if (statements[st].c == var_b->ofs)
+                                               {
+                                                       st = -1;
+                                                       break;
+                                               }
+                                       }
                                }
-                               if (st < 0)
-                                       QCC_PR_ParseError(ERR_INTERNAL, "XSTOREP_F: pointer was not generated from previous statement");
+                               else
+                                       st = -1;
+
                                var_c = QCC_GetTemp(*op->type_c);
-                               if (need_lock)
-                                       QCC_LockTemp(var_c); /*that temp needs to be preserved over calls*/
+                               if (st < 0)
+                               {
+                                       /*generate new OP_LOADP instruction*/
+                                       statement->op = ((*op->type_c)->type==ev_vector)?OP_LOADP_V:OP_LOADP_F;
+                                       statement->a = var_b->ofs;
+                                       statement->b = var_c->ofs;
+                                       statement->c = 0;
+                               }
+                               else
+                               {
+                                       /*it came from an OP_ADDRESS - st says the instruction*/
+                                       if (need_lock)
+                                       {
+                                               QCC_ForceLockTempForOffset(statements[st].a);
+                                               QCC_ForceLockTempForOffset(statements[st].b);
+                                               QCC_LockTemp(var_c); /*that temp needs to be preserved over calls*/
+                                       }
 
-                               statement_linenums[statement-statements] = statement_linenums[st];
-                               statement->op = OP_ADDRESS;
-                               statement->a = statements[st].a;
-                               statement->b = statements[st].b;
-                               statement->c = statements[st].c;
+                                       /*generate new OP_ADDRESS instruction - FIXME: the arguments may have changed since the original instruction*/
+                                       statement_linenums[statement-statements] = statement_linenums[st];
+                                       statement->op = OP_ADDRESS;
+                                       statement->a = statements[st].a;
+                                       statement->b = statements[st].b;
+                                       statement->c = statements[st].c;
 
-                               statement_linenums[st] = pr_source_line;
-                               statements[st].op = OP_LOAD_F;
-                               statements[st].a = statements[st].a;
-                               statements[st].b = statements[st].b;
-                               statements[st].c = var_c->ofs;
+                                       /*convert old one to an OP_LOAD*/
+                                       statement_linenums[st] = pr_source_line;
+                                       statements[st].op = ((*op->type_c)->type==ev_vector)?OP_LOAD_V:OP_LOAD_F;
+                                       statements[st].a = statements[st].a;
+                                       statements[st].b = statements[st].b;
+                                       statements[st].c = var_c->ofs;
+                               }
                        }
 
                        statement = &statements[numstatements];
@@ -2288,9 +2426,24 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                        statement_linenums[statement-statements] = pr_source_line;
                        switch(op - pr_opcodes)
                        {
+                       case OP_SUBSTOREP_V:
+                               statement->op = OP_SUB_V;
+                               break;
+                       case OP_ADDSTOREP_V:
+                               statement->op = OP_ADD_V;
+                               break;
+                       case OP_MULSTOREP_VF:
+                               statement->op = OP_MUL_VF;
+                               break;
+                       case OP_MULSTOREP_VI:
+                               statement->op = OP_MUL_VI;
+                               break;
                        case OP_SUBSTOREP_F:
                                statement->op = OP_SUB_F;
                                break;
+                       case OP_SUBSTOREP_I:
+                               statement->op = OP_SUB_I;
+                               break;
                        case OP_SUBSTOREP_IF:
                                statement->op = OP_SUB_IF;
                                break;
@@ -2318,6 +2471,9 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                        case OP_ADDSTOREP_F:
                                statement->op = OP_ADD_F;
                                break;
+                       case OP_ADDSTOREP_I:
+                               statement->op = OP_ADD_I;
+                               break;
                        case OP_MULSTOREP_F:
                                statement->op = OP_MUL_F;
                                break;
@@ -2370,7 +2526,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                                var_a = var_c;  //this is the value.
                        }
 
-                       op = &pr_opcodes[OP_STOREP_F];
+                       op = &pr_opcodes[((*op->type_c)->type==ev_vector)?OP_STOREP_V:OP_STOREP_F];
                        QCC_FreeTemp(var_c);
                        var_c = NULL;
                        QCC_FreeTemp(var_b);
@@ -2379,86 +2535,6 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
                        numstatements++;
                        break;
 
-               case OP_MULSTOREP_V:
-               case OP_SUBSTOREP_V:
-               case OP_ADDSTOREP_V:
-//                     QCC_PR_ParseWarning(0, "XSTOREP_V emulation is still experimental");
-                       QCC_UnFreeTemp(var_a);
-                       QCC_UnFreeTemp(var_b);
-                       //don't chain these... this expansion is not the same.
-                       {
-                               int st;
-                               int need_lock = false;
-                               for (st = numstatements-2; st>=0; st--)
-                               {
-                                       if (statements[st].op == OP_ADDRESS)
-                                               if (statements[st].c == var_b->ofs)
-                                                       break;
-
-                                       if ((statements[st].op >= OP_CALL0 && statements[st].op <= OP_CALL8) || (statements[st].op >= OP_CALL1H && statements[st].op <= OP_CALL8H))
-                                               need_lock = true;
-
-                                       if (statements[st].c == var_b->ofs)
-                                               QCC_PR_ParseWarning(0, "Temp-reuse may have broken your %s", op->name);
-                               }
-                               if (st < 0)
-                                       QCC_PR_ParseError(ERR_INTERNAL, "XSTOREP_V couldn't find pointer generation");
-                               var_c = QCC_GetTemp(*op->type_c);
-                               if (need_lock)
-                                       QCC_LockTemp(var_c); /*that temp needs to be preserved over calls*/
-
-                               statement_linenums[statement-statements] = statement_linenums[st];
-                               statement->op = OP_ADDRESS;
-                               statement->a = statements[st].a;
-                               statement->b = statements[st].b;
-                               statement->c = statements[st].c;
-
-                               statement_linenums[st] = pr_source_line;
-                               statements[st].op = OP_LOAD_V;
-                               statements[st].a = statements[st].a;
-                               statements[st].b = statements[st].b;
-                               statements[st].c = var_c->ofs;
-                       }
-
-                       statement = &statements[numstatements];
-                       numstatements++;
-
-                       statement_linenums[statement-statements] = pr_source_line;
-                       switch(op - pr_opcodes)
-                       {
-                       case OP_SUBSTOREP_V:
-                               statement->op = OP_SUB_V;
-                               break;
-                       case OP_ADDSTOREP_V:
-                               statement->op = OP_ADD_V;
-                               break;
-                       case OP_MULSTOREP_V:
-                               statement->op = OP_MUL_VF;
-                               break;
-                       default:        //no way will this be hit...
-                               QCC_PR_ParseError(ERR_INTERNAL, "opcode invalid 3 times %i", op - pr_opcodes);
-                       }
-                       statement->a = var_a ? var_a->ofs : 0;
-                       statement->b = var_c ? var_c->ofs : 0;
-                       QCC_FreeTemp(var_c);
-                       var_c = QCC_GetTemp(*op->type_c);
-                       statement->c = var_c ? var_c->ofs : 0;
-
-                       var_b = var_b;  //this is the ptr.
-                       QCC_FreeTemp(var_a);
-                       var_a = var_c;  //this is the value.
-                       op = &pr_opcodes[OP_STOREP_V];
-
-
-
-
-                       QCC_FreeTemp(var_c);
-                       var_c = NULL;
-                       QCC_FreeTemp(var_b);
-
-                       statement = &statements[numstatements];
-                       numstatements++;
-                       break;
                default:
                        QCC_PR_ParseError(ERR_BADEXTENSION, "Opcode \"%s|%s\" not valid for target", op->name, op->opname);
                        break;
@@ -2571,21 +2647,32 @@ QCC_def_t       *QCC_PR_ParseImmediate (void)
 
        if (pr_immediate_type == type_float)
        {
-               cn = QCC_MakeFloatDef(pr_immediate._float);
+               cn = QCC_MakeFloatConst(pr_immediate._float);
                QCC_PR_Lex ();
                return cn;
        }
        if (pr_immediate_type == type_integer)
        {
-               cn = QCC_MakeIntDef(pr_immediate._int);
+               cn = QCC_MakeIntConst(pr_immediate._int);
                QCC_PR_Lex ();
                return cn;
        }
 
        if (pr_immediate_type == type_string)
        {
-               cn = QCC_MakeStringDef(pr_immediate_string);
-               QCC_PR_Lex ();
+               char tmp[8192];
+               strcpy(tmp, pr_immediate_string);
+
+               for(;;)
+               {
+                       QCC_PR_Lex ();
+                       if (pr_token_type == tt_immediate && pr_token_type == tt_immediate)
+                               strcat(tmp, pr_immediate_string);
+                       else
+                               break;
+               } 
+
+               cn = QCC_MakeStringConst(tmp);
                return cn;
        }
 
@@ -2876,7 +2963,7 @@ QCC_def_t *QCC_PR_GenerateFunctionCall (QCC_def_t *func, QCC_def_t *arglist[], i
 
                //FIXME: problems could occur with hexen2 calling conventions when parm0/1 is 'self'
                //thiscall. copy the right ent into 'self' (if it's not the same offset)
-               d = QCC_PR_GetDef(type_entity, "self", NULL, true, 1, false);
+               d = QCC_PR_GetDef(type_entity, "self", NULL, true, 0, false);
                if (statements[laststatement-1].a != d->ofs)
                {
                        oself = QCC_GetTemp(type_entity);
@@ -2922,11 +3009,11 @@ QCC_def_t *QCC_PR_GenerateFunctionCall (QCC_def_t *func, QCC_def_t *arglist[], i
                                //first two args are passed in the call opcode, so don't need to be copied
                                arglist[i]->references++;
                                d->references++;
-                               QCC_FreeTemp(arglist[i]);
+                               /*don't free these temps yet, free them after the return check*/
                                continue;
                        }
 
-               if (arglist[i]->type->size>1 || !opt_nonvec_parms)
+               if (arglist[i]->type->size == 3 || !opt_nonvec_parms)
                        QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_V], arglist[i], d, (QCC_dstatement_t **)0xffffffff));
                else
                {
@@ -2938,12 +3025,28 @@ QCC_def_t *QCC_PR_GenerateFunctionCall (QCC_def_t *func, QCC_def_t *arglist[], i
 
        //if the return value was in use, save it off now, so that it doesn't get clobbered
        if (def_ret.temp->used)
-       {
                oldret = QCC_GetTemp(def_ret.type);
+       else
+               oldret = NULL;
+
+       /*can free temps used for arguments now*/
+       if (callconvention == OP_CALL1H)
+       {
+               for (i = 0; i < argcount && i < 2; i++)
+                       QCC_FreeTemp(arglist[i]);
+       }
+
+       if (oldret && !def_ret.temp->used)
+       {
+               QCC_FreeTemp(oldret);
+               oldret = NULL;
+       }
+       else if (def_ret.temp->used)
+       {
                if (def_ret.type->size == 3)
-                       QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_V], &def_ret, oldret, NULL));
+                       QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_V], &def_ret, oldret, (void*)0xffffffff));
                else
-                       QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], &def_ret, oldret, NULL));
+                       QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], &def_ret, oldret, (void*)0xffffffff));
                QCC_UnFreeTemp(oldret);
                QCC_UnFreeTemp(&def_ret);
                QCC_PR_ParseWarning(WARN_FIXEDRETURNVALUECONFLICT, "Return value conflict - output is inefficient");
@@ -2983,35 +3086,29 @@ QCC_def_t *QCC_PR_GenerateFunctionCall (QCC_def_t *func, QCC_def_t *arglist[], i
        if (oself)
                QCC_PR_SimpleStatement(OP_STORE_ENT, oself->ofs, d->ofs, 0, false);
 
-       for(; argcount; argcount--)
-       {
-               QCC_FreeTemp(arglist[argcount-1]);
-       }
-
        if (oldret)
        {
-               // Make sure our def_ret backup temp wasn't freed above
-               QCC_UnFreeTemp(oldret); //this bug fix was brought to you by Blub, the character \ and the number 0.
-
+               if (oldret->temp && !oldret->temp->used)
+                       QCC_PR_ParseWarning(0, "Ret was freed\n");
 
                //if we preserved the ofs_ret global, restore it here
                if (t->type == ev_variant)
                {
                        d = QCC_GetTemp(type_variant);
-                       QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, &def_ret, d, NULL));
+                       QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, &def_ret, d, (void*)0xffffffff));
                }
                else
                {
                        d = QCC_GetTemp(t->aux_type);
                        if (t->aux_type->size == 3)
-                               QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, &def_ret, d, NULL));
+                               QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, &def_ret, d, (void*)0xffffffff));
                        else
-                               QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, &def_ret, d, NULL));
+                               QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, &def_ret, d, (void*)0xffffffff));
                }
                if (def_ret.type->size == 3)
-                       QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, oldret, &def_ret, NULL));
+                       QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, oldret, &def_ret, (void*)0xffffffff));
                else
-                       QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, oldret, &def_ret, NULL));
+                       QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, oldret, &def_ret, (void*)0xffffffff));
                QCC_FreeTemp(oldret);
                QCC_UnFreeTemp(&def_ret);
                QCC_UnFreeTemp(d);
@@ -3068,9 +3165,36 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func)    //warning, the func could
 
        if (!t->num_parms&&t->type != ev_variant)       //intrinsics. These base functions have variable arguments. I would check for (...) args too, but that might be used for extended builtin functionality. (this code wouldn't compile otherwise)
        {
+               if (!strcmp(func->name, "sizeof"))
+               {
+                       QCC_type_t *t;
+                       if (!func->initialized)
+                               func->initialized = 3;
+                       func->references++;
+                       t = QCC_PR_ParseType(false, false);
+                       QCC_PR_Expect(")");
+                       return QCC_MakeIntConst(t->size * 4);
+               }
+               if (!strcmp(func->name, "_"))
+               {
+                       if (!func->initialized)
+                               func->initialized = 3;
+                       func->references++;
+                       if (pr_token_type == tt_immediate && pr_immediate_type->type == ev_string)
+                       {
+                               d = QCC_MakeTranslateStringConst(pr_immediate_string);
+                               QCC_PR_Lex();
+                       }
+                       else
+                               QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHPARM, func, "_() intrinsic accepts only a string immediate", 1);
+                       QCC_PR_Expect(")");
+                       return d;
+               }
                if (!strcmp(func->name, "random"))
                {
                        old = NULL;
+                       if (!func->initialized)
+                               func->initialized = 3;
                        func->references++;
                        if (!QCC_PR_CheckToken(")"))
                        {
@@ -3094,12 +3218,24 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func)   //warning, the func could
                                d = NULL;
                        }
 
+                       out = &def_ret;
                        if (QCC_OPCodeValid(&pr_opcodes[OP_RAND0]))
                        {
-                               if(def_ret.temp->used)
+                               if(qcc_targetformat != QCF_HEXEN2)
                                        out = QCC_GetTemp(type_float);
+                               else if (out->temp->used)
+                               {
+                                       old = QCC_GetTemp(out->type);
+                                       if (def_ret.type->size == 3)
+                                               QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_V], out, old, NULL));
+                                       else
+                                               QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], out, old, NULL));
+                                       QCC_UnFreeTemp(old);
+                                       QCC_UnFreeTemp(out);
+                                       QCC_PR_ParseWarning(WARN_FIXEDRETURNVALUECONFLICT, "Return value conflict - output is inefficient");
+                               }
                                else
-                                       out = &def_ret;
+                                       old = NULL;
 
                                if (e)
                                {
@@ -3113,15 +3249,15 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func)   //warning, the func could
                        }
                        else
                        {
-                               if (def_ret.temp->used)
+                               if (out->temp->used)
                                {
-                                       old = QCC_GetTemp(def_ret.type);
+                                       old = QCC_GetTemp(out->type);
                                        if (def_ret.type->size == 3)
-                                               QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_V], &def_ret, old, NULL));
+                                               QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_V], out, old, NULL));
                                        else
-                                               QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], &def_ret, old, NULL));
+                                               QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], out, old, NULL));
                                        QCC_UnFreeTemp(old);
-                                       QCC_UnFreeTemp(&def_ret);
+                                       QCC_UnFreeTemp(out);
                                        QCC_PR_ParseWarning(WARN_FIXEDRETURNVALUECONFLICT, "Return value conflict - output is inefficient");
                                }
                                else
@@ -3191,16 +3327,21 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func)   //warning, the func could
                                return d;
                        }
 
-                       if (def_ret.temp->used)
-                               QCC_PR_ParseWarning(0, "Return value conflict - output is likly to be invalid");
-                       def_ret.temp->used = true;
-                       def_ret.type = type_float;
-                       return &def_ret;
+                       if (out == &def_ret)
+                       {
+                               if (out->temp->used)
+                                       QCC_PR_ParseWarning(0, "Return value conflict - output is likly to be invalid");
+                               out->temp->used = true;
+                               out->type = type_float;
+                       }
+                       return out;
 
                }
                if (!strcmp(func->name, "randomv"))
                {
                        out = NULL;
+                       if (!func->initialized)
+                               func->initialized = 3;
                        func->references++;
                        if (!QCC_PR_CheckToken(")"))
                        {
@@ -3428,7 +3569,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func)     //warning, the func could
                        {
                                char genfunc[2048];
                                sprintf(genfunc, "Class*%s", rettype->name);
-                               func = QCC_PR_GetDef(type_function, genfunc, NULL, true, 1, false);
+                               func = QCC_PR_GetDef(type_function, genfunc, NULL, true, 0, false);
                                func->references++;
                        }
                        QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
@@ -3455,39 +3596,32 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func)   //warning, the func could
                {
                        //t = (a/%1) / (nextent(world)/%1)
                        //a/%1 does a (int)entity to float conversion type thing
-                       func->initialized = 1;
+                       if (!func->initialized)
+                               func->initialized = 3;
+                       func->references++;
 
                        e = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
                        QCC_PR_Expect(")");
-                       e = QCC_PR_Statement(&pr_opcodes[OP_DIV_F], e, QCC_MakeIntDef(1), (QCC_dstatement_t **)0xffffffff);
+                       e = QCC_PR_Statement(&pr_opcodes[OP_DIV_F], e, QCC_MakeIntConst(1), (QCC_dstatement_t **)0xffffffff);
 
                        d = QCC_PR_GetDef(NULL, "nextent", NULL, false, 0, false);
                        if (!d)
                                QCC_PR_ParseError(0, "the nextent builtin is not defined");
                        QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], e, &def_parms[0], (QCC_dstatement_t **)0xffffffff));
                        d = QCC_PR_Statement(&pr_opcodes[OP_CALL0], d, NULL, NULL);
-                       d = QCC_PR_Statement(&pr_opcodes[OP_DIV_F], d, QCC_MakeIntDef(1), (QCC_dstatement_t **)0xffffffff);
+                       d = QCC_PR_Statement(&pr_opcodes[OP_DIV_F], d, QCC_MakeIntConst(1), (QCC_dstatement_t **)0xffffffff);
 
                        e = QCC_PR_Statement(&pr_opcodes[OP_DIV_F], e, d, (QCC_dstatement_t **)0xffffffff);
 
                        return e;
                }
-               else if (!strcmp(func->name, "_") && !QCC_PR_CheckToken(")"))
-               {
-                       // return string as is, but set the dotranslate flag
-                       ++dotranslate;
-                       e = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
-                       --dotranslate;
-                       QCC_PR_Expect(")");
-                       return e;
-               }
        }       //so it's not an intrinsic.
 
        if (opt_precache_file)  //should we strip out all precache_file calls?
        {
                if (!strncmp(func->name,"precache_file", 13))
                {
-                       if (pr_token_type == tt_immediate && pr_immediate_type->type == ev_string)
+                       if (pr_token_type == tt_immediate && pr_immediate_type->type == ev_string && pr_scope && !strcmp(pr_scope->name, "main"))
                        {
                                optres_precache_file += strlen(pr_immediate_string);
                                QCC_PR_Lex();
@@ -3524,7 +3658,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func)     //warning, the func could
                                QCC_PR_ParseErrorPrintDef (ERR_TOOMANYPARAMETERSVARARGS, func, "More than %i parameters on varargs function", MAX_PARMS);
                        else if (arg >= MAX_PARMS+MAX_EXTRA_PARMS)
                                QCC_PR_ParseErrorPrintDef (ERR_TOOMANYTOTALPARAMETERS, func, "More than %i parameters", MAX_PARMS+MAX_EXTRA_PARMS);
-                       if (!extraparms && arg >= t->num_parms)
+                       if (!extraparms && arg >= t->num_parms && !p)
                        {
                                QCC_PR_ParseWarning (WARN_TOOMANYPARAMETERSFORFUNC, "too many parameters");
                                QCC_PR_ParsePrintDef(WARN_TOOMANYPARAMETERSFORFUNC, func);
@@ -3539,12 +3673,13 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func)   //warning, the func could
                                e = &def_parms[arg];
 
                                e->ofs = OFS_PARM0+0;
-                               QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(pr_immediate.vector[0]), e, (QCC_dstatement_t **)0xffffffff));
+                               QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(pr_immediate.vector[0]), e, (QCC_dstatement_t **)0xffffffff));
                                e->ofs = OFS_PARM0+1;
-                               QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(pr_immediate.vector[1]), e, (QCC_dstatement_t **)0xffffffff));
+                               QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(pr_immediate.vector[1]), e, (QCC_dstatement_t **)0xffffffff));
                                e->ofs = OFS_PARM0+2;
-                               QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(pr_immediate.vector[2]), e, (QCC_dstatement_t **)0xffffffff));
+                               QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(pr_immediate.vector[2]), e, (QCC_dstatement_t **)0xffffffff));
                                e->ofs = OFS_PARM0;
+                               e->type = type_vector;
 
                                QCC_PR_Lex();
                        }
@@ -3583,7 +3718,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func)     //warning, the func could
 
                        if (pr_classtype && e->type->type == ev_field && p->type != ev_field)
                        {       //convert.
-                               oself = QCC_PR_GetDef(type_entity, "self", NULL, true, 1, false);
+                               oself = QCC_PR_GetDef(type_entity, "self", NULL, true, 0, false);
                                switch(e->type->aux_type->type)
                                {
                                case ev_string:
@@ -3620,11 +3755,11 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func)   //warning, the func could
                                                e = QCC_PR_Statement(pr_opcodes+OP_CONV_FTOI, e, NULL, NULL);
                                        else if (p->type == ev_float && e->type->type == ev_integer)    //convert float -> int... is this a constant?
                                                e = QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, e, NULL, NULL);
-                                       else if (p->type == ev_function && e->type->type == ev_integer && e->constant && !((int*)qcc_pr_globals)[e->ofs])
+                                       else if ((p->type == ev_function && p->type == ev_string) && e->type->type == ev_integer && e->constant && !((int*)qcc_pr_globals)[e->ofs])
                                        {       //you're allowed to use int 0 to pass a null function pointer
                                                //this is basically because __NULL__ is defined as ~0 (int 0)
                                        }
-                                       else if (p->type != ev_variant) //can cast to variant whatever happens
+                                       else if (p->type != ev_variant && e->type->type != ev_variant)  //can cast to variant whatever happens
                                        {
                                                if (flag_laxcasts || (p->type == ev_function && e->type->type == ev_function))
                                                {
@@ -3674,7 +3809,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func)     //warning, the func could
 int constchecks;
 int varchecks;
 int typechecks;
-QCC_def_t *QCC_MakeIntDef(int value)
+QCC_def_t *QCC_MakeIntConst(int value)
 {
        QCC_def_t       *cn;
 
@@ -3708,18 +3843,23 @@ QCC_def_t *QCC_MakeIntDef(int value)
        cn->constant = true;
        cn->initialized = 1;
        cn->scope = NULL;               // always share immediates
-       cn->arraysize = 1;
+       cn->arraysize = 0;
 
-// copy the immediate to the global area
-       cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]);
+       if (!value)
+               G_INT(cn->ofs) = 0;
+       else
+       {
+       // copy the immediate to the global area
+               cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]);
 
-       G_INT(cn->ofs) = value;
+               G_INT(cn->ofs) = value;
+       }
 
 
        return cn;
 }
 
-QCC_def_t *QCC_MakeVectorDef(float a, float b, float c)
+QCC_def_t *QCC_MakeVectorConst(float a, float b, float c)
 {
        QCC_def_t       *cn;
 
@@ -3755,7 +3895,7 @@ QCC_def_t *QCC_MakeVectorDef(float a, float b, float c)
        cn->constant = true;
        cn->initialized = 1;
        cn->scope = NULL;               // always share immediates
-       cn->arraysize = 1;
+       cn->arraysize = 0;
 
 // copy the immediate to the global area
        cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_vector->type]);
@@ -3767,8 +3907,8 @@ QCC_def_t *QCC_MakeVectorDef(float a, float b, float c)
        return cn;
 }
 
-hashtable_t floatconstdefstable;
-QCC_def_t *QCC_MakeFloatDef(float value)
+extern hashtable_t floatconstdefstable;
+QCC_def_t *QCC_MakeFloatConst(float value)
 {
        QCC_def_t       *cn;
 
@@ -3796,7 +3936,7 @@ QCC_def_t *QCC_MakeFloatDef(float value)
        cn->constant = true;
        cn->initialized = 1;
        cn->scope = NULL;               // always share immediates
-       cn->arraysize = 1;
+       cn->arraysize = 0;
 
 // copy the immediate to the global area
        cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]);
@@ -3809,56 +3949,66 @@ QCC_def_t *QCC_MakeFloatDef(float value)
        return cn;
 }
 
-extern hashtable_t stringconstdefstable;
-extern hashtable_t stringconstdefstable_dotranslate;
-QCC_def_t *QCC_MakeStringDef(char *value)
+extern hashtable_t stringconstdefstable, stringconstdefstable_trans;
+int dotranslate_count;
+static QCC_def_t *QCC_MakeStringConstInternal(char *value, pbool translate)
 {
        QCC_def_t       *cn;
        int string;
-       hashtable_t *tbl = dotranslate ? &stringconstdefstable_dotranslate : &stringconstdefstable;
-       char buf[64];
 
-       cn = pHash_Get(tbl, value);
+       cn = pHash_Get(translate?&stringconstdefstable_trans:&stringconstdefstable, value);
        if (cn)
                return cn;
 
 // allocate a new one
-       cn = (void *)qccHunkAlloc (sizeof(QCC_def_t));
+       if(translate)
+       {
+               char buf[64];
+               sprintf(buf, "dotranslate_%i", ++dotranslate_count);
+               cn = (void *)qccHunkAlloc (sizeof(QCC_def_t) + strlen(buf)+1);
+               cn->name = (char*)(cn+1);
+               strcpy(cn->name, buf);
+       }
+       else
+       {
+               cn = (void *)qccHunkAlloc (sizeof(QCC_def_t));
+               cn->name = "IMMEDIATE";
+       }
        cn->next = NULL;
        pr.def_tail->next = cn;
        pr.def_tail = cn;
 
        cn->type = type_string;
-       if(dotranslate > 0)
-       {
-               sprintf(buf, "dotranslate_%d", ++dotranslate_count);
-               cn->name = strdup(buf);
-       }
-       else
-               cn->name = "IMMEDIATE";
        cn->constant = true;
        cn->initialized = 1;
        cn->scope = NULL;               // always share immediates
-       cn->arraysize = 1;
+       cn->arraysize = 0;
 
 // copy the immediate to the global area
        cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]);
 
        string = QCC_CopyString (value);
 
-       pHash_Add(tbl, strings+string, cn, qccHunkAlloc(sizeof(bucket_t)));
+       pHash_Add(translate?&stringconstdefstable_trans:&stringconstdefstable, strings+string, cn, qccHunkAlloc(sizeof(bucket_t)));
 
        G_INT(cn->ofs) = string;
 
-
        return cn;
 }
 
-QCC_type_t *QCC_PR_NewType (char *name, int basictype);
+QCC_def_t *QCC_MakeStringConst(char *value)
+{
+       return QCC_MakeStringConstInternal(value, false);
+}
+QCC_def_t *QCC_MakeTranslateStringConst(char *value)
+{
+       return QCC_MakeStringConstInternal(value, true);
+}
+
 QCC_type_t *QCC_PointerTypeTo(QCC_type_t *type)
 {
        QCC_type_t *newtype;
-       newtype = QCC_PR_NewType("POINTER TYPE", ev_pointer);
+       newtype = QCC_PR_NewType("ptr", ev_pointer, false);
        newtype->aux_type = type;
        return newtype;
 }
@@ -3938,7 +4088,7 @@ void QCC_PR_EmitFieldsForMembers(QCC_type_t *clas)
                f = QCC_MemberInParentClass(mt->name, clas->parentclass);
                if (f)
                {
-                       if (m->arraysize>1)
+                       if (m->arraysize)
                                QCC_Error(ERR_INTERNAL, "FTEQCC does not support overloaded arrays of members");
                        a=0;
                        for (o = 0; o < m->type->size; o++)
@@ -3946,16 +4096,20 @@ void QCC_PR_EmitFieldsForMembers(QCC_type_t *clas)
                        continue;
                }
 
-               for (a = 0; a < m->arraysize; a++)
+               for (a = 0; a < (m->arraysize?m->arraysize:1); a++)
                {
+                       /*if it was already set, don't go recursive and generate 500 fields for a one-member class that was intheritted from 500 times*/
+                       if (((int *)qcc_pr_globals)[o+a*mt->size+m->ofs])
+                               continue;
+
                        //we need the type in here so saved games can still work without saving ints as floats. (would be evil)
-                       ft = QCC_PR_NewType(basictypenames[mt->type], ev_field);
-                       ft->aux_type = QCC_PR_NewType(basictypenames[mt->type], mt->type);
+                       ft = QCC_PR_NewType(basictypenames[mt->type], ev_field, false);
+                       ft->aux_type = QCC_PR_NewType(basictypenames[mt->type], mt->type, false);
                        ft->aux_type->aux_type = type_void;
                        ft->size = ft->aux_type->size;
                        ft = QCC_PR_FindType(ft);
                        sprintf(membername, "__f_%s_%i", ft->name, ++basictypefield[mt->type]);
-                       f = QCC_PR_GetDef(ft, membername, NULL, true, 1, true);
+                       f = QCC_PR_GetDef(ft, membername, NULL, true, 0, true);
 
                        for (o = 0; o < m->type->size; o++)
                                ((int *)qcc_pr_globals)[o+a*mt->size+m->ofs] = ((int *)qcc_pr_globals)[o+f->ofs];
@@ -3994,7 +4148,7 @@ void QCC_PR_EmitClassFunctionTable(QCC_type_t *clas, QCC_type_t *childclas, QCC_
                if (type->type == ev_function)  //FIXME: inheritance will not install all the member functions.
                {
                        sprintf(membername, "%s::"MEMBERFIELDNAME, clas->name, type->name);
-                       member = QCC_PR_GetDef(NULL, membername, NULL, false, 1, false);
+                       member = QCC_PR_GetDef(NULL, membername, NULL, false, 0, false);
                        if (!member)
                        {
                                QCC_PR_Warning(0, NULL, 0, "Member function %s was not defined", membername);
@@ -4006,7 +4160,7 @@ void QCC_PR_EmitClassFunctionTable(QCC_type_t *clas, QCC_type_t *childclas, QCC_
                        }
                        point = QCC_PR_Statement(&pr_opcodes[OP_ADDRESS], ed, member, NULL);
                        sprintf(membername, "%s::%s", clas->name, type->name);
-                       virt = QCC_PR_GetDef(type, membername, NULL, false, 1, false);
+                       virt = QCC_PR_GetDef(type, membername, NULL, false, 0, false);
                        QCC_PR_Statement(&pr_opcodes[OP_STOREP_FNC], virt, point, NULL);
                }
        }
@@ -4029,6 +4183,8 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname)
        if (!basetype)
                QCC_PR_ParseError(ERR_INTERNAL, "Type %s was not defined...", tname);
 
+       if (numfunctions >= MAX_FUNCTIONS)
+               QCC_Error(ERR_INTERNAL, "Too many function defs");
 
        pr_scope = NULL;
        memset(basictypefield, 0, sizeof(basictypefield));
@@ -4052,7 +4208,7 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname)
        G_FUNCTION(scope->ofs) = df - functions;
 
        //locals here...
-       ed = QCC_PR_GetDef(type_entity, "ent", pr_scope, true, 1, false);
+       ed = QCC_PR_GetDef(type_entity, "ent", pr_scope, true, 0, false);
 
        virt = QCC_PR_GetDef(type_function, "spawn", NULL, false, 0, false);
        if (!virt)
@@ -4069,7 +4225,7 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname)
        if (constructor)
        {       //self = ent;
                self = QCC_PR_GetDef(type_entity, "self", NULL, false, 0, false);
-               oself = QCC_PR_GetDef(type_entity, "oself", scope, true, 1, false);
+               oself = QCC_PR_GetDef(type_entity, "oself", scope, true, 0, false);
                QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], self, oself, NULL));
                QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], ed, self, NULL));      //return to our old self. boom boom.
                QCC_PR_SimpleStatement(OP_CALL0, constructor->ofs, 0, 0, false);
@@ -4088,684 +4244,480 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname)
        locals_end = numpr_globals + basetype->size;
        df->locals = locals_end - df->parm_start;
 }
-/*
-============
-PR_ParseValue
 
-Returns the global ofs for the current token
-============
-*/
-QCC_def_t      *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
+QCC_def_t *QCC_PR_ParseArrayPointer (QCC_def_t *d, pbool allowarrayassign)
 {
-       QCC_def_t       *ao=NULL;       //arrayoffset
-       QCC_def_t               *d, *nd, *od;
-       char            *name;
+       QCC_type_t *t;
+       QCC_def_t *idx;
+       QCC_def_t *tmp;
        QCC_dstatement_t *st;
-       int i;
-       static QCC_def_t intrinsic = {
-               NULL,   // QCC_type_t           *type;
-               NULL,   // char         *name;
-               NULL,   // struct QCC_def_s     *next;
-               NULL,   // struct QCC_def_s     *nextlocal;     //provides a chain of local variables for the opt_locals_marshalling optimisation.
-               0,      // gofs_t               ofs;
-               NULL,   // struct QCC_def_s     *scope;         // function the var was defined in, or NULL
-               1,      // int                  initialized;    // 1 when a declaration included "= immediate"
-               1,      // int                  constant;               // 1 says we can use the value over and over again
-               1,      // int references;
-               0,      // int timescalled;     //part of the opt_stripfunctions optimisation.
-               0,      // int s_file;
-               0,      // int s_line;
-               0,      // int arraysize;
-               0,      // pbool shared;
-               0,      // pbool saved;
-               0,      // pbool isstatic;
-               NULL    // temp_t *temp;
-       };
+       pbool allowarray;
 
-       char membername[2048];
+       t = d->type;
+       idx = NULL;
+       while(1)
+       {
+               allowarray = false;
+               if (idx)
+                       allowarray = t->arraysize>0;
+               else if (!idx)
+               {
+                       allowarray = d->arraysize ||
+                                               (d->type->type == ev_pointer) ||
+                                               (d->type->type == ev_string) ||
+                                               (d->type->type == ev_vector);
+               }
 
-// if the token is an immediate, allocate a constant for it
-       if (pr_token_type == tt_immediate)
-               return QCC_PR_ParseImmediate ();
+               if (allowarray && QCC_PR_CheckToken("["))
+               {
+                       tmp = QCC_PR_Expression (TOP_PRIORITY, 0);
+                       QCC_PR_Expect("]");
 
-       if (QCC_PR_CheckToken("["))     //reacc support
-       {       //looks like a funky vector. :)
-               vec3_t v;
-               pr_immediate_type = type_vector;
-               v[0] = pr_immediate._float;
-               QCC_PR_Lex();
-               v[1] = pr_immediate._float;
-               QCC_PR_Lex();
-               v[2] = pr_immediate._float;
-               pr_immediate.vector[0] = v[0];
-               pr_immediate.vector[1] = v[1];
-               pr_immediate.vector[2] = v[2];
-               pr_immediate_type = type_vector;
-               d = QCC_PR_ParseImmediate();
-               QCC_PR_Expect("]");
-               return d;
-       }
-       name = QCC_PR_ParseName ();
-
-       if (assumeclass && assumeclass->parentclass)    // 'testvar' becomes 'self::testvar'
-       {       //try getting a member.
-               QCC_type_t *type;
-               type = assumeclass;
-               d = NULL;
-               while(type != type_entity && type)
-               {
-                       sprintf(membername, "%s::"MEMBERFIELDNAME, type->name, name);
-                       od = d = QCC_PR_GetDef (NULL, membername, pr_scope, false, 0, false);
-                       if (d)
-                               break;
-
-                       type = type->parentclass;
-               }
-               if (!d)
-                       od = d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0, false);
-       }
-       else
-
-// look through the defs
-       od = d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0, false);
+                       /*if its a pointer that got dereferenced, follow the type*/
+                       if (!idx && t->type == ev_pointer && !d->arraysize)
+                               t = t->aux_type;
 
-       if (!d)
-       {
-               if (    (!strcmp(name, "random" ))      ||
-                               (!strcmp(name, "randomv"))      ||
-                               (!strcmp(name, "entnum"))       ||
-                               (!strcmp(name, "_"))    )       //intrinsics, any old function with no args will do.
-               {
-                       intrinsic.name = name;
-                       intrinsic.type = type_function; // can't put that in the static var
-                       od = d = &intrinsic;
-               }
-               else if (keyword_class && !strcmp(name, "this"))
-               {
-                       if (!pr_classtype)
-                               QCC_PR_ParseError(ERR_NOTANAME, "Cannot use 'this' outside of an OO function\n");
-                       od = QCC_PR_GetDef(NULL, "self", NULL, true, 1, false);
-                       od = d = QCC_PR_DummyDef(pr_classtype, "this", pr_scope, 1, od->ofs, true, false);
-               }
-               else if (keyword_class && !strcmp(name, "super"))
-               {
-                       if (!pr_classtype)
-                               QCC_PR_ParseError(ERR_NOTANAME, "Cannot use 'super' outside of an OO function\n");
-                       od = QCC_PR_GetDef(NULL, "self", NULL, true, 1, false);
-                       od = d = QCC_PR_DummyDef(pr_classtype, "super", pr_scope, 1, od->ofs, true, false);
-               }
-               else
-               {
-                       od = d = QCC_PR_GetDef (type_variant, name, pr_scope, true, 1, false);
-                       if (!d)
-                               QCC_PR_ParseError (ERR_UNKNOWNVALUE, "Unknown value \"%s\"", name);
-                       else
+                       if (!idx && d->type->type == ev_pointer)
                        {
-                               QCC_PR_ParseWarning (ERR_UNKNOWNVALUE, "Unknown value \"%s\".", name);
+                               /*no bounds checks on pointer dereferences*/
                        }
-               }
-       }
-
-reloop:
-
-
-//FIXME: Make this work with double arrays/2nd level structures.
-//Should they just jump back to here?
-       if (QCC_PR_CheckToken("["))
-       {
-               QCC_type_t *newtype;
-               if (ao)
-               {
-                       numstatements--;        //remove the last statement
-
-                       nd = QCC_PR_Expression (TOP_PRIORITY, 0);
-                       QCC_PR_Expect("]");
-
-                       if (d->type->size != 1) //we need to multiply it to find the offset.
+                       else if (!idx && d->type->type == ev_string && !d->arraysize)
                        {
-                               if (ao->type->type == ev_integer)
-                                       nd = QCC_PR_Statement(&pr_opcodes[OP_MUL_I], nd, QCC_MakeIntDef(d->type->size), NULL);  //get add part
-                               else if (ao->type->type == ev_float)
-                                       nd = QCC_PR_Statement(&pr_opcodes[OP_MUL_F], nd, QCC_MakeFloatDef((float)d->type->size), NULL); //get add part
-                               else
+                               /*automatic runtime bounds checks on strings, I'm not going to check this too much...*/
+                       }
+                       else if (!idx && d->type->type == ev_vector && !d->arraysize)
+                       {
+                               if (tmp->constant)
                                {
-                                       QCC_PR_ParseError(ERR_BADARRAYINDEXTYPE, "Array offset is not of integer or float type");
-                                       nd = NULL;
+                                       unsigned int i;
+                                       if (tmp->type->type == ev_integer)
+                                               i = G_INT(tmp->ofs);
+                                       else if (tmp->type->type == ev_float)
+                                               i = G_FLOAT(tmp->ofs);
+                                       if (i < 0 || i >= 3)
+                                               QCC_PR_ParseErrorPrintDef(0, d, "(vector) array index out of bounds");
                                }
+                               else if (QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))
+                               {
+                                       tmp = QCC_SupplyConversion(tmp, ev_integer, true);
+                                       QCC_PR_SimpleStatement (OP_BOUNDCHECK, tmp->ofs, 3, 0, false);
+                               }
+                               t = type_float;
                        }
-
-                       if (nd->type->type == ao->type->type)
+                       else if (!((!idx)?d->arraysize:t->arraysize))
                        {
-                               if (ao->type->type == ev_integer)
-                                       ao = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], ao, nd, NULL);     //get add part
-                               else if (ao->type->type == ev_float)
-                                       ao = QCC_PR_Statement(&pr_opcodes[OP_ADD_F], ao, nd, NULL);     //get add part
-                               else
+                               QCC_PR_ParseErrorPrintDef(0, d, "array index on non-array");
+                       }
+                       else if (tmp->constant)
+                       {
+                               unsigned int i;
+                               if (tmp->type->type == ev_integer)
+                                       i = G_INT(tmp->ofs);
+                               else if (tmp->type->type == ev_float)
+                                       i = G_FLOAT(tmp->ofs);
+                               if (i < 0 || i >= ((!idx)?d->arraysize:t->arraysize))
+                                       QCC_PR_ParseErrorPrintDef(0, d, "(constant) array index out of bounds");
+                       }
+                       else
+                       {
+                               if (QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))
                                {
-                                       QCC_PR_ParseError(ERR_BADARRAYINDEXTYPE, "Array offset is not of integer or float type");
-                                       nd = NULL;
+                                       tmp = QCC_SupplyConversion(tmp, ev_integer, true);
+                                       QCC_PR_SimpleStatement (OP_BOUNDCHECK, tmp->ofs, ((!idx)?d->arraysize:t->arraysize), 0, false);
                                }
                        }
-                       else
+                       if (t->size != 1 && (idx || QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))) /*don't multiply by type size if the instruction/emulation will do that instead*/
                        {
-                               if (nd->type->type == ev_float)
-                                       nd = QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], nd, 0, NULL);
-                               ao = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], ao, nd, NULL);     //get add part
+                               if (tmp->type->type == ev_float)
+                                       tmp = QCC_PR_Statement(&pr_opcodes[OP_MUL_F], tmp, QCC_MakeFloatConst(t->size), NULL);
+                               else
+                                       tmp = QCC_PR_Statement(&pr_opcodes[OP_MUL_I], tmp, QCC_MakeIntConst(t->size), NULL);
                        }
 
-                       newtype = d->type;
-                       d = od;
+                       /*calc the new index*/
+                       if (idx)
+                               idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], idx, QCC_SupplyConversion(tmp, ev_integer, true), NULL);
+                       else
+                               idx = tmp;
                }
-               else
+               else if ((t->type == ev_pointer || t->type == ev_struct || t->type == ev_union) && (QCC_PR_CheckToken(".") || QCC_PR_CheckToken("->")))
                {
-                       ao = QCC_PR_Expression (TOP_PRIORITY, 0);
-                       QCC_PR_Expect("]");
+                       if (!idx && t->type == ev_pointer && !d->arraysize)
+                               t = t->aux_type;
 
-                       if (QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]) && d->type->size != 1)     //we need to multiply it to find the offset.
+                       for (t = t->param; t; t = t->next)
                        {
-                               if (ao->type->type == ev_integer)
-                                       ao = QCC_PR_Statement(&pr_opcodes[OP_MUL_I], ao, QCC_MakeIntDef(d->type->size), NULL);  //get add part
-                               else if (ao->type->type == ev_float)
-                                       ao = QCC_PR_Statement(&pr_opcodes[OP_MUL_F], ao, QCC_MakeFloatDef((float)d->type->size), NULL); //get add part
-                               else
+                               if (QCC_PR_CheckName(t->name))
                                {
-                                       nd = NULL;
-                                       QCC_PR_ParseError(ERR_BADARRAYINDEXTYPE, "Array offset is not of integer or float type");
+                                       break;
                                }
+                       
                        }
+                       if (!t)
+                               QCC_PR_ParseError(0, "%s is not a member", pr_token);
 
-                       newtype = d->type;
+                       tmp = QCC_MakeIntConst(t->ofs);
+                       if (idx)
+                               idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], idx, tmp, NULL);
+                       else
+                               idx = tmp;
                }
-               if (ao->type->type == ev_integer)
+               else
+                       break;
+       }
+
+       if (idx)
+       {
+               if (d->type->type == ev_pointer)
                {
-                       switch(newtype->type)
+                       switch (t->type)
                        {
+                       case ev_pointer:
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
+                               break;
                        case ev_float:
-                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_F], d, ao, NULL);    //get pointer to precise def.
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_F], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
+                               break;
+                       case ev_integer:
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
                                break;
                        case ev_string:
-                               if (d->arraysize <= 1)
-                               {
-                                       nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_C], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_ITOF], ao, 0, NULL), NULL);     //get pointer to precise def.
-                                       newtype = nd->type;//don't be fooled
-                               }
-                               else
-                               {
-                                       nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_S], d, ao, NULL);    //get pointer to precise def.
-                               }
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_S], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
                                break;
                        case ev_vector:
-                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_V], d, ao, NULL);    //get pointer to precise def.
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_V], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
                                break;
                        case ev_entity:
-                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_ENT], d, ao, NULL);  //get pointer to precise def.
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_ENT], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
                                break;
                        case ev_field:
-                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FLD], d, ao, NULL);  //get pointer to precise def.
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_FLD], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
                                break;
                        case ev_function:
-                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FNC], d, ao, NULL);  //get pointer to precise def.
-                               nd->type = d->type;
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_FNC], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
+                               break;
+                       case ev_struct:
+                       case ev_union:
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
                                break;
+
+                       default:
+                               QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler");
+                       }
+                       d->type = t;
+               }
+               else if (d->type->type == ev_string && d->arraysize == 0)
+               {
+                       d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_C], d, QCC_SupplyConversion(idx, ev_float, true), NULL);
+               }
+               else if (d->type->type == ev_vector && d->arraysize == 0)
+               {
+                       d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_F], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
+                       d->type = type_float;
+               }
+               else if (QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))
+               {
+                       /*don't care about assignments. the code can convert an OP_LOADA_F to an OP_ADDRESS on assign*/
+                       /*source type is a struct, or its an array, or something that can otherwise be directly accessed*/
+                       switch(t->type)
+                       {
                        case ev_pointer:
-                               if (ao->constant && !G_INT(ao->ofs))
-                                       ao->ofs = 0;
-                               if (d->arraysize>1)     //use the array
-                               {
-                                       nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, ao, NULL);    //get pointer to precise def.
-                                       nd->type = d->type->aux_type;
-                               }
-                               else
-                               {       //dereference the pointer.
-                                       switch(newtype->aux_type->type)
-                                       {
-                                       case ev_pointer:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, ao, NULL);    //get pointer to precise def.
-                                               nd->type = d->type->aux_type;
-                                               break;
-                                       case ev_float:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_F], d, ao, NULL);    //get pointer to precise def.
-                                               nd->type = d->type->aux_type;
-                                               break;
-                                       case ev_vector:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_V], d, ao, NULL);    //get pointer to precise def.
-                                               nd->type = d->type->aux_type;
-                                               break;
-                                       case ev_integer:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, ao, NULL);    //get pointer to precise def.
-                                               nd->type = d->type->aux_type;
-                                               break;
-                                       default:
-                                               QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler");
-                                               nd = NULL;
-                                               break;
-                                       }
-                               }
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
+                               break;
+                       case ev_float:
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_F], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
                                break;
                        case ev_integer:
-                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, ao, NULL);    //get pointer to precise def.
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
+                               break;
+                       case ev_string:
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_S], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
+                               break;
+                       case ev_vector:
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_V], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
+                               break;
+                       case ev_entity:
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_ENT], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
+                               break;
+                       case ev_field:
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FLD], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
+                               break;
+                       case ev_function:
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FNC], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
                                break;
                        case ev_struct:
-                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, ao, NULL);    //get pointer to precise def.
-                               nd->type = d->type;
+                       case ev_union:
+                               //FIXME...
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_STRUCT], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
                                break;
                        default:
                                QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler");
-                               nd = NULL;
-                               break;
                        }
-                       d=nd;
+                       d->type = t;
                }
-               else if (ao->type->type == ev_float)
+               else if (idx->constant)
                {
-                       if (qcc_targetformat == QCF_HEXEN2)
-                       {       //hexen2 style retrieval, mixed with q1 style assignments...
-                               if (QCC_PR_CheckToken("="))     //(hideous concept)
-                               {
-                                       QCC_def_t *funcretr;
-                                       QCC_def_t *args[2];
-                                       if (d->scope)
-                                               QCC_PR_ParseError(0, "Scoped array without specific engine support");
-
-                                       funcretr = QCC_PR_GetDef(type_function, qcva("ArraySet*%s", d->name), NULL, true, 1, false);
-                                       nd = QCC_PR_Expression(TOP_PRIORITY, 0);
-                                       if (nd->type->type != d->type->type)
-                                               QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, d, "Type Mismatch on array assignment");
-
-                                       args[0] = ao;
-                                       args[1] = nd;
-                                       return QCC_PR_GenerateFunctionCall(funcretr, args, 2);
-                               }
-
-                               switch(newtype->type)
-                               {
-                               case ev_float:
-                                       nd = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_F], d, ao, &st); //get pointer to precise def.
-                                       st->a = d->ofs;
-                                       break;
-                               case ev_vector:
-                                       nd = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_V], d, ao, &st); //get pointer to precise def.
-                                       st->a = d->ofs;
-                                       break;
-                               case ev_string:
-                                       nd = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_S], d, ao, &st); //get pointer to precise def.
-                                       st->a = d->ofs;
-                                       break;
-                               case ev_entity:
-                                       nd = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_E], d, ao, &st); //get pointer to precise def.
-                                       st->a = d->ofs;
-                                       break;
-                               case ev_function:
-                                       nd = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_FNC], d, ao, &st);       //get pointer to precise def.
-                                       st->a = d->ofs;
-                                       break;
-                               default:
-                                       QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler");
-                                       nd = NULL;
-                                       break;
-                               }
-                               QCC_FreeTemp(d);
-                               QCC_FreeTemp(ao);
+                       int cidx;
+                       idx = QCC_SupplyConversion(idx, ev_integer, true);
+                       cidx = G_INT(idx->ofs);
 
-                               d=nd;
-                               d->type = newtype;
-                               return d;
-                       }
-                       else
-                       {
-                               if (!QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))  //q1 compatible.
-                               {       //you didn't see this, okay?
-                                       QCC_def_t *funcretr;
-                                       if (d->scope)
-                                               QCC_PR_ParseError(0, "Scoped array without specific engine support");
+                       d->references++;
+                       tmp = (void *)qccHunkAlloc (sizeof(QCC_def_t));
+                       memcpy (tmp, d, sizeof(QCC_def_t));
+                       tmp->arraysize = 0;
+                       tmp->ofs = d->ofs + (cidx * type_size[d->type->type]);
+                       d = tmp;
 
-                                       if (allowarrayassign && QCC_PR_CheckToken("="))
-                                       {
-                                               QCC_def_t *args[2];
+                       //d can be assigned to freely
+               }
+               else if (allowarrayassign && QCC_PR_CheckToken("="))
+               {
+                       /*if its assigned to, generate a functioncall to do the store*/
+                       QCC_def_t *args[2], *funcretr, *rhs;
 
-                                               funcretr = QCC_PR_GetDef(type_function, qcva("ArraySet*%s", d->name), NULL, true, 1, false);
+                       d->references++;
+                       funcretr = QCC_PR_GetDef(type_function, qcva("ArraySet*%s", d->name), NULL, true, 0, false);
 
-                                               nd = QCC_PR_Expression(TOP_PRIORITY, 0);
-                                               if (nd->type->type != d->type->type)
-                                                       QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, d, "Type Mismatch on array assignment");
+                       rhs = QCC_PR_Expression(TOP_PRIORITY, 0);
+                       if (rhs->type->type != d->type->type)
+                               QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, d, "Type Mismatch on array assignment");
 
-                                               args[0] = ao;
-                                               args[1] = nd;
-                                               qcc_usefulstatement=true;
-                                               nd = QCC_PR_GenerateFunctionCall(funcretr, args, 2);
-                                               nd->type = d->type->aux_type;
-                                       }
-                                       else
-                                       {
-                                               QCC_def_t *args[1];
-
-                                               def_parms[0].type = type_float;
-                                               funcretr = QCC_PR_GetDef(type_function, qcva("ArrayGet*%s", d->name), NULL, true, 1, false);
+                       args[0] = QCC_SupplyConversion(idx, ev_float, true);
+                       args[1] = rhs;
+                       qcc_usefulstatement=true;
+                       d = QCC_PR_GenerateFunctionCall(funcretr, args, 2);
+                       d->type = t;
 
-                                               args[0] = ao;
-                                               nd = QCC_PR_GenerateFunctionCall(funcretr, args, 1);
-                                               nd->type = d->type->aux_type;
-                                       }
-                               }
-                               else
-                               {
-                                       switch(newtype->type)
-                                       {
-                                       case ev_pointer:
-                                               if (d->arraysize>1)     //use the array
-                                               {
-                                                       nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL);     //get pointer to precise def.
-                                                       nd->type = d->type->aux_type;
-                                               }
-                                               else
-                                               {       //dereference the pointer.
-                                                       switch(newtype->aux_type->type)
-                                                       {
-                                                       case ev_pointer:
-                                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL);     //get pointer to precise def.
-                                                               nd->type = d->type->aux_type;
-                                                               break;
-                                                       case ev_float:
-                                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_F], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL);     //get pointer to precise def.
-                                                               nd->type = d->type->aux_type;
-                                                               break;
-                                                       case ev_vector:
-                                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_V], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL);     //get pointer to precise def.
-                                                               nd->type = d->type->aux_type;
-                                                               break;
-                                                       case ev_integer:
-                                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL);     //get pointer to precise def.
-                                                               nd->type = d->type->aux_type;
-                                                               break;
-                                                       default:
-                                                               QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler");
-                                                               nd = NULL;
-                                                               break;
-                                                       }
-                                               }
-                                               break;
+                       return d;
+               }
+               else if (QCC_OPCodeValid(&pr_opcodes[OP_FETCH_GBL_F]))
+               {
+                       if (!d->arraysize)
+                               QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, d, "array lookup on non-array");
 
-                                       case ev_float:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_F], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL);     //get pointer to precise def.
-                                               break;
-                                       case ev_string:
-                                               if (d->arraysize <= 1)
-                                               {
-                                                       nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_C], d, ao, NULL);    //get pointer to precise def.
-                                                       newtype = nd->type;//don't be fooled
-                                               }
-                                               else
-                                                       nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_S], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL);     //get pointer to precise def.
-                                               break;
-                                       case ev_vector:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_V], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL);     //get pointer to precise def.
-                                               break;
-                                       case ev_entity:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_ENT], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL);   //get pointer to precise def.
-                                               break;
-                                       case ev_field:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FLD], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL);   //get pointer to precise def.
-                                               break;
-                                       case ev_function:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FNC], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL);   //get pointer to precise def.
-                                               nd->type = d->type;
-                                               break;
-                                       case ev_integer:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL);     //get pointer to precise def.
-                                               break;
+                       if (d->temp)
+                               QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, d, "array lookup on a temp");
 
-                                       case ev_struct:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL);     //get pointer to precise def.
-                                               nd->type = d->type;
-                                               break;
-                                       default:
-                                               QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler");
-                                               nd = NULL;
-                                               break;
-                                       }
-                               }
+                       /*hexen2 format has opcodes to read arrays (but has no way to write)*/
+                       switch(t->type)
+                       {
+                       case ev_float:
+                               d = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_F], d, QCC_SupplyConversion(idx, ev_float, true), &st);   //get pointer to precise def.
+//                             st->a = d->ofs;
+                               break;
+                       case ev_vector:
+                               d = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_V], d, QCC_SupplyConversion(idx, ev_float, true), &st);   //get pointer to precise def.
+//                             st->a = d->ofs;
+                               break;
+                       case ev_string:
+                               d = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_S], d, QCC_SupplyConversion(idx, ev_float, true), &st);   //get pointer to precise def.
+//                             st->a = d->ofs;
+                               break;
+                       case ev_entity:
+                               d = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_E], d, QCC_SupplyConversion(idx, ev_float, true), &st);   //get pointer to precise def.
+//                             st->a = d->ofs;
+                               break;
+                       case ev_function:
+                               d = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_FNC], d, QCC_SupplyConversion(idx, ev_float, true), &st); //get pointer to precise def.
+//                             st->a = d->ofs;
+                               break;
+                       default:
+                               QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler");
+                               d = NULL;
+                               break;
                        }
-                       d=nd;
+                       d->type = t;
                }
                else
-                       QCC_PR_ParseError(ERR_BADARRAYINDEXTYPE, "Array offset is not of integer or float type");
-
-               d->type = newtype;
-               goto reloop;
-       }
+               {
+                       /*emulate the array access using a function call to do the read for us*/
+                       QCC_def_t *args[1], *funcretr;
 
+                       d->references++;
 
-       i = d->type->type;
-       if (i == ev_pointer)
-       {
-               int j;
-               QCC_type_t *type;
-               if (QCC_PR_CheckToken(".") || QCC_PR_CheckToken("->"))
-               {
-                       for (i = d->type->num_parms, type = d->type+1; i; i--, type++)
-                       {
-                               if (QCC_PR_CheckName(type->name))
-                               {
-                                       //give result
-                                       if (ao)
-                                       {
-                                               numstatements--;        //remove the last statement
-                                               d = od;
+                       /*make sure the function type that we're calling exists*/
+                       def_parms[0].type = type_float;
+                       funcretr = QCC_PR_GetDef(type_function, qcva("ArrayGet*%s", d->name), NULL, true, 0, false);
 
-                                               nd = QCC_MakeIntDef(type->ofs);
-                                               ao = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], ao, nd, NULL);     //get add part
+                       args[0] = QCC_SupplyConversion(idx, ev_float, true);
+                       d = QCC_PR_GenerateFunctionCall(funcretr, args, 1);
+                       d->type = t;
+               }
 
-                                               //so that we may offset it and readd it.
-                                       }
-                                       else
-                                               ao = QCC_MakeIntDef(type->ofs);
-                                       switch (type->type)
-                                       {
-                                       case ev_float:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_F], d, ao, NULL);    //get pointer to precise def.
-                                               break;
-                                       case ev_string:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_S], d, ao, NULL);    //get pointer to precise def.
-                                               break;
-                                       case ev_vector:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_V], d, ao, NULL);    //get pointer to precise def.
-                                               break;
-                                       case ev_entity:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_ENT], d, ao, NULL);  //get pointer to precise def.
-                                               break;
-                                       case ev_field:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_FLD], d, ao, NULL);  //get pointer to precise def.
-                                               break;
-                                       case ev_function:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_FNC], d, ao, NULL);  //get pointer to precise def.
-                                               nd->type = type;
-                                               break;
-                                       case ev_integer:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, ao, NULL);    //get pointer to precise def.
-                                               break;
+               /*parse recursively*/
+               d = QCC_PR_ParseArrayPointer(d, allowarrayassign);
+       }
 
-//                                     case ev_struct:
-                                               //no suitable op.
-//                                             nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, ao, NULL);    //get pointer to precise def.
-//                                             nd->type = type;
-//                                             break;
-                                       default:
-                                               QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler");
-                                               nd = NULL;
-                                               break;
-                                       }
+       return d;
+}
 
-                                       d=nd;
-                                       break;
-                               }
-                               if (type->num_parms)
-                               {
-                                       for (j = type->num_parms; j;j--)
-                                               type++;
-                               }
-                       }
-                       if (!i)
-                               QCC_PR_ParseError (ERR_MEMBERNOTVALID, "\"%s\" is not a member of \"%s\"", pr_token, od->type->name);
+/*
+============
+PR_ParseValue
 
-                       goto reloop;
-               }
-       }
-       else if (i == ev_struct || i == ev_union)
-       {
-               int j;
-               QCC_type_t *type;
-               if (QCC_PR_CheckToken(".") || QCC_PR_CheckToken("->"))
-               {
-                       for (i = d->type->num_parms, type = d->type+1; i; i--, type++)
-                       {
-                               if (QCC_PR_CheckName(type->name))
-                               {
-                                       //give result
-                                       if (ao)
-                                       {
-                                               numstatements--;        //remove the last statement
-                                               d = od;
+Returns the global ofs for the current token
+============
+*/
+QCC_def_t      *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
+{
+       QCC_def_t               *d, *od, *tmp;
+       QCC_type_t              *t;
+       char            *name;
 
-                                               nd = QCC_MakeIntDef(type->ofs);
-                                               ao = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], ao, nd, NULL);     //get add part
+       char membername[2048];
 
-                                               //so that we may offset it and readd it.
-                                       }
-                                       else
-                                               ao = QCC_MakeIntDef(type->ofs);
-                                       switch (type->type)
-                                       {
-                                       case ev_float:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_F], d, ao, NULL);    //get pointer to precise def.
-                                               break;
-                                       case ev_string:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_S], d, ao, NULL);    //get pointer to precise def.
-                                               break;
-                                       case ev_vector:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_V], d, ao, NULL);    //get pointer to precise def.
-                                               break;
-                                       case ev_entity:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_ENT], d, ao, NULL);  //get pointer to precise def.
-                                               break;
-                                       case ev_field:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FLD], d, ao, NULL);  //get pointer to precise def.
-                                               break;
-                                       case ev_function:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FNC], d, ao, NULL);  //get pointer to precise def.
-                                               nd->type = type;
-                                               break;
-                                       case ev_integer:
-                                               nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, ao, NULL);    //get pointer to precise def.
-                                               break;
+// if the token is an immediate, allocate a constant for it
+       if (pr_token_type == tt_immediate)
+               return QCC_PR_ParseImmediate ();
 
-//                                     case ev_struct:
-                                               //no suitable op.
-//                                             nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, ao, NULL);    //get pointer to precise def.
-//                                             nd->type = type;
-//                                             break;
-                                       default:
-                                               QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler");
-                                               nd = NULL;
-                                               break;
-                                       }
+       if (QCC_PR_CheckToken("["))     //reacc support
+       {       //looks like a funky vector. :)
+               vec3_t v;
+               pr_immediate_type = type_vector;
+               v[0] = pr_immediate._float;
+               QCC_PR_Lex();
+               v[1] = pr_immediate._float;
+               QCC_PR_Lex();
+               v[2] = pr_immediate._float;
+               pr_immediate.vector[0] = v[0];
+               pr_immediate.vector[1] = v[1];
+               pr_immediate.vector[2] = v[2];
+               pr_immediate_type = type_vector;
+               d = QCC_PR_ParseImmediate();
+               QCC_PR_Expect("]");
+               return d;
+       }
+       name = QCC_PR_ParseName ();
 
-                                       d=nd;
-                                       break;
-                               }
-                               if (type->num_parms)
-                               {
-                                       for (j = type->num_parms; j;j--)
-                                               type++;
-                               }
-                       }
-                       if (!i)
-                               QCC_PR_ParseError (ERR_MEMBERNOTVALID, "\"%s\" is not a member of \"%s\"", pr_token, od->type->name);
+       if (assumeclass && assumeclass->parentclass)    // 'testvar' becomes 'self::testvar'
+       {       //try getting a member.
+               QCC_type_t *type;
+               type = assumeclass;
+               d = NULL;
+               while(type != type_entity && type)
+               {
+                       sprintf(membername, "%s::"MEMBERFIELDNAME, type->name, name);
+                       d = QCC_PR_GetDef (NULL, membername, pr_scope, false, 0, false);
+                       if (d)
+                               break;
 
-                       goto reloop;
+                       type = type->parentclass;
                }
+               if (!d)
+                       d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0, false);
+       }
+       else
+       {
+               // look through the defs
+               d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0, false);
        }
 
-/*     if (d->type->type == ev_pointer)
-       {       //expand now, not in function call/maths parsing
-               switch(d->type->aux_type->type)
+       if (!d)
+       {
+               if (    (!strcmp(name, "random" ))      ||
+                               (!strcmp(name, "randomv"))      ||
+                               (!strcmp(name, "sizeof"))       ||
+                               (!strcmp(name, "entnum"))       ||
+                               (!strcmp(name, "_")))   //intrinsics, any old function with no args will do.
                {
-               case ev_string:
-                       d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_S], d, NULL, NULL);
-                       break;
-               case ev_float:
-                       d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_F], d, NULL, NULL);
-                       break;
+                       d = QCC_PR_GetDef (type_function, name, NULL, true, 0, false);
+                       d->initialized = 0;
+               }
+               else if (keyword_class && !strcmp(name, "this"))
+               {
+                       if (!pr_classtype)
+                               QCC_PR_ParseError(ERR_NOTANAME, "Cannot use 'this' outside of an OO function\n");
+                       od = QCC_PR_GetDef(NULL, "self", NULL, true, 0, false);
+                       d = QCC_PR_DummyDef(pr_classtype, "this", pr_scope, 0, od->ofs, true, false);
+               }
+               else if (keyword_class && !strcmp(name, "super"))
+               {
+                       if (!pr_classtype)
+                               QCC_PR_ParseError(ERR_NOTANAME, "Cannot use 'super' outside of an OO function\n");
+                       od = QCC_PR_GetDef(NULL, "self", NULL, true, 0, false);
+                       d = QCC_PR_DummyDef(pr_classtype, "super", pr_scope, 0, od->ofs, true, false);
+               }
+               else
+               {
+                       d = QCC_PR_GetDef (type_variant, name, pr_scope, true, 0, false);
+                       if (!d)
+                               QCC_PR_ParseError (ERR_UNKNOWNVALUE, "Unknown value \"%s\"", name);
+                       else
+                       {
+                               QCC_PR_ParseWarning (ERR_UNKNOWNVALUE, "Unknown value \"%s\".", name);
+                       }
                }
        }
-*/
-       if (!keyword_class)
-               return d;
 
-       if (d->type->parentclass||d->type->type == ev_entity)   //class
+       d = QCC_PR_ParseArrayPointer(d, allowarrayassign);
+
+       t = d->type;
+       if (keyword_class && t->type == ev_entity && t->parentclass && (QCC_PR_CheckToken(".") || QCC_PR_CheckToken("->")))
        {
-               if (QCC_PR_CheckToken(".") || QCC_PR_CheckToken("->"))
+               QCC_def_t *field;
+               if (QCC_PR_CheckToken("("))
                {
-                       QCC_def_t *field;
-                       if (QCC_PR_CheckToken("("))
+                       field = QCC_PR_Expression(TOP_PRIORITY, 0);
+                       QCC_PR_Expect(")");
+               }
+               else
+                       field = QCC_PR_ParseValue(d->type, false);
+               if (field->type->type == ev_field)
+               {
+                       if (!field->type->aux_type)
                        {
-                               field = QCC_PR_Expression(TOP_PRIORITY, 0);
-                               QCC_PR_Expect(")");
+                               QCC_PR_ParseWarning(ERR_INTERNAL, "Field with null aux_type");
+                               d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_FLD], d, field, NULL);
                        }
                        else
-                               field = QCC_PR_ParseValue(d->type, false);
-                       if (field->type->type == ev_field)
-                       {
-                               if (!field->type->aux_type)
-                               {
-                                       QCC_PR_ParseWarning(ERR_INTERNAL, "Field with null aux_type");
-                                       return QCC_PR_Statement(&pr_opcodes[OP_LOAD_FLD], d, field, NULL);
-                               }
-                               else
-                               {
-                                       switch(field->type->aux_type->type)
-                                       {
-                                       default:
-                                               QCC_PR_ParseError(ERR_INTERNAL, "Bad field type");
-                                               return d;
-                                       case ev_integer:
-                                               return QCC_PR_Statement(&pr_opcodes[OP_LOAD_I], d, field, NULL);
-                                       case ev_field:
-                                               d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_FLD], d, field, NULL);
-                                               nd = (void *)qccHunkAlloc (sizeof(QCC_def_t));
-                                               memset (nd, 0, sizeof(QCC_def_t));
-                                               nd->type = field->type->aux_type;
-                                               nd->ofs = d->ofs;
-                                               nd->temp = d->temp;
-                                               nd->constant = false;
-                                               nd->name = d->name;
-                                               return nd;
-                                       case ev_float:
-                                               return QCC_PR_Statement(&pr_opcodes[OP_LOAD_F], d, field, NULL);
-                                       case ev_string:
-                                               return QCC_PR_Statement(&pr_opcodes[OP_LOAD_S], d, field, NULL);
-                                       case ev_vector:
-                                               return QCC_PR_Statement(&pr_opcodes[OP_LOAD_V], d, field, NULL);
-                                       case ev_function:
-                                               {       //complicated for a typecast
-                                               d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_FNC], d, field, NULL);
-                                               nd = (void *)qccHunkAlloc (sizeof(QCC_def_t));
-                                               memset (nd, 0, sizeof(QCC_def_t));
-                                               nd->type = field->type->aux_type;
-                                               nd->ofs = d->ofs;
-                                               nd->temp = d->temp;
-                                               nd->constant = false;
-                                               nd->name = d->name;
-                                               return nd;
-
-                                               }
-                                       case ev_entity:
-                                               return QCC_PR_Statement(&pr_opcodes[OP_LOAD_ENT], d, field, NULL);
-                                       }
+                       {
+                               switch(field->type->aux_type->type)
+                               {
+                               default:
+                                       QCC_PR_ParseError(ERR_INTERNAL, "Bad field type");
+                                       break;
+                               case ev_integer:
+                                       d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_I], d, field, NULL);
+                                       break;
+                               case ev_field:
+                                       d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_FLD], d, field, NULL);
+                                       tmp = (void *)qccHunkAlloc (sizeof(QCC_def_t));
+                                       memset (tmp, 0, sizeof(QCC_def_t));
+                                       tmp->type = field->type->aux_type;
+                                       tmp->ofs = d->ofs;
+                                       tmp->temp = d->temp;
+                                       tmp->constant = false;
+                                       tmp->name = d->name;
+                                       d = tmp;
+                                       break;
+                               case ev_float:
+                                       d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_F], d, field, NULL);
+                                       break;
+                               case ev_string:
+                                       d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_S], d, field, NULL);
+                                       break;
+                               case ev_vector:
+                                       d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_V], d, field, NULL);
+                                       break;
+                               case ev_function:
+                                       d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_FNC], d, field, NULL);
+                                       tmp = (void *)qccHunkAlloc (sizeof(QCC_def_t));
+                                       memset (tmp, 0, sizeof(QCC_def_t));
+                                       tmp->type = field->type->aux_type;
+                                       tmp->ofs = d->ofs;
+                                       tmp->temp = d->temp;
+                                       tmp->constant = false;
+                                       tmp->name = d->name;
+                                       d = tmp;
+                                       break;
+                               case ev_entity:
+                                       d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_ENT], d, field, NULL);
+                                       break;
                                }
                        }
-                       else
-                               QCC_PR_IncludeChunk(".", false, NULL);
                }
+               else
+                       QCC_PR_IncludeChunk(".", false, NULL);
        }
 
        return d;
@@ -4794,10 +4746,10 @@ QCC_def_t *QCC_PR_Term (void)
                        switch (e->type->type)
                        {
                        case ev_integer:
-                               QCC_PR_Statement3(&pr_opcodes[OP_ADD_I], e, QCC_MakeIntDef(1), e, false);
+                               QCC_PR_Statement3(&pr_opcodes[OP_ADD_I], e, QCC_MakeIntConst(1), e, false);
                                break;
                        case ev_float:
-                               QCC_PR_Statement3(&pr_opcodes[OP_ADD_F], e, QCC_MakeFloatDef(1), e, false);
+                               QCC_PR_Statement3(&pr_opcodes[OP_ADD_F], e, QCC_MakeFloatConst(1), e, false);
                                break;
                        default:
                                QCC_PR_ParseError(ERR_BADPLUSPLUSOPERATOR, "++ operator on unsupported type");
@@ -4816,10 +4768,10 @@ QCC_def_t *QCC_PR_Term (void)
                        switch (e->type->type)
                        {
                        case ev_integer:
-                               QCC_PR_Statement3(&pr_opcodes[OP_SUB_I], e, QCC_MakeIntDef(1), e, false);
+                               QCC_PR_Statement3(&pr_opcodes[OP_SUB_I], e, QCC_MakeIntConst(1), e, false);
                                break;
                        case ev_float:
-                               QCC_PR_Statement3(&pr_opcodes[OP_SUB_F], e, QCC_MakeFloatDef(1), e, false);
+                               QCC_PR_Statement3(&pr_opcodes[OP_SUB_F], e, QCC_MakeFloatConst(1), e, false);
                                break;
                        default:
                                QCC_PR_ParseError(ERR_BADPLUSPLUSOPERATOR, "-- operator on unsupported type");
@@ -4857,18 +4809,30 @@ QCC_def_t *QCC_PR_Term (void)
                else if (QCC_PR_CheckToken ("&"))
                {
                        int st = numstatements;
-                       e = QCC_PR_Expression (UNARY_PRIORITY, 0);
+                       e = QCC_PR_Expression (UNARY_PRIORITY, EXPR_DISALLOW_COMMA);
                        t = e->type->type;
 
                        if (st != numstatements)
                                //woo, something like ent.field?
                        {
-                               if ((unsigned)(statements[numstatements-1].op - OP_LOAD_F) < 6 || statements[numstatements-1].op == OP_LOAD_I || statements[numstatements-1].op == OP_LOAD_P)
+                               if ((OP_LOAD_F <= statements[numstatements-1].op && statements[numstatements-1].op <= OP_LOAD_FNC) || statements[numstatements-1].op == OP_LOAD_I || statements[numstatements-1].op == OP_LOAD_P)
                                {
                                        statements[numstatements-1].op = OP_ADDRESS;
                                        e->type = QCC_PR_PointerType(e->type);
                                        return e;
                                }
+                               else if (OP_LOADA_F <= statements[numstatements-1].op && statements[numstatements-1].op <= OP_LOADA_I)
+                               {
+                                       statements[numstatements-1].op = OP_GLOBALADDRESS;
+                                       e->type = QCC_PR_PointerType(e->type);
+                                       return e;
+                               }
+                               else if (OP_LOADP_F <= statements[numstatements-1].op && statements[numstatements-1].op <= OP_LOADP_I)
+                               {
+                                       statements[numstatements-1].op = OP_POINTER_ADD;
+                                       e->type = QCC_PR_PointerType(e->type);
+                                       return e;
+                               }
                                else    //this is a restriction that could be lifted, I just want to make sure that I got all the bits first.
                                {
                                        QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for '&' Must be singular expression or field reference");
@@ -4886,62 +4850,65 @@ QCC_def_t *QCC_PR_Term (void)
                }
                else if (QCC_PR_CheckToken ("*"))
                {
-                       e = QCC_PR_Expression (UNARY_PRIORITY, 0);
+                       e = QCC_PR_Expression (UNARY_PRIORITY, EXPR_DISALLOW_COMMA);
                        t = e->type->type;
 
-                       if (t != ev_pointer)
-                               QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for *");
-
-                       switch(e->type->aux_type->type)
+                       if (t == ev_string)
+                               e2 = QCC_PR_Statement(&pr_opcodes[OP_LOADP_C], e, QCC_MakeFloatConst(0), NULL);
+                       else if (t == ev_pointer)
                        {
-                       case ev_float:
-                               e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_F], e, 0, NULL);
-                               break;
-                       case ev_string:
-                               e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_S], e, 0, NULL);
-                               break;
-                       case ev_vector:
-                               e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_V], e, 0, NULL);
-                               break;
-                       case ev_entity:
-                               e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_ENT], e, 0, NULL);
-                               break;
-                       case ev_field:
-                               e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_FLD], e, 0, NULL);
-                               break;
-                       case ev_function:
-                               e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_FLD], e, 0, NULL);
-                               break;
-                       case ev_integer:
-                               e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_I], e, 0, NULL);
-                               break;
-                       case ev_pointer:
-                               e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_I], e, 0, NULL);
-                               break;
+                               switch(e->type->aux_type->type)
+                               {
+                               case ev_float:
+                                       e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_F], e, 0, NULL);
+                                       break;
+                               case ev_string:
+                                       e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_S], e, 0, NULL);
+                                       break;
+                               case ev_vector:
+                                       e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_V], e, 0, NULL);
+                                       break;
+                               case ev_entity:
+                                       e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_ENT], e, 0, NULL);
+                                       break;
+                               case ev_field:
+                                       e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_FLD], e, 0, NULL);
+                                       break;
+                               case ev_function:
+                                       e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_FLD], e, 0, NULL);
+                                       break;
+                               case ev_integer:
+                                       e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_I], e, 0, NULL);
+                                       break;
+                               case ev_pointer:
+                                       e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_I], e, 0, NULL);
+                                       break;
 
-                       default:
-                               QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for * (unrecognised type)");
-                               e2 = NULL;
-                               break;
+                               default:
+                                       QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for * (unrecognised type)");
+                                       e2 = NULL;
+                                       break;
+                               }
+                               e2->type = e->type->aux_type;
                        }
-
-                       e2->type = e->type->aux_type;
+                       else
+                               QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for *");
                        return e2;
                }
                else if (QCC_PR_CheckToken ("-"))
                {
-                       e = QCC_PR_Expression (UNARY_PRIORITY, 0);
+                       e = QCC_PR_Expression (UNARY_PRIORITY, EXPR_DISALLOW_COMMA);
 
                        switch(e->type->type)
                        {
                        case ev_float:
-                               e2 = QCC_PR_Statement (&pr_opcodes[OP_SUB_F], QCC_MakeFloatDef(0), e, NULL);
+                               e2 = QCC_PR_Statement (&pr_opcodes[OP_SUB_F], QCC_MakeFloatConst(0), e, NULL);
                                break;
                        case ev_vector:
-                               e2 = QCC_PR_Statement (&pr_opcodes[OP_SUB_V], QCC_MakeVectorDef(0, 0, 0), e, NULL);
+                               e2 = QCC_PR_Statement (&pr_opcodes[OP_SUB_V], QCC_MakeVectorConst(0, 0, 0), e, NULL);
                                break;
                        case ev_integer:
-                               e2 = QCC_PR_Statement (&pr_opcodes[OP_SUB_I], QCC_MakeIntDef(0), e, NULL);
+                               e2 = QCC_PR_Statement (&pr_opcodes[OP_SUB_I], QCC_MakeIntConst(0), e, NULL);
                                break;
                        default:
                                QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for -");
@@ -4952,7 +4919,7 @@ QCC_def_t *QCC_PR_Term (void)
                }
                else if (QCC_PR_CheckToken ("+"))
                {
-                       e = QCC_PR_Expression (UNARY_PRIORITY, 0);
+                       e = QCC_PR_Expression (UNARY_PRIORITY, EXPR_DISALLOW_COMMA);
 
                        switch(e->type->type)
                        {
@@ -4975,7 +4942,72 @@ QCC_def_t *QCC_PR_Term (void)
 
                if (QCC_PR_CheckToken ("("))
                {
-                       if (QCC_PR_CheckKeyword(keyword_float, "float"))        //check for type casts
+                       QCC_type_t *newtype;
+                       newtype = QCC_PR_ParseType(false, true);
+                       if (newtype)
+                       {
+                               QCC_PR_Expect (")");
+                               e = QCC_PR_Expression (UNARY_PRIORITY, EXPR_DISALLOW_COMMA);
+
+                               /*you may cast from a type to itself*/
+                               if (!typecmp(e->type, newtype))
+                               {
+                               }
+                               /*you may cast from const 0 to any type of same size for free (from either int or float for simplicity)*/
+                               else if (newtype->size == e->type->size && (e->type->type == ev_integer || e->type->type == ev_float) && e->constant && !G_INT(e->ofs))
+                               {
+                                       //direct cast
+                                       e2 = (void *)qccHunkAlloc (sizeof(QCC_def_t));
+                                       memset (e2, 0, sizeof(QCC_def_t));
+
+                                       e2->type = newtype;
+                                       e2->ofs = e->ofs;
+                                       e2->constant = true;
+                                       e2->temp = e->temp;
+                                       return e2;
+                               }
+                               /*cast from int->float will convert*/
+                               else if (newtype->type == ev_float && e->type->type == ev_integer)
+                                       return QCC_PR_Statement (&pr_opcodes[OP_CONV_ITOF], e, 0, NULL);
+                               /*cast from float->int will convert*/
+                               else if (newtype->type == ev_integer && e->type->type == ev_float)
+                                       return QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], e, 0, NULL);
+                               /*you may freely cast between pointers (and ints, as this is explicit) (strings count as pointers - WARNING: some strings may not be expressable as pointers)*/
+                               else if (
+                                       //pointers
+                                       ((newtype->type == ev_pointer || newtype->type == ev_string || newtype->type == ev_integer) && (e->type->type == ev_pointer || e->type->type == ev_string || e->type->type == ev_integer))
+                                       //ents/classs
+                                       || (newtype->type == ev_entity && e->type->type == ev_entity)
+                                       //variants are fine too
+                                       || (newtype->type == ev_variant || e->type->type == ev_variant)
+                                       )
+                               {
+                                       //direct cast
+                                       e2 = (void *)qccHunkAlloc (sizeof(QCC_def_t));
+                                       memset (e2, 0, sizeof(QCC_def_t));
+
+                                       e2->type = newtype;
+                                       e2->ofs = e->ofs;
+                                       e2->constant = true;
+                                       e2->temp = e->temp;
+                                       return e2;
+                               }
+                               else
+                                       QCC_PR_ParseError(0, "Bad type cast\n");
+                       }
+/*                     else if (QCC_PR_CheckToken("*"))
+                       {
+                               QCC_PR_Expect (")");
+                               e = QCC_PR_Term();
+                               e2 = (void *)qccHunkAlloc (sizeof(QCC_def_t));
+                               memset (e2, 0, sizeof(QCC_def_t));
+                               e2->type = type_pointer;
+                               e2->ofs = e->ofs;
+                               e2->constant = true;
+                               e2->temp = e->temp;
+                               return e2;
+                       }
+                       else if (QCC_PR_CheckKeyword(keyword_float, "float"))   //check for type casts
                        {
                                QCC_PR_Expect (")");
                                e = QCC_PR_Term();
@@ -5036,7 +5068,7 @@ QCC_def_t *QCC_PR_Term (void)
                                else
                                        QCC_PR_ParseError (ERR_BADTYPECAST, "invalid typecast");
                        }
-                       else
+*/                     else
                        {
                                pbool oldcond = conditional;
                                conditional = conditional?2:0;
@@ -5068,6 +5100,9 @@ int QCC_canConv(QCC_def_t *from, etype_t to)
                }
        }
 
+       if (from->type->type == ev_variant)
+               return 3;
+
 /*     if (from->type->type == ev_pointer && from->type->aux_type->type == to)
                return 1;
 
@@ -5077,6 +5112,9 @@ int QCC_canConv(QCC_def_t *from, etype_t to)
        if (from->type->type == ev_integer && to == ev_function)
                return 1;
 
+       if (from->constant && from->arraysize == 0 && (from->type->type == ev_integer || from->type->type == ev_float) && !G_INT(from->ofs))
+               return 2;
+
        return -100;
 }
 /*
@@ -5105,7 +5143,7 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
 
        while (1)
        {
-               if (priority == 1)
+               if (priority == FUNC_PRIORITY)
                {
                        if (QCC_PR_CheckToken ("(") )
                        {
@@ -5141,8 +5179,8 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
 
                if (pr_token_type == tt_immediate)
                {
-                       if (pr_immediate_type->type == ev_float)
-                               if (pr_immediate._float < 0)    //hehehe... was a minus all along...
+                       if ((pr_immediate_type->type == ev_float && pr_immediate._float < 0) ||
+                               (pr_immediate_type->type == ev_integer && pr_immediate._int < 0))       //hehehe... was a minus all along...
                                {
                                        QCC_PR_IncludeChunk(pr_token, true, NULL);
                                        strcpy(pr_token, "+");//two negatives would make a positive.
@@ -5189,21 +5227,15 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
                                                //this kills the add 0.
                                                e->ofs = statements[numstatements-1].a;
                                                numstatements--;
-
-                                               if (e->type->type != ev_pointer)
-                                               {
-                                                       type_pointer->aux_type->type = e->type->type;
-                                                       e->type = type_pointer;
-                                               }
                                        }
                                        else
                                        {
-                                               statements[numstatements-1].op = OP_ADD_I;
-                                               if (e->type->type != ev_pointer)
-                                               {
-                                                       type_pointer->aux_type->type = e->type->type;
-                                                       e->type = type_pointer;
-                                               }
+                                               statements[numstatements-1].op = OP_POINTER_ADD;
+                                       }
+                                       if (e->type != type_pointer)
+                                       {
+                                               type_pointer->aux_type->type = e->type->type;
+                                               e->type = type_pointer;
                                        }
                                }
                                if ( !simplestore && statements[numstatements-1].op == OP_LOADP_C && e->ofs == statements[numstatements-1].c)
@@ -5271,6 +5303,7 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
                                                {//assignment
                                                        if (op->type_a == &type_pointer)        //ent var
                                                        {
+                                                               /*FIXME: I don't like this code*/
                                                                if (e->type->type != ev_pointer)
                                                                        c = -200;       //don't cast to a pointer.
                                                                else if ((*op->type_c)->type == ev_void && op->type_b == &type_pointer && e2->type->type == ev_pointer)
@@ -5285,6 +5318,8 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
                                                                c=QCC_canConv(e2, (*op->type_b)->type);
                                                                if (type_a != (*op->type_a)->type)      //in this case, a is the final assigned value
                                                                        c = -300;       //don't use this op, as we must not change var b's type
+                                                               else if ((*op->type_a)->type == ev_pointer && e->type->aux_type->type != (*op->type_a)->aux_type->type)
+                                                                       c = -300;       //don't use this op if its a pointer to a different type
                                                        }
                                                }
                                                else
@@ -5404,12 +5439,12 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
                                        QCC_PR_SimpleStatement(OP_ADDRESS, statements[numstatements-1].a, statements[numstatements-1].b, e3->ofs, false);
                                        if (e->type->type == ev_float)
                                        {
-                                               QCC_PR_Statement3(&pr_opcodes[OP_ADD_F], e, QCC_MakeFloatDef(1), e2, false);
+                                               QCC_PR_Statement3(&pr_opcodes[OP_ADD_F], e, QCC_MakeFloatConst(1), e2, false);
                                                QCC_PR_Statement3(&pr_opcodes[OP_STOREP_F], e2, e3, NULL, false);
                                        }
                                        else if (e->type->type == ev_integer)
                                        {
-                                               QCC_PR_Statement3(&pr_opcodes[OP_ADD_I], e, QCC_MakeIntDef(1), e2, false);
+                                               QCC_PR_Statement3(&pr_opcodes[OP_ADD_I], e, QCC_MakeIntConst(1), e2, false);
                                                QCC_PR_Statement3(&pr_opcodes[OP_STOREP_I], e2, e3, NULL, false);
                                        }
                                        else
@@ -5430,7 +5465,7 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
 
                                        e2 = QCC_GetTemp(type_float);
                                        QCC_PR_Statement3(&pr_opcodes[OP_STORE_F], e, e2, NULL, false);
-                                       QCC_PR_Statement3(&pr_opcodes[OP_ADD_F], e, QCC_MakeFloatDef(1), e, false);
+                                       QCC_PR_Statement3(&pr_opcodes[OP_ADD_F], e, QCC_MakeFloatConst(1), e, false);
                                        QCC_FreeTemp(e);
                                        e = e2;
                                }
@@ -5441,7 +5476,7 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
 
                                        e2 = QCC_GetTemp(type_integer);
                                        QCC_PR_Statement3(&pr_opcodes[OP_STORE_I], e, e2, NULL, false);
-                                       QCC_PR_Statement3(&pr_opcodes[OP_ADD_I], e, QCC_MakeIntDef(1), e, false);
+                                       QCC_PR_Statement3(&pr_opcodes[OP_ADD_I], e, QCC_MakeIntConst(1), e, false);
                                        QCC_FreeTemp(e);
                                        e = e2;
                                }
@@ -5466,12 +5501,12 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
                                        QCC_PR_SimpleStatement(OP_ADDRESS, statements[numstatements-1].a, statements[numstatements-1].b, e3->ofs, false);
                                        if (e->type->type == ev_float)
                                        {
-                                               QCC_PR_Statement3(&pr_opcodes[OP_SUB_F], e, QCC_MakeFloatDef(1), e2, false);
+                                               QCC_PR_Statement3(&pr_opcodes[OP_SUB_F], e, QCC_MakeFloatConst(1), e2, false);
                                                QCC_PR_Statement3(&pr_opcodes[OP_STOREP_F], e2, e3, NULL, false);
                                        }
                                        else if (e->type->type == ev_integer)
                                        {
-                                               QCC_PR_Statement3(&pr_opcodes[OP_SUB_I], e, QCC_MakeIntDef(1), e2, false);
+                                               QCC_PR_Statement3(&pr_opcodes[OP_SUB_I], e, QCC_MakeIntConst(1), e2, false);
                                                QCC_PR_Statement3(&pr_opcodes[OP_STOREP_I], e2, e3, NULL, false);
                                        }
                                        else
@@ -5489,7 +5524,7 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
 
                                        e2 = QCC_GetTemp(type_float);
                                        QCC_PR_Statement3(&pr_opcodes[OP_STORE_F], e, e2, NULL, false);
-                                       QCC_PR_Statement3(&pr_opcodes[OP_SUB_F], e, QCC_MakeFloatDef(1), e, false);
+                                       QCC_PR_Statement3(&pr_opcodes[OP_SUB_F], e, QCC_MakeFloatConst(1), e, false);
                                        QCC_FreeTemp(e);
                                        e = e2;
                                }
@@ -5500,7 +5535,7 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
 
                                        e2 = QCC_GetTemp(type_integer);
                                        QCC_PR_Statement3(&pr_opcodes[OP_STORE_I], e, e2, NULL, false);
-                                       QCC_PR_Statement3(&pr_opcodes[OP_SUB_I], e, QCC_MakeIntDef(1), e, false);
+                                       QCC_PR_Statement3(&pr_opcodes[OP_SUB_I], e, QCC_MakeIntConst(1), e, false);
                                        QCC_FreeTemp(e);
                                        e = e2;
                                }
@@ -5519,13 +5554,36 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
 
        if (!(exprflags&EXPR_DISALLOW_COMMA) && priority == TOP_PRIORITY && QCC_PR_CheckToken (","))
        {
+               if (!qcc_usefulstatement)
+                       QCC_PR_ParseWarning(WARN_POINTLESSSTATEMENT, "Effectless statement");
+
                QCC_FreeTemp(e);
-               return QCC_PR_Expression(TOP_PRIORITY, exprflags);
+               qcc_usefulstatement = false;
+               e = QCC_PR_Expression(TOP_PRIORITY, exprflags);
        }
 
        return e;
 }
 
+int QCC_PR_IntConstExpr(void)
+{
+       QCC_def_t *def = QCC_PR_Expression(TOP_PRIORITY, 0);
+       if (def->constant)
+       {
+               def->references++;
+               if (def->type->type == ev_integer)
+                       return G_INT(def->ofs);
+               if (def->type->type == ev_float)
+               {
+                       int i = G_FLOAT(def->ofs);
+                       if ((float)i == G_FLOAT(def->ofs))
+                               return i;
+               }
+       }
+       QCC_PR_ParseError(ERR_NOTACONSTANT, "Value is not an integer constant");
+       return true;
+}
+
 void QCC_PR_GotoStatement (QCC_dstatement_t *patch2, char *labelname)
 {
        if (num_gotos >= max_gotos)
@@ -5606,7 +5664,7 @@ void QCC_PR_ParseStatement (void)
                {
                        e = QCC_PR_GetDef(NULL, "__oself", pr_scope, false, 0);
                        e2 = QCC_PR_GetDef(NULL, "self", NULL, false, 0);
-                       QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], e, QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 1, e2->ofs, false), NULL));
+                       QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], e, QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 0, e2->ofs, false), NULL));
                }*/
 
                if (QCC_PR_CheckToken (";"))
@@ -5620,7 +5678,7 @@ void QCC_PR_ParseStatement (void)
                        return;
                }
                e = QCC_PR_Expression (TOP_PRIORITY, 0);
-               e2 = QCC_SupplyConversion(e, pr_scope->type->aux_type->type);
+               e2 = QCC_SupplyConversion(e, pr_scope->type->aux_type->type, true);
                if (e != e2)
                {
                        QCC_PR_ParseWarning(WARN_CORRECTEDRETURNTYPE, "\'%s\' returned %s, expected %s, conversion supplied", pr_scope->name, e->type->name, pr_scope->type->aux_type->name);
@@ -5902,7 +5960,7 @@ void QCC_PR_ParseStatement (void)
                float frame = pr_immediate._float;
                QCC_PR_Lex();
                name = QCC_PR_ParseName();
-               QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STATE], QCC_MakeFloatDef(frame), QCC_PR_GetDef(type_function, name, NULL, false, 0, false), NULL));
+               QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STATE], QCC_MakeFloatConst(frame), QCC_PR_GetDef(type_function, name, NULL, false, 0, false), NULL));
                QCC_PR_Expect(";");
                return;
        }
@@ -6116,7 +6174,7 @@ void QCC_PR_ParseStatement (void)
                                if (pr_casesdef[i]->type->type != e->type->type)
                                {
                                        if (e->type->type == ev_integer && pr_casesdef[i]->type->type == ev_float)
-                                               pr_casesdef[i] = QCC_MakeIntDef((int)qcc_pr_globals[pr_casesdef[i]->ofs]);
+                                               pr_casesdef[i] = QCC_MakeIntConst((int)qcc_pr_globals[pr_casesdef[i]->ofs]);
                                        else
                                                QCC_PR_ParseWarning(WARN_SWITCHTYPEMISMATCH, "switch case type mismatch");
                                }
@@ -6125,7 +6183,7 @@ void QCC_PR_ParseStatement (void)
                                        if (pr_casesdef2[i]->type->type != e->type->type)
                                        {
                                                if (e->type->type == ev_integer && pr_casesdef[i]->type->type == ev_float)
-                                                       pr_casesdef2[i] = QCC_MakeIntDef((int)qcc_pr_globals[pr_casesdef2[i]->ofs]);
+                                                       pr_casesdef2[i] = QCC_MakeIntConst((int)qcc_pr_globals[pr_casesdef2[i]->ofs]);
                                                else
                                                        QCC_PR_ParseWarning(WARN_SWITCHTYPEMISMATCH, "switch caserange type mismatch");
                                        }
@@ -6496,7 +6554,7 @@ void QCC_PR_ParseState (void)
 
                        frame = QCC_PR_Statement(&pr_opcodes[OP_LOAD_F], self, framef, NULL);
                        if (cycle_wrapped)
-                               QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(0), cycle_wrapped, NULL));
+                               QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(0), cycle_wrapped, NULL));
                        QCC_UnFreeTemp(frame);
 
                        //make sure the frame is within the bounds given.
@@ -6513,25 +6571,25 @@ void QCC_PR_ParseState (void)
                        t1 = QCC_PR_Statement(&pr_opcodes[OP_GE_F], def, s1, NULL);
                        QCC_PR_SimpleStatement(OP_IFNOT_I, t1->ofs, 7, 0, false);
                        QCC_FreeTemp(t1);       //this block is the 'it's in a forwards direction'
-                               QCC_PR_SimpleStatement(OP_ADD_F, frame->ofs, QCC_MakeFloatDef(1)->ofs, frame->ofs, false);
+                               QCC_PR_SimpleStatement(OP_ADD_F, frame->ofs, QCC_MakeFloatConst(1)->ofs, frame->ofs, false);
                                t1 = QCC_PR_Statement(&pr_opcodes[OP_GT_F], frame, def, NULL);
                                QCC_PR_SimpleStatement(OP_IFNOT_I, t1->ofs,2, 0, false);
                                QCC_FreeTemp(t1);
                                        QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], s1, frame, NULL));
                                        QCC_UnFreeTemp(frame);
                                        if (cycle_wrapped)
-                                               QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(1), cycle_wrapped, NULL));
+                                               QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(1), cycle_wrapped, NULL));
 
                        QCC_PR_SimpleStatement(OP_GOTO, 6, 0, 0, false);
                                //reverse animation.
-                               QCC_PR_SimpleStatement(OP_SUB_F, frame->ofs, QCC_MakeFloatDef(1)->ofs, frame->ofs, false);
+                               QCC_PR_SimpleStatement(OP_SUB_F, frame->ofs, QCC_MakeFloatConst(1)->ofs, frame->ofs, false);
                                t1 = QCC_PR_Statement(&pr_opcodes[OP_LT_F], frame, s1, NULL);
                                QCC_PR_SimpleStatement(OP_IFNOT_I, t1->ofs,2, 0, false);
                                QCC_FreeTemp(t1);
                                        QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], def, frame, NULL));
                                        QCC_UnFreeTemp(frame);
                                        if (cycle_wrapped)
-                                               QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(1), cycle_wrapped, NULL));
+                                               QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(1), cycle_wrapped, NULL));
 
                        //self.frame = frame happens with the normal state opcode.
                        QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STATE], frame, pr_scope, NULL));
@@ -6550,7 +6608,7 @@ void QCC_PR_ParseState (void)
 
        name = QCC_PR_ParseName ();
        pr_scope = NULL;
-       def = QCC_PR_GetDef (type_function, name, NULL, true, 1, false);
+       def = QCC_PR_GetDef (type_function, name, NULL, true, 0, false);
        pr_scope = sc;
 
        QCC_PR_Expect ("]");
@@ -7109,6 +7167,7 @@ void QCC_Marshal_Locals(int first, int laststatement)
 {
        QCC_def_t *local;
        unsigned int newofs;
+       int size;
 
 //     if (!opt_overlaptemps)  //clear these after each function. we arn't overlapping them so why do we need to keep track of them?
 //     {
@@ -7144,9 +7203,11 @@ void QCC_Marshal_Locals(int first, int laststatement)
                if (local->constant)
                        continue;
 
-               newofs += local->type->size*local->arraysize;
-               if (local->arraysize>1)
-                       newofs++;
+               size = local->type->size*(local->arraysize?local->arraysize:1);
+               if (local->arraysize)
+                       size++;
+
+               newofs += size;
        }
 
        locals_start = MAX_REGS;
@@ -7163,12 +7224,14 @@ void QCC_Marshal_Locals(int first, int laststatement)
                if (((int*)qcc_pr_globals)[local->ofs])
                        QCC_PR_ParseError(ERR_INTERNAL, "Marshall of a set value");
 
-               newofs -= local->type->size*local->arraysize;
-               if (local->arraysize>1)
-                       newofs--;
+               size = local->type->size*(local->arraysize?local->arraysize:1);
+               if (local->arraysize)
+                       size++;
+
+               newofs -= size;
 
-               QCC_RemapOffsets(first, laststatement, local->ofs, local->ofs+local->type->size*local->arraysize, newofs);
-               QCC_FreeOffset(local->ofs, local->type->size*local->arraysize);
+               QCC_RemapOffsets(first, laststatement, local->ofs, local->ofs+size, newofs);
+               QCC_FreeOffset(local->ofs, size);
 
                local->ofs = newofs;
        }
@@ -7203,9 +7266,9 @@ void QCC_WriteAsmFunction(QCC_def_t       *sc, unsigned int firststatement, gofs_t fir
                                break;
                }
                if (param)
-                       fprintf(asmfile, "%s %s /* at %d */", TypeName(type), param->name, o);
+                       fprintf(asmfile, "%s %s", TypeName(type), param->name);
                else
-                       fprintf(asmfile, "%s /* at %d */", TypeName(type), o);
+                       fprintf(asmfile, "%s", TypeName(type));
 
                o += type->size;
        }
@@ -7250,7 +7313,7 @@ void QCC_WriteAsmFunction(QCC_def_t       *sc, unsigned int firststatement, gofs_t fir
                                }
                        }
                }
-               fprintf(asmfile, ";\n");
+               fprintf(asmfile, "; /*%i*/\n", statement_linenums[i]);
        }
 
        fprintf(asmfile, "}\n\n");
@@ -7334,7 +7397,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_type_t *type)
        {
                if (!*pr_parm_names[i])
                        QCC_PR_ParseError(ERR_PARAMWITHNONAME, "Parameter is not named");
-               defs[i] = QCC_PR_GetDef (parm, pr_parm_names[i], pr_scope, true, 1, false);
+               defs[i] = QCC_PR_GetDef (parm, pr_parm_names[i], pr_scope, true, 0, false);
 
                defs[i]->references++;
                if (i < MAX_PARMS)
@@ -7379,9 +7442,9 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_type_t *type)
        /*if (pr_classtype)
        {
                QCC_def_t *e, *e2;
-               e = QCC_PR_GetDef(pr_classtype, "__oself", pr_scope, true, 1);
-               e2 = QCC_PR_GetDef(type_entity, "self", NULL, true, 1);
-               QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 1, e2->ofs, false), e, NULL));
+               e = QCC_PR_GetDef(pr_classtype, "__oself", pr_scope, true, 0);
+               e2 = QCC_PR_GetDef(type_entity, "self", NULL, true, 0);
+               QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 0, e2->ofs, false), e, NULL));
        }*/
 
 //
@@ -7404,7 +7467,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_type_t *type)
                        do {
                                name = QCC_PR_ParseName();
                                QCC_PR_Expect(":");
-                               e2 = QCC_PR_GetDef(QCC_PR_ParseType(false), name, pr_scope, true, 1, false);
+                               e2 = QCC_PR_GetDef(QCC_PR_ParseType(false, false), name, pr_scope, true, 0, false);
                                QCC_PR_Expect(";");
                        } while(!QCC_PR_CheckToken("{"));
                }
@@ -7469,7 +7532,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_type_t *type)
                        QCC_def_t *e, *e2;
                        e = QCC_PR_GetDef(NULL, "__oself", pr_scope, false, 0);
                        e2 = QCC_PR_GetDef(NULL, "self", NULL, false, 0);
-                       QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], e, QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 1, e2->ofs, false), NULL));
+                       QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], e, QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 0, e2->ofs, false), NULL));
                }*/
 
                QCC_PR_Statement (pr_opcodes, 0,0, NULL);
@@ -7521,7 +7584,7 @@ void QCC_PR_ArrayRecurseDivideRegular(QCC_def_t *array, QCC_def_t *index, int mi
        QCC_def_t *eq;
        if (min == max || min+1 == max)
        {
-               eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef(min+0.5f), NULL);
+               eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst(min+0.5f), NULL);
                QCC_UnFreeTemp(index);
                QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
                st->b = 2;
@@ -7534,7 +7597,7 @@ void QCC_PR_ArrayRecurseDivideRegular(QCC_def_t *array, QCC_def_t *index, int mi
 
                if (max-min>4)
                {
-                       eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef(mid+0.5f), NULL);
+                       eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst(mid+0.5f), NULL);
                        QCC_UnFreeTemp(index);
                        QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
                }
@@ -7555,7 +7618,7 @@ void QCC_PR_ArrayRecurseDivideUsingVectors(QCC_def_t *array, QCC_def_t *index, i
        QCC_def_t *eq;
        if (min == max || min+1 == max)
        {
-               eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef(min+0.5f), NULL);
+               eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst(min+0.5f), NULL);
                QCC_UnFreeTemp(index);
                QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
                st->b = 2;
@@ -7568,7 +7631,7 @@ void QCC_PR_ArrayRecurseDivideUsingVectors(QCC_def_t *array, QCC_def_t *index, i
 
                if (max-min>4)
                {
-                       eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef(mid+0.5f), NULL);
+                       eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst(mid+0.5f), NULL);
                        QCC_UnFreeTemp(index);
                        QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
                }
@@ -7587,10 +7650,13 @@ QCC_def_t *QCC_PR_EmitArrayGetVector(QCC_def_t *array)
        QCC_dfunction_t *df;
        QCC_def_t *temp, *index, *func;
 
-       func = QCC_PR_GetDef(type_function, qcva("ArrayGetVec*%s", array->name), NULL, true, 1, false);
+       func = QCC_PR_GetDef(type_function, qcva("ArrayGetVec*%s", array->name), NULL, true, 0, false);
 
        pr_scope = func;
 
+       if (numfunctions >= MAX_FUNCTIONS)
+               QCC_Error(ERR_INTERNAL, "Too many function defs");
+
        df = &functions[numfunctions];
        numfunctions++;
 
@@ -7600,17 +7666,17 @@ QCC_def_t *QCC_PR_EmitArrayGetVector(QCC_def_t *array)
        df->parm_size[0] = 1;
        df->numparms = 1;
        df->parm_start = numpr_globals;
-       index = QCC_PR_GetDef(type_float, "index___", func, true, 1, false);
+       index = QCC_PR_GetDef(type_float, "index___", func, true, 0, false);
        index->references++;
-       temp = QCC_PR_GetDef(type_float, "div3___", func, true, 1, false);
+       temp = QCC_PR_GetDef(type_float, "div3___", func, true, 0, false);
        locals_end = numpr_globals;
        df->locals = locals_end - df->parm_start;
-       QCC_PR_Statement3(pr_opcodes+OP_DIV_F, index, QCC_MakeFloatDef(3), temp, false);
+       QCC_PR_Statement3(pr_opcodes+OP_DIV_F, index, QCC_MakeFloatConst(3), temp, false);
        QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, temp, temp, temp, false);//round down to int
 
        QCC_PR_ArrayRecurseDivideUsingVectors(array, temp, 0, (array->arraysize+2)/3);  //round up
 
-       QCC_PR_Statement(pr_opcodes+OP_RETURN, QCC_MakeFloatDef(0), 0, NULL);   //err... we didn't find it, give up.
+       QCC_PR_Statement(pr_opcodes+OP_RETURN, QCC_MakeFloatConst(0), 0, NULL); //err... we didn't find it, give up.
        QCC_PR_Statement(pr_opcodes+OP_DONE, 0, 0, NULL);       //err... we didn't find it, give up.
 
        G_FUNCTION(func->ofs) = df - functions;
@@ -7630,7 +7696,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
        QCC_def_t *fasttrackpossible;
 
        if (flag_fasttrackarrays)
-               fasttrackpossible = QCC_PR_GetDef(type_float, "__ext__fasttrackarrays", NULL, true, 1, false);
+               fasttrackpossible = QCC_PR_GetDef(type_float, "__ext__fasttrackarrays", NULL, true, 0, false);
        else
                fasttrackpossible = NULL;
 
@@ -7645,6 +7711,9 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
 
        pr_scope = scope;
 
+       if (numfunctions >= MAX_FUNCTIONS)
+               QCC_Error(ERR_INTERNAL, "Too many function defs");
+
        df = &functions[numfunctions];
        numfunctions++;
 
@@ -7654,7 +7723,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
        df->parm_size[0] = 1;
        df->numparms = 1;
        df->parm_start = numpr_globals;
-       index = QCC_PR_GetDef(type_float, "indexg___", def, true, 1, false);
+       index = QCC_PR_GetDef(type_float, "indexg___", def, true, 0, false);
 
        G_FUNCTION(scope->ofs) = df - functions;
 
@@ -7683,44 +7752,44 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
                //we need to work out which part, x/y/z that it's stored in.
                //0,1,2 = i - ((int)i/3 *) 3;
 
-               div3 = QCC_PR_GetDef(type_float, "div3___", def, true, 1, false);
-               intdiv3 = QCC_PR_GetDef(type_float, "intdiv3___", def, true, 1, false);
+               div3 = QCC_PR_GetDef(type_float, "div3___", def, true, 0, false);
+               intdiv3 = QCC_PR_GetDef(type_float, "intdiv3___", def, true, 0, false);
 
-               eq = QCC_PR_Statement(pr_opcodes+OP_GE_F, index, QCC_MakeFloatDef((float)def->arraysize), NULL);        //escape clause - should call some sort of error function instead.. that'd rule!
+               eq = QCC_PR_Statement(pr_opcodes+OP_GE_F, index, QCC_MakeFloatConst((float)def->arraysize), NULL);      //escape clause - should call some sort of error function instead.. that'd rule!
                QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
                st->b = 2;
-               QCC_PR_Statement(pr_opcodes+OP_RETURN, QCC_MakeFloatDef(0), 0, &st);
+               QCC_PR_Statement(pr_opcodes+OP_RETURN, QCC_MakeFloatConst(0), 0, &st);
 
                div3->references++;
                QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, index, index, index, false);
-               QCC_PR_Statement3(pr_opcodes+OP_DIV_F, index, QCC_MakeFloatDef(3), div3, false);
+               QCC_PR_Statement3(pr_opcodes+OP_DIV_F, index, QCC_MakeFloatConst(3), div3, false);
                QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, div3, div3, intdiv3, false);
 
                QCC_PR_Statement3(pr_opcodes+OP_STORE_F, index, &def_parms[0], NULL, false);
                QCC_PR_Statement3(pr_opcodes+OP_CALL1, vectortrick, NULL, NULL, false);
                vectortrick->references++;
-               ret = QCC_PR_GetDef(type_vector, "vec__", pr_scope, true, 1, false);
+               ret = QCC_PR_GetDef(type_vector, "vec__", pr_scope, true, 0, false);
                ret->references+=4;
                QCC_PR_Statement3(pr_opcodes+OP_STORE_V, &def_ret, ret, NULL, false);
                QCC_FreeTemp(&def_ret);
 
-               div3 = QCC_PR_Statement(pr_opcodes+OP_MUL_F, intdiv3, QCC_MakeFloatDef(3), NULL);
+               div3 = QCC_PR_Statement(pr_opcodes+OP_MUL_F, intdiv3, QCC_MakeFloatConst(3), NULL);
                QCC_PR_Statement3(pr_opcodes+OP_SUB_F, index, div3, index, false);
                QCC_FreeTemp(div3);
 
-               eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef(0+0.5f), NULL);
+               eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst(0+0.5f), NULL);
                QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
                st->b = 2;
                QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st);
                st->a = ret->ofs + 0;
 
-               eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef(1+0.5f), NULL);
+               eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst(1+0.5f), NULL);
                QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
                st->b = 2;
                QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st);
                st->a = ret->ofs + 1;
 
-               eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef(2+0.5), NULL);
+               eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst(2+0.5), NULL);
                QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
                st->b = 2;
                QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st);
@@ -7734,7 +7803,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
                QCC_PR_ArrayRecurseDivideRegular(def, index, 0, def->arraysize);
        }
 
-       QCC_PR_Statement(pr_opcodes+OP_RETURN, QCC_MakeFloatDef(0), 0, NULL);
+       QCC_PR_Statement(pr_opcodes+OP_RETURN, QCC_MakeFloatConst(0), 0, NULL);
 
        QCC_PR_Statement(pr_opcodes+OP_DONE, 0, 0, NULL);
 
@@ -7753,7 +7822,7 @@ void QCC_PR_ArraySetRecurseDivide(QCC_def_t *array, QCC_def_t *index, QCC_def_t
        QCC_def_t *eq;
        if (min == max || min+1 == max)
        {
-               eq = QCC_PR_Statement(pr_opcodes+OP_EQ_F, index, QCC_MakeFloatDef((float)min), NULL);
+               eq = QCC_PR_Statement(pr_opcodes+OP_EQ_F, index, QCC_MakeFloatConst((float)min), NULL);
                QCC_UnFreeTemp(index);
                QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
                st->b = 3;
@@ -7770,7 +7839,7 @@ void QCC_PR_ArraySetRecurseDivide(QCC_def_t *array, QCC_def_t *index, QCC_def_t
 
                if (max-min>4)
                {
-                       eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef((float)mid), NULL);
+                       eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst((float)mid), NULL);
                        QCC_UnFreeTemp(index);
                        QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
                }
@@ -7791,13 +7860,16 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname)
        QCC_def_t *fasttrackpossible;
 
        if (flag_fasttrackarrays)
-               fasttrackpossible = QCC_PR_GetDef(type_float, "__ext__fasttrackarrays", NULL, true, 1, false);
+               fasttrackpossible = QCC_PR_GetDef(type_float, "__ext__fasttrackarrays", NULL, true, 0, false);
        else
                fasttrackpossible = NULL;
 
        def = QCC_PR_GetDef(NULL, arrayname, NULL, false, 0, false);
        pr_scope = scope;
 
+       if (numfunctions >= MAX_FUNCTIONS)
+               QCC_Error(ERR_INTERNAL, "Too many function defs");
+
        df = &functions[numfunctions];
        numfunctions++;
 
@@ -7808,8 +7880,8 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname)
        df->parm_size[1] = def->type->size;
        df->numparms = 2;
        df->parm_start = numpr_globals;
-       index = QCC_PR_GetDef(type_float, "indexs___", def, true, 1, false);
-       value = QCC_PR_GetDef(def->type, "value___", def, true, 1, false);
+       index = QCC_PR_GetDef(type_float, "indexs___", def, true, 0, false);
+       value = QCC_PR_GetDef(def->type, "value___", def, true, 0, false);
        locals_end = numpr_globals;
        df->locals = locals_end - df->parm_start;
 
@@ -7825,7 +7897,7 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname)
                QCC_PR_Statement3(&pr_opcodes[OP_CONV_FTOI], index, NULL, index, true); //address stuff is integer based, but standard qc (which this accelerates in supported engines) only supports floats
                QCC_PR_SimpleStatement (OP_BOUNDCHECK, index->ofs, ((int*)qcc_pr_globals)[def->ofs-1]+1, 0, true);//annoy the programmer. :p
                if (def->type->size != 1)//shift it upwards for larger types
-                       QCC_PR_Statement3(&pr_opcodes[OP_MUL_I], index, QCC_MakeIntDef(def->type->size), index, true);
+                       QCC_PR_Statement3(&pr_opcodes[OP_MUL_I], index, QCC_MakeIntConst(def->type->size), index, true);
                QCC_PR_Statement3(&pr_opcodes[OP_GLOBALADDRESS], def, index, index, true);      //comes with built in add
                if (def->type->size >= 3)
                        QCC_PR_Statement3(&pr_opcodes[OP_STOREP_V], value, index, NULL, true);  //*b = a
@@ -7883,7 +7955,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
                KEYWORD(asm);
        }
 
-       for (a = 0; a < arraysize; a++)
+       for (a = 0; a < (arraysize?arraysize:1); a++)
        {
                if (a == 0)
                        *array = '\0';
@@ -7899,7 +7971,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
                def = (void *)qccHunkAlloc (sizeof(QCC_def_t));
                memset (def, 0, sizeof(*def));
                def->next = NULL;
-               def->arraysize = arraysize;
+               def->arraysize = a?0:arraysize;
                if (name)
                {
                        pr.def_tail->next = def;
@@ -7911,6 +7983,8 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
 
                def->s_line = pr_source_line;
                def->s_file = s_file;
+               if (a)
+                       def->initialized = 1;
 
                def->name = (void *)qccHunkAlloc (strlen(newname)+1);
                strcpy (def->name, newname);
@@ -7919,7 +7993,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
                def->scope = scope;
                def->saved = saved;
 
-       //      if (arraysize>1)
+               //if (type->type = ev_field)
                        def->constant = true;
 
                if (ofs + type->size*a >= MAX_REGS)
@@ -7941,14 +8015,14 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
                                {
                                case ev_vector:
                                        sprintf(newname, "%s%s.%s", name, array, parttype->name);
-                                       QCC_PR_DummyDef(parttype, newname, scope, 1, ofs + type->size*a + parttype->ofs, false, saved);
+                                       QCC_PR_DummyDef(parttype, newname, scope, 0, ofs + type->size*a + parttype->ofs, false, saved);
 
                                        sprintf(newname, "%s%s.%s_x", name, array, parttype->name);
-                                       QCC_PR_DummyDef(type_float, newname, scope, 1, ofs + type->size*a + parttype->ofs, false, false);
+                                       QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a + parttype->ofs, false, false);
                                        sprintf(newname, "%s%s.%s_y", name, array, parttype->name);
-                                       QCC_PR_DummyDef(type_float, newname, scope, 1, ofs + type->size*a + parttype->ofs+1, false, false);
+                                       QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a + parttype->ofs+1, false, false);
                                        sprintf(newname, "%s%s.%s_z", name, array, parttype->name);
-                                       QCC_PR_DummyDef(type_float, newname, scope, 1, ofs + type->size*a + parttype->ofs+2, false, false);
+                                       QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a + parttype->ofs+2, false, false);
                                        break;
 
                                case ev_float:
@@ -7961,12 +8035,12 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
                                case ev_union:
                                case ev_variant:        //for lack of any better alternative
                                        sprintf(newname, "%s%s.%s", name, array, parttype->name);
-                                       QCC_PR_DummyDef(parttype, newname, scope, 1, ofs + type->size*a + parttype->ofs, false, saved);
+                                       QCC_PR_DummyDef(parttype, newname, scope, 0, ofs + type->size*a + parttype->ofs, false, saved);
                                        break;
 
                                case ev_function:
                                        sprintf(newname, "%s%s.%s", name, array, parttype->name);
-                                       QCC_PR_DummyDef(parttype, newname, scope, 1, ofs + type->size*a +parttype->ofs, false, saved)->initialized = true;
+                                       QCC_PR_DummyDef(parttype, newname, scope, 0, ofs + type->size*a +parttype->ofs, false, saved)->initialized = true;
                                        break;
                                case ev_void:
                                        break;
@@ -7977,11 +8051,11 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
                else if (type->type == ev_vector)
                {       //do the vector thing.
                        sprintf(newname, "%s%s_x", name, array);
-                       QCC_PR_DummyDef(type_float, newname, scope, 1, ofs + type->size*a+0, referable, false);
+                       QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a+0, referable, false);
                        sprintf(newname, "%s%s_y", name, array);
-                       QCC_PR_DummyDef(type_float, newname, scope, 1, ofs + type->size*a+1, referable, false);
+                       QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a+1, referable, false);
                        sprintf(newname, "%s%s_z", name, array);
-                       QCC_PR_DummyDef(type_float, newname, scope, 1, ofs + type->size*a+2, referable, false);
+                       QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a+2, referable, false);
                }
                else if (type->type == ev_field)
                {
@@ -7989,20 +8063,21 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
                        {
                                //do the vector thing.
                                sprintf(newname, "%s%s_x", name, array);
-                               QCC_PR_DummyDef(type_floatfield, newname, scope, 1, ofs + type->size*a+0, referable, false);
+                               QCC_PR_DummyDef(type_floatfield, newname, scope, 0, ofs + type->size*a+0, referable, false);
                                sprintf(newname, "%s%s_y", name, array);
-                               QCC_PR_DummyDef(type_floatfield, newname, scope, 1, ofs + type->size*a+1, referable, false);
+                               QCC_PR_DummyDef(type_floatfield, newname, scope, 0, ofs + type->size*a+1, referable, false);
                                sprintf(newname, "%s%s_z", name, array);
-                               QCC_PR_DummyDef(type_floatfield, newname, scope, 1, ofs + type->size*a+2, referable, false);
+                               QCC_PR_DummyDef(type_floatfield, newname, scope, 0, ofs + type->size*a+2, referable, false);
                        }
                }
+               first->deftail = pr.def_tail;
        }
 
        if (referable)
        {
                if (!pHash_Get(&globalstable, "end_sys_fields"))
                        first->references++;    //anything above needs to be left in, and so warning about not using it is just going to pee people off.
-               if (arraysize <= 1 && first->type->type != ev_field)
+               if (!arraysize && first->type->type != ev_field)
                        first->constant = false;
                if (scope)
                        pHash_Add(&localstable, first->name, first, qccHunkAlloc(sizeof(bucket_t)));
@@ -8010,7 +8085,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
                        pHash_Add(&globalstable, first->name, first, qccHunkAlloc(sizeof(bucket_t)));
 
                if (!scope && asmfile)
-                       fprintf(asmfile, "%s %s; /* at %d */\n", TypeName(first->type), first->name, first->ofs);
+                       fprintf(asmfile, "%s %s;\n", TypeName(first->type), first->name);
        }
 
        return first;
@@ -8022,6 +8097,9 @@ PR_GetDef
 
 If type is NULL, it will match any type
 If allocate is true, a new def will be allocated if it can't be found
+If arraysize=0, its not an array and has 1 element.
+If arraysize>0, its an array and requires array notation
+If arraysize<0, its an array with undefined size - GetDef will fail if its not already allocated.
 ============
 */
 
@@ -8033,6 +8111,9 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
        unsigned int i;
        QCC_def_t *foundstatic = NULL;
 
+       if (!allocate)
+               arraysize = -1;
+
        if (scope)
        {
                def = Hash_Get(&localstable, name);
@@ -8047,7 +8128,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
 
                        if (type && typecmp(def->type, type))
                                QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type), TypeName(def->type));
-                       if (def->arraysize != arraysize && arraysize)
+                       if (def->arraysize != arraysize && arraysize>=0)
                                QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHARRAYSIZE, def, "Array sizes for redecleration of %s do not match",name);
                        if (allocate && scope)
                        {
@@ -8083,7 +8164,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
                        if (!pr_scope)
                                QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type), TypeName(def->type));
                }
-               if (def->arraysize != arraysize && arraysize)
+               if (def->arraysize != arraysize && arraysize>=0)
                        QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCHARRAYSIZE, def, "Array sizes for redecleration of %s do not match",name);
                if (allocate && scope)
                {
@@ -8117,7 +8198,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
 
                                if (type && typecmp(def->type, type))
                                        QCC_PR_ParseError (ERR_TYPEMISMATCHREDEC, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type), TypeName(def->type));
-                               if (def->arraysize != arraysize && arraysize)
+                               if (def->arraysize != arraysize && arraysize>=0)
                                        QCC_PR_ParseError (ERR_TYPEMISMATCHARRAYSIZE, "Array sizes for redecleration of %s do not match",name);
                                if (allocate && scope)
                                {
@@ -8153,7 +8234,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
                                if (!pr_scope)
                                        QCC_PR_ParseError (ERR_TYPEMISMATCHREDEC, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type), TypeName(def->type));
                        }
-                       if (def->arraysize != arraysize && arraysize)
+                       if (def->arraysize != arraysize && arraysize>=0)
                                QCC_PR_ParseError (ERR_TYPEMISMATCHARRAYSIZE, "Array sizes for redecleration of %s do not match",name);
                        if (allocate && scope)
                        {
@@ -8181,7 +8262,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
        if (!allocate)
                return NULL;
 
-       if (arraysize < 1)
+       if (arraysize < 0)
        {
                QCC_PR_ParseError (ERR_ARRAYNEEDSSIZE, "First declaration of array %s with no size",name);
        }
@@ -8193,7 +8274,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
        }
 
        ofs = numpr_globals;
-       if (arraysize > 1)
+       if (arraysize)
        {       //write the array size
                ofs = QCC_GetFreeOffsetSpace(1 + (type->size    * arraysize));
 
@@ -8201,14 +8282,14 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
                ofs++;
        }
        else
-               ofs = QCC_GetFreeOffsetSpace(type->size * arraysize);
+               ofs = QCC_GetFreeOffsetSpace(type->size);
 
        def = QCC_PR_DummyDef(type, name, scope, arraysize, ofs, true, saved);
 
        //fix up fields.
        if (type->type == ev_field && allocate != 2)
        {
-               for (i = 0; i < type->size*arraysize; i++)      //make arrays of fields work.
+               for (i = 0; i < type->size*(arraysize?arraysize:1); i++)        //make arrays of fields work.
                        *(int *)&qcc_pr_globals[def->ofs+i] = pr.size_fields+i;
 
                pr.size_fields += i;
@@ -8235,7 +8316,7 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, char *name, QCC_def_t *scope,
        startfield = *fieldofs;
        maxfield = startfield;
 
-       for (a = 0; a < arraysize; a++)
+       for (a = 0; a < (arraysize?arraysize:1); a++)
        {
                if (a == 0)
                        *array = '\0';
@@ -8309,14 +8390,14 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, char *name, QCC_def_t *scope,
                                                sprintf(newname, "%s%s.%s", name, array, parttype->name);
                                        else
                                                sprintf(newname, "%s%s", parttype->name, array);
-                                       ftype = QCC_PR_NewType("FIELD TYPE", ev_field);
+                                       ftype = QCC_PR_NewType("FIELD TYPE", ev_field, false);
                                        ftype->aux_type = parttype;
                                        if (parttype->type == ev_vector)
                                                ftype->size = parttype->size;   //vector fields create a _y and _z too, so we need this still.
-                                       def = QCC_PR_GetDef(NULL, newname, scope, false, 1, saved);
+                                       def = QCC_PR_GetDef(NULL, newname, scope, false, 0, saved);
                                        if (!def)
                                        {
-                                               def = QCC_PR_GetDef(ftype, newname, scope, true, 1, saved);
+                                               def = QCC_PR_GetDef(ftype, newname, scope, true, 0, saved);
                                        }
                                        else
                                        {
@@ -8330,9 +8411,9 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, char *name, QCC_def_t *scope,
                                                sprintf(newname, "%s%s.%s", name, array, parttype->name);
                                        else
                                                sprintf(newname, "%s%s", parttype->name, array);
-                                       ftype = QCC_PR_NewType("FIELD TYPE", ev_field);
+                                       ftype = QCC_PR_NewType("FIELD TYPE", ev_field, false);
                                        ftype->aux_type = parttype;
-                                       def = QCC_PR_GetDef(ftype, newname, scope, true, 1, saved);
+                                       def = QCC_PR_GetDef(ftype, newname, scope, true, 0, saved);
                                        def->initialized = true;
                                        ((int *)qcc_pr_globals)[def->ofs] = *fieldofs;
                                        *fieldofs += parttype->size;
@@ -8363,6 +8444,221 @@ void QCC_PR_ExpandUnionToFields(QCC_type_t *type, int *fields)
        QCC_PR_DummyFieldDef(pass, "", pr_scope, 1, fields, true);
 }
 
+
+void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *def, QCC_type_t *type, int offset)
+{
+       QCC_def_t *tmp;
+       int i;
+
+       if (arraysize)
+       {
+               //arrays go recursive
+               QCC_PR_Expect("{");
+               for (i = 0; i < arraysize; i++)
+               {
+                       QCC_PR_ParseInitializerType(0, def, type, offset + i*type->size);
+                       if (!QCC_PR_CheckToken(","))
+                               break;
+               }
+               QCC_PR_Expect("}");
+       }
+       else
+       {
+               if (type->type == ev_function && pr_token_type == tt_punct)
+               {
+                       /*begin function special case*/
+                       QCC_def_t *parentfunc = pr_scope;
+                       QCC_function_t *f;
+                       QCC_dfunction_t *df;
+                       QCC_type_t *parm;
+
+                       tmp = NULL;
+
+                       def->references++;
+                       pr_scope = def;
+                       if (QCC_PR_CheckToken ("#") || QCC_PR_CheckToken (":"))
+                       {
+                               int binum = 0;
+                               if (pr_token_type == tt_immediate
+                               && pr_immediate_type == type_float
+                               && pr_immediate._float == (int)pr_immediate._float)
+                                       binum = (int)pr_immediate._float;
+                               else if (pr_token_type == tt_immediate && pr_immediate_type == type_integer)
+                                       binum = pr_immediate._int;
+                               else
+                                       QCC_PR_ParseError (ERR_BADBUILTINIMMEDIATE, "Bad builtin immediate");
+                               QCC_PR_Lex();
+
+                               if (def->initialized)
+                               for (i = 0; i < numfunctions; i++)
+                               {
+                                       if (functions[i].first_statement == -binum)
+                                       {
+                                               tmp = QCC_MakeIntConst(i);
+                                               break;
+                                       }
+                               }
+
+                               if (!tmp)
+                               {
+                                       f = (void *)qccHunkAlloc (sizeof(QCC_function_t));
+                                       f->builtin = binum;
+
+                                       locals_start = locals_end = OFS_PARM0; //hmm...
+                               }
+                               else
+                                       f = NULL;
+                       }
+                       else
+                               f = QCC_PR_ParseImmediateStatements (type);
+                       if (!tmp)
+                       {
+                               pr_scope = parentfunc;
+                               tmp = QCC_MakeIntConst(numfunctions);
+                               f->def = def;
+
+                               if (numfunctions >= MAX_FUNCTIONS)
+                                       QCC_Error(ERR_INTERNAL, "Too many function defs");
+
+               // fill in the dfunction
+                               df = &functions[numfunctions];
+                               numfunctions++;
+                               if (f->builtin)
+                                       df->first_statement = -f->builtin;
+                               else
+                                       df->first_statement = f->code;
+
+                               if (f->builtin && opt_function_names)
+                                       optres_function_names += strlen(f->def->name);
+                               else
+                                       df->s_name = QCC_CopyString (f->def->name);
+                               df->s_file = s_file2;
+                               df->numparms =  f->def->type->num_parms;
+                               df->locals = locals_end - locals_start;
+                               df->parm_start = locals_start;
+                               for (i=0,parm = type->param ; i<df->numparms ; i++, parm = parm->next)
+                               {
+                                       df->parm_size[i] = parm->size;
+                               }
+                               /*end function special case*/
+                       }
+               }
+               else if (type->type == ev_string && QCC_PR_CheckName("_"))
+               {
+                       char trname[128];
+                       QCC_PR_Expect("(");
+                       if (pr_token_type != tt_immediate || pr_immediate_type->type != ev_string)
+                               QCC_PR_ParseError(0, "_() intrinsic accepts only a string immediate");
+                       tmp = QCC_MakeStringConst(pr_immediate_string);
+                       QCC_PR_Lex();
+                       QCC_PR_Expect(")");
+
+                       if (!pr_scope || def->constant)
+                       {
+                               QCC_def_t *dt;
+                               sprintf(trname, "dotranslate_%i", ++dotranslate_count);
+                               dt = QCC_PR_DummyDef(type_string, trname, pr_scope, 0, offset, true, true);
+                               dt->references = 1;
+                               dt->constant = 1;
+                               dt->initialized = 1;
+                       }
+               }
+               else if (type->type == ev_struct || type->type == ev_union)
+               {
+                       //structs go recursive
+                       QCC_type_t *parttype;
+                       int partnum;
+                       int parms;
+                       pbool isunion;
+                       QCC_PR_Expect("{");
+
+                       isunion = ((type)->type == ev_union);
+                       for (partnum = 0, parttype = (type)->param, parms = (type)->num_parms; partnum < parms; partnum++, parttype = parttype->next)
+                       {
+                               QCC_PR_ParseInitializerType(parttype->arraysize, def, parttype, offset + parttype->ofs);
+                               if (isunion || !QCC_PR_CheckToken(","))
+                                       break;
+                       }
+                       QCC_PR_Expect("}");
+                       return;
+               }
+               else
+               {
+                       tmp = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
+                       if (typecmp(type, tmp->type))
+                       {
+                               /*you can cast from const 0 to anything*/
+                               if (tmp->type->size == type->size && (tmp->type->type == ev_integer || tmp->type->type == ev_float) && tmp->constant && !G_INT(tmp->ofs))
+                               {
+                               }
+                               /*cast from int->float will convert*/
+                               else if (type->type == ev_float && tmp->type->type == ev_integer)
+                                       tmp = QCC_PR_Statement (&pr_opcodes[OP_CONV_ITOF], tmp, 0, NULL);
+                               /*cast from float->int will convert*/
+                               else if (type->type == ev_integer && tmp->type->type == ev_float)
+                                       tmp = QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], tmp, 0, NULL);
+                               else
+                                       QCC_PR_ParseErrorPrintDef (ERR_BADIMMEDIATETYPE, def, "wrong initializer type");
+                       }
+               }
+
+               if (!pr_scope || def->constant)
+               {
+                       if (!tmp->constant)
+                               QCC_PR_ParseErrorPrintDef (ERR_BADIMMEDIATETYPE, def, "initializer is not constant");
+
+                       if (def->initialized)
+                       {
+                               for (i = 0; (unsigned)i < type->size; i++)
+                                       if (G_INT(offset+i) != G_INT(tmp->ofs+i))
+                                               QCC_PR_ParseErrorPrintDef (ERR_REDECLARATION, def, "incompatible redeclaration");
+                       }
+                       else
+                       {
+                               for (i = 0; (unsigned)i < type->size; i++)
+                                       G_INT(offset+i) = G_INT(tmp->ofs+i);
+                       }
+               }
+               else
+               {
+                       QCC_def_t lhs, rhs;
+                       if (def->initialized)
+                               QCC_PR_ParseErrorPrintDef (ERR_REDECLARATION, def, "%s initialised twice", def->name);
+
+                       memset(&lhs, 0, sizeof(lhs));
+                       memset(&rhs, 0, sizeof(rhs));
+                       def->references++;
+                       for (i = 0; (unsigned)i < type->size; )
+                       {
+                               rhs.type = lhs.type = type_float;
+                               lhs.ofs = offset+i;
+                               tmp->references++;
+                               rhs.ofs = tmp->ofs+i;
+
+                               if (type->size - i >= 3)
+                               {
+                                       QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_V], &rhs, &lhs, NULL));
+                                       i+=3;
+                               }
+                               else
+                               {
+                                       QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], &rhs, &lhs, NULL));
+                                       i++;
+                               }
+                       }
+               }
+               QCC_FreeTemp(tmp);
+       }
+}
+
+void QCC_PR_ParseInitializerDef(QCC_def_t *def, pbool isvar, pbool isconst)
+{
+       def->constant = (isconst || (!isvar && !pr_scope));
+       QCC_PR_ParseInitializerType(def->arraysize, def, def->type, def->ofs);
+       if (!def->initialized)
+               def->initialized = 1;
+}
+
 int accglobalsblock;   //0 = error, 1 = var, 2 = function, 3 = objdata
 /*
 ================
@@ -8388,10 +8684,12 @@ void QCC_PR_ParseDefs (char *classname)
        pbool nosave = false;
        pbool allocatenew = true;
        pbool inlinefunction = false;
-       int ispointer;
        gofs_t oldglobals;
        int arraysize;
 
+       while (QCC_PR_CheckToken(";"))
+               ;
+
        if (QCC_PR_CheckKeyword(keyword_enum, "enum"))
        {
                if (QCC_PR_CheckKeyword(keyword_integer, "integer") || QCC_PR_CheckKeyword(keyword_int, "int"))
@@ -8424,7 +8722,7 @@ void QCC_PR_ParseDefs (char *classname)
                                                QCC_PR_Lex();
                                        }
                                }
-                               def = QCC_MakeIntDef(iv);
+                               def = QCC_MakeIntConst(iv);
                                pHash_Add(&globalstable, name, def, qccHunkAlloc(sizeof(bucket_t)));
                                iv++;
 
@@ -8466,7 +8764,7 @@ void QCC_PR_ParseDefs (char *classname)
                                                QCC_PR_Lex();
                                        }
                                }
-                               def = QCC_MakeFloatDef(fv);
+                               def = QCC_MakeFloatConst(fv);
                                pHash_Add(&globalstable, name, def, qccHunkAlloc(sizeof(bucket_t)));
                                fv++;
 
@@ -8528,11 +8826,11 @@ void QCC_PR_ParseDefs (char *classname)
                                                        bits++;
                                                i>>=1;
                                        }
-                                       if (bits != 1)
+                                       if (bits > 1)
                                                QCC_PR_ParseWarning(WARN_ENUMFLAGS_NOTBINARY, "enumflags - value %i not a single bit", (int)iv);
                                }
 
-                               def = QCC_MakeIntDef(iv);
+                               def = QCC_MakeIntConst(iv);
                                pHash_Add(&globalstable, name, def, qccHunkAlloc(sizeof(bucket_t)));
 
                                iv*=2;
@@ -8587,11 +8885,11 @@ void QCC_PR_ParseDefs (char *classname)
                                                        bits++;
                                                i>>=1;
                                        }
-                                       if (bits != 1)
+                                       if (bits > 1)
                                                QCC_PR_ParseWarning(WARN_ENUMFLAGS_NOTBINARY, "enumflags - value %i not a single bit", (int)fv);
                                }
 
-                               def = QCC_MakeFloatDef(fv);
+                               def = QCC_MakeFloatConst(fv);
                                pHash_Add(&globalstable, name, def, qccHunkAlloc(sizeof(bucket_t)));
 
                                fv*=2;
@@ -8607,12 +8905,13 @@ void QCC_PR_ParseDefs (char *classname)
 
        if (QCC_PR_CheckKeyword (keyword_typedef, "typedef"))
        {
-               type = QCC_PR_ParseType(true);
+               type = QCC_PR_ParseType(true, false);
                if (!type)
                {
                        QCC_PR_ParseError(ERR_NOTANAME, "typedef found unexpected tokens");
                }
                type->name = QCC_CopyString(pr_token)+strings;
+               type->typedefed = true;
                QCC_PR_Lex();
                QCC_PR_Expect(";");
                return;
@@ -8637,7 +8936,7 @@ void QCC_PR_ParseDefs (char *classname)
                        if (accglobalsblock == 3)
                        {
                                if (!QCC_PR_GetDef(type_void, "end_sys_fields", NULL, false, 0, false))
-                                       QCC_PR_GetDef(type_void, "end_sys_fields", NULL, true, 1, false);
+                                       QCC_PR_GetDef(type_void, "end_sys_fields", NULL, true, 0, false);
                        }
 
                        QCC_PR_ParseName();
@@ -8656,11 +8955,11 @@ void QCC_PR_ParseDefs (char *classname)
                        if (accglobalsblock == 3)
                        {
                                if (!QCC_PR_GetDef(type_void, "end_sys_fields", NULL, false, 0, false))
-                                       QCC_PR_GetDef(type_void, "end_sys_fields", NULL, true, 1, false);
+                                       QCC_PR_GetDef(type_void, "end_sys_fields", NULL, true, 0, false);
                        }
                        else
                                if (!QCC_PR_GetDef(type_void, "end_sys_globals", NULL, false, 0, false))
-                                       QCC_PR_GetDef(type_void, "end_sys_globals", NULL, true, 1, false);
+                                       QCC_PR_GetDef(type_void, "end_sys_globals", NULL, true, 0, false);
                        accglobalsblock = 3;
                }
        }
@@ -8681,12 +8980,12 @@ void QCC_PR_ParseDefs (char *classname)
                        break;
                }
                if (QCC_PR_CheckKeyword(keyword_object, "object"))
-                       QCC_PR_GetDef(type_entity, name, NULL, true, 1, true);
+                       QCC_PR_GetDef(type_entity, name, NULL, true, 0, true);
                else if (QCC_PR_CheckKeyword(keyword_string, "string"))
-                       QCC_PR_GetDef(type_string, name, NULL, true, 1, true);
+                       QCC_PR_GetDef(type_string, name, NULL, true, 0, true);
                else if (QCC_PR_CheckKeyword(keyword_real, "real"))
                {
-                       def = QCC_PR_GetDef(type_float, name, NULL, true, 1, true);
+                       def = QCC_PR_GetDef(type_float, name, NULL, true, 0, true);
                        if (QCC_PR_CheckToken("="))
                        {
                                G_FLOAT(def->ofs) = pr_immediate._float;
@@ -8695,7 +8994,7 @@ void QCC_PR_ParseDefs (char *classname)
                }
                else if (QCC_PR_CheckKeyword(keyword_vector, "vector"))
                {
-                       def = QCC_PR_GetDef(type_vector, name, NULL, true, 1, true);
+                       def = QCC_PR_GetDef(type_vector, name, NULL, true, 0, true);
                        if (QCC_PR_CheckToken("="))
                        {
                                QCC_PR_Expect("[");
@@ -8709,7 +9008,7 @@ void QCC_PR_ParseDefs (char *classname)
                        }
                }
                else if (QCC_PR_CheckKeyword(keyword_pfunc, "pfunc"))
-                       QCC_PR_GetDef(type_function, name, NULL, true, 1, true);
+                       QCC_PR_GetDef(type_function, name, NULL, true, 0, true);
                else
                        QCC_PR_ParseError(ERR_BADNOTTYPE, "Bad type\n");
                QCC_PR_Expect (";");
@@ -8736,15 +9035,15 @@ void QCC_PR_ParseDefs (char *classname)
                        break;
                }
                if (QCC_PR_CheckKeyword(keyword_object, "object"))
-                       QCC_PR_GetDef(QCC_PR_FieldType(type_entity), name, NULL, true, 1, true);
+                       QCC_PR_GetDef(QCC_PR_FieldType(type_entity), name, NULL, true, 0, true);
                else if (QCC_PR_CheckKeyword(keyword_string, "string"))
-                       QCC_PR_GetDef(QCC_PR_FieldType(type_string), name, NULL, true, 1, true);
+                       QCC_PR_GetDef(QCC_PR_FieldType(type_string), name, NULL, true, 0, true);
                else if (QCC_PR_CheckKeyword(keyword_real, "real"))
-                       QCC_PR_GetDef(QCC_PR_FieldType(type_float), name, NULL, true, 1, true);
+                       QCC_PR_GetDef(QCC_PR_FieldType(type_float), name, NULL, true, 0, true);
                else if (QCC_PR_CheckKeyword(keyword_vector, "vector"))
-                       QCC_PR_GetDef(QCC_PR_FieldType(type_vector), name, NULL, true, 1, true);
+                       QCC_PR_GetDef(QCC_PR_FieldType(type_vector), name, NULL, true, 0, true);
                else if (QCC_PR_CheckKeyword(keyword_pfunc, "pfunc"))
-                       QCC_PR_GetDef(QCC_PR_FieldType(type_function), name, NULL, true, 1, true);
+                       QCC_PR_GetDef(QCC_PR_FieldType(type_function), name, NULL, true, 0, true);
                else
                        QCC_PR_ParseError(ERR_BADNOTTYPE, "Bad type\n");
                QCC_PR_Expect (";");
@@ -8778,7 +9077,7 @@ void QCC_PR_ParseDefs (char *classname)
                        break;
        }
 
-       type = QCC_PR_ParseType (false);
+       type = QCC_PR_ParseType (false, false);
        if (type == NULL)       //ignore
                return;
 
@@ -8796,9 +9095,7 @@ void QCC_PR_ParseDefs (char *classname)
                QCC_PR_Expect("(");
                type = QCC_PR_ParseFunctionTypeReacc(false, type);
                QCC_PR_Expect(";");
-               if (!stricmp(name, "null"))
-                       printf("null!\n");
-               def = QCC_PR_GetDef (type, name, NULL, true, 1, false);
+               def = QCC_PR_GetDef (type, name, NULL, true, 0, false);
 
                if (autoprototype)
                {       //ignore the code and stuff
@@ -8850,6 +9147,9 @@ void QCC_PR_ParseDefs (char *classname)
 //                             if (pr_dumpasm)
 //                                     PR_PrintFunction (def);
 
+               if (numfunctions >= MAX_FUNCTIONS)
+                       QCC_Error(ERR_INTERNAL, "Too many function defs");
+
 // fill in the dfunction
                df = &functions[numfunctions];
                numfunctions++;
@@ -8878,15 +9178,8 @@ void QCC_PR_ParseDefs (char *classname)
 //             QCC_PR_ParseError ("Fields must be global");
 
        do
-       {
-               if (QCC_PR_CheckToken ("*"))
-               {
-                       ispointer = 1;
-                       while(QCC_PR_CheckToken ("*"))
-                               ispointer++;
-                       name = QCC_PR_ParseName ();
-               }
-               else if (QCC_PR_CheckToken (";"))
+       {               
+               if (QCC_PR_CheckToken (";"))
                {
                        if (type->type == ev_field && (type->aux_type->type == ev_union || type->aux_type->type == ev_struct))
                        {
@@ -8899,12 +9192,10 @@ void QCC_PR_ParseDefs (char *classname)
 //                     }
                        QCC_PR_ParseError (ERR_TYPEWITHNONAME, "type with no name");
                        name = NULL;
-                       ispointer = false;
                }
                else
                {
                        name = QCC_PR_ParseName ();
-                       ispointer = false;
                }
 
                if (QCC_PR_CheckToken("::") && !classname)
@@ -8940,46 +9231,18 @@ void QCC_PR_ParseDefs (char *classname)
                        }
                        else
                        {
-                               def = QCC_PR_Expression(TOP_PRIORITY, 0);
-                               if (!def->constant)
-                                       QCC_PR_ParseError(ERR_BADARRAYSIZE, "Array size is not a constant value");
-                               else if (def->type->type == ev_integer)
-                                       arraysize = G_INT(def->ofs);
-                               else if (def->type->type == ev_float)
-                               {
-                                       arraysize = (int)G_FLOAT(def->ofs);
-                                       if ((float)arraysize != G_FLOAT(def->ofs))
-                                               QCC_PR_ParseError(ERR_BADARRAYSIZE, "Array size is not a constant value");
-                               }
-                               else
-                                       QCC_PR_ParseError(ERR_BADARRAYSIZE, "Array size must be of int value");
-/*                             if(pr_token_type == tt_name)
-                               {
-                                       def = QCC_PR_GetDef(NULL, QCC_PR_ParseName(), pr_scope, false, 0);
-                                       if (def && def->arraysize==1)
-                                       {
-                                               if (def->type->type == ev_integer)
-                                                       arraysize = G_INT(def->ofs);
-                                               else if (def->type->type == ev_float && (float)(int)G_FLOAT(def->ofs) == G_FLOAT(def->ofs))
-                                                       arraysize = (int)G_FLOAT(def->ofs);
-                                       }
-                               }
-                               else if (pr_token_type == tt_immediate)
-                               {
-                                       arraysize = atoi (pr_token);
-                                       QCC_PR_Lex();
-                               }
-*/                             QCC_PR_Expect("]");
+                               arraysize = QCC_PR_IntConstExpr();
+                               QCC_PR_Expect("]");
                        }
 
                        if (arraysize < 1)
                        {
                                QCC_PR_ParseError (ERR_BADARRAYSIZE, "Definition of array (%s) size is not of a numerical value", name);
-                               arraysize=0;    //grrr...
+                               arraysize=1;    //grrr...
                        }
                }
                else
-                       arraysize = 1;
+                       arraysize = 0;
 
                if (QCC_PR_CheckToken("("))
                {
@@ -9007,19 +9270,7 @@ void QCC_PR_ParseDefs (char *classname)
 
                oldglobals = numpr_globals;
 
-               if (ispointer)
-               {
-                       parm = type;
-                       while(ispointer)
-                       {
-                               ispointer--;
-                               parm = QCC_PointerTypeTo(parm);
-                       }
-
-                       def = QCC_PR_GetDef (parm, name, pr_scope, allocatenew, arraysize, !nosave);
-               }
-               else
-                       def = QCC_PR_GetDef (type, name, pr_scope, allocatenew, arraysize, !nosave);
+               def = QCC_PR_GetDef (type, name, pr_scope, allocatenew, arraysize, !nosave);
 
                if (!def)
                        QCC_PR_ParseError(ERR_NOTANAME, "%s is not part of class %s", name, classname);
@@ -9051,13 +9302,12 @@ void QCC_PR_ParseDefs (char *classname)
                                QCC_PR_ParseError (ERR_INITIALISEDLOCALFUNCTION, "local functions may not be initialised");
                        }
 
-                       arraysize = def->arraysize;
-                       d = def;        //apply to ALL elements
-                       while(arraysize--)
+                       d = def;
+                       while (d != def->deftail)
                        {
+                               d = d->next;
                                d->initialized = 1;     //fake function
                                G_FUNCTION(d->ofs) = 0;
-                               d = d->next;
                        }
 
                        continue;
@@ -9074,14 +9324,14 @@ void QCC_PR_ParseDefs (char *classname)
                                QCC_PR_ParseError (ERR_SHAREDINITIALISED, "shared values may not be assigned an initial value", name);
                        if (def->initialized == 1)
                        {
-                               if (def->type->type == ev_function)
-                               {
-                                       i = G_FUNCTION(def->ofs);
-                                       df = &functions[i];
-                                       QCC_PR_ParseErrorPrintDef (ERR_REDECLARATION, def, "%s redeclared, prev instance is in %s", name, strings+df->s_file);
-                               }
-                               else
-                                       QCC_PR_ParseErrorPrintDef(ERR_REDECLARATION, def, "%s redeclared", name);
+//                             if (def->type->type == ev_function)
+//                             {
+//                                     i = G_FUNCTION(def->ofs);
+//                                     df = &functions[i];
+//                                     QCC_PR_ParseErrorPrintDef (ERR_REDECLARATION, def, "%s redeclared, prev instance is in %s", name, strings+df->s_file);
+//                             }
+//                             else
+//                                     QCC_PR_ParseErrorPrintDef(ERR_REDECLARATION, def, "%s redeclared", name);
                        }
 
                        if (autoprototype)
@@ -9119,588 +9369,7 @@ void QCC_PR_ParseDefs (char *classname)
                                continue;
                        }
 
-                       if (pr_scope)
-                       {
-                               d = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
-                               if (typecmp(def->type, d->type))
-                                       QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "wrong immediate type for %s", name);
-                               if (d->constant)
-                               {
-                                       for (i = 0; (unsigned)i < def->type->size; i++)
-                                               G_INT(def->ofs+i) = G_INT(d->ofs+i);
-                                       def->constant = !isvar;
-                                       def->initialized = 1;
-                                       continue;
-                               }
-                               else if (def->type->size >= 3)
-                               {
-                                       QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_V], d, def, NULL));
-                                       def->constant = false;
-                                       def->initialized = false;
-                                       continue;
-                               }
-                               else
-                               {
-                                       QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], d, def, NULL));
-                                       def->constant = false;
-                                       def->initialized = false;
-                                       continue;
-                               }
-                       }
-                       else
-                               if (pr_token_type == tt_name && strcmp(pr_token, "_"))
-                       {
-                               unsigned int i;
-
-                               if (def->arraysize>1)
-                                       QCC_PR_ParseError(ERR_ARRAYNEEDSBRACES, "Array initialisation requires curly braces");
-
-                               d = QCC_PR_GetDef(NULL, pr_token, pr_scope, false, 0, false);
-                               if (!d)
-                                       QCC_PR_ParseError(ERR_NOTDEFINED, "%s was not defined\n", pr_token);
-                               if (typecmp(def->type, d->type))
-                                       QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "wrong immediate type for %s", name);
-
-
-                               for (i = 0; i < d->type->size; i++)
-                                       G_INT(def->ofs) = G_INT(d->ofs);
-                               QCC_PR_Lex();
-
-                               if (type->type == ev_function)
-                               {
-                                       def->initialized = 1;
-                                       def->constant = !isvar;
-                               }
-                               continue;
-                       }
-
-                       else if (type->type == ev_function)
-                       {
-                               if (isvar)
-                                       def->constant = false;
-                               else
-                                       def->constant = true;
-                               if (QCC_PR_CheckImmediate("0") || QCC_PR_CheckImmediate("0i"))
-                               {
-                                       def->constant = 0;
-                                       def->initialized = 1;   //fake function
-                                       G_FUNCTION(def->ofs) = 0;
-                                       continue;
-                               }
-
-                               if (!def->constant && arraysize==1)
-                               {
-                                       def->constant = 0;
-                                       def->initialized = 1;   //fake function
-
-                                       name = QCC_PR_ParseName ();
-                                       d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0, false);
-                                       if (!d)
-                                               QCC_PR_ParseError(ERR_NOTDEFINED, "%s was not previously defined", name);
-                                       G_FUNCTION(def->ofs+i) = G_FUNCTION(d->ofs);
-                                       continue;
-                               }
-
-                               if (arraysize>1)
-                               {
-                                       int i;
-                                       def->initialized = 1;   //fake function
-                                       QCC_PR_Expect ("{");
-                                       i = 0;
-                                       do
-                                       {
-                                               if (pr_token_type == tt_immediate && (
-                                                       (pr_immediate_type == type_integer && pr_immediate._int == 0) ||
-                                                       (pr_immediate_type == type_float && pr_immediate._float == 0)))
-                                               {
-                                                       QCC_PR_Lex();
-                                                       G_FUNCTION(def->ofs+i) = 0;
-                                               }
-                                               else
-                                               {
-                                                       name = QCC_PR_ParseName ();
-
-                                                       d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0, false);
-                                                       if (!d)
-                                                               QCC_PR_ParseError(ERR_NOTDEFINED, "%s was not defined", name);
-                                                       else
-                                                       {
-                                                               if (!d->initialized)
-                                                                       QCC_PR_ParseWarning(WARN_NOTDEFINED, "initialisation of function arrays must be placed after the body of all functions used (%s)", name);
-                                                               G_FUNCTION(def->ofs+i) = G_FUNCTION(d->ofs);
-                                                       }
-                                               }
-
-                                               i++;
-                                       } while(QCC_PR_CheckToken(","));
-
-                                       arraysize = def->arraysize;
-                                       d = def;        //apply to ALL elements
-                                       while(arraysize--)
-                                       {
-                                               d->initialized = 1;     //fake function
-                                               d = d->next;
-                                       }
-
-                                       QCC_PR_Expect("}");
-                                       if (i > def->arraysize)
-                                               QCC_PR_ParseError(ERR_TOOMANYINITIALISERS, "Too many initializers");
-                                       continue;
-                               }
-                               if (!def->constant)
-                                       QCC_PR_ParseError(0, "Initialised functions must be constant");
-
-                               def->references++;
-                               pr_scope = def;
-                               f = QCC_PR_ParseImmediateStatements (type);
-                               pr_scope = NULL;
-                               def->initialized = 1;
-                               G_FUNCTION(def->ofs) = numfunctions;
-                               f->def = def;
-//                             if (pr_dumpasm)
-//                                     PR_PrintFunction (def);
-
-               // fill in the dfunction
-                               df = &functions[numfunctions];
-                               numfunctions++;
-                               if (f->builtin)
-                                       df->first_statement = -f->builtin;
-                               else
-                                       df->first_statement = f->code;
-
-                               if (f->builtin && opt_function_names)
-                                       optres_function_names += strlen(f->def->name);
-                               else
-                                       df->s_name = QCC_CopyString (f->def->name);
-                               df->s_file = s_file2;
-                               df->numparms =  f->def->type->num_parms;
-                               df->locals = locals_end - locals_start;
-                               df->parm_start = locals_start;
-                               for (i=0,parm = type->param ; i<df->numparms ; i++, parm = parm->next)
-                               {
-                                       df->parm_size[i] = parm->size;
-                               }
-
-                               continue;
-                       }
-
-                       else if (type->type == ev_struct)
-                       {
-                               int arraypart, partnum;
-                               QCC_type_t *parttype;
-                               def->initialized = 1;
-                               if (isvar)
-                                       def->constant = true;
-                               else
-                                       def->constant = false;
-//                             if (constant)
-//                                     QCC_PR_ParseError("const used on a struct isn't useful");
-
-                               //FIXME: should do this recursivly
-                               QCC_PR_Expect("{");
-                               for (arraypart = 0; arraypart < arraysize; arraypart++)
-                               {
-                                       parttype = type->param;
-                                       QCC_PR_Expect("{");
-                                       for (partnum = 0; partnum < type->num_parms; partnum++)
-                                       {
-                                               switch (parttype->type)
-                                               {
-                                               case ev_float:
-                                               case ev_integer:
-                                               case ev_vector:
-                                                       if (pr_token_type == tt_punct)
-                                                       {
-                                                               if (QCC_PR_CheckToken("{"))
-                                                               {
-                                                                       QCC_PR_Expect("}");
-                                                               }
-                                                               else
-                                                                       QCC_PR_ParseError(ERR_UNEXPECTEDPUNCTUATION, "Unexpected punctuation");
-
-                                                       }
-                                                       else if (pr_token_type == tt_immediate)
-                                                       {
-                                                               if (pr_immediate_type->type == ev_float && parttype->type == ev_integer)
-                                                                       G_INT(def->ofs + arraypart*type->size + parttype->ofs) = (int)pr_immediate._float;
-                                                               else if (pr_immediate_type->type != parttype->type)
-                                                                       QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "wrong immediate subtype for %s.%s", def->name, parttype->name);
-                                                               else
-                                                                       memcpy (qcc_pr_globals + def->ofs + arraypart*type->size + parttype->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
-                                                       }
-                                                       else if (pr_token_type == tt_name)
-                                                       {
-                                                               d = QCC_PR_GetDef(NULL, pr_token, pr_scope, false, 0, false);
-                                                               if (!d)
-                                                                       QCC_PR_ParseError(ERR_NOTDEFINED, "%s was not defined\n", pr_token);
-                                                               else if (d->type->type != parttype->type)
-                                                                       QCC_PR_ParseError (ERR_WRONGSUBTYPE, "wrong subtype for %s.%s", def->name, parttype->name);
-                                                               else if (!d->constant)
-                                                                       QCC_PR_ParseError(ERR_NOTACONSTANT, "%s isn't a constant\n", pr_token);
-
-                                                               memcpy (qcc_pr_globals + def->ofs + arraypart*type->size + parttype->ofs, qcc_pr_globals + d->ofs, 4*d->type->size);
-                                                       }
-                                                       else
-                                                               QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "wrong immediate subtype for %s.%s", def->name, parttype->name);
-                                                       QCC_PR_Lex ();
-
-                                                       break;
-                                               case ev_string:
-                                                       if (pr_token_type == tt_punct)
-                                                       {
-                                                               if (QCC_PR_CheckToken("{"))
-                                                               {
-                                                                       unsigned int i;
-                                                                       for (i = 0; i < parttype->size; i++)
-                                                                       {
-/*                                                                             //the executor defines strings as true c strings, but reads in index from string table.
-                                                                               //structures can hide these strings.
-                                                                               d = (void *)qccHunkAlloc (sizeof(QCC_def_t));
-                                                                               d->next = NULL;
-                                                                               pr.def_tail->next = d;
-                                                                               pr.def_tail = d;
-
-                                                                               d->type = parttype;
-                                                                               d->name = "STRUCTIMMEDIATE";
-                                                                               d->constant = constant;
-                                                                               d->initialized = 1;
-                                                                               d->scope = NULL;
-
-                                                                               d->ofs = def->ofs+arraypart*type->size+parttype->ofs+i;
-*/
-                                                                               G_INT(def->ofs+arraypart*type->size+parttype->ofs+i) = QCC_CopyString(pr_immediate_string);
-                                                                               QCC_PR_Lex ();
-
-                                                                               if (!QCC_PR_CheckToken(","))
-                                                                               {
-                                                                                       i++;
-                                                                                       break;
-                                                                               }
-                                                                       }
-                                                                       for (; i < parttype->size; i++)
-                                                                       {
-/*                                                                             //the executor defines strings as true c strings, but reads in index from string table.
-                                                                               //structures can hide these strings.
-                                                                               d = (void *)qccHunkAlloc (sizeof(QCC_def_t));
-                                                                               d->next = NULL;
-                                                                               pr.def_tail->next = d;
-                                                                               pr.def_tail = d;
-
-                                                                               d->type = parttype;
-                                                                               d->name = "STRUCTIMMEDIATE";
-                                                                               d->constant = constant;
-                                                                               d->initialized = 1;
-                                                                               d->scope = NULL;
-
-                                                                               d->ofs = def->ofs+arraypart*type->size+parttype->ofs+i;
-*/
-                                                                               G_INT(def->ofs+arraypart*type->size+parttype->ofs+i) = 0;
-                                                                       }
-                                                                       QCC_PR_Expect("}");
-                                                               }
-                                                               else
-                                                                       QCC_PR_ParseError(ERR_UNEXPECTEDPUNCTUATION, "Unexpected punctuation");
-                                                       }
-                                                       else
-                                                       {
-/*                                                             //the executor defines strings as true c strings, but reads in index from string table.
-                                                               //structures can hide these strings.
-                                                               d = (void *)qccHunkAlloc (sizeof(QCC_def_t));
-                                                               d->next = NULL;
-                                                               pr.def_tail->next = d;
-                                                               pr.def_tail = d;
-
-                                                               d->type = parttype;
-                                                               d->name = "STRUCTIMMEDIATE";
-                                                               d->constant = constant;
-                                                               d->initialized = 1;
-                                                               d->scope = NULL;
-
-                                                               d->ofs = def->ofs+arraypart*type->size+parttype->ofs;
-*/
-                                                               G_INT(def->ofs+arraypart*type->size+parttype->ofs) = QCC_CopyString(pr_immediate_string);
-                                                               QCC_PR_Lex ();
-                                                       }
-                                                       break;
-                                               case ev_function:
-                                                       if (pr_token_type == tt_immediate)
-                                                       {
-                                                               if (pr_immediate._int != 0)
-                                                                       QCC_PR_ParseError(ERR_NOTFUNCTIONTYPE, "Expected function name or NULL");
-                                                               G_FUNCTION(def->ofs+arraypart*type->size+parttype->ofs) = 0;
-                                                               QCC_PR_Lex();
-                                                       }
-                                                       else
-                                                       {
-                                                               name = QCC_PR_ParseName ();
-
-                                                               d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0, false);
-                                                               if (!d)
-                                                                       QCC_PR_ParseError(ERR_NOTDEFINED, "%s was not defined\n", name);
-                                                               else
-                                                                       G_FUNCTION(def->ofs+arraypart*type->size+parttype->ofs) = G_FUNCTION(d->ofs);
-                                                       }
-                                                       break;
-                                               default:
-                                                       QCC_PR_ParseError(ERR_TYPEINVALIDINSTRUCT, "type %i not valid in a struct", parttype->type);
-                                                       QCC_PR_Lex();
-                                                       break;
-                                               }
-                                               if (!QCC_PR_CheckToken(","))
-                                                       break;
-
-                                               parttype=parttype->next;
-                                       }
-                                       QCC_PR_Expect("}");
-                                       if (!QCC_PR_CheckToken(","))
-                                               break;
-                               }
-                               QCC_PR_Expect("}");
-                               continue;
-                       }
-
-                       else if (type->type == ev_integer)      //handle these differently, because they may need conversions
-                       {
-                               if (isvar)
-                                       def->constant = false;
-                               else
-                                       def->constant = true;
-
-                               def->initialized = 1;
-                               memcpy (qcc_pr_globals + def->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
-                               QCC_PR_Lex ();
-
-                               if (pr_immediate_type->type == ev_float)
-                                       G_INT(def->ofs) = (int)pr_immediate._float;
-                               else if (pr_immediate_type->type != ev_integer)
-                                       QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "wrong immediate type for %s", name);
-
-                               continue;
-                       }
-                       else if (type->type == ev_string)
-                       {
-                               int dotranslate = 0;
-                               char buf[64];
-                               if (!strcmp(pr_token, "_"))
-                               {
-                                       dotranslate = 1;
-                                       QCC_PR_Lex();
-                               }
-                               if(dotranslate)
-                                       QCC_PR_Expect("(");
-
-                               if (arraysize>=1 && QCC_PR_CheckToken("{"))
-                               {
-                                       int i;
-                                       for (i = 0; i < arraysize; i++)
-                                       {
-                                               int dotranslate2;
-
-                                               //the executor defines strings as true c strings, but reads in index from string table.
-                                               //structures can hide these strings.
-                                               if (i != 0)     //not for the first entry - already a string def for that
-                                               {
-                                                       d = (void *)qccHunkAlloc (sizeof(QCC_def_t));
-                                                       d->next = NULL;
-                                                       pr.def_tail->next = d;
-                                                       pr.def_tail = d;
-
-                                                       d->name = "IMMEDIATE";
-                                                       d->type = type_string;
-                                                       if (isvar)
-                                                               d->constant = false;
-                                                       else
-                                                               d->constant = true;
-                                                       d->initialized = 1;
-                                                       d->scope = NULL;
-
-                                                       d->ofs = def->ofs+i;
-                                                       if (d->ofs >= MAX_REGS)
-                                                               QCC_Error(ERR_TOOMANYGLOBALS, "MAX_REGS is too small");
-                                               }
-
-                                               if (!strcmp(pr_token, "_"))
-                                               {
-                                                       dotranslate2 = 1;
-                                                       QCC_PR_Lex();
-                                               }
-                                               if(dotranslate2)
-                                                       QCC_PR_Expect("(");
-
-                                               if(dotranslate || dotranslate2)
-                                               {
-                                                       sprintf(buf, "dotranslate_%d", ++dotranslate_count);
-                                                       d->name = strdup(buf);
-                                               }
-
-                                               (((int *)qcc_pr_globals)[def->ofs+i]) = QCC_CopyString(pr_immediate_string);
-                                               QCC_PR_Lex ();
-
-                                               if(dotranslate2)
-                                                       QCC_PR_Expect(")");
-
-                                               if (!QCC_PR_CheckToken(","))
-                                                       break;
-                                       }
-                                       QCC_PR_Expect("}");
-                               }
-                               else if (arraysize<=1)
-                               {
-                                       if (isvar)
-                                               def->constant = false;
-                                       else
-                                               def->constant = true;
-                                       def->initialized = 1;
-                                       (((int *)qcc_pr_globals)[def->ofs]) = QCC_CopyString(pr_immediate_string);
-                                       QCC_PR_Lex ();
-
-                                       if(dotranslate)
-                                       {
-                                               sprintf(buf, "dotranslate_%d", ++dotranslate_count);
-                                               def->name = strdup(buf);
-                                       }
-
-                                       if (pr_immediate_type->type == ev_float)
-                                               G_INT(def->ofs) = (int)pr_immediate._float;
-                                       else if (pr_immediate_type->type != ev_string)
-                                               QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "wrong immediate type for %s", name);
-                               }
-                               else
-                                       QCC_PR_ParseError(ERR_ARRAYNEEDSBRACES, "Array initialisation requires curly brasces");
-
-                               if(dotranslate)
-                                       QCC_PR_Expect(")");
-                               continue;
-                       }
-                       else if (type->type == ev_float)
-                       {
-                               if (arraysize>=1 && QCC_PR_CheckToken("{"))
-                               {
-                                       int i;
-                                       for (i = 0; i < arraysize; i++)
-                                       {
-                                               if (pr_immediate_type->type != ev_float)
-                                                       QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "wrong immediate type for %s", name);
-                                               (((float *)qcc_pr_globals)[def->ofs+i]) = pr_immediate._float;
-                                               QCC_PR_Lex ();
-
-                                               if (!QCC_PR_CheckToken(","))
-                                                       break;
-                                       }
-                                       QCC_PR_Expect("}");
-
-                                       continue;
-                               }
-                               else if (arraysize<=1)
-                               {
-                                       if (isvar)
-                                               def->constant = false;
-                                       else
-                                               def->constant = true;
-
-                                       def->initialized = 1;
-
-                                       if (pr_immediate_type->type != ev_float)
-                                               QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "wrong immediate type for %s", name);
-
-                                       if (def->constant && opt_dupconstdefs)
-                                       {
-                                               if (def->ofs == oldglobals)
-                                               {
-                                                       if (Hash_GetKey(&floatconstdefstable, *(int*)&pr_immediate._float))
-                                                               optres_dupconstdefs++;
-                                                       QCC_FreeOffset(def->ofs, def->type->size);
-                                                       d = QCC_MakeFloatDef(pr_immediate._float);
-                                                       d->references++;
-                                                       def->ofs = d->ofs;
-                                                       QCC_PR_Lex();
-                                                       continue;
-                                               }
-                                       }
-
-                                       (((float *)qcc_pr_globals)[def->ofs]) = pr_immediate._float;
-                                       QCC_PR_Lex ();
-
-                                       continue;
-                               }
-                               else
-                                       QCC_PR_ParseError(ERR_ARRAYNEEDSBRACES, "Array initialisation requires curly brasces");
-                       }
-                       else if (type->type == ev_vector)
-                       {
-                               if (arraysize>=1 && QCC_PR_CheckToken("{"))
-                               {
-                                       int i;
-                                       for (i = 0; i < arraysize; i++)
-                                       {
-                                               if (pr_immediate_type->type != ev_vector)
-                                                       QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "wrong immediate type for %s", name);
-                                               (((float *)qcc_pr_globals)[def->ofs+i*3+0]) = pr_immediate.vector[0];
-                                               (((float *)qcc_pr_globals)[def->ofs+i*3+1]) = pr_immediate.vector[1];
-                                               (((float *)qcc_pr_globals)[def->ofs+i*3+2]) = pr_immediate.vector[2];
-                                               QCC_PR_Lex ();
-
-                                               if (!QCC_PR_CheckToken(","))
-                                                       break;
-                                       }
-                                       QCC_PR_Expect("}");
-
-                                       continue;
-                               }
-                               else if (arraysize<=1)
-                               {
-                                       if (isvar)
-                                               def->constant = false;
-                                       else
-                                               def->constant = true;
-                                       def->initialized = 1;
-
-                                       if (pr_immediate_type->type != ev_vector)
-                                               QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "wrong immediate type for %s", name);
-                                       (((float *)qcc_pr_globals)[def->ofs+0]) = pr_immediate.vector[0];
-                                       (((float *)qcc_pr_globals)[def->ofs+1]) = pr_immediate.vector[1];
-                                       (((float *)qcc_pr_globals)[def->ofs+2]) = pr_immediate.vector[2];
-                                       QCC_PR_Lex ();
-
-                                       continue;
-                               }
-                               else
-                                       QCC_PR_ParseError(ERR_ARRAYNEEDSBRACES, "Array initialisation requires curly brasces");
-                       }
-                       else if (pr_token_type == tt_name)
-                       {
-//                             if (pr_scope)//create a new instance, emit a copy op
-//                             {
-//                                     QCC_PR_ParseError ("name defined for local : %s", name);
-//                             }
-//                             else
-                               {
-                                       d = QCC_PR_GetDef (NULL, pr_token, pr_scope, false, 0, false);
-                                       if (!d)
-                                               QCC_PR_ParseError (ERR_NOTDEFINED, "initialisation name not defined : %s", pr_token);
-                                       if (!d->constant)
-                                       {
-                                               QCC_PR_ParseWarning (WARN_NOTCONSTANT, "initialisation name not a constant : %s", pr_token);
-                                               QCC_PR_ParsePrintDef(WARN_NOTCONSTANT, d);
-                                       }
-                                       memcpy (def, d, sizeof(*d));
-                                       def->name = name;
-                                       def->initialized = true;
-                               }
-                       }
-                       else if (pr_token_type != tt_immediate)
-                               QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "not an immediate for %s - %s", name, pr_token);
-                       else if (pr_immediate_type->type != type->type)
-                               QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "wrong immediate type for %s - %s", name, pr_token);
-                       else
-                               memcpy (qcc_pr_globals + def->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
-
-                       if (isvar)
-                               def->constant = false;
-                       else
-                               def->constant = true;
-                       def->initialized = true;
-                       QCC_PR_Lex ();
+                       QCC_PR_ParseInitializerDef(def, isvar, isconstant);
                }
                else
                {
@@ -9723,7 +9392,13 @@ void QCC_PR_ParseDefs (char *classname)
                                def->constant = isconstant;
                }
 
-
+               d = def;
+               while (d != def->deftail)
+               {
+                       d = d->next;
+                       d->constant = def->constant;
+                       d->initialized = def->initialized;
+               }
        } while (QCC_PR_CheckToken (","));
 
        if (type->type == ev_function)
@@ -9817,7 +9492,6 @@ pbool QCC_Include(char *filename)
        int opr_source_line;
        char *ocompilingfile;
        struct qcc_includechunk_s *oldcurrentchunk;
-       extern struct qcc_includechunk_s *currentchunk;
 
        ocompilingfile = compilingfile;
        os_file = s_file;
index 9bdd11c42d543d22c0c0e5a8f3ea069da45b7107..7a4319ba64ce795e16bcfe68c3cb3df93f76ae58 100644 (file)
@@ -6,22 +6,14 @@
 #endif
 #include "time.h"
 
-// I put the following here to resolve "undefined reference to `__imp__vsnprintf'" with MinGW64 ~ Moodles
-#ifdef __MINGW64__
-#ifndef QCCONLY
-       #if (_MSC_VER >= 1400)
-               //with MSVC 8, use MS extensions
-               #define snprintf linuxlike_snprintf_vc8
-               int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ...) LIKEPRINTF(3);
-               #define vsnprintf(a, b, c, d) vsnprintf_s(a, b, _TRUNCATE, c, d)
-       #else
-               //msvc crap
-               #define snprintf linuxlike_snprintf
-               int VARGS linuxlike_snprintf(char *buffer, int size, const char *format, ...) LIKEPRINTF(3);
-               #define vsnprintf linuxlike_vsnprintf
-               int VARGS linuxlike_vsnprintf(char *buffer, int size, const char *format, va_list argptr);
-       #endif
-#endif
+#ifdef _WIN64
+        #ifdef _SDL
+                #define snprintf linuxlike_snprintf
+                int VARGS linuxlike_snprintf(char *buffer, int size, const char *format, ...) LIKEPRINTF(3);
+                #define vsnprintf linuxlike_vsnprintf
+                int VARGS linuxlike_vsnprintf(char *buffer, int size, const char *format, va_list argptr);
+                //void *__imp__vsnprintf = vsnprintf;
+        #endif
 #endif
 
 #define MEMBERFIELDNAME "__m%s"
@@ -82,6 +74,8 @@ QCC_type_t    *type_function;// = {ev_function/*, &def_function*/,NULL,&type_void};
 QCC_type_t     *type_pointer;// = {ev_pointer/*, &def_pointer*/};
 QCC_type_t     *type_integer;// = {ev_integer/*, &def_integer*/};
 QCC_type_t     *type_variant;// = {ev_integer/*, &def_integer*/};
+QCC_type_t     *type_floatpointer;
+QCC_type_t     *type_intpointer;
 
 QCC_type_t     *type_floatfield;// = {ev_field/*, &def_field*/, NULL, &type_float};
 
@@ -106,13 +100,6 @@ void QCC_PR_LexWhitespace (void);
 
 //for compiler constants and file includes.
 
-typedef struct qcc_includechunk_s {
-       struct qcc_includechunk_s *prev;
-       char *filename;
-       char *currentdatapoint;
-       int currentlinenumber;
-       CompilerConstant_t *cnst;
-} qcc_includechunk_t;
 qcc_includechunk_t *currentchunk;
 void QCC_PR_IncludeChunkEx (char *data, pbool duplicate, char *filename, CompilerConstant_t *cnst)
 {
@@ -237,16 +224,34 @@ int ParsePrecompilerIf(void)
 {
        CompilerConstant_t *c;
        int eval = 0;
-       //char *start = pr_file_p; //warning: unused variable âstartâ
+       pbool notted = false;
+       
+       /*skip whitespace*/
+       while (*pr_file_p && *pr_file_p <= ' ' && *pr_file_p != '\n')
+       {
+               pr_file_p++;
+       }
+       if (*pr_file_p == '!')
+       {
+               pr_file_p++;
+               notted = true;
+               while (*pr_file_p && *pr_file_p <= ' ' && *pr_file_p != '\n')
+               {
+                       pr_file_p++;
+               }
+       }
+
        if (!QCC_PR_SimpleGetToken())
        {
                if (*pr_file_p == '(')
                {
+                       pr_file_p++;
                        eval = ParsePrecompilerIf();
                        while (*pr_file_p == ' ' || *pr_file_p == '\t')
                                pr_file_p++;
                        if (*pr_file_p != ')')
                                QCC_PR_ParseError(ERR_EXPECTED, "unclosed bracket condition\n");
+                       pr_file_p++;
                }
                else
                        QCC_PR_ParseError(ERR_EXPECTED, "expected bracket or constant\n");
@@ -280,6 +285,9 @@ int ParsePrecompilerIf(void)
                        eval = atoi(c->value);
        }
 
+       if (notted)
+               eval = !eval;
+
        QCC_PR_SimpleGetToken();
        if (!strcmp(pr_token, "||"))
                eval = ParsePrecompilerIf()||eval;
@@ -514,7 +522,7 @@ pbool QCC_PR_Precompiler(void)
                        for (a = 0; a < sizeof(msg)-1 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++)
                                msg[a] = pr_file_p[a];
 
-                       msg[a-1] = '\0';
+                       msg[a] = '\0';
 
                        while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line, yes, I KNOW we are going to register an error, and not properly leave this function tree, but...
                        {
@@ -647,11 +655,6 @@ pbool QCC_PR_Precompiler(void)
                                if (*pr_file_p == '\r')
                                        pr_file_p++;
 
-                               for (a = 0; a < sizeof(msg)-1 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++)
-                                       msg[a] = pr_file_p[a];
-
-                               msg[a-1] = '\0';
-
                                while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line
                                {
                                        pr_file_p++;
@@ -831,6 +834,18 @@ pbool QCC_PR_Precompiler(void)
                        {
                                defaultstatic = atoi(msg);
                        }
+                       else if (!strncmp(qcc_token, "wrasm", 5))
+                       {
+                               pbool on = atoi(msg);
+
+                               if (asmfile && !on)
+                               {
+                                       fclose(asmfile);
+                                       asmfile = NULL;
+                               }                       
+                               if (!asmfile && on)
+                                       asmfile = fopen("qc.asm", "wb");
+                       }
                        else if (!strncmp(qcc_token, "sourcefile", 10))
                        {
        #define MAXSOURCEFILESLIST 8
@@ -847,7 +862,7 @@ pbool QCC_PR_Precompiler(void)
                                        if (!strcmp(sourcefileslist[i], qcc_token))
                                                break;
                                }
-                               if (i == numsourcefiles)
+                               if (i == numsourcefiles && numsourcefiles < MAXSOURCEFILESLIST)
                                        strcpy(sourcefileslist[numsourcefiles++], qcc_token);
                        }
                        else if (!QC_strcasecmp(qcc_token, "TARGET"))
@@ -857,7 +872,7 @@ pbool QCC_PR_Precompiler(void)
                                else if (!QC_strcasecmp(msg, "H2") || !QC_strcasecmp(msg, "HEXEN2"))
                                {
                                        if (numstatements)
-                                               QCC_PR_ParseWarning(WARN_BADTARGET, "Cannot switch from hexen2 target \'%s\'. Ignored.", msg);
+                                               QCC_PR_ParseWarning(WARN_BADTARGET, "Cannot switch to hexen2 target \'%s\'. Ignored.", msg);
                                        else
                                                qcc_targetformat = QCF_HEXEN2;
                                }
@@ -1354,7 +1369,7 @@ int QCC_PR_LexInteger (void)
                len++;
                pr_file_p++;
                c = *pr_file_p;
-       } while ((c >= '0' && c<= '9') || c == '.' || (c>='a' && c <= 'f'));
+       } while ((c >= '0' && c<= '9') || (c == '.'&&pr_file_p[1]!='.') || (c>='a' && c <= 'f'));
        pr_token[len] = 0;
        return atoi (pr_token);
 }
@@ -1407,7 +1422,7 @@ void QCC_PR_LexNumber (void)
                        num*=base;
                        num += c -'A'+10;
                }
-               else if (c == '.')
+               else if (c == '.' && pr_file_p[1]!='.')
                {
                        pr_token[tokenlen++] = c;
                        pr_file_p++;
@@ -1434,6 +1449,15 @@ void QCC_PR_LexNumber (void)
                        pr_immediate._float = (float)atof(pr_token);
                        return;
                }
+               else if (c == 'f')
+               {
+                       pr_token[tokenlen++] = c;
+                       pr_token[tokenlen++] = 0;
+                       pr_file_p++;
+                       pr_immediate_type = type_float;
+                       pr_immediate._float = num*sign;
+                       return;
+               }
                else if (c == 'i')
                {
                        pr_token[tokenlen++] = c;
@@ -1487,6 +1511,8 @@ float QCC_PR_LexFloat (void)
                pr_file_p++;
                c = *pr_file_p;
        } while ((c >= '0' && c<= '9') || (c == '.'&&pr_file_p[1]!='.'));       //only allow a . if the next isn't too...
+       if (*pr_file_p == 'f')
+               pr_file_p++;
        pr_token[len] = 0;
        return (float)atof (pr_token);
 }
@@ -1532,6 +1558,7 @@ void QCC_PR_LexVector (void)
                default:
                        QCC_PR_ParseError (ERR_INVALIDVECTORIMMEDIATE, "Bad character constant");
                }
+               pr_file_p++;
                if (*pr_file_p != '\'')
                        QCC_PR_ParseError (ERR_INVALIDVECTORIMMEDIATE, "Bad character constant");
                pr_file_p++;
@@ -1680,6 +1707,7 @@ void QCC_PR_LexWhitespace (void)
                                }
                                if (pr_file_p[1] == 0)
                                {
+                                       QCC_PR_ParseError(0, "EOF inside comment\n");
                                        pr_file_p++;
                                        return;
                                }
@@ -1964,7 +1992,7 @@ CompilerConstant_t *QCC_PR_DefineName(char *name)
 //     if (numCompilerConstants >= MAX_CONSTANTS)
 //             QCC_PR_ParseError("Too many compiler constants - %i >= %i", numCompilerConstants, MAX_CONSTANTS);
 
-       if (strlen(name) >= MAXCONSTANTLENGTH || !*name)
+       if (strlen(name) >= MAXCONSTANTNAMELENGTH || !*name)
                QCC_PR_ParseError(ERR_NAMETOOLONG, "Compiler constant name length is too long or short");
 
        cnst = pHash_Get(&compconstantstable, name);
@@ -2112,6 +2140,43 @@ void QCC_PR_ConditionCompilation(void)
        pr_file_p = s;
 }
 
+/* *buffer, *bufferlen and *buffermax should be NULL/0 at the start */
+static void QCC_PR_ExpandStrCat(char **buffer, int *bufferlen, int *buffermax,   char *newdata, int newlen)
+{
+       int newmax = *bufferlen + newlen;
+       if (newmax < *bufferlen)
+       {
+               QCC_PR_ParseWarning(ERR_INTERNAL, "out of memory");
+               return;
+       }
+       if (newmax > *buffermax)
+       {
+               char *newbuf;
+               if (newmax < 64)
+                       newmax = 64;
+               if (newmax < *bufferlen * 2)
+               {
+                       newmax = *bufferlen * 2;
+                       if (newmax < *bufferlen) /*overflowed?*/
+                       {
+                               QCC_PR_ParseWarning(ERR_INTERNAL, "out of memory");
+                               return;
+                       }
+               }
+               newbuf = realloc(*buffer, newmax);
+               if (!newbuf)
+               {
+                       QCC_PR_ParseWarning(ERR_INTERNAL, "out of memory");
+                       return; /*OOM*/
+               }
+               *buffer = newbuf;
+               *buffermax = newmax;
+       }
+       memcpy(*buffer + *bufferlen, newdata, newlen);
+       *bufferlen += newlen;
+       /*no null terminator, remember to cat one if required*/
+}
+
 int QCC_PR_CheakCompConst(void)
 {
        char            *oldpr_file_p = pr_file_p;
@@ -2165,7 +2230,10 @@ int QCC_PR_CheakCompConst(void)
                        {
                                int p;
                                char *start;
-                               char buffer[1024];
+                               char *starttok;
+                               char *buffer;
+                               int buffermax;
+                               int bufferlen;
                                char *paramoffset[MAXCONSTANTPARAMS+1];
                                int param=0;
                                int plevel=0;
@@ -2220,38 +2288,45 @@ int QCC_PR_CheakCompConst(void)
                                        QCC_PR_ParseError(ERR_TOOFEWPARAMS, "Not enough macro parameters");
                                paramoffset[param] = start;
 
-                               *buffer = '\0';
+                               buffer = NULL;
+                               bufferlen = 0;
+                               buffermax = 0;
 
                                oldpr_file_p = pr_file_p;
                                pr_file_p = c->value;
                                for(;;)
                                {
-                                       whitestart = p = strlen(buffer);
+                                       whitestart = bufferlen;
+                                       starttok = pr_file_p;
                                        while(*pr_file_p <= ' ')        //copy across whitespace
                                        {
                                                if (!*pr_file_p)
                                                        break;
-                                               buffer[p++] = *pr_file_p++;
+                                               pr_file_p++;
+                                       }
+                                       if (starttok != pr_file_p)
+                                       {
+                                               QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax,   starttok, pr_file_p - starttok);
                                        }
-                                       buffer[p] = 0;
 
                                        if(*pr_file_p == '\"')
                                        {
+                                               starttok = pr_file_p;
                                                do
                                                {
-                                                       buffer[p++] = *pr_file_p;
-                                                       ++pr_file_p;
+                                                       pr_file_p++;
                                                } while( (pr_file_p[-1] == '\\' || pr_file_p[0] != '\"') && *pr_file_p && *pr_file_p != '\n' );
-                                               buffer[p++] = *pr_file_p; // copy the end-quote too
-                                               buffer[p] = 0;
-                                               ++pr_file_p; // and skip it
+                                               if(*pr_file_p == '\"')
+                                                       pr_file_p++;
+
+                                               QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax,   starttok, pr_file_p - starttok);
                                                continue;
                                        }
                                        else if (*pr_file_p == '#')     //if you ask for #a##b you will be shot. use #a #b instead, or chain macros.
                                        {
                                                if (pr_file_p[1] == '#')
-                                               {       //concatinate (srip out whitespace)
-                                                       buffer[whitestart] = '\0';
+                                               {       //concatinate (strip out whitespace before the token)
+                                                       bufferlen = whitestart;
                                                        pr_file_p+=2;
                                                }
                                                else
@@ -2265,16 +2340,16 @@ int QCC_PR_CheakCompConst(void)
                                                        {
                                                                if (!STRCMP(qcc_token, c->params[p]))
                                                                {
-                                                                       strcat(buffer, "\"");
-                                                                       strcat(buffer, paramoffset[p]);
-                                                                       strcat(buffer, "\"");
+                                                                       QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax,   "\"", 1);
+                                                                       QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax,   paramoffset[p], strlen(paramoffset[p]));
+                                                                       QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax,   "\"", 1);
                                                                        break;
                                                                }
                                                        }
                                                        if (p == param)
                                                        {
-                                                               strcat(buffer, "#");
-                                                               strcat(buffer, qcc_token);
+                                                               QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax,   "#", 1);
+                                                               QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax,   qcc_token, strlen(qcc_token));
                                                                //QCC_PR_ParseWarning(0, "Stringification ignored");
                                                        }
                                                        continue;       //already did this one
@@ -2289,12 +2364,12 @@ int QCC_PR_CheakCompConst(void)
                                        {
                                                if (!STRCMP(qcc_token, c->params[p]))
                                                {
-                                                       strcat(buffer, paramoffset[p]);
+                                                       QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax,   paramoffset[p], strlen(paramoffset[p]));
                                                        break;
                                                }
                                        }
                                        if (p == param)
-                                               strcat(buffer, qcc_token);
+                                               QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax,   qcc_token, strlen(qcc_token));
                                }
 
                                for (p = 0; p < param-1; p++)
@@ -2302,12 +2377,17 @@ int QCC_PR_CheakCompConst(void)
                                paramoffset[p][strlen(paramoffset[p])] = ')';
 
                                pr_file_p = oldpr_file_p;
-                               if (!*buffer)
+                               if (!bufferlen)
                                        expandedemptymacro = true;
-                               QCC_PR_IncludeChunkEx(buffer, true, NULL, c);
+                               else
+                               {
+                                       QCC_PR_ExpandStrCat(&buffer, &bufferlen, &buffermax,   "\0", 1);
+                                       QCC_PR_IncludeChunkEx(buffer, true, NULL, c);
+                               }
+                               free(buffer);
                        }
                        else
-                               QCC_PR_ParseError(ERR_TOOFEWPARAMS, "Macro without opening brace");
+                               QCC_PR_ParseError(ERR_TOOFEWPARAMS, "Macro without argument list");
                }
                else
                {
@@ -2495,7 +2575,7 @@ void QCC_PR_Lex (void)
                QCC_PR_LexNumber();
                return;
        }
-       if ( (c == '.'&&pr_file_p[1] >='0' && pr_file_p[1] <= '9') || (c >= '0' && c <= '9') || ( c=='-' && pr_file_p[1]>='0' && pr_file_p[1] <='9') )
+       if ( (c == '.'&&pr_file_p[1]!='.'&&pr_file_p[1] >='0' && pr_file_p[1] <= '9') || (c >= '0' && c <= '9') || ( c=='-' && pr_file_p[1]>='0' && pr_file_p[1] <='9') )
        {
                pr_token_type = tt_immediate;
                QCC_PR_LexNumber ();
@@ -2688,13 +2768,13 @@ void VARGS QCC_PR_Note (int type, char *file, int line, char *error, ...)
                printf ("note: %s\n", string);
 }
 
-void VARGS QCC_PR_Warning (int type, char *file, int line, char *error, ...)
+pbool VARGS QCC_PR_Warning (int type, char *file, int line, char *error, ...)
 {
        va_list         argptr;
        char            string[1024];
 
        if (qccwarningdisabled[type])
-               return;
+               return false;
 
        va_start (argptr,error);
        QC_vsnprintf (string,sizeof(string)-1, error,argptr);
@@ -2711,6 +2791,8 @@ void VARGS QCC_PR_Warning (int type, char *file, int line, char *error, ...)
        else
                printf ("warning: %s\n", string);
        pr_warning_count++;
+
+       return true;
 }
 
 
@@ -2816,7 +2898,12 @@ char *QCC_PR_ParseName (void)
        char *ret;
 
        if (pr_token_type != tt_name)
-               QCC_PR_ParseError (ERR_NOTANAME, "\"%s\" - not a name", pr_token);
+       {
+               if (pr_token_type == tt_eof)
+                       QCC_PR_ParseError (ERR_EOF, "unexpected EOF", pr_token);
+               else
+                       QCC_PR_ParseError (ERR_NOTANAME, "\"%s\" - not a name", pr_token);
+       }
        if (strlen(pr_token) >= MAX_NAME-1)
                QCC_PR_ParseError (ERR_NAMETOOLONG, "name too long");
        strcpy (ident, pr_token);
@@ -2838,7 +2925,6 @@ a new one and copies it out.
 */
 
 //0 if same
-QCC_type_t *QCC_PR_NewType (char *name, int basictype);
 int typecmp(QCC_type_t *a, QCC_type_t *b)
 {
        if (a == b)
@@ -2849,7 +2935,9 @@ int typecmp(QCC_type_t *a, QCC_type_t *b)
        if (a->type != b->type)
                return 1;
        if (a->num_parms != b->num_parms)
+       {
                return 1;
+       }
 
        if (a->size != b->size)
                return 1;
@@ -2883,7 +2971,7 @@ QCC_type_t *QCC_PR_DuplicateType(QCC_type_t *in)
        if (!in)
                return NULL;
 
-       out = QCC_PR_NewType(in->name, in->type);
+       out = QCC_PR_NewType(in->name, in->type, false);
        out->aux_type = QCC_PR_DuplicateType(in->aux_type);
        out->param = QCC_PR_DuplicateType(in->param);
        ip = in->param;
@@ -2896,6 +2984,7 @@ QCC_type_t *QCC_PR_DuplicateType(QCC_type_t *in)
                        op = (op->next = QCC_PR_DuplicateType(ip));
                ip = ip->next;
        }
+       out->arraysize = in->arraysize;
        out->size = in->size;
        out->num_parms = in->num_parms;
        out->ofs = in->ofs;
@@ -2923,17 +3012,29 @@ char *TypeName(QCC_type_t *type)
 
        if (type->type == ev_function)
        {
+               pbool varg = type->num_parms < 0;
+               int args = type->num_parms;
+               if (args < 0)
+                       args = -(args+1);
                strcat(ret, type->aux_type->name);
                strcat(ret, " (");
                type = type->param;
                while(type)
                {
+                       if (args<=0)
+                               strcat(ret, "optional ");
+                       args--;
+
                        strcat(ret, type->name);
                        type = type->next;
 
-                       if (type)
+                       if (type || varg)
                                strcat(ret, ", ");
                }
+               if (varg)
+               {
+                       strcat(ret, "...");
+               }
                strcat(ret, ")");
        }
        else if (type->type == ev_entity && type->parentclass)
@@ -3060,17 +3161,18 @@ char    pr_parm_names[MAX_PARMS][MAX_NAME];
 
 pbool recursivefunctiontype;
 
-QCC_type_t *QCC_PR_NewType (char *name, int basictype);
 //expects a ( to have already been parsed.
 QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype)
 {
        QCC_type_t      *ftype, *ptype, *nptype;
        char    *name;
        int definenames = !recursivefunctiontype;
+       int optional = 0;
+       int numparms = 0;
 
        recursivefunctiontype++;
 
-       ftype = QCC_PR_NewType(type_function->name, ev_function);
+       ftype = QCC_PR_NewType(type_function->name, ev_function, false);
 
        ftype->aux_type = returntype;   // return type
        ftype->num_parms = 0;
@@ -3089,11 +3191,21 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype)
 
                                if (QCC_PR_CheckToken ("..."))
                                {
-                                       ftype->num_parms = (ftype->num_parms * -1) - 1;
+                                       if (optional)
+                                               numparms = optional-1;
+                                       ftype->num_parms = (numparms * -1) - 1;
                                        break;
                                }
 
-                               nptype = QCC_PR_ParseType(true);
+                               if (QCC_PR_CheckKeyword(keyword_optional, "optional"))
+                               {
+                                       if (!optional)
+                                               optional = numparms+1;
+                               }
+                               else if (optional)
+                                       QCC_PR_ParseWarning(WARN_MISSINGOPTIONAL, "optional not specified on all optional args\n");
+
+                               nptype = QCC_PR_ParseType(true, false);
 
                                if (nptype->type == ev_void)
                                        break;
@@ -3114,11 +3226,15 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype)
                                {
                                        name = QCC_PR_ParseName ();
                                        if (definenames)
-                                               strcpy (pr_parm_names[ftype->num_parms], name);
+                                               strcpy (pr_parm_names[numparms], name);
                                }
                                else if (definenames)
-                                       strcpy (pr_parm_names[ftype->num_parms], "");
-                               ftype->num_parms++;
+                                       strcpy (pr_parm_names[numparms], "");
+                               numparms++;
+                               if (optional)
+                                       ftype->num_parms = optional-1;
+                               else
+                                       ftype->num_parms = numparms;
                        } while (QCC_PR_CheckToken (","));
 
                QCC_PR_Expect (")");
@@ -3137,7 +3253,7 @@ QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype)
 
        recursivefunctiontype++;
 
-       ftype = QCC_PR_NewType(type_function->name, ev_function);
+       ftype = QCC_PR_NewType(type_function->name, ev_function, false);
 
        ftype->aux_type = returntype;   // return type
        ftype->num_parms = 0;
@@ -3164,19 +3280,19 @@ QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype)
                                {
                                        sprintf(argname, "arg%i", ftype->num_parms);
                                        name = argname;
-                                       nptype = QCC_PR_NewType("Variant", ev_variant);
+                                       nptype = QCC_PR_NewType("Variant", ev_variant, false);
                                }
                                else if (QCC_PR_CheckName("vect"))      //this can only be of vector sizes, so...
                                {
                                        sprintf(argname, "arg%i", ftype->num_parms);
                                        name = argname;
-                                       nptype = QCC_PR_NewType("Vector", ev_vector);
+                                       nptype = QCC_PR_NewType("Vector", ev_vector, false);
                                }
                                else
                                {
                                        name = QCC_PR_ParseName();
                                        QCC_PR_Expect(":");
-                                       nptype = QCC_PR_ParseType(true);
+                                       nptype = QCC_PR_ParseType(true, false);
                                }
 
                                if (nptype->type == ev_void)
@@ -3207,26 +3323,34 @@ QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype)
 }
 QCC_type_t *QCC_PR_PointerType (QCC_type_t *pointsto)
 {
-       QCC_type_t      *ptype;
-       char name[128];
-       sprintf(name, "*%s", pointsto->name);
-       ptype = QCC_PR_NewType(name, ev_pointer);
+       QCC_type_t      *ptype, *e;
+       ptype = QCC_PR_NewType("ptr", ev_pointer, false);
        ptype->aux_type = pointsto;
-       return QCC_PR_FindType (ptype);
+       e = QCC_PR_FindType (ptype);
+       if (e == ptype)
+       {
+               char name[128];
+               sprintf(name, "ptr to %s", pointsto->name);
+               e->name = strdup(name);
+       }
+       return e;
 }
 QCC_type_t *QCC_PR_FieldType (QCC_type_t *pointsto)
 {
        QCC_type_t      *ptype;
        char name[128];
        sprintf(name, "FIELD TYPE(%s)", pointsto->name);
-       ptype = QCC_PR_NewType(name, ev_field);
+       ptype = QCC_PR_NewType(name, ev_field, false);
        ptype->aux_type = pointsto;
        ptype->size = ptype->aux_type->size;
        return QCC_PR_FindType (ptype);
 }
 
 pbool type_inlinefunction;
-QCC_type_t *QCC_PR_ParseType (int newtype)
+/*newtype=true: creates a new type always
+  silentfail=true: function is permitted to return NULL if it was not given a type, otherwise never returns NULL
+*/
+QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
 {
        QCC_type_t      *newparm;
        QCC_type_t      *newt;
@@ -3240,14 +3364,14 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
 
        if (QCC_PR_CheckToken (".."))   //so we don't end up with the user specifying '. .vector blah' (hexen2 added the .. token for array ranges)
        {
-               newt = QCC_PR_NewType("FIELD TYPE", ev_field);
-               newt->aux_type = QCC_PR_ParseType (false);
+               newt = QCC_PR_NewType("FIELD TYPE", ev_field, false);
+               newt->aux_type = QCC_PR_ParseType (false, false);
 
                newt->size = newt->aux_type->size;
 
                newt = QCC_PR_FindType (newt);
 
-               type = QCC_PR_NewType("FIELD TYPE", ev_field);
+               type = QCC_PR_NewType("FIELD TYPE", ev_field, false);
                type->aux_type = newt;
 
                type->size = type->aux_type->size;
@@ -3258,8 +3382,8 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
        }
        if (QCC_PR_CheckToken ("."))
        {
-               newt = QCC_PR_NewType("FIELD TYPE", ev_field);
-               newt->aux_type = QCC_PR_ParseType (false);
+               newt = QCC_PR_NewType("FIELD TYPE", ev_field, false);
+               newt->aux_type = QCC_PR_ParseType (false, false);
 
                newt->size = newt->aux_type->size;
 
@@ -3286,6 +3410,8 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
                /* Look to see if this type is already defined */
                for(i=0;i<numtypeinfos;i++)
                {
+                       if (!qcc_typeinfo[i].typedefed)
+                               continue;
                        if (STRCMP(qcc_typeinfo[i].name, classname) == 0)
                        {
                                newt = &qcc_typeinfo[i];
@@ -3300,7 +3426,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
                        QCC_PR_ParseError(ERR_REDECLARATION, "Redeclaration of class %s", classname);
 
                if (!newt)
-                       newt = QCC_PR_NewType(classname, ev_entity);
+                       newt = QCC_PR_NewType(classname, ev_entity, true);
 
                newt->size=type_entity->size;
 
@@ -3333,7 +3459,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
 //                     if (QCC_PR_CheckToken(","))
 //                             type->next = QCC_PR_NewType(type->name, type->type);
 //                     else
-                               newparm = QCC_PR_ParseType(true);
+                               newparm = QCC_PR_ParseType(true, false);
 
                        if (newparm->type == ev_struct || newparm->type == ev_union)    //we wouldn't be able to handle it.
                                QCC_PR_ParseError(ERR_INTERNAL, "Struct or union in class %s", classname);
@@ -3354,10 +3480,10 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
                                newparm->name = QCC_CopyString("")+strings;
 
                        sprintf(membername, "%s::"MEMBERFIELDNAME, classname, newparm->name);
-                       fieldtype = QCC_PR_NewType(newparm->name, ev_field);
+                       fieldtype = QCC_PR_NewType(newparm->name, ev_field, false);
                        fieldtype->aux_type = newparm;
                        fieldtype->size = newparm->size;
-                       QCC_PR_GetDef(fieldtype, membername, pr_scope, 2, 1, false);
+                       QCC_PR_GetDef(fieldtype, membername, pr_scope, 2, 0, false);
 
 
                        newparm->ofs = 0;//newt->size;
@@ -3377,7 +3503,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
        }
        if (QCC_PR_CheckKeyword (keyword_struct, "struct"))
        {
-               newt = QCC_PR_NewType("struct", ev_struct);
+               newt = QCC_PR_NewType("struct", ev_struct, false);
                newt->size=0;
                QCC_PR_Expect("{");
 
@@ -3392,10 +3518,10 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
                        {
                                if (!newparm)
                                        QCC_PR_ParseError(ERR_NOTANAME, "element missing type");
-                               newparm = QCC_PR_NewType(newparm->name, newparm->type);
+                               newparm = QCC_PR_NewType(newparm->name, newparm->type, false);
                        }
                        else
-                               newparm = QCC_PR_ParseType(true);
+                               newparm = QCC_PR_ParseType(true, false);
 
                        if (!QCC_PR_CheckToken(";"))
                        {
@@ -3403,8 +3529,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
                                QCC_PR_Lex();
                                if (QCC_PR_CheckToken("["))
                                {
-                                       newparm->size*=atoi(pr_token);
-                                       QCC_PR_Lex();
+                                       newparm->arraysize=QCC_PR_IntConstExpr();
                                        QCC_PR_Expect("]");
                                }
                                QCC_PR_CheckToken(";");
@@ -3412,7 +3537,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
                        else
                                newparm->name = QCC_CopyString("")+strings;
                        newparm->ofs = newt->size;
-                       newt->size += newparm->size;
+                       newt->size += newparm->size*(newparm->arraysize?newparm->arraysize:1);
                        newt->num_parms++;
 
                        if (type)
@@ -3425,7 +3550,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
        }
        if (QCC_PR_CheckKeyword (keyword_union, "union"))
        {
-               newt = QCC_PR_NewType("union", ev_union);
+               newt = QCC_PR_NewType("union", ev_union, false);
                newt->size=0;
                QCC_PR_Expect("{");
 
@@ -3435,25 +3560,34 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
                newparm = NULL;
                while (!QCC_PR_CheckToken("}"))
                {
+                       int arraysize;
                        if (QCC_PR_CheckToken(","))
                        {
                                if (!newparm)
                                        QCC_PR_ParseError(ERR_NOTANAME, "element missing type");
-                               newparm = QCC_PR_NewType(newparm->name, newparm->type);
+                               newparm = QCC_PR_NewType(newparm->name, newparm->type, false);
                        }
                        else
-                               newparm = QCC_PR_ParseType(true);
+                               newparm = QCC_PR_ParseType(true, false);
                        if (QCC_PR_CheckToken(";"))
                                newparm->name = QCC_CopyString("")+strings;
                        else
                        {
                                newparm->name = QCC_CopyString(pr_token)+strings;
                                QCC_PR_Lex();
+                               if (QCC_PR_CheckToken("["))
+                               {
+                                       newparm->arraysize=QCC_PR_IntConstExpr();
+                                       QCC_PR_Expect("]");
+                               }
                                QCC_PR_Expect(";");
                        }
                        newparm->ofs = 0;
-                       if (newparm->size > newt->size)
-                               newt->size = newparm->size;
+                       arraysize = newparm->arraysize;
+                       if (!arraysize)
+                               arraysize = 1;
+                       if (newparm->size*arraysize > newt->size)
+                               newt->size = newparm->size*arraysize;
                        newt->num_parms++;
 
                        if (type)
@@ -3467,6 +3601,8 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
        type = NULL;
        for (i = 0; i < numtypeinfos; i++)
        {
+               if (!qcc_typeinfo[i].typedefed)
+                       continue;
                if (!STRCMP(qcc_typeinfo[i].name, name))
                {
                        type = &qcc_typeinfo[i];
@@ -3492,16 +3628,22 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
                        type = type_function;
                else
                {
+                       if (silentfail)
+                               return NULL;
+
                        QCC_PR_ParseError (ERR_NOTATYPE, "\"%s\" is not a type", name);
                        type = type_float;      // shut up compiler warning
                }
        }
        QCC_PR_Lex ();
 
+       while (QCC_PR_CheckToken("*"))
+               type = QCC_PointerTypeTo(type);
+
        if (QCC_PR_CheckToken ("("))    //this is followed by parameters. Must be a function.
        {
                type_inlinefunction = true;
-               return QCC_PR_ParseFunctionType(newtype, type);
+               type = QCC_PR_ParseFunctionType(newtype, type);
        }
        else
        {
@@ -3509,9 +3651,8 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
                {
                        type = QCC_PR_DuplicateType(type);
                }
-
-               return type;
        }
+       return type;
 }
 
 #endif
index e6fb7bd029c9346d8a4d36a14fa348df91a27482..9bcd907770f4601c6286670807849e71cb4a87b8 100644 (file)
@@ -4,19 +4,18 @@
 #include <commdlg.h>
 #include <richedit.h>
 #include <stdio.h>
+#include <sys/stat.h>
 
 #include "qcc.h"
 #include "gui.h"
 
 
-
-
 /*
 ==============
 LoadFile
 ==============
 */
-unsigned char *QCC_ReadFile (char *fname, void *buffer, int len)
+unsigned char *QCC_ReadFile (const char *fname, void *buffer, int len)
 {
        long    length;
        FILE *f;
@@ -31,7 +30,7 @@ unsigned char *QCC_ReadFile (char *fname, void *buffer, int len)
 
        return buffer;
 }
-int QCC_FileSize (char *fname)
+int QCC_FileSize (const char *fname)
 {
        long    length;
        FILE *f;
@@ -45,7 +44,7 @@ int QCC_FileSize (char *fname)
        return length;
 }
 
-pbool QCC_WriteFile (char *name, void *data, int len)
+pbool QCC_WriteFile (const char *name, void *data, int len)
 {
        long    length;
        FILE *f;
@@ -281,11 +280,14 @@ typedef struct editor_s {
        char filename[MAX_PATH];        //abs
        HWND window;
        HWND editpane;
+       pbool modified;
+       time_t filemodifiedtime;
        struct editor_s *next;
 } editor_t;
 
 editor_t *editors;
 
+void EditorReload(editor_t *editor);
 int EditorSave(editor_t *edit);
 void EditFile(char *name, int line);
 pbool EditorModified(editor_t *e);
@@ -318,7 +320,7 @@ void GenericMenu(WPARAM wParam)
                break;
 
        case IDM_ABOUT:
-               MessageBox(NULL, "FTE QuakeC Compiler\nWritten by Forethough Entertainment.\nBasically that means it was written by Spike.\n\nIt has a few cool features, like a useful IDE.\n\nSupports:\nPrecompiler (with macros)\nArrays\n+= / -= / *= / /= operations.\nSwitch statements\nfor loops\nLots of optimisations.", "About", 0);
+               MessageBox(NULL, "FTE QuakeC Compiler\nWritten by Forethough Entertainment.\n\nIt has a few cool features, like a semi-useful IDE.\n\nSupports:\nPrecompiler (with macros)\nArrays\n+= / -= / *= / /= operations.\nSwitch statements\nfor loops\nLots of optimisations.", "About", 0);
                break;
 
        case IDM_CASCADE:
@@ -409,7 +411,7 @@ static LONG CALLBACK EditorWndProc(HWND hWnd,UINT message,
        {
        case WM_CLOSE:
        case WM_QUIT:
-               if (EditorModified(editor))
+               if (editor->modified)
                {
                        switch (MessageBox(hWnd, "Would you like to save?", editor->filename, MB_YESNOCANCEL))
                        {
@@ -478,22 +480,49 @@ static LONG CALLBACK EditorWndProc(HWND hWnd,UINT message,
                return TRUE;
                break;
        case WM_COMMAND:
-               if (mdibox)
-                       goto gdefault;
-               EditorMenu(editor, wParam);
+               if (HIWORD(wParam) == EN_CHANGE && (HWND)lParam == editor->editpane)
+               {
+                       if (!editor->modified)
+                       {
+                               char title[2048];
+                               CHARRANGE chrg;
+
+                               editor->modified = true;
+                               if (EditorModified(editor))
+                                       if (MessageBox(NULL, "warning: file was modified externally. reload?", "Modified!", MB_YESNO) == IDYES)
+                                               EditorReload(editor);
+
+
+                               SendMessage(editor->editpane, EM_EXGETSEL, 0, (LPARAM) &chrg);
+                               if (editor->modified)
+                                       sprintf(title, "*%s:%i - FTEQCC Editor", editor->filename, 1+Edit_LineFromChar(editor->editpane, chrg.cpMin));
+                               else
+                                       sprintf(title, "%s:%i - FTEQCC Editor", editor->filename, 1+Edit_LineFromChar(editor->editpane, chrg.cpMin));
+                               SetWindowText(editor->window, title);
+                       }
+               }
+               else
+               {
+                       if (mdibox)
+                               goto gdefault;
+                       EditorMenu(editor, wParam);
+               }
                break;
        case WM_NOTIFY:
                {
                    NMHDR *nmhdr;
                        SELCHANGE *sel;
-                       char message[2048];
+                       char title[2048];
                        nmhdr = (NMHDR *)lParam;
                        switch(nmhdr->code)
                        {
                        case EN_SELCHANGE:
                                sel = (SELCHANGE *)nmhdr;
-                               sprintf(message, "%s:%i - FTEQCC Editor", editor->filename, 1+Edit_LineFromChar(editor->editpane, sel->chrg.cpMin));
-                               SetWindowText(editor->window, message);
+                               if (editor->modified)
+                                       sprintf(title, "*%s:%i - FTEQCC Editor", editor->filename, 1+Edit_LineFromChar(editor->editpane, sel->chrg.cpMin));
+                               else
+                                       sprintf(title, "%s:%i - FTEQCC Editor", editor->filename, 1+Edit_LineFromChar(editor->editpane, sel->chrg.cpMin));
+                               SetWindowText(editor->window, title);
                                break;
                        }
                }
@@ -758,7 +787,7 @@ int Rehighlight(editor_t *edit)
        InvalidateRect(edit->editpane, NULL, true);
        InvalidateRect(edit->window, NULL, true);
 
-       SendMessage(edit->editpane, EM_SETEVENTMASK, 0, ENM_SELCHANGE);
+       SendMessage(edit->editpane, EM_SETEVENTMASK, 0, ENM_SELCHANGE|ENM_CHANGE);
 
        SendMessage(edit->editpane, EM_SETSCROLLPOS, 0, (LPARAM)&scrollpos);
        SendMessage(edit->editpane, EM_EXSETSEL, 0, (LPARAM) &chrg);
@@ -845,11 +874,46 @@ int Rehighlight(editor_t *edit)
 }
 #endif
 
-void EditFile(char *name, int line)
+void EditorReload(editor_t *editor)
 {
-       char title[1024];
+       struct stat sbuf;
        int flen;
        char *file;
+
+       flen = QCC_FileSize(editor->filename);
+       if (flen >= 0)
+       {
+               file = malloc(flen+1);
+               QCC_ReadFile(editor->filename, file, flen);
+               file[flen] = 0;
+       }
+
+       SendMessage(editor->editpane, EM_SETEVENTMASK, 0, 0);
+
+       /*clear it out*/
+       Edit_SetSel(editor->editpane,0,Edit_GetTextLength(editor->editpane));
+       Edit_ReplaceSel(editor->editpane,"");
+
+       if (!fl_autohighlight)
+       {
+               GUIPrint(editor->editpane, file);
+       }
+       else
+       {
+               GUIFormattingPrint(editor->editpane, file);
+       }
+       free(file);
+
+       editor->modified = false;
+       stat(editor->filename, &sbuf);
+       editor->filemodifiedtime = sbuf.st_mtime;
+
+       SendMessage(editor->editpane, EM_SETEVENTMASK, 0, ENM_SELCHANGE|ENM_CHANGE);
+}
+
+void EditFile(char *name, int line)
+{
+       char title[1024];
        editor_t *neweditor;
        WNDCLASS wndclass;
        HMENU menu, menufile, menuhelp, menunavig;
@@ -871,8 +935,7 @@ void EditFile(char *name, int line)
                }
        }
 
-       flen = QCC_FileSize(name);
-       if (flen == -1)
+       if (QCC_FileSize(name) == -1)
        {
                MessageBox(NULL, "File not found.", "Error", 0);
                return;
@@ -896,9 +959,9 @@ void EditFile(char *name, int line)
                menufile = CreateMenu();
                menuhelp = CreateMenu();
                menunavig = CreateMenu();
-               AppendMenu(menu, MF_POPUP, (UINT)menufile,      "&File");
-               AppendMenu(menu, MF_POPUP, (UINT)menunavig,     "&Navigation");
-               AppendMenu(menu, MF_POPUP, (UINT)menuhelp,      "&Help");
+               AppendMenu(menu, MF_POPUP, (UINT_PTR)menufile,  "&File");
+               AppendMenu(menu, MF_POPUP, (UINT_PTR)menunavig, "&Navigation");
+               AppendMenu(menu, MF_POPUP, (UINT_PTR)menuhelp,  "&Help");
                AppendMenu(menufile, 0, IDM_OPENNEW,    "Open &new file ");
                AppendMenu(menufile, 0, IDM_SAVE,               "&Save          ");
        //      AppendMenu(menufile, 0, IDM_FIND,               "&Find");
@@ -940,7 +1003,7 @@ void EditFile(char *name, int line)
                mcs.lParam = 0;
 
                neweditor->window = (HWND) SendMessage (mdibox, WM_MDICREATE, 0, 
-                       (LONG) (LPMDICREATESTRUCT) &mcs); 
+                       (LONG_PTR) (LPMDICREATESTRUCT) &mcs); 
        }
        else
        {
@@ -959,23 +1022,7 @@ void EditFile(char *name, int line)
                return;
        }
 
-       flen = QCC_FileSize(name);
-       file = malloc(flen+1);
-       QCC_ReadFile(name, file, flen);
-       file[flen] = 0;
-
-       SendMessage(neweditor->editpane, EM_SETEVENTMASK, 0, 0);
-
-       if (!fl_autohighlight)
-       {
-               GUIPrint(neweditor->editpane, file);
-       }
-       else
-       {
-               GUIFormattingPrint(neweditor->editpane, file);
-       }
-
-       SendMessage(neweditor->editpane, EM_SETEVENTMASK, 0, ENM_SELCHANGE);
+       EditorReload(neweditor);
 
        if (line >= 0)
                Edit_SetSel(neweditor->editpane, Edit_LineIndex(neweditor->editpane, line), Edit_LineIndex(neweditor->editpane, line+1));
@@ -992,6 +1039,7 @@ void EditFile(char *name, int line)
 
 int EditorSave(editor_t *edit)
 {
+       struct stat sbuf;
        int len;
        char *file;
        len = Edit_GetTextLength(edit->editpane);
@@ -1009,6 +1057,11 @@ int EditorSave(editor_t *edit)
        }
        free(file);
 
+       /*now whatever is on disk should have the current time*/
+       edit->modified = false;
+       stat(edit->filename, &sbuf);
+       edit->filemodifiedtime = sbuf.st_mtime;
+
        return true;
 }
 void EditorsRun(void)
@@ -1016,7 +1069,7 @@ void EditorsRun(void)
 }
 
 
-char *GUIReadFile(char *fname, void *buffer, int blen)
+char *GUIReadFile(const char *fname, void *buffer, int blen)
 {
        editor_t *e;
        for (e = editors; e; e = e->next)
@@ -1032,7 +1085,7 @@ char *GUIReadFile(char *fname, void *buffer, int blen)
        return QCC_ReadFile(fname, buffer, blen);
 }
 
-int GUIFileSize(char *fname)
+int GUIFileSize(const char *fname)
 {
        editor_t *e;
        for (e = editors; e; e = e->next)
@@ -1046,26 +1099,14 @@ int GUIFileSize(char *fname)
        return QCC_FileSize(fname);
 }
 
+/*checks if the file has been modified externally*/
 pbool EditorModified(editor_t *e)
 {
-       char *buffer;
-       int elen, flen;
-       elen = Edit_GetTextLength(e->editpane);
-       flen = QCC_FileSize(e->filename);
-
-       if (elen != flen)
+       struct stat sbuf;
+       stat(e->filename, &sbuf);
+       if (e->filemodifiedtime != sbuf.st_mtime)
                return true;
 
-       buffer = malloc(elen+flen);
-       Edit_GetText(e->editpane, buffer, elen);
-       QCC_ReadFile(e->filename, buffer+elen, flen);
-       if (memcmp(buffer, buffer+elen, elen))
-       {
-               free(buffer);
-               return true;
-       }
-       free(buffer);
-
        return false;
 }
 
@@ -1559,20 +1600,20 @@ static LONG CALLBACK MainWndProc(HWND hWnd,UINT message,
                        HMENU rootmenu, windowmenu, m;
                        rootmenu = CreateMenu();
                        
-                               AppendMenu(rootmenu, MF_POPUP, (UINT)(m = CreateMenu()),        "&File");
+                               AppendMenu(rootmenu, MF_POPUP, (UINT_PTR)(m = CreateMenu()),    "&File");
                                        AppendMenu(m, 0, IDM_OPENNEW,   "Open &new file ");
                                        AppendMenu(m, 0, IDM_SAVE,              "&Save          ");
                                //      AppendMenu(m, 0, IDM_FIND,              "&Find");
                                        AppendMenu(m, 0, IDM_UNDO,              "&Undo          Ctrl+Z");
                                        AppendMenu(m, 0, IDM_REDO,              "&Redo          Ctrl+Y");
-                               AppendMenu(rootmenu, MF_POPUP, (UINT)(m = CreateMenu()),        "&Navigation");
+                               AppendMenu(rootmenu, MF_POPUP, (UINT_PTR)(m = CreateMenu()),    "&Navigation");
                                        AppendMenu(m, 0, IDM_GOTODEF, "Go to definition");
                                        AppendMenu(m, 0, IDM_OPENDOCU, "Open selected file");
-                               AppendMenu(rootmenu, MF_POPUP, (UINT)(m = windowmenu = CreateMenu()),   "&Window");
+                               AppendMenu(rootmenu, MF_POPUP, (UINT_PTR)(m = windowmenu = CreateMenu()),       "&Window");
                                        AppendMenu(m, 0, IDM_CASCADE, "&Cascade");
                                        AppendMenu(m, 0, IDM_TILE_HORIZ, "Tile &Horizontally");
                                        AppendMenu(m, 0, IDM_TILE_VERT, "Tile &Vertically");
-                               AppendMenu(rootmenu, MF_POPUP, (UINT)(m = CreateMenu()),        "&Help");
+                               AppendMenu(rootmenu, MF_POPUP, (UINT_PTR)(m = CreateMenu()),    "&Help");
                                        AppendMenu(m, 0, IDM_ABOUT, "About");
 
                        SetMenu(hWnd, rootmenu);
@@ -1893,11 +1934,46 @@ int GUIprintf(const char *msg, ...)
 void Sys_Error(const char *text, ...);
 void RunCompiler(char *args)
 {
-       char *argv[64];
+       char *argv[128];
        int argc;
        progexterns_t ext;
        progfuncs_t funcs;
 
+       editor_t *editor;
+       for (editor = editors; editor; editor = editor->next)
+       {
+               if (editor->modified)
+               {
+                       if (EditorModified(editor))
+                       {
+                               char msg[1024];
+                               sprintf(msg, "%s is modified in both memory and on disk. Overwrite external modification? (saying no will reload from disk)", editor->filename);
+                               switch(MessageBox(NULL, msg, "Modification conflict", MB_YESNOCANCEL))
+                               {
+                               case IDYES:
+                                       EditorSave(editor);
+                                       break;
+                               case IDNO:
+                                       EditorReload(editor);
+                                       break;
+                               case IDCANCEL:
+                                       break; /*compiling will use whatever is in memory*/
+                               }
+                       }
+                       else
+                       {
+                               /*not modified on disk, but modified in memory? try and save it, cos we might as well*/
+                               EditorSave(editor);
+                       }
+               }
+               else
+               {
+                       /*modified on disk but not in memory? just reload it off disk*/
+                       if (EditorModified(editor))
+                               EditorReload(editor);
+               }
+       }
+
        memset(&funcs, 0, sizeof(funcs));
        funcs.parms = &ext;
        memset(&ext, 0, sizeof(ext));
@@ -1957,7 +2033,7 @@ void CreateOutputWindow(void)
                mcs.lParam = 0;
 
                outputwindow = (HWND) SendMessage (mdibox, WM_MDICREATE, 0, 
-               (LONG) (LPMDICREATESTRUCT) &mcs); 
+               (LONG_PTR) (LPMDICREATESTRUCT) &mcs); 
 
                ShowWindow(outputwindow, SW_SHOW);
        }
index cad17a6cb73e8db1788c6fb63b777afdd33a3dec..8c84930746c6b6e6d04c9d61383eea3eae072990 100644 (file)
@@ -27,8 +27,6 @@ void QCC_PR_LexWhitespace (void);
 void *FS_ReadToMem(char *fname, void *membuf, int *len);
 void FS_CloseFromMem(void *mem);
 
-struct qcc_includechunk_s *currentchunk;
-
 unsigned int MAX_REGS;
 
 int    MAX_STRINGS;
@@ -78,14 +76,17 @@ int                 numfielddefs;
 
 PATHSTRING             *precache_sounds;
 int                    *precache_sounds_block;
+int                    *precache_sounds_used;
 int                    numsounds;
 
 PATHSTRING             *precache_textures;
 int                    *precache_textures_block;
+int                    *precache_textures_block;
 int                    numtextures;
 
 PATHSTRING             *precache_models;
 int                    *precache_models_block;
+int                    *precache_models_used;
 int                    nummodels;
 
 PATHSTRING             *precache_files;
@@ -96,11 +97,13 @@ extern int numCompilerConstants;
 hashtable_t compconstantstable;
 hashtable_t globalstable;
 hashtable_t localstable;
+#ifdef WRITEASM
+FILE *asmfile;
+#endif
 hashtable_t floatconstdefstable;
 hashtable_t stringconstdefstable;
-hashtable_t stringconstdefstable_dotranslate;
-int dotranslate;
-int dotranslate_count;
+hashtable_t stringconstdefstable_trans;
+extern int dotranslate_count;
 
 pbool qccwarningdisabled[WARN_MAX];
 
@@ -184,7 +187,7 @@ optimisations_t optimisations[] =
        {&opt_return_only,                              "ro",   3,      FLAG_KILLSDEBUGGERS,                                    "return_only",          "Functions ending in a return statement do not need a done statement at the end of the function. This can confuse some decompilers, making functions appear larger than they were."},
        {&opt_compound_jumps,                   "cj",   3,      FLAG_KILLSDEBUGGERS,                                    "compound_jumps",       "This optimisation plays an effect mostly with nested if/else statements, instead of jumping to an unconditional jump statement, it'll jump to the final destination instead. This will bewilder decompilers."},
 //     {&opt_comexprremoval,                   "cer",  4,      0,                                              "expression_removal",   "Eliminate common sub-expressions"},    //this would be too hard...
-       {&opt_stripfunctions,                   "sf",   3,      0,                                              "strip_functions",      "Strips out the 'defs' of functions that were only ever called directly. This does not affect saved games."},
+       {&opt_stripfunctions,                   "sf",   4,      0,                                              "strip_functions",      "Strips out the 'defs' of functions that were only ever called directly. This does not affect saved games. This can affect FTE_MULTIPROGS."},
        {&opt_locals_marshalling,               "lm",   4,      FLAG_KILLSDEBUGGERS,            "locals_marshalling", "Store all locals in one section of the pr_globals. Vastly reducing it. This effectivly does the job of overlaptemps. It's been noticed as buggy by a few, however, and the curcumstances where it causes problems are not yet known."},
        {&opt_vectorcalls,                              "vc",   4,      FLAG_KILLSDEBUGGERS,                                    "vectorcalls",          "Where a function is called with just a vector, this causes the function call to store three floats instead of one vector. This can save a good number of pr_globals where those vectors contain many duplicate coordinates but do not match entirly."},
        {NULL}
@@ -215,6 +218,7 @@ compiler_flag_t compiler_flag[] = {
        {&keyword_nosave,               defaultkeyword, "nosave",               "Keyword: nosave",              "Disables the 'nosave' keyword."},      //don't write the def to the output.
        {&keyword_shared,               defaultkeyword, "shared",               "Keyword: shared",              "Disables the 'shared' keyword."},      //mark global to be copied over when progs changes (part of FTE_MULTIPROGS)
        {&keyword_state,                nondefaultkeyword,"state",              "Keyword: state",               "Disables the 'state' keyword."},
+       {&keyword_optional,             defaultkeyword,"optional",              "Keyword: optional",    "Disables the 'optional' keyword."},
        {&keyword_string,               defaultkeyword, "string",               "Keyword: string",              "Disables the 'string' keyword."},
        {&keyword_struct,               defaultkeyword, "struct",               "Keyword: struct",              "Disables the 'struct' keyword."},
        {&keyword_switch,               defaultkeyword, "switch",               "Keyword: switch",              "Disables the 'switch' keyword."},
@@ -241,7 +245,9 @@ compiler_flag_t compiler_flag[] = {
        {&flag_filetimes,               0,                              "filetimes",    "Check Filetimes",              "Recompiles the progs only if the file times are modified."},
        {&flag_fasttrackarrays, FLAG_MIDCOMPILE|FLAG_ASDEFAULT,"fastarrays","fast arrays where possible",       "Generates extra instructions inside array handling functions to detect engine and use extension opcodes only in supporting engines.\nAdds a global which is set by the engine if the engine supports the extra opcodes. Note that this applies to all arrays or none."},
        {&flag_assume_integer,  FLAG_MIDCOMPILE,"assumeint",    "Assume Integers",              "Numerical constants are assumed to be integers, instead of floats."},
-       {&pr_subscopedlocals,           FLAG_MIDCOMPILE,                "subscope",     "Subscoped Locals",             "Restrict the scope of locals to the block they are actually defined within, as in C."},
+       {&pr_subscopedlocals,   FLAG_MIDCOMPILE,"subscope",             "Subscoped Locals",             "Restrict the scope of locals to the block they are actually defined within, as in C."},
+       {&verbose,                              FLAG_MIDCOMPILE,"verbose",              "Verbose",                              "Lots of extra compiler messages."},
+       {&flag_typeexplicit,    FLAG_MIDCOMPILE,"typeexplicit", "Explicit types",               "All type conversions must be explicit or directly supported by instruction set."},
        {NULL}
 };
 
@@ -313,11 +319,13 @@ int       QCC_CopyString (char *str)
        int             old;
        char *s;
 
+       if (!str)
+               return 0;
+       if (!*str)
+               return 1;
+
        if (opt_noduplicatestrings)
        {
-               if (!str || !*str)
-                       return 0;
-
                for (s = strings; s < strings+strofs; s++)
                        if (!strcmp(s, str))
                        {
@@ -482,7 +490,7 @@ void QCC_InitData (void)
        qcc_sourcefile = NULL;
 
        numstatements = 1;
-       strofs = 1;
+       strofs = 2;
        numfunctions = 1;
        numglobaldefs = 1;
        numfielddefs = 1;
@@ -516,7 +524,7 @@ int WriteBodylessFuncs (int handle)
        {
                if (d->type->type == ev_function && !d->scope)// function parms are ok
                {
-                       if (d->initialized != 1 && d->references>0)
+                       if (!(d->initialized & 1) && d->references>0)
                        {
                                SafeWrite(handle, d->name, strlen(d->name)+1);
                                ret++;
@@ -648,8 +656,8 @@ pbool QCC_WriteData (int crc)
                if (compressoutput)             progs.blockscompressed |=64;    //line numbers
                if (compressoutput)             progs.blockscompressed |=128;   //types
                //include a type block?
-               types = debugtarget;//!!QCC_PR_CheckCompConstDefined("TYPES");  //useful for debugging and saving (maybe, anyway...).
-               if (sizeof(char *) != sizeof(string_t))
+               types = debugtarget;
+               if (types && sizeof(char *) != sizeof(string_t))
                {
                        //qcc_typeinfo_t has a char* inside it, which changes size
                        printf("AMD64 builds cannot write typeinfo structures\n");
@@ -692,6 +700,18 @@ pbool QCC_WriteData (int crc)
 
        for (def = pr.def_head.next ; def ; def = def->next)
        {
+               if ((def->type->type == ev_struct || def->type->type == ev_union || def->arraysize) && def->deftail)
+               {
+                       QCC_def_t               *d;
+                       d = def;
+                       while (d != def->deftail)
+                       {
+                               d = d->next;
+                               h = d->references;
+                               d->references += def->references;
+                               def->references += h;
+                       }
+               }
                if (def->type->type == ev_vector || (def->type->type == ev_field && def->type->aux_type->type == ev_vector))
                {       //do the references, so we don't get loadsa not referenced VEC_HULL_MINS_x
                        sprintf(element, "%s_x", def->name);
@@ -727,14 +747,14 @@ pbool QCC_WriteData (int crc)
                }
                if (def->references<=0)
                {
-                       if (def->constant)
-                               QCC_PR_Warning(WARN_NOTREFERENCEDCONST, strings + def->s_file, def->s_line, "%s  no references", def->name);
-                       else
-                               QCC_PR_Warning(WARN_NOTREFERENCED, strings + def->s_file, def->s_line, "%s  no references", def->name);
-                       if (!warnedunref)
+                       int wt = def->constant?WARN_NOTREFERENCEDCONST:WARN_NOTREFERENCED;
+                       if (QCC_PR_Warning(wt, strings + def->s_file, def->s_line, "%s  no references", def->name))
                        {
-                               QCC_PR_Note(WARN_NOTREFERENCED, NULL, 0, "You can use the noref prefix or pragma to silence this message.");
-                               warnedunref = true;
+                               if (!warnedunref)
+                               {
+                                       QCC_PR_Note(WARN_NOTREFERENCED, NULL, 0, "You can use the noref prefix or pragma to silence this message.");
+                                       warnedunref = true;
+                               }
                        }
 
                        if (opt_unreferenced && def->type->type != ev_field)
@@ -770,13 +790,15 @@ pbool QCC_WriteData (int crc)
                }
                else if (def->type->type == ev_field && def->constant)
                {
+                       if (numfielddefs >= MAX_FIELDS)
+                               QCC_PR_ParseError(0, "Too many fields. Limit is %u\n", MAX_FIELDS);
                        dd = &fields[numfielddefs];
                        numfielddefs++;
                        dd->type = def->type->aux_type->type;
                        dd->s_name = QCC_CopyString (def->name);
                        dd->ofs = G_INT(def->ofs);
                }
-               else if ((def->scope||def->constant) && (def->type->type != ev_string || opt_constant_names_strings))
+               else if ((def->scope||def->constant) && (def->type->type != ev_string || (strncmp(def->name, "dotranslate_", 12) && opt_constant_names_strings)))
                {
                        if (opt_constant_names)
                        {
@@ -831,9 +853,10 @@ pbool QCC_WriteData (int crc)
                                continue;
                        if (dd->ofs == qcc_globals[h].ofs)
                        {
-                               if (dd->type != qcc_globals[h].type)
+                               if ((dd->type&~DEF_SAVEGLOBAL) != (qcc_globals[h].type&~DEF_SAVEGLOBAL))
                                {
-                                       if (dd->type != ev_vector && qcc_globals[h].type != ev_float)
+                                       if (!(((dd->type&~DEF_SAVEGLOBAL) == ev_vector && (qcc_globals[h].type&~DEF_SAVEGLOBAL) == ev_float) ||
+                                               ((dd->type&~DEF_SAVEGLOBAL) == ev_struct || (dd->type&~DEF_SAVEGLOBAL) == ev_union)))
                                                QCC_PR_Warning(0, NULL, 0, "Mismatched union global types (%s and %s)", strings+dd->s_name, strings+qcc_globals[h].s_name);
                                }
                                //remove the saveglobal flag on the duplicate globals.
@@ -1593,7 +1616,7 @@ PR_PrintDefs
                QCC_PR_PrintOfs (d->ofs);
 }*/
 
-QCC_type_t *QCC_PR_NewType (char *name, int basictype)
+QCC_type_t *QCC_PR_NewType (char *name, int basictype, pbool typedefed)
 {
        if (numtypeinfos>= maxtypeinfos)
                QCC_Error(ERR_TOOMANYTYPES, "Too many types");
@@ -1603,6 +1626,8 @@ QCC_type_t *QCC_PR_NewType (char *name, int basictype)
        qcc_typeinfo[numtypeinfos].num_parms = 0;
        qcc_typeinfo[numtypeinfos].param = NULL;
        qcc_typeinfo[numtypeinfos].size = type_size[basictype];
+       qcc_typeinfo[numtypeinfos].arraysize = 0;
+       qcc_typeinfo[numtypeinfos].typedefed = typedefed;
 
 
        numtypeinfos++;
@@ -1638,40 +1663,44 @@ void    QCC_PR_BeginCompilation (void *memory, int memsize)
                pr_global_defs[i] = &def_void;
 */
 
-       type_void = QCC_PR_NewType("void", ev_void);
-       type_string = QCC_PR_NewType("string", ev_string);
-       type_float = QCC_PR_NewType("float", ev_float);
-       type_vector = QCC_PR_NewType("vector", ev_vector);
-       type_entity = QCC_PR_NewType("entity", ev_entity);
-       type_field = QCC_PR_NewType("field", ev_field);
-       type_function = QCC_PR_NewType("function", ev_function);
-       type_pointer = QCC_PR_NewType("pointer", ev_pointer);
-       type_integer = QCC_PR_NewType("__integer", ev_integer);
-       type_variant = QCC_PR_NewType("__variant", ev_variant);
-
-       type_floatfield = QCC_PR_NewType("fieldfloat", ev_field);
+       type_void = QCC_PR_NewType("void", ev_void, true);
+       type_string = QCC_PR_NewType("string", ev_string, true);
+       type_float = QCC_PR_NewType("float", ev_float, true);
+       type_vector = QCC_PR_NewType("vector", ev_vector, true);
+       type_entity = QCC_PR_NewType("entity", ev_entity, true);
+       type_field = QCC_PR_NewType("__field", ev_field, false);
+       type_function = QCC_PR_NewType("__function", ev_function, false);
+       type_pointer = QCC_PR_NewType("__pointer", ev_pointer, false);
+       type_integer = QCC_PR_NewType("__integer", ev_integer, true);
+       type_variant = QCC_PR_NewType("variant", ev_variant, true);
+       type_variant = QCC_PR_NewType("__variant", ev_variant, true);
+
+       type_floatfield = QCC_PR_NewType("fieldfloat", ev_field, false);
        type_floatfield->aux_type = type_float;
-       type_pointer->aux_type = QCC_PR_NewType("pointeraux", ev_float);
+       type_pointer->aux_type = QCC_PR_NewType("pointeraux", ev_float, false);
+
+       type_intpointer = QCC_PR_NewType("__intpointer", ev_pointer, false);
+       type_intpointer->aux_type = type_integer;
+       type_floatpointer = QCC_PR_NewType("__floatpointer", ev_pointer, false);
+       type_floatpointer->aux_type = type_float;
 
        type_function->aux_type = type_void;
 
        //type_field->aux_type = type_float;
 
-       if (keyword_integer)
-               type_integer = QCC_PR_NewType("integer", ev_integer);
-       if (keyword_int)
-               type_integer = QCC_PR_NewType("int", ev_integer);
+       type_integer = QCC_PR_NewType("integer", ev_integer, keyword_integer?true:false);
+       type_integer = QCC_PR_NewType("int", ev_integer, keyword_integer?true:false);
 
 
 
        if (output_parms)
        {       //this tends to confuse the brains out of decompilers. :)
                numpr_globals = 1;
-               QCC_PR_GetDef(type_vector, "RETURN", NULL, true, 1, false)->references++;
+               QCC_PR_GetDef(type_vector, "RETURN", NULL, true, 0, false)->references++;
                for (i = 0; i < MAX_PARMS; i++)
                {
                        sprintf(name, "PARM%i", i);
-                       QCC_PR_GetDef(type_vector, name, NULL, true, 1, false)->references++;
+                       QCC_PR_GetDef(type_vector, name, NULL, true, 0, false)->references++;
                }
        }
        else
@@ -1733,11 +1762,12 @@ int QCC_PR_FinishCompilation (void)
                                }
                                else
                                {
-                                       QCC_PR_ParseErrorPrintDef(ERR_NOFUNC, d, "function %s was not defined",d->name);
+                                       QCC_PR_ParseWarning(ERR_NOFUNC, "function %s was not defined",d->name);
+                                       QCC_PR_ParsePrintDef(ERR_NOFUNC, d);
                                        bodylessfuncs = true;
                                        errors = true;
                                }
-                               s_file = NULL;
+                               s_file = 0;
 //                             errors = true;
                        }
                        else if (d->initialized==2)
@@ -1870,6 +1900,7 @@ unsigned short QCC_PR_WriteProgdefs (char *filename)
        QCC_def_t       *d;
        int     f;
        unsigned short          crc;
+       QCC_def_t *ld;
 //     int             c;
 
        file[0] = '\0';
@@ -1904,6 +1935,7 @@ unsigned short QCC_PR_WriteProgdefs (char *filename)
        ADD3(qcva("\tint\tpad[%i];\n", RESERVED_OFS));
        for (d=pr.def_head.next ; d ; d=d->next)
        {
+               ld = d;
                if (!strcmp (d->name, "end_sys_globals"))
                        break;
                if (d->ofs<RESERVED_OFS)
@@ -1916,7 +1948,8 @@ unsigned short QCC_PR_WriteProgdefs (char *filename)
                        break;
                case ev_vector:
                        ADD(qcva("\tvec3_t\t%s;\n",d->name));
-                       d=d->next->next->next;  // skip the elements
+                       if (d->deftail)
+                               d=d->deftail;   // skip the elements
                        break;
                case ev_string:
                        ADD(qcva("\tstring_t\t%s;\n",d->name));
@@ -1956,7 +1989,8 @@ unsigned short QCC_PR_WriteProgdefs (char *filename)
                        break;
                case ev_vector:
                        ADD(qcva("\tvec3_t\t%s;\n",d->name));
-                       d=d->next->next->next;  // skip the elements
+                       if (d->deftail)
+                               d=d->deftail;   // skip the elements
                        break;
                case ev_string:
                        ADD(qcva("\tstring_t\t%s;\n",d->name));
@@ -2755,6 +2789,7 @@ void QCC_SetDefaultProperties (void)
        qccwarningdisabled[WARN_FTE_SPECIFIC] = true;
        qccwarningdisabled[WARN_EXTENSION_USED] = true;
        qccwarningdisabled[WARN_IFSTRING_USED] = true;
+       qccwarningdisabled[WARN_CORRECTEDRETURNTYPE] = true;
 
 
 
@@ -2866,10 +2901,10 @@ void QCC_main (int argc, char **argv)   //as part of the quake engine
        pHash_GetNext = &Hash_GetNext;
        pHash_Add = &Hash_Add;
 
-       MAX_REGS                = 65536;
+       MAX_REGS                = 1<<17;
        MAX_STRINGS             = 1000000;
-       MAX_GLOBALS             = 65535;
-       MAX_FIELDS              = 2048;
+       MAX_GLOBALS             = 1<<17;
+       MAX_FIELDS              = 1<<12;
        MAX_STATEMENTS  = 0x80000;
        MAX_FUNCTIONS   = 16384;
        maxtypeinfos    = 16384;
@@ -2977,7 +3012,7 @@ void QCC_main (int argc, char **argv)     //as part of the quake engine
        QCC_PurgeTemps();
 
        strings = (void *)qccHunkAlloc(sizeof(char) * MAX_STRINGS);
-       strofs = 1;
+       strofs = 2;
 
        statements = (void *)qccHunkAlloc(sizeof(QCC_dstatement_t) * MAX_STATEMENTS);
        numstatements = 0;
@@ -2991,13 +3026,12 @@ void QCC_main (int argc, char **argv)   //as part of the quake engine
        qcc_pr_globals = (void *)qccHunkAlloc(sizeof(float) * MAX_REGS);
        numpr_globals=0;
 
-       Hash_InitTable(&globalstable, MAX_REGS, qccHunkAlloc(Hash_BytesForBuckets(MAX_REGS)));
-       Hash_InitTable(&localstable, MAX_REGS, qccHunkAlloc(Hash_BytesForBuckets(MAX_REGS)));
-       Hash_InitTable(&floatconstdefstable, MAX_REGS+1, qccHunkAlloc(Hash_BytesForBuckets(MAX_REGS+1)));
-       Hash_InitTable(&stringconstdefstable, MAX_REGS, qccHunkAlloc(Hash_BytesForBuckets(MAX_REGS)));
-       Hash_InitTable(&stringconstdefstable_dotranslate, MAX_REGS, qccHunkAlloc(Hash_BytesForBuckets(MAX_REGS)));
-       dotranslate=0;
-       dotranslate_count=0;
+       Hash_InitTable(&globalstable, MAX_REGS/2, qccHunkAlloc(Hash_BytesForBuckets(MAX_REGS/2)));
+       Hash_InitTable(&localstable, MAX_REGS/2, qccHunkAlloc(Hash_BytesForBuckets(MAX_REGS/2)));
+       Hash_InitTable(&floatconstdefstable, MAX_REGS/2+1, qccHunkAlloc(Hash_BytesForBuckets(MAX_REGS/2+1)));
+       Hash_InitTable(&stringconstdefstable, MAX_REGS/2, qccHunkAlloc(Hash_BytesForBuckets(MAX_REGS/2)));
+       Hash_InitTable(&stringconstdefstable_trans, 1000, qccHunkAlloc(Hash_BytesForBuckets(1000)));
+       dotranslate_count = 0;
 
 //     pr_global_defs = (QCC_def_t **)qccHunkAlloc(sizeof(QCC_def_t *) * MAX_REGS);
 
index 24fc433f604e28c8ce37124fe6a1655ff89ec17f..8e0b27885b1e6af8dcc38218cdd2ae4811fa9afd 100644 (file)
@@ -51,9 +51,11 @@ extern QCC_type_t    *type_function;// = {ev_function/*, &def_function*/,NULL,&type
 // type_function is a void() function used for state defs
 extern QCC_type_t      *type_pointer;// = {ev_pointer/*, &def_pointer*/};
 extern QCC_type_t      *type_integer;// = {ev_integer/*, &def_integer*/};
+extern QCC_type_t      *type_floatpointer;
+extern QCC_type_t      *type_intpointer;
 
 extern QCC_type_t      *type_floatfield;// = {ev_field/*, &def_field*/, NULL, &type_float};
-QCC_type_t *QCC_PR_NewType (char *name, int basictype);
+QCC_type_t *QCC_PR_NewType (char *name, int basictype, pbool typedefed);
 
 
 jmp_buf decompilestatementfailure;
@@ -763,21 +765,21 @@ void FigureOutTypes(progfuncs_t *progfuncs)
        memset(ofstype,         0, sizeof(*ofstype)*65535);
        memset(ofsflags,        0, sizeof(*ofsflags)*65535);
 
-       type_void = QCC_PR_NewType("void", ev_void);
-       type_string = QCC_PR_NewType("string", ev_string);
-       type_float = QCC_PR_NewType("float", ev_float);
-       type_vector = QCC_PR_NewType("vector", ev_vector);
-       type_entity = QCC_PR_NewType("entity", ev_entity);
-       type_field = QCC_PR_NewType("field", ev_field);
-       type_function = QCC_PR_NewType("function", ev_function);
-       type_pointer = QCC_PR_NewType("pointer", ev_pointer);
-       type_integer = QCC_PR_NewType("integer", ev_integer);
+       type_void = QCC_PR_NewType("void", ev_void, true);
+       type_string = QCC_PR_NewType("string", ev_string, true);
+       type_float = QCC_PR_NewType("float", ev_float, true);
+       type_vector = QCC_PR_NewType("vector", ev_vector, true);
+       type_entity = QCC_PR_NewType("entity", ev_entity, true);
+       type_field = QCC_PR_NewType("field", ev_field, false);
+       type_function = QCC_PR_NewType("function", ev_function, false);
+       type_pointer = QCC_PR_NewType("pointer", ev_pointer, false);
+       type_integer = QCC_PR_NewType("integer", ev_integer, true);
 
 //     type_variant = QCC_PR_NewType("__variant", ev_variant);
 
-       type_floatfield = QCC_PR_NewType("fieldfloat", ev_field);
+       type_floatfield = QCC_PR_NewType("fieldfloat", ev_field, false);
        type_floatfield->aux_type = type_float;
-       type_pointer->aux_type = QCC_PR_NewType("pointeraux", ev_float);
+       type_pointer->aux_type = QCC_PR_NewType("pointeraux", ev_float, false);
 
        type_function->aux_type = type_void;
 
diff --git a/misc/source/fteqcc-src/vc6/qcc.dsp b/misc/source/fteqcc-src/vc6/qcc.dsp
new file mode 100644 (file)
index 0000000..62c6bfe
--- /dev/null
@@ -0,0 +1,256 @@
+# Microsoft Developer Studio Project File - Name="qcc" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=qcc - Win32 GUIDebug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "qcc.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "qcc.mak" CFG="qcc - Win32 GUIDebug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "qcc - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "qcc - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "qcc - Win32 GUIDebug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "qcc - Win32 GUIRelease" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "qcc - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "QCCONLY" /YX /FD /c\r
+# ADD BASE RSC /l 0x809 /d "NDEBUG"\r
+# ADD RSC /l 0x809 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 ../../libs/zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../../fteqcc.exe"\r
+\r
+!ELSEIF  "$(CFG)" == "qcc - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "QCCONLY" /FR /YX /FD /GZ /c\r
+# ADD BASE RSC /l 0x809 /d "_DEBUG"\r
+# ADD RSC /l 0x809 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 ../../libs/zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../fteqcc_dbg.exe" /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "qcc - Win32 GUIDebug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "qcc___Win32_GUIDebug"\r
+# PROP BASE Intermediate_Dir "qcc___Win32_GUIDebug"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "qcc___Win32_GUIDebug"\r
+# PROP Intermediate_Dir "qcc___Win32_GUIDebug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "QCCONLY" /FR /YX /FD /GZ /c\r
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "QCCONLY" /FR /YX /FD /GZ /c\r
+# ADD BASE RSC /l 0x809 /d "_DEBUG"\r
+# ADD RSC /l 0x809 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 ../../libs/zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../../fteqcc.exe" /pdbtype:sept\r
+# ADD LINK32 ../../libs/zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib comdlg32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"..\..\fteqcc.exe" /pdbtype:sept\r
+# SUBTRACT LINK32 /pdb:none\r
+\r
+!ELSEIF  "$(CFG)" == "qcc - Win32 GUIRelease"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "qcc___Win32_GUIRelease0"\r
+# PROP BASE Intermediate_Dir "qcc___Win32_GUIRelease0"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "qcc___Win32_GUIRelease0"\r
+# PROP Intermediate_Dir "qcc___Win32_GUIRelease0"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "QCCONLY" /YX /FD /c\r
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "QCCONLY" /FR /YX /FD /c\r
+# ADD BASE RSC /l 0x809 /d "NDEBUG"\r
+# ADD RSC /l 0x809 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 ../../libs/zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../../../fteqcc.exe"\r
+# ADD LINK32 ../../libs/zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /machine:I386 /out:"../../fteqccgui.exe"\r
+# SUBTRACT LINK32 /pdb:none\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "qcc - Win32 Release"\r
+# Name "qcc - Win32 Debug"\r
+# Name "qcc - Win32 GUIDebug"\r
+# Name "qcc - Win32 GUIRelease"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=..\Comprout.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\hash.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\qcc_cmdlib.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\qcc_gtk.c\r
+# PROP Exclude_From_Build 1\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\qcc_pr_comp.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\qcc_pr_lex.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\qccgui.c\r
+\r
+!IF  "$(CFG)" == "qcc - Win32 Release"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "qcc - Win32 Debug"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "qcc - Win32 GUIDebug"\r
+\r
+!ELSEIF  "$(CFG)" == "qcc - Win32 GUIRelease"\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\qccguistuff.c\r
+\r
+!IF  "$(CFG)" == "qcc - Win32 Release"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "qcc - Win32 Debug"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "qcc - Win32 GUIDebug"\r
+\r
+!ELSEIF  "$(CFG)" == "qcc - Win32 GUIRelease"\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\QccMain.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\qcctui.c\r
+\r
+!IF  "$(CFG)" == "qcc - Win32 Release"\r
+\r
+!ELSEIF  "$(CFG)" == "qcc - Win32 Debug"\r
+\r
+!ELSEIF  "$(CFG)" == "qcc - Win32 GUIDebug"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "qcc - Win32 GUIRelease"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\qcd_main.c\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=..\gui.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\pr_comp.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\qcc.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Resource Files"\r
+\r
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/misc/source/fteqcc-src/vc6/qcc.dsw b/misc/source/fteqcc-src/vc6/qcc.dsw
new file mode 100644 (file)
index 0000000..4b65a4d
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "qcc"=".\qcc.dsp" - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r