.50 version
This commit is contained in:
parent
92214f13b3
commit
f7de8f0d61
|
@ -47,9 +47,9 @@ lib/windows/res.aps
|
|||
lib/windows/tic.aps
|
||||
.DS_Store
|
||||
lib/macos/.DS_Store
|
||||
build/macosx/tic.icns
|
||||
build/macosx/tic.app/
|
||||
build/macosx/tic.dmg
|
||||
build/macosx/tic80.icns
|
||||
build/macosx/tic80.app/
|
||||
build/macosx/tic80.dmg
|
||||
tools/bundler/assets/
|
||||
tools/bundler/bin/
|
||||
tools/bin2txt/*.exe
|
||||
|
@ -81,3 +81,14 @@ build/uwp/tic80/x64/
|
|||
build/uwp/tic80/ARM/
|
||||
build/uwp/tic/Package.StoreAssociation.xml
|
||||
build/uwp/tic/tic_StoreKey.pfx
|
||||
build/windows/gif/Debug Pro/
|
||||
build/windows/gif/Release Pro/
|
||||
build/windows/lua/Debug Pro/
|
||||
build/windows/lua/Release Pro/
|
||||
build/windows/tic/Debug PRO/
|
||||
build/windows/tic/Release PRO/
|
||||
build/windows/tic80/Debug Pro/
|
||||
build/windows/tic80/Release Pro/
|
||||
build/windows/zlib/Debug Pro/
|
||||
build/windows/zlib/Release Pro/
|
||||
build/windows/example/Release Pro/
|
||||
|
|
|
@ -31,10 +31,10 @@ made by [@matheuslessarodrigues](https://github.com/matheuslessarodrigues)
|
|||
## Linux
|
||||
run the following commands in the Terminal
|
||||
```
|
||||
sudo apt-get install git build-essential libgtk-3-dev
|
||||
sudo apt-get install git build-essential libgtk-3-dev libsdl2-dev lua5.3-dev zlib1g-dev
|
||||
git clone https://github.com/nesbox/TIC-80
|
||||
cd TIC-80
|
||||
make linux32 (or linux64/arm depending on your system)
|
||||
make linux
|
||||
```
|
||||
|
||||
## iOS / tvOS
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -4,8 +4,8 @@
|
|||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.nesbox.tic"
|
||||
android:versionCode="4700"
|
||||
android:versionName="0.47.0"
|
||||
android:versionCode="5000"
|
||||
android:versionName="0.50.0"
|
||||
android:installLocation="auto">
|
||||
|
||||
<!-- Android 2.3.3 -->
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
<key>CFBundleDisplayName</key>
|
||||
<string>TIC-80</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>tic</string>
|
||||
<string>tic80</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>tic.icns</string>
|
||||
<string>tic80.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.nesbox.tic</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
|
@ -19,10 +19,12 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.47.0</string>
|
||||
<string>0.50.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.47.0</string>
|
||||
<string>0.50.0</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>http://tic.computer © 2017</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -1,4 +1,4 @@
|
|||
APPNAME=tic
|
||||
APPNAME=tic80
|
||||
APPBUNDLE=$(APPNAME).app
|
||||
APPBUNDLECONTENTS=$(APPBUNDLE)/Contents
|
||||
APPBUNDLEEXE=$(APPBUNDLECONTENTS)/MacOS
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
|
@ -1,10 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug Pro|Win32">
|
||||
<Configuration>Debug Pro</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug Pro|x64">
|
||||
<Configuration>Debug Pro</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Pro|Win32">
|
||||
<Configuration>Release Pro</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Pro|x64">
|
||||
<Configuration>Release Pro</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
|
@ -22,6 +38,12 @@
|
|||
<ClCompile Include="..\..\..\examples\sdl-renderer.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\3rd-party\SDL2-2.0.5\VisualC\SDLmain\SDLmain.vcxproj">
|
||||
<Project>{da956fd3-e142-46f2-9dd5-c78bebb56b7a}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\..\3rd-party\SDL2-2.0.5\VisualC\SDL\SDL.vcxproj">
|
||||
<Project>{81ce8daf-ebb2-4761-8e45-b71abcca8c68}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\tic80\tic80.vcxproj">
|
||||
<Project>{c4d8bc10-ebf6-42bb-9b5d-6712fb428a50}</Project>
|
||||
</ProjectReference>
|
||||
|
@ -39,6 +61,12 @@
|
|||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
|
@ -46,12 +74,25 @@
|
|||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
|
@ -59,6 +100,13 @@
|
|||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
|
@ -67,28 +115,52 @@
|
|||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
|
@ -100,7 +172,22 @@
|
|||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>SDL2main.lib;SDL2.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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\..\include\sdl2;..\..\..\include\tic80;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
@ -115,7 +202,22 @@
|
|||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>SDL2main.lib;SDL2.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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\..\include\sdl2;..\..\..\include\tic80;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
@ -134,7 +236,26 @@
|
|||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>SDL2main.lib;SDL2.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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\..\include\sdl2;..\..\..\include\tic80;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
@ -153,7 +274,26 @@
|
|||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>SDL2main.lib;SDL2.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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\..\include\sdl2;..\..\..\include\tic80;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
|
|
@ -1,10 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug Pro|Win32">
|
||||
<Configuration>Debug Pro</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug Pro|x64">
|
||||
<Configuration>Debug Pro</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Pro|Win32">
|
||||
<Configuration>Release Pro</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Pro|x64">
|
||||
<Configuration>Release Pro</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
|
@ -41,6 +57,12 @@
|
|||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
|
@ -48,12 +70,25 @@
|
|||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
|
@ -61,6 +96,13 @@
|
|||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
|
@ -69,15 +111,27 @@
|
|||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
|
@ -93,6 +147,19 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
|
@ -106,6 +173,19 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
|
@ -123,6 +203,23 @@
|
|||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
|
@ -140,6 +237,23 @@
|
|||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
|
|
@ -1,10 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug Pro|Win32">
|
||||
<Configuration>Debug Pro</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug Pro|x64">
|
||||
<Configuration>Debug Pro</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Pro|Win32">
|
||||
<Configuration>Release Pro</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Pro|x64">
|
||||
<Configuration>Release Pro</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
|
@ -70,6 +86,12 @@
|
|||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
|
@ -77,12 +99,25 @@
|
|||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
|
@ -90,6 +125,13 @@
|
|||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
|
@ -98,15 +140,27 @@
|
|||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
|
@ -123,6 +177,20 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>LUA_COMPAT_5_2;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\..\include\lua;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
|
@ -137,6 +205,20 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>LUA_COMPAT_5_2;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\..\include\lua;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
|
@ -155,6 +237,24 @@
|
|||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>LUA_COMPAT_5_2;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\..\include\lua;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
|
@ -173,6 +273,24 @@
|
|||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>LUA_COMPAT_5_2;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\..\include\lua;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
|
|
@ -21,72 +21,140 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2main", "..\..\..\..\3rd
|
|||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug Pro|x64 = Debug Pro|x64
|
||||
Debug Pro|x86 = Debug Pro|x86
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release Pro|x64 = Release Pro|x64
|
||||
Release Pro|x86 = Release Pro|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Debug Pro|x64.ActiveCfg = Debug Pro|x64
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Debug Pro|x64.Build.0 = Debug Pro|x64
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Debug Pro|x86.ActiveCfg = Debug Pro|Win32
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Debug Pro|x86.Build.0 = Debug Pro|Win32
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Debug|x64.Build.0 = Debug|x64
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Release Pro|x64.ActiveCfg = Release Pro|x64
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Release Pro|x64.Build.0 = Release Pro|x64
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Release Pro|x86.ActiveCfg = Release Pro|Win32
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Release Pro|x86.Build.0 = Release Pro|Win32
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Release|x64.ActiveCfg = Release|x64
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Release|x64.Build.0 = Release|x64
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B6ECC66E-26FA-42C2-8F6C-E4338424F38A}.Release|x86.Build.0 = Release|Win32
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Debug Pro|x64.ActiveCfg = Debug Pro|x64
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Debug Pro|x64.Build.0 = Debug Pro|x64
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Debug Pro|x86.ActiveCfg = Debug Pro|Win32
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Debug Pro|x86.Build.0 = Debug Pro|Win32
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Debug|x64.Build.0 = Debug|x64
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Debug|x86.Build.0 = Debug|Win32
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Release Pro|x64.ActiveCfg = Release Pro|x64
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Release Pro|x64.Build.0 = Release Pro|x64
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Release Pro|x86.ActiveCfg = Release Pro|Win32
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Release Pro|x86.Build.0 = Release Pro|Win32
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Release|x64.ActiveCfg = Release|x64
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Release|x64.Build.0 = Release|x64
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Release|x86.ActiveCfg = Release|Win32
|
||||
{57D2471B-3138-495E-AF18-6E290D098FFC}.Release|x86.Build.0 = Release|Win32
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Debug Pro|x64.ActiveCfg = Debug Pro|x64
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Debug Pro|x64.Build.0 = Debug Pro|x64
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Debug Pro|x86.ActiveCfg = Debug Pro|Win32
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Debug Pro|x86.Build.0 = Debug Pro|Win32
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Debug|x64.Build.0 = Debug|x64
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Debug|x86.Build.0 = Debug|Win32
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Release Pro|x64.ActiveCfg = Release Pro|x64
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Release Pro|x64.Build.0 = Release Pro|x64
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Release Pro|x86.ActiveCfg = Release Pro|Win32
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Release Pro|x86.Build.0 = Release Pro|Win32
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Release|x64.ActiveCfg = Release|x64
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Release|x64.Build.0 = Release|x64
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Release|x86.ActiveCfg = Release|Win32
|
||||
{1DFBDFA2-F204-42FF-B99E-250E4B2EBA04}.Release|x86.Build.0 = Release|Win32
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Debug Pro|x64.ActiveCfg = Debug Pro|x64
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Debug Pro|x64.Build.0 = Debug Pro|x64
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Debug Pro|x86.ActiveCfg = Debug Pro|Win32
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Debug Pro|x86.Build.0 = Debug Pro|Win32
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Debug|x64.Build.0 = Debug|x64
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Debug|x86.Build.0 = Debug|Win32
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Release Pro|x64.ActiveCfg = Release Pro|x64
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Release Pro|x64.Build.0 = Release Pro|x64
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Release Pro|x86.ActiveCfg = Release Pro|Win32
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Release Pro|x86.Build.0 = Release Pro|Win32
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Release|x64.ActiveCfg = Release|x64
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Release|x64.Build.0 = Release|x64
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Release|x86.ActiveCfg = Release|Win32
|
||||
{6EA9D998-7557-4AED-ABFC-142F9960C9B6}.Release|x86.Build.0 = Release|Win32
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Debug Pro|x64.ActiveCfg = Debug Pro|x64
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Debug Pro|x64.Build.0 = Debug Pro|x64
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Debug Pro|x86.ActiveCfg = Debug Pro|Win32
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Debug Pro|x86.Build.0 = Debug Pro|Win32
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Debug|x64.Build.0 = Debug|x64
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Debug|x86.Build.0 = Debug|Win32
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Release Pro|x64.ActiveCfg = Release Pro|x64
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Release Pro|x64.Build.0 = Release Pro|x64
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Release Pro|x86.ActiveCfg = Release Pro|Win32
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Release Pro|x86.Build.0 = Release Pro|Win32
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Release|x64.ActiveCfg = Release|x64
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Release|x64.Build.0 = Release|x64
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Release|x86.ActiveCfg = Release|Win32
|
||||
{C4D8BC10-EBF6-42BB-9B5D-6712FB428A50}.Release|x86.Build.0 = Release|Win32
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Debug Pro|x64.ActiveCfg = Debug Pro|x64
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Debug Pro|x64.Build.0 = Debug Pro|x64
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Debug Pro|x86.ActiveCfg = Debug Pro|Win32
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Debug Pro|x86.Build.0 = Debug Pro|Win32
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Debug|x64.Build.0 = Debug|x64
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Debug|x86.Build.0 = Debug|Win32
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Release Pro|x64.ActiveCfg = Release Pro|x64
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Release Pro|x64.Build.0 = Release Pro|x64
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Release Pro|x86.ActiveCfg = Release Pro|Win32
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Release Pro|x86.Build.0 = Release Pro|Win32
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Release|x64.ActiveCfg = Release|x64
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Release|x64.Build.0 = Release|x64
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Release|x86.ActiveCfg = Release|Win32
|
||||
{86CAA9C1-C61A-40D8-AC77-33D94754C824}.Release|x86.Build.0 = Release|Win32
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug Pro|x64.ActiveCfg = Debug Pro|x64
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug Pro|x64.Build.0 = Debug Pro|x64
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug Pro|x86.ActiveCfg = Debug Pro|Win32
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug Pro|x86.Build.0 = Debug Pro|Win32
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.Build.0 = Debug|x64
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x86.Build.0 = Debug|Win32
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release Pro|x64.ActiveCfg = Release Pro|x64
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release Pro|x64.Build.0 = Release Pro|x64
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release Pro|x86.ActiveCfg = Release Pro|Win32
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release Pro|x86.Build.0 = Release Pro|Win32
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.ActiveCfg = Release|x64
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.Build.0 = Release|x64
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x86.ActiveCfg = Release|Win32
|
||||
{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x86.Build.0 = Release|Win32
|
||||
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug Pro|x64.ActiveCfg = Debug Pro|x64
|
||||
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug Pro|x64.Build.0 = Debug Pro|x64
|
||||
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug Pro|x86.ActiveCfg = Debug Pro|Win32
|
||||
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug Pro|x86.Build.0 = Debug Pro|Win32
|
||||
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x64.Build.0 = Debug|x64
|
||||
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x86.Build.0 = Debug|Win32
|
||||
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release Pro|x64.ActiveCfg = Release Pro|x64
|
||||
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release Pro|x64.Build.0 = Release Pro|x64
|
||||
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release Pro|x86.ActiveCfg = Release Pro|Win32
|
||||
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release Pro|x86.Build.0 = Release Pro|Win32
|
||||
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x64.ActiveCfg = Release|x64
|
||||
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x64.Build.0 = Release|x64
|
||||
{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x86.ActiveCfg = Release|Win32
|
||||
|
|
|
@ -1,10 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug Pro|Win32">
|
||||
<Configuration>Debug Pro</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug Pro|x64">
|
||||
<Configuration>Debug Pro</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Pro|Win32">
|
||||
<Configuration>Release Pro</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Pro|x64">
|
||||
<Configuration>Release Pro</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
|
@ -88,6 +104,12 @@
|
|||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
|
@ -95,12 +117,25 @@
|
|||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
|
@ -108,6 +143,13 @@
|
|||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
|
@ -116,28 +158,52 @@
|
|||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
|
@ -152,6 +218,24 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;version.lib;Imm32.lib;Winmm.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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
<OutputFile>$(OutDir)tic80$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>TIC80_PRO;_CRT_SECURE_NO_WARNINGS;LUA_COMPAT_5_2;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\include;..\..\..\include\tic80;..\..\..\include\lua;..\..\..\include\gif;..\..\..\include\sdl2;..\..\..\include\zlib;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;version.lib;Imm32.lib;Winmm.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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
<OutputFile>$(OutDir)tic80$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
|
@ -168,6 +252,24 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;version.lib;Imm32.lib;Winmm.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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
<OutputFile>$(OutDir)tic80$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>TIC80_PRO;_CRT_SECURE_NO_WARNINGS;LUA_COMPAT_5_2;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\include;..\..\..\include\tic80;..\..\..\include\lua;..\..\..\include\gif;..\..\..\include\sdl2;..\..\..\include\zlib;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;version.lib;Imm32.lib;Winmm.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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
<OutputFile>$(OutDir)tic80$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
|
@ -188,6 +290,28 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;version.lib;Imm32.lib;Winmm.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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
<OutputFile>$(OutDir)tic80$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>TIC80_PRO;_CRT_SECURE_NO_WARNINGS;LUA_COMPAT_5_2;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\include;..\..\..\include\tic80;..\..\..\include\lua;..\..\..\include\gif;..\..\..\include\sdl2;..\..\..\include\zlib;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;version.lib;Imm32.lib;Winmm.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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
<OutputFile>$(OutDir)tic80$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
@ -208,6 +332,28 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;version.lib;Imm32.lib;Winmm.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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
<OutputFile>$(OutDir)tic80$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>TIC80_PRO;_CRT_SECURE_NO_WARNINGS;LUA_COMPAT_5_2;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\include;..\..\..\include\tic80;..\..\..\include\lua;..\..\..\include\gif;..\..\..\include\sdl2;..\..\..\include\zlib;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;version.lib;Imm32.lib;Winmm.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;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\lib\windows</AdditionalLibraryDirectories>
|
||||
<OutputFile>$(OutDir)tic80$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
|
|
@ -1,4 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'">
|
||||
<LocalDebuggerCommand>$(OutDir)tic80$(TargetExt)</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'">
|
||||
<LocalDebuggerCommand>$(OutDir)tic80$(TargetExt)</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LocalDebuggerCommand>$(OutDir)tic80$(TargetExt)</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LocalDebuggerCommand>$(OutDir)tic80$(TargetExt)</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'">
|
||||
<LocalDebuggerCommand>$(OutDir)tic80$(TargetExt)</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'">
|
||||
<LocalDebuggerCommand>$(OutDir)tic80$(TargetExt)</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LocalDebuggerCommand>$(OutDir)tic80$(TargetExt)</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LocalDebuggerCommand>$(OutDir)tic80$(TargetExt)</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
</Project>
|
Binary file not shown.
Binary file not shown.
|
@ -1,10 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug Pro|Win32">
|
||||
<Configuration>Debug Pro</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug Pro|x64">
|
||||
<Configuration>Debug Pro</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Pro|Win32">
|
||||
<Configuration>Release Pro</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Pro|x64">
|
||||
<Configuration>Release Pro</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
|
@ -55,6 +71,12 @@
|
|||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
|
@ -62,12 +84,25 @@
|
|||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
|
@ -75,6 +110,13 @@
|
|||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
|
@ -83,28 +125,52 @@
|
|||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
|
@ -120,6 +186,21 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>TIC80_PRO;TIC80_SHARED;WIN32;_DEBUG;_WINDOWS;_USRDLL;TIC80_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\..\include\tic80;..\..\..\include\lua;..\..\..\include\gif</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
|
@ -135,6 +216,21 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>TIC80_PRO;TIC80_SHARED;_DEBUG;_WINDOWS;_USRDLL;TIC80_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\..\include\tic80;..\..\..\include\lua;..\..\..\include\gif</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
|
@ -154,6 +250,25 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>TIC80_PRO;TIC80_SHARED;WIN32;NDEBUG;_WINDOWS;_USRDLL;TIC80_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\..\include\tic80;..\..\..\include\lua;..\..\..\include\gif</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
|
@ -173,6 +288,25 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>TIC80_PRO;TIC80_SHARED;NDEBUG;_WINDOWS;_USRDLL;TIC80_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\..\include\tic80;..\..\..\include\lua;..\..\..\include\gif</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
|
|
@ -1,10 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug Pro|Win32">
|
||||
<Configuration>Debug Pro</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug Pro|x64">
|
||||
<Configuration>Debug Pro</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Pro|Win32">
|
||||
<Configuration>Release Pro</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Pro|x64">
|
||||
<Configuration>Release Pro</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
|
@ -48,6 +64,12 @@
|
|||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
|
@ -55,12 +77,25 @@
|
|||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
|
@ -68,6 +103,13 @@
|
|||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
|
@ -76,15 +118,27 @@
|
|||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
|
@ -100,6 +154,19 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
|
@ -113,6 +180,19 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Pro|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
|
@ -130,6 +210,23 @@
|
|||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
|
@ -147,6 +244,23 @@
|
|||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Pro|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
|
BIN
config.tic
BIN
config.tic
Binary file not shown.
Binary file not shown.
|
@ -56,9 +56,9 @@ int main(int argc, char **argv)
|
|||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
|
||||
|
||||
{
|
||||
SDL_Window* window = SDL_CreateWindow("TIC-80 SDL demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, TIC80_WIDTH, TIC80_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
||||
SDL_Window* window = SDL_CreateWindow("TIC-80 SDL demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, TIC80_FULLWIDTH, TIC80_FULLHEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
||||
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||
SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, TIC80_WIDTH, TIC80_HEIGHT);
|
||||
SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, TIC80_FULLWIDTH, TIC80_FULLHEIGHT);
|
||||
|
||||
SDL_AudioDeviceID audioDevice = 0;
|
||||
SDL_AudioSpec audioSpec;
|
||||
|
|
|
@ -31,6 +31,8 @@ extern "C" {
|
|||
|
||||
#define TIC80_WIDTH 240
|
||||
#define TIC80_HEIGHT 136
|
||||
#define TIC80_FULLWIDTH 256
|
||||
#define TIC80_FULLHEIGHT (TIC80_FULLWIDTH*9/16)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -47,15 +49,8 @@ typedef struct
|
|||
s32 count;
|
||||
} sound;
|
||||
|
||||
u32 screen[TIC80_WIDTH * TIC80_HEIGHT];
|
||||
u32 border[TIC80_HEIGHT];
|
||||
|
||||
struct
|
||||
{
|
||||
s8 x;
|
||||
s8 y;
|
||||
s8 rows[TIC80_HEIGHT];
|
||||
} offset;
|
||||
u32 screen[TIC80_FULLWIDTH * TIC80_FULLHEIGHT];
|
||||
|
||||
} tic80;
|
||||
|
||||
typedef union
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
334
makefile
334
makefile
|
@ -1,334 +0,0 @@
|
|||
CC=gcc
|
||||
OPT=-O3 -Wall -std=c99
|
||||
OPT_ARM=-D__ARM_LINUX__
|
||||
|
||||
RM= rm -f
|
||||
|
||||
INCLUDES= \
|
||||
-Iinclude/lua \
|
||||
-Iinclude/zlib \
|
||||
-Iinclude/gif \
|
||||
-Iinclude/sdl2 \
|
||||
-Iinclude/tic80
|
||||
|
||||
MINGW_LINKER_FLAGS= \
|
||||
-Llib/mingw \
|
||||
-lmingw32 \
|
||||
-lSDL2main \
|
||||
-lSDL2 \
|
||||
-lz \
|
||||
-lgif \
|
||||
-llua \
|
||||
-lcomdlg32 \
|
||||
-lws2_32 \
|
||||
-mwindows
|
||||
|
||||
LINUX_INCLUDES= \
|
||||
`pkg-config --cflags gtk+-3.0`
|
||||
|
||||
LINUX64_LIBS= \
|
||||
`pkg-config --libs gtk+-3.0` \
|
||||
-Llib/linux
|
||||
|
||||
LINUX32_LIBS= \
|
||||
`pkg-config --libs gtk+-3.0` \
|
||||
-Llib/linux32
|
||||
|
||||
LINUX_ARM_LIBS= \
|
||||
-Llib/arm
|
||||
|
||||
LINUX_LINKER_FLAGS= \
|
||||
-D_GNU_SOURCE \
|
||||
-lSDL2 \
|
||||
-llua \
|
||||
-ldl \
|
||||
-lm \
|
||||
-lpthread \
|
||||
-lrt \
|
||||
-lz \
|
||||
-lgif
|
||||
|
||||
MINGW_OUTPUT=bin/tic.exe
|
||||
|
||||
EMS_CC=emcc
|
||||
EMS_OPT= \
|
||||
-D_GNU_SOURCE \
|
||||
-Wno-typedef-redefinition \
|
||||
-s USE_SDL=2 \
|
||||
-s TOTAL_MEMORY=67108864 \
|
||||
--llvm-lto 1 \
|
||||
--memory-init-file 0 \
|
||||
--pre-js lib/emscripten/prejs.js
|
||||
|
||||
EMS_LINKER_FLAGS= \
|
||||
-Llib/emscripten \
|
||||
-llua \
|
||||
-lgif \
|
||||
-lz
|
||||
|
||||
MACOSX_OPT= \
|
||||
-mmacosx-version-min=10.6 \
|
||||
-Wno-typedef-redefinition \
|
||||
-D_THREAD_SAFE \
|
||||
-D_GNU_SOURCE
|
||||
|
||||
MACOSX_LIBS= \
|
||||
-Llib/macos \
|
||||
-L/usr/local/lib \
|
||||
-lSDL2 -lm -liconv -lobjc -llua -lz -lgif \
|
||||
-Wl,-framework,CoreAudio \
|
||||
-Wl,-framework,AudioToolbox \
|
||||
-Wl,-framework,ForceFeedback \
|
||||
-Wl,-framework,CoreVideo \
|
||||
-Wl,-framework,Cocoa \
|
||||
-Wl,-framework,Carbon \
|
||||
-Wl,-framework,IOKit
|
||||
|
||||
SOURCES=\
|
||||
src/studio.c \
|
||||
src/console.c \
|
||||
src/run.c \
|
||||
src/ext/file_dialog.c \
|
||||
src/ext/md5.c \
|
||||
src/ext/gif.c \
|
||||
src/ext/net/SDLnet.c \
|
||||
src/ext/net/SDLnetTCP.c \
|
||||
src/ext/net/SDLnetselect.c \
|
||||
src/fs.c \
|
||||
src/tools.c \
|
||||
src/start.c \
|
||||
src/sprite.c \
|
||||
src/map.c \
|
||||
src/sfx.c \
|
||||
src/music.c \
|
||||
src/history.c \
|
||||
src/world.c \
|
||||
src/config.c \
|
||||
src/keymap.c \
|
||||
src/code.c \
|
||||
src/dialog.c \
|
||||
src/menu.c \
|
||||
src/net.c \
|
||||
src/surf.c
|
||||
|
||||
SOURCES_EXT= \
|
||||
src/html.c
|
||||
|
||||
DEMO_ASSETS= \
|
||||
bin/assets/fire.tic.dat \
|
||||
bin/assets/p3d.tic.dat \
|
||||
bin/assets/palette.tic.dat \
|
||||
bin/assets/quest.tic.dat \
|
||||
bin/assets/sfx.tic.dat \
|
||||
bin/assets/music.tic.dat \
|
||||
bin/assets/font.tic.dat \
|
||||
bin/assets/tetris.tic.dat \
|
||||
bin/assets/jsdemo.tic.dat \
|
||||
bin/assets/luademo.tic.dat \
|
||||
bin/assets/moondemo.tic.dat \
|
||||
bin/assets/config.tic.dat
|
||||
|
||||
all: run
|
||||
|
||||
TIC80_H = include/tic80/tic80_types.h include/tic80/tic80.h include/tic80/tic80_config.h src/tic.h src/ticapi.h src/machine.h
|
||||
|
||||
TIC_H= src/*.h \
|
||||
src/ext/*.h
|
||||
|
||||
bin/studio.o: src/studio.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/console.o: src/console.c $(TIC80_H) $(TIC_H) $(DEMO_ASSETS)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/run.o: src/run.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/file_dialog.o: src/ext/file_dialog.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/md5.o: src/ext/md5.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/gif.o: src/ext/gif.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/SDLnet.o: src/ext/net/SDLnet.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/SDLnetTCP.o: src/ext/net/SDLnetTCP.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/SDLnetselect.o: src/ext/net/SDLnetselect.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/fs.o: src/fs.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/tools.o: src/tools.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/start.o: src/start.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/sprite.o: src/sprite.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/map.o: src/map.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/sfx.o: src/sfx.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/music.o: src/music.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/history.o: src/history.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/world.o: src/world.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/config.o: src/config.c $(TIC80_H) $(TIC_H) $(DEMO_ASSETS)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/keymap.o: src/keymap.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/code.o: src/code.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/net.o: src/net.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/dialog.o: src/dialog.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/menu.o: src/menu.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/surf.o: src/surf.c $(TIC80_H) $(TIC_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
TIC_O=\
|
||||
bin/studio.o \
|
||||
bin/console.o \
|
||||
bin/run.o \
|
||||
bin/file_dialog.o \
|
||||
bin/md5.o \
|
||||
bin/gif.o \
|
||||
bin/SDLnet.o \
|
||||
bin/SDLnetTCP.o \
|
||||
bin/SDLnetselect.o \
|
||||
bin/fs.o \
|
||||
bin/tools.o \
|
||||
bin/start.o \
|
||||
bin/sprite.o \
|
||||
bin/map.o \
|
||||
bin/sfx.o \
|
||||
bin/music.o \
|
||||
bin/history.o \
|
||||
bin/world.o \
|
||||
bin/config.o \
|
||||
bin/keymap.o \
|
||||
bin/code.o \
|
||||
bin/net.o \
|
||||
bin/dialog.o \
|
||||
bin/menu.o \
|
||||
bin/surf.o
|
||||
|
||||
bin/tic80.o: src/tic80.c $(TIC80_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -DTIC80_SHARED -c -o $@
|
||||
|
||||
bin/tic.o: src/tic.c $(TIC80_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/blip_buf.o: src/ext/blip_buf.c $(TIC80_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/jsapi.o: src/jsapi.c $(TIC80_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/luaapi.o: src/luaapi.c $(TIC80_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
bin/duktape.o: src/ext/duktape/duktape.c $(TIC80_H)
|
||||
$(CC) $< $(OPT) $(INCLUDES) -c -o $@
|
||||
|
||||
TIC80_SRC = src/tic80.c src/tic.c src/ext/blip_buf.c src/jsapi.c src/luaapi.c src/ext/duktape/duktape.c
|
||||
TIC80_O = bin/tic80.o bin/tic.o bin/tools.o bin/blip_buf.o bin/jsapi.o bin/luaapi.o bin/duktape.o bin/gif.o
|
||||
TIC80_A = bin/libtic80.a
|
||||
TIC80_DLL = bin/tic80.dll
|
||||
|
||||
$(TIC80_DLL): $(TIC80_O)
|
||||
$(CC) $(OPT) -shared $(TIC80_O) -Llib/mingw -llua -lgif -Wl,--out-implib,$(TIC80_A) -o $@
|
||||
|
||||
emscripten:
|
||||
$(EMS_CC) $(SOURCES) $(TIC80_SRC) $(SOURCES_EXT) $(OPT) $(INCLUDES) $(EMS_OPT) $(EMS_LINKER_FLAGS) -o build/html/tic.js
|
||||
|
||||
mingw: $(DEMO_ASSETS) $(TIC80_DLL) $(TIC_O) bin/html.o bin/res.o
|
||||
$(CC) $(TIC_O) bin/html.o bin/res.o $(TIC80_A) $(OPT) $(INCLUDES) $(MINGW_LINKER_FLAGS) -o $(MINGW_OUTPUT)
|
||||
|
||||
run: mingw
|
||||
$(MINGW_OUTPUT)
|
||||
|
||||
linux64:
|
||||
$(CC) $(LINUX_INCLUDES) $(SOURCES) $(TIC80_SRC) $(SOURCES_EXT) $(OPT) $(INCLUDES) $(LINUX64_LIBS) $(LINUX_LINKER_FLAGS) -flto -o bin/tic
|
||||
|
||||
linux32:
|
||||
$(CC) $(LINUX_INCLUDES) $(SOURCES) $(TIC80_SRC) $(SOURCES_EXT) $(OPT) $(INCLUDES) $(LINUX32_LIBS) $(LINUX_LINKER_FLAGS) -flto -o bin/tic
|
||||
|
||||
arm:
|
||||
$(CC) $(OPT_ARM) $(SOURCES) $(TIC80_SRC) $(OPT) $(INCLUDES) $(LINUX_ARM_LIBS) $(LINUX_LINKER_FLAGS) -flto -o bin/tic
|
||||
|
||||
macosx:
|
||||
$(CC) $(SOURCES) $(TIC80_SRC) $(SOURCES_EXT) src/ext/file_dialog.m $(OPT) $(MACOSX_OPT) $(INCLUDES) $(MACOSX_LIBS) -o bin/tic
|
||||
|
||||
bin/res.o: lib/mingw/res.rc lib/mingw/icon.ico
|
||||
windres $< $@
|
||||
|
||||
BIN2TXT= tools/bin2txt/bin2txt
|
||||
|
||||
bin/html.o: src/html.c build/html/index.html build/html/tic.js
|
||||
$(BIN2TXT) build/html/index.html bin/assets/index.html.dat -z
|
||||
$(BIN2TXT) build/html/tic.js bin/assets/tic.js.dat -z
|
||||
$(CC) -c src/html.c $(OPT) $(INCLUDES) -o $@
|
||||
|
||||
bin/assets/config.tic.dat: config.tic
|
||||
$(BIN2TXT) $< $@ -z
|
||||
|
||||
bin/assets/fire.tic.dat: demos/fire.tic
|
||||
$(BIN2TXT) $< $@ -z
|
||||
|
||||
bin/assets/p3d.tic.dat: demos/p3d.tic
|
||||
$(BIN2TXT) $< $@ -z
|
||||
|
||||
bin/assets/palette.tic.dat: demos/palette.tic
|
||||
$(BIN2TXT) $< $@ -z
|
||||
|
||||
bin/assets/quest.tic.dat: demos/quest.tic
|
||||
$(BIN2TXT) $< $@ -z
|
||||
|
||||
bin/assets/sfx.tic.dat: demos/sfx.tic
|
||||
$(BIN2TXT) $< $@ -z
|
||||
|
||||
bin/assets/font.tic.dat: demos/font.tic
|
||||
$(BIN2TXT) $< $@ -z
|
||||
|
||||
bin/assets/music.tic.dat: demos/music.tic
|
||||
$(BIN2TXT) $< $@ -z
|
||||
|
||||
bin/assets/tetris.tic.dat: demos/tetris.tic
|
||||
$(BIN2TXT) $< $@ -z
|
||||
|
||||
bin/assets/jsdemo.tic.dat: demos/jsdemo.tic
|
||||
$(BIN2TXT) $< $@ -z
|
||||
|
||||
bin/assets/luademo.tic.dat: demos/luademo.tic
|
||||
$(BIN2TXT) $< $@ -z
|
||||
|
||||
bin/assets/moondemo.tic.dat: demos/moondemo.tic
|
||||
$(BIN2TXT) $< $@ -z
|
||||
|
||||
clean: $(TIC_O) $(TIC80_O)
|
||||
$(RM) $(TIC_O) $(TIC80_O)
|
|
@ -83,6 +83,7 @@ static void drawCode(Code* code, bool withCursor)
|
|||
|
||||
if(code->cursor.selection && pointer >= selection.start && pointer < selection.end)
|
||||
code->tic->api.rect(code->tic, x-1, y-1, TIC_FONT_WIDTH+1, TIC_FONT_HEIGHT+1, getConfig()->theme.code.select);
|
||||
else code->tic->api.draw_char(code->tic, symbol, x+1, y+1, 0);
|
||||
|
||||
code->tic->api.draw_char(code->tic, symbol, x, y, *colorPointer);
|
||||
|
||||
|
@ -143,9 +144,9 @@ static s32 getLinesCount(Code* code)
|
|||
|
||||
static void removeInvalidChars(char* code)
|
||||
{
|
||||
// remove \r symbol
|
||||
char* s; char* d;
|
||||
for(s = d = code; (*d = *s); d += (*s++ != '\r'));
|
||||
// remove \r symbol
|
||||
char* s; char* d;
|
||||
for(s = d = code; (*d = *s); d += (*s++ != '\r'));
|
||||
}
|
||||
|
||||
static void updateEditor(Code* code)
|
||||
|
@ -647,7 +648,7 @@ static void pageDown(Code* code)
|
|||
s32 line = 0;
|
||||
getCursorPosition(code, &column, &line);
|
||||
s32 lines = getLinesCount(code);
|
||||
setCursorPosition(code, column, line < lines - TEXT_BUFFER_HEIGHT ? line + TEXT_BUFFER_HEIGHT : lines);
|
||||
setCursorPosition(code, column, line < lines - TEXT_BUFFER_HEIGHT ? line + TEXT_BUFFER_HEIGHT : lines);
|
||||
}
|
||||
|
||||
static bool replaceSelection(Code* code)
|
||||
|
|
13
src/config.c
13
src/config.c
|
@ -56,6 +56,16 @@ static void readConfigCheckNewVersion(Config* config, lua_State* lua)
|
|||
lua_pop(lua, 1);
|
||||
}
|
||||
|
||||
static void readConfigNoSound(Config* config, lua_State* lua)
|
||||
{
|
||||
lua_getglobal(lua, "NO_SOUND");
|
||||
|
||||
if(lua_isboolean(lua, -1))
|
||||
config->data.noSound = lua_toboolean(lua, -1);
|
||||
|
||||
lua_pop(lua, 1);
|
||||
}
|
||||
|
||||
static void readCursorTheme(Config* config, lua_State* lua)
|
||||
{
|
||||
lua_getfield(lua, -1, "CURSOR");
|
||||
|
@ -156,6 +166,7 @@ static void readConfig(Config* config)
|
|||
readConfigVideoLength(config, lua);
|
||||
readConfigVideoScale(config, lua);
|
||||
readConfigCheckNewVersion(config, lua);
|
||||
readConfigNoSound(config, lua);
|
||||
readTheme(config, lua);
|
||||
}
|
||||
|
||||
|
@ -173,6 +184,8 @@ static void update(Config* config, const u8* buffer, size_t size)
|
|||
|
||||
static void setDefault(Config* config)
|
||||
{
|
||||
SDL_memset(&config->data, 0, sizeof(StudioConfig));
|
||||
|
||||
{
|
||||
static const u8 DefaultBiosZip[] =
|
||||
{
|
||||
|
|
603
src/console.c
603
src/console.c
|
@ -40,7 +40,7 @@
|
|||
#define CONSOLE_BUFFER_SCREENS 64
|
||||
#define CONSOLE_BUFFER_SIZE (CONSOLE_BUFFER_WIDTH * CONSOLE_BUFFER_HEIGHT * CONSOLE_BUFFER_SCREENS)
|
||||
|
||||
#if defined(__WINDOWS__) || (defined(__LINUX__) && !defined(__ARM_LINUX__)) || defined(__MACOSX__)
|
||||
#if defined(__WINDOWS__) || defined(__LINUX__) || defined(__MACOSX__)
|
||||
#define CAN_EXPORT 1
|
||||
#endif
|
||||
|
||||
|
@ -62,27 +62,30 @@ static struct
|
|||
.fast = false,
|
||||
};
|
||||
|
||||
static const char CartExt[] = ".tic";
|
||||
|
||||
static const char DefaultLuaTicPath[] = TIC_LOCAL "default.tic";
|
||||
static const char DefaultMoonTicPath[] = TIC_LOCAL "default_moon.tic";
|
||||
static const char DefaultJSTicPath[] = TIC_LOCAL "default_js.tic";
|
||||
|
||||
static const char* getRomName(const char* name)
|
||||
static const char* getName(const char* name, const char* ext)
|
||||
{
|
||||
static char path[FILENAME_MAX];
|
||||
|
||||
strcpy(path, name);
|
||||
|
||||
size_t ps = strlen(path);
|
||||
size_t es = strlen(CartExt);
|
||||
size_t es = strlen(ext);
|
||||
|
||||
if(!(ps > es && strstr(path, CartExt) + es == path + ps))
|
||||
strcat(path, CartExt);
|
||||
if(!(ps > es && strstr(path, ext) + es == path + ps))
|
||||
strcat(path, ext);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static const char* getCartName(const char* name)
|
||||
{
|
||||
return getName(name, CART_EXT);
|
||||
}
|
||||
|
||||
static void scrollBuffer(char* buffer)
|
||||
{
|
||||
memmove(buffer, buffer + CONSOLE_BUFFER_WIDTH, CONSOLE_BUFFER_SIZE - CONSOLE_BUFFER_WIDTH);
|
||||
|
@ -288,7 +291,7 @@ static s32 writeGifData(const tic_mem* tic, u8* dst, const u8* src, s32 width, s
|
|||
|
||||
if(palette)
|
||||
{
|
||||
const tic_rgb* pal = tic->ram.vram.palette.colors;
|
||||
const tic_rgb* pal = tic->cart.palette.colors;
|
||||
for(s32 i = 0; i < TIC_PALETTE_SIZE; i++, pal++)
|
||||
palette[i].r = pal->r, palette[i].g = pal->g, palette[i].b = pal->b;
|
||||
|
||||
|
@ -337,13 +340,13 @@ static bool onConsoleLoadSectionCommand(Console* console, const char* param)
|
|||
|
||||
for(s32 i = 0; i < COUNT_OF(Sections); i++)
|
||||
{
|
||||
sprintf(buf, "%s %s", CartExt, Sections[i]);
|
||||
sprintf(buf, "%s %s", CART_EXT, Sections[i]);
|
||||
char* pos = SDL_strstr(param, buf);
|
||||
|
||||
if(pos)
|
||||
{
|
||||
pos[sizeof(CartExt) - 1] = 0;
|
||||
const char* name = getRomName(param);
|
||||
pos[sizeof(CART_EXT) - 1] = 0;
|
||||
const char* name = getCartName(param);
|
||||
s32 size = 0;
|
||||
void* data = fsLoadFile(console->fs, name, &size);
|
||||
|
||||
|
@ -475,7 +478,7 @@ static void onConsoleLoadDemoCommandConfirmed(Console* console, const char* para
|
|||
else if(strcmp(param, DefaultJSTicPath) == 0)
|
||||
data = getDemoCart(console, tic_script_js, &size);
|
||||
|
||||
const char* name = getRomName(param);
|
||||
const char* name = getCartName(param);
|
||||
|
||||
strcpy(console->romName, name);
|
||||
|
||||
|
@ -490,6 +493,302 @@ static void onConsoleLoadDemoCommandConfirmed(Console* console, const char* para
|
|||
SDL_free(data);
|
||||
}
|
||||
|
||||
static void onCartLoaded(Console* console, const char* name)
|
||||
{
|
||||
strcpy(console->romName, name);
|
||||
|
||||
studioRomLoaded();
|
||||
|
||||
printBack(console, "\ncart ");
|
||||
printFront(console, console->romName);
|
||||
printBack(console, " loaded!\nuse ");
|
||||
printFront(console, "RUN");
|
||||
printBack(console, " command to run it\n");
|
||||
|
||||
}
|
||||
|
||||
static bool hasExt(const char* name, const char* ext)
|
||||
{
|
||||
return strcmp(name + strlen(name) - strlen(ext), ext) == 0;
|
||||
}
|
||||
|
||||
#if defined(TIC80_PRO)
|
||||
|
||||
static bool hasProjectExt(const char* name)
|
||||
{
|
||||
return hasExt(name, PROJECT_LUA_EXT) || hasExt(name, PROJECT_MOON_EXT) || hasExt(name, PROJECT_JS_EXT);
|
||||
}
|
||||
|
||||
static const char* projectComment(const char* name)
|
||||
{
|
||||
return hasExt(name, PROJECT_JS_EXT) ? "//" : "--";
|
||||
}
|
||||
|
||||
static void buf2str(const void* data, s32 size, char* ptr, bool flip)
|
||||
{
|
||||
enum {Len = 2};
|
||||
|
||||
for(s32 i = 0; i < size; i++, ptr+=Len)
|
||||
{
|
||||
sprintf(ptr, "%02x", ((u8*)data)[i]);
|
||||
|
||||
if(flip)
|
||||
{
|
||||
char tmp = ptr[0];
|
||||
ptr[0] = ptr[1];
|
||||
ptr[1] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool bufferEmpty(const u8* data, s32 size)
|
||||
{
|
||||
for(s32 i = 0; i < size; i++)
|
||||
if(*data++)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static char* saveTextSection(char* ptr, const char* data)
|
||||
{
|
||||
if(strlen(data) == 0)
|
||||
return ptr;
|
||||
|
||||
sprintf(ptr, "%s\n", data);
|
||||
ptr += strlen(ptr);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static char* saveBinaryBuffer(char* ptr, const char* comment, const void* data, s32 size, s32 row, bool flip)
|
||||
{
|
||||
if(bufferEmpty(data, size))
|
||||
return ptr;
|
||||
|
||||
sprintf(ptr, "%s %03i:", comment, row);
|
||||
ptr += strlen(ptr);
|
||||
|
||||
buf2str(data, size, ptr, flip);
|
||||
ptr += strlen(ptr);
|
||||
|
||||
sprintf(ptr, "\n");
|
||||
ptr += strlen(ptr);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static char* saveBinarySection(char* ptr, const char* comment, const char* tag, s32 count, const void* data, s32 size, bool flip)
|
||||
{
|
||||
if(bufferEmpty(data, size * count))
|
||||
return ptr;
|
||||
|
||||
sprintf(ptr, "%s <%s>\n", comment, tag);
|
||||
ptr += strlen(ptr);
|
||||
|
||||
for(s32 i = 0; i < count; i++, data = (u8*)data + size)
|
||||
ptr = saveBinaryBuffer(ptr, comment, data, size, i, flip);
|
||||
|
||||
sprintf(ptr, "%s </%s>\n\n", comment, tag);
|
||||
ptr += strlen(ptr);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
typedef struct {char* tag; s32 count; s32 offset; s32 size; bool flip;} BinarySection;
|
||||
static const BinarySection BinarySections[] =
|
||||
{
|
||||
{"PALETTE", 1, offsetof(tic_cartridge, palette.data), sizeof(tic_palette), false},
|
||||
{"TILES", TIC_BANK_SPRITES, offsetof(tic_cartridge, gfx.tiles), sizeof(tic_tile), true},
|
||||
{"SPRITES", TIC_BANK_SPRITES, offsetof(tic_cartridge, gfx.sprites), sizeof(tic_tile), true},
|
||||
{"MAP", TIC_MAP_HEIGHT, offsetof(tic_cartridge, gfx.map), TIC_MAP_WIDTH, true},
|
||||
{"WAVES", ENVELOPES_COUNT, offsetof(tic_cartridge,sound.sfx.waveform.envelopes), sizeof(tic_waveform), true},
|
||||
{"SFX", SFX_COUNT, offsetof(tic_cartridge, sound.sfx.data), sizeof(tic_sound_effect), true},
|
||||
{"PATTERNS", MUSIC_PATTERNS, offsetof(tic_cartridge, sound.music.patterns), sizeof(tic_track_pattern), true},
|
||||
{"TRACKS", MUSIC_TRACKS, offsetof(tic_cartridge, sound.music.tracks), sizeof(tic_track), true},
|
||||
};
|
||||
|
||||
static s32 saveProject(Console* console, void* buffer, const char* comment)
|
||||
{
|
||||
tic_mem* tic = console->tic;
|
||||
|
||||
char* stream = buffer;
|
||||
char* ptr = saveTextSection(stream, tic->cart.code.data);
|
||||
|
||||
for(s32 i = 0; i < COUNT_OF(BinarySections); i++)
|
||||
{
|
||||
const BinarySection* section = &BinarySections[i];
|
||||
ptr = saveBinarySection(ptr, comment, section->tag, section->count, (u8*)&tic->cart + section->offset, section->size, section->flip);
|
||||
}
|
||||
|
||||
saveBinarySection(ptr, comment, "COVER", 1, &tic->cart.cover, tic->cart.cover.size + sizeof(s32), true);
|
||||
|
||||
return strlen(stream);
|
||||
}
|
||||
|
||||
static bool loadTextSection(const char* project, const char* comment, void* dst, s32 size)
|
||||
{
|
||||
bool done = false;
|
||||
|
||||
const char* start = project;
|
||||
const char* end = project + strlen(project);
|
||||
|
||||
{
|
||||
char tagbuf[64];
|
||||
|
||||
for(s32 i = 0; i < COUNT_OF(BinarySections); i++)
|
||||
{
|
||||
sprintf(tagbuf, "\n%s <%s>\n", comment, BinarySections[i].tag);
|
||||
|
||||
const char* ptr = SDL_strstr(project, tagbuf);
|
||||
|
||||
if(ptr && ptr < end)
|
||||
end = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
if(end > start)
|
||||
{
|
||||
SDL_memcpy(dst, start, SDL_min(size, end - start));
|
||||
done = true;
|
||||
}
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
static bool loadBinarySection(const char* project, const char* comment, const char* tag, s32 count, void* dst, s32 size, bool flip)
|
||||
{
|
||||
char tagbuf[64];
|
||||
sprintf(tagbuf, "%s <%s>\n", comment, tag);
|
||||
|
||||
const char* start = SDL_strstr(project, tagbuf);
|
||||
bool done = false;
|
||||
|
||||
if(start)
|
||||
{
|
||||
start += strlen(tagbuf);
|
||||
|
||||
sprintf(tagbuf, "\n%s </%s>", comment, tag);
|
||||
const char* end = SDL_strstr(start, tagbuf);
|
||||
|
||||
if(end > start)
|
||||
{
|
||||
const char* ptr = start;
|
||||
|
||||
if(size > 0)
|
||||
{
|
||||
while(ptr < end)
|
||||
{
|
||||
static char lineStr[] = "999";
|
||||
memcpy(lineStr, ptr + sizeof("-- ") - 1, sizeof lineStr - 1);
|
||||
|
||||
s32 index = SDL_atoi(lineStr);
|
||||
|
||||
if(index < count)
|
||||
{
|
||||
ptr += sizeof("-- 999:") - 1;
|
||||
str2buf(ptr, size*2, (u8*)dst + size*index, flip);
|
||||
ptr += size*2 + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr += sizeof("-- 999:") - 1;
|
||||
str2buf(ptr, end - ptr, (u8*)dst, flip);
|
||||
}
|
||||
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
static bool loadProject(Console* console, const char* name, const char* data, s32 size, tic_cartridge* dst)
|
||||
{
|
||||
tic_mem* tic = console->tic;
|
||||
|
||||
char* project = (char*)SDL_malloc(size+1);
|
||||
|
||||
bool done = false;
|
||||
|
||||
if(project)
|
||||
{
|
||||
SDL_memcpy(project, data, size);
|
||||
project[size] = '\0';
|
||||
|
||||
// remove all the '\r' chars
|
||||
{
|
||||
char *s, *d;
|
||||
for(s = d = project; (*d = *s); d += (*s++ != '\r'));
|
||||
}
|
||||
|
||||
tic_cartridge* cart = (tic_cartridge*)SDL_malloc(sizeof(tic_cartridge));
|
||||
|
||||
if(cart)
|
||||
{
|
||||
SDL_memset(cart, 0, sizeof(tic_cartridge));
|
||||
SDL_memcpy(&cart->palette, &tic->config.palette.data, sizeof(tic_palette));
|
||||
|
||||
const char* comment = projectComment(name);
|
||||
|
||||
if(loadTextSection(project, comment, cart->code.data, sizeof(tic_code)))
|
||||
done = true;
|
||||
|
||||
for(s32 i = 0; i < COUNT_OF(BinarySections); i++)
|
||||
{
|
||||
const BinarySection* section = &BinarySections[i];
|
||||
if(loadBinarySection(project, comment, section->tag, section->count, (u8*)cart + section->offset, section->size, section->flip))
|
||||
done = true;
|
||||
}
|
||||
|
||||
if(loadBinarySection(project, comment, "COVER", 1, &cart->cover, -1, true))
|
||||
done = true;
|
||||
|
||||
SDL_memcpy(dst, cart, sizeof(tic_cartridge));
|
||||
|
||||
SDL_free(cart);
|
||||
}
|
||||
|
||||
SDL_free(project);
|
||||
}
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
static void updateProject(Console* console)
|
||||
{
|
||||
tic_mem* tic = console->tic;
|
||||
|
||||
if(strlen(console->romName) && hasProjectExt(console->romName))
|
||||
{
|
||||
s32 size = 0;
|
||||
void* data = fsLoadFile(console->fs, console->romName, &size);
|
||||
|
||||
if(data)
|
||||
{
|
||||
tic_cartridge* cart = SDL_malloc(sizeof(tic_cartridge));
|
||||
|
||||
if(cart)
|
||||
{
|
||||
if(loadProject(console, console->romName, data, size, cart))
|
||||
{
|
||||
SDL_memcpy(&tic->cart, cart, sizeof(tic_cartridge));
|
||||
|
||||
studioRomLoaded();
|
||||
}
|
||||
|
||||
SDL_free(cart);
|
||||
}
|
||||
SDL_free(data);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void onConsoleLoadCommandConfirmed(Console* console, const char* param)
|
||||
{
|
||||
if(onConsoleLoadSectionCommand(console, param)) return;
|
||||
|
@ -497,7 +796,7 @@ static void onConsoleLoadCommandConfirmed(Console* console, const char* param)
|
|||
if(param)
|
||||
{
|
||||
s32 size = 0;
|
||||
const char* name = getRomName(param);
|
||||
const char* name = getCartName(param);
|
||||
|
||||
void* data = strcmp(name, CONFIG_TIC_PATH) == 0
|
||||
? fsLoadRootFile(console->fs, name, &size)
|
||||
|
@ -507,21 +806,40 @@ static void onConsoleLoadCommandConfirmed(Console* console, const char* param)
|
|||
{
|
||||
console->showGameMenu = fsIsInPublicDir(console->fs);
|
||||
|
||||
strcpy(console->romName, name);
|
||||
|
||||
loadRom(console->tic, data, size, true);
|
||||
|
||||
studioRomLoaded();
|
||||
|
||||
printBack(console, "\ncart ");
|
||||
printFront(console, console->romName);
|
||||
printBack(console, " loaded!\nuse ");
|
||||
printFront(console, "RUN");
|
||||
printBack(console, " command to run it\n");
|
||||
onCartLoaded(console, name);
|
||||
|
||||
SDL_free(data);
|
||||
}
|
||||
else printBack(console, "\ncart loading error");
|
||||
else
|
||||
{
|
||||
#if defined(TIC80_PRO)
|
||||
const char* name = getName(param, PROJECT_LUA_EXT);
|
||||
|
||||
if(!fsExistsFile(console->fs, name))
|
||||
name = getName(param, PROJECT_MOON_EXT);
|
||||
|
||||
if(!fsExistsFile(console->fs, name))
|
||||
name = getName(param, PROJECT_JS_EXT);
|
||||
|
||||
void* data = fsLoadFile(console->fs, name, &size);
|
||||
|
||||
if(data)
|
||||
{
|
||||
loadProject(console, name, data, size, &console->tic->cart);
|
||||
onCartLoaded(console, name);
|
||||
|
||||
SDL_free(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
printBack(console, "\ncart loading error");
|
||||
}
|
||||
#else
|
||||
printBack(console, "\ncart loading error");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else printBack(console, "\ncart name is missing");
|
||||
|
||||
|
@ -676,6 +994,7 @@ typedef struct
|
|||
|
||||
static bool printFilename(const char* name, const char* info, s32 id, void* data, bool dir)
|
||||
{
|
||||
|
||||
PrintFileNameData* printData = data;
|
||||
Console* console = printData->console;
|
||||
|
||||
|
@ -683,6 +1002,7 @@ static bool printFilename(const char* name, const char* info, s32 id, void* data
|
|||
|
||||
if(dir)
|
||||
{
|
||||
|
||||
printBack(console, "[");
|
||||
printBack(console, name);
|
||||
printBack(console, "]");
|
||||
|
@ -819,18 +1139,24 @@ static void onConsoleInstallDemosCommand(Console* console, const char* param)
|
|||
#include "../bin/assets/tetris.tic.dat"
|
||||
};
|
||||
|
||||
static const u8 Benchmark[] =
|
||||
{
|
||||
#include "../bin/assets/benchmark.tic.dat"
|
||||
};
|
||||
|
||||
FileSystem* fs = console->fs;
|
||||
|
||||
static const struct {const char* name; const u8* data; s32 size;} Demos[] =
|
||||
{
|
||||
{"fire.tic", DemoFire, sizeof DemoFire},
|
||||
{"font.tic", DemoFont, sizeof DemoFont},
|
||||
{"music.tic", DemoMusic, sizeof DemoMusic},
|
||||
{"p3d.tic", DemoP3D, sizeof DemoP3D},
|
||||
{"palette.tic", DemoPalette, sizeof DemoPalette},
|
||||
{"quest.tic", GameQuest, sizeof GameQuest},
|
||||
{"sfx.tic", DemoSFX, sizeof DemoSFX},
|
||||
{"tetris.tic", GameTetris, sizeof GameTetris},
|
||||
{"fire.tic", DemoFire, sizeof DemoFire},
|
||||
{"font.tic", DemoFont, sizeof DemoFont},
|
||||
{"music.tic", DemoMusic, sizeof DemoMusic},
|
||||
{"p3d.tic", DemoP3D, sizeof DemoP3D},
|
||||
{"palette.tic", DemoPalette, sizeof DemoPalette},
|
||||
{"quest.tic", GameQuest, sizeof GameQuest},
|
||||
{"sfx.tic", DemoSFX, sizeof DemoSFX},
|
||||
{"tetris.tic", GameTetris, sizeof GameTetris},
|
||||
{"benchmark.tic", Benchmark, sizeof Benchmark},
|
||||
};
|
||||
|
||||
printBack(console, "\nadded carts:\n\n");
|
||||
|
@ -852,12 +1178,26 @@ static void onConsoleSurfCommand(Console* console, const char* param)
|
|||
commandDone(console);
|
||||
}
|
||||
|
||||
static void onConsoleCodeCommand(Console* console, const char* param)
|
||||
{
|
||||
gotoCode();
|
||||
commandDone(console);
|
||||
}
|
||||
|
||||
|
||||
static void onConsoleKeymapCommand(Console* console, const char* param)
|
||||
{
|
||||
setStudioMode(TIC_KEYMAP_MODE);
|
||||
commandDone(console);
|
||||
}
|
||||
|
||||
static void onConsoleVersionCommand(Console* console, const char* param)
|
||||
{
|
||||
printBack(console, "\n");
|
||||
consolePrint(console, TIC_VERSION_LABEL, CONSOLE_BACK_TEXT_COLOR);
|
||||
commandDone(console);
|
||||
}
|
||||
|
||||
static void onConsoleConfigCommand(Console* console, const char* param)
|
||||
{
|
||||
if(param == NULL)
|
||||
|
@ -891,13 +1231,6 @@ static void onConsoleConfigCommand(Console* console, const char* param)
|
|||
commandDone(console);
|
||||
}
|
||||
|
||||
static s32 saveRom(tic_mem* tic, void* buffer)
|
||||
{
|
||||
s32 size = tic->api.save(&tic->cart, buffer);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static void onFileDownloaded(GetResult result, void* data)
|
||||
{
|
||||
Console* console = (Console*)data;
|
||||
|
@ -1153,7 +1486,7 @@ static void exportMap(Console* console)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(__EMSCRIPTEN__) || defined(__ARM_LINUX__)
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
|
||||
static void onConsoleExportCommand(Console* console, const char* param)
|
||||
{
|
||||
|
@ -1231,6 +1564,8 @@ static void writeMemoryString(MemoryBuffer* memory, const char* str)
|
|||
|
||||
static void onConsoleExportHtmlCommand(Console* console, const char* name)
|
||||
{
|
||||
tic_mem* tic = console->tic;
|
||||
|
||||
char cartName[FILENAME_MAX];
|
||||
strcpy(cartName, name);
|
||||
|
||||
|
@ -1272,43 +1607,46 @@ static void onConsoleExportHtmlCommand(Console* console, const char* name)
|
|||
{
|
||||
writeMemoryString(&output, "var cartridge = [");
|
||||
|
||||
s32 size = saveRom(console->tic, buffer);
|
||||
s32 size = tic->api.save(&tic->cart, buffer);
|
||||
|
||||
// zip buffer
|
||||
if(size)
|
||||
{
|
||||
unsigned long outSize = sizeof(tic_cartridge);
|
||||
u8* output = (u8*)SDL_malloc(outSize);
|
||||
// zip buffer
|
||||
{
|
||||
unsigned long outSize = sizeof(tic_cartridge);
|
||||
u8* output = (u8*)SDL_malloc(outSize);
|
||||
|
||||
compress2(output, &outSize, buffer, size, Z_BEST_COMPRESSION);
|
||||
SDL_free(buffer);
|
||||
|
||||
buffer = output;
|
||||
size = outSize;
|
||||
}
|
||||
|
||||
{
|
||||
u8* ptr = buffer;
|
||||
u8* end = ptr + size;
|
||||
|
||||
char value[] = "999,";
|
||||
while(ptr != end)
|
||||
{
|
||||
sprintf(value, "%i,", *ptr++);
|
||||
writeMemoryString(&output, value);
|
||||
}
|
||||
}
|
||||
|
||||
compress2(output, &outSize, buffer, size, Z_BEST_COMPRESSION);
|
||||
SDL_free(buffer);
|
||||
|
||||
buffer = output;
|
||||
size = outSize;
|
||||
writeMemoryString(&output, "];\n");
|
||||
|
||||
writeMemoryData(&output, EmbedTicJs, EmbedTicJsSize);
|
||||
writeMemoryString(&output, "</script>\n");
|
||||
|
||||
ptr += sizeof(Placeholder)-1;
|
||||
writeMemoryData(&output, ptr, EmbedIndexSize - (ptr - EmbedIndex));
|
||||
|
||||
fsGetFileData(onFileDownloaded, cartName, output.data, output.size, DEFAULT_CHMOD, console);
|
||||
}
|
||||
|
||||
{
|
||||
u8* ptr = buffer;
|
||||
u8* end = ptr + size;
|
||||
|
||||
char value[] = "999,";
|
||||
while(ptr != end)
|
||||
{
|
||||
sprintf(value, "%i,", *ptr++);
|
||||
writeMemoryString(&output, value);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free(buffer);
|
||||
|
||||
writeMemoryString(&output, "];\n");
|
||||
|
||||
writeMemoryData(&output, EmbedTicJs, EmbedTicJsSize);
|
||||
writeMemoryString(&output, "</script>\n");
|
||||
|
||||
ptr += sizeof(Placeholder)-1;
|
||||
writeMemoryData(&output, ptr, EmbedIndexSize - (ptr - EmbedIndex));
|
||||
|
||||
fsGetFileData(onFileDownloaded, cartName, output.data, output.size, DEFAULT_CHMOD, console);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1321,6 +1659,8 @@ static void onConsoleExportHtmlCommand(Console* console, const char* name)
|
|||
|
||||
static void* embedCart(Console* console, s32* size)
|
||||
{
|
||||
tic_mem* tic = console->tic;
|
||||
|
||||
void* data = fsReadFile(console->appPath, size);
|
||||
|
||||
if(data)
|
||||
|
@ -1330,13 +1670,15 @@ static void* embedCart(Console* console, s32* size)
|
|||
if(start)
|
||||
{
|
||||
embed.yes = true;
|
||||
memcpy(&embed.file, &console->tic->cart, sizeof(tic_cartridge));
|
||||
memcpy(start, &embed, sizeof(embed));
|
||||
SDL_memcpy(&embed.file, &tic->cart, sizeof(tic_cartridge));
|
||||
SDL_memcpy(start, &embed, sizeof(embed));
|
||||
embed.yes = false;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
return data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
|
@ -1512,11 +1854,13 @@ static void onConsoleExportCommand(Console* console, const char* param)
|
|||
|
||||
static CartSaveResult saveCartName(Console* console, const char* name)
|
||||
{
|
||||
tic_mem* tic = console->tic;
|
||||
|
||||
bool success = false;
|
||||
|
||||
if(name && strlen(name))
|
||||
{
|
||||
u8* buffer = (u8*)SDL_malloc(sizeof(tic_cartridge));
|
||||
u8* buffer = (u8*)SDL_malloc(sizeof(tic_cartridge) * 3);
|
||||
|
||||
if(buffer)
|
||||
{
|
||||
|
@ -1529,16 +1873,25 @@ static CartSaveResult saveCartName(Console* console, const char* name)
|
|||
}
|
||||
else
|
||||
{
|
||||
s32 size = saveRom(console->tic, buffer);
|
||||
s32 size = 0;
|
||||
|
||||
name = getRomName(name);
|
||||
#if defined(TIC80_PRO)
|
||||
if(hasProjectExt(name))
|
||||
{
|
||||
size = saveProject(console, buffer, projectComment(name));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
name = getCartName(name);
|
||||
size = tic->api.save(&tic->cart, buffer);
|
||||
}
|
||||
|
||||
if(size && fsSaveFile(console->fs, name, buffer, size, true))
|
||||
{
|
||||
strcpy(console->romName, name);
|
||||
success = true;
|
||||
studioRomSaved();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1579,7 +1932,7 @@ static void onConsoleSaveCommandConfirmed(Console* console, const char* param)
|
|||
|
||||
static void onConsoleSaveCommand(Console* console, const char* param)
|
||||
{
|
||||
if(param && strlen(param) && fsExistsFile(console->fs, getRomName(param)))
|
||||
if(param && strlen(param) && fsExistsFile(console->fs, getCartName(param)))
|
||||
{
|
||||
static const char* Rows[] =
|
||||
{
|
||||
|
@ -1761,32 +2114,28 @@ static void onConsoleRamCommand(Console* console, const char* param)
|
|||
"\n| ADDR | INFO | SIZE |" \
|
||||
"\n+-------+-------------------+-------+");
|
||||
|
||||
#define ADDR_RECORD(addr, name) {(s32)((u8*)&addr - (u8*)console->tic), name}
|
||||
|
||||
const struct{s32 addr; const char* info;} Layout[] =
|
||||
static const struct{s32 addr; const char* info;} Layout[] =
|
||||
{
|
||||
ADDR_RECORD(console->tic->ram.vram.screen, "SCREEN"),
|
||||
ADDR_RECORD(console->tic->ram.vram.palette, "PALETTE"),
|
||||
ADDR_RECORD(console->tic->ram.vram.mapping, "PALETTE MAP"),
|
||||
ADDR_RECORD(console->tic->ram.vram.vars.border, "BORDER COLOR"),
|
||||
ADDR_RECORD(console->tic->ram.vram.vars.offset, "SCREEN OFFSET"),
|
||||
ADDR_RECORD(console->tic->ram.vram.vars.mask, "GAMEPAD MASK"),
|
||||
ADDR_RECORD(console->tic->ram.vram.input.gamepad, "GAMEPAD"),
|
||||
ADDR_RECORD(console->tic->ram.vram.input.reserved, "..."),
|
||||
ADDR_RECORD(console->tic->ram.gfx.tiles, "SPRITES"),
|
||||
ADDR_RECORD(console->tic->ram.gfx.map, "MAP"),
|
||||
ADDR_RECORD(console->tic->ram.persistent, "PERSISTENT MEMORY"),
|
||||
ADDR_RECORD(console->tic->ram.registers, "SOUND REGISTERS"),
|
||||
ADDR_RECORD(console->tic->ram.sound.sfx.waveform, "WAVEFORMS"),
|
||||
ADDR_RECORD(console->tic->ram.sound.sfx.data, "SFX"),
|
||||
ADDR_RECORD(console->tic->ram.sound.music.patterns.data, "MUSIC PATTERNS"),
|
||||
ADDR_RECORD(console->tic->ram.sound.music.tracks.data, "MUSIC TRACKS"),
|
||||
ADDR_RECORD(console->tic->ram.music_pos, "MUSIC POS"),
|
||||
{TIC_RAM_SIZE, "..."},
|
||||
{offsetof(tic_ram, vram.screen), "SCREEN"},
|
||||
{offsetof(tic_ram, vram.palette), "PALETTE"},
|
||||
{offsetof(tic_ram, vram.mapping), "PALETTE MAP"},
|
||||
{offsetof(tic_ram, vram.vars.colors), "BORDER/BG COLOR"},
|
||||
{offsetof(tic_ram, vram.vars.offset), "SCREEN OFFSET"},
|
||||
{offsetof(tic_ram, vram.vars.mask), "GAMEPAD MASK"},
|
||||
{offsetof(tic_ram, vram.input.gamepad), "GAMEPAD"},
|
||||
{offsetof(tic_ram, vram.input.reserved), "..."},
|
||||
{offsetof(tic_ram, gfx.tiles), "SPRITES"},
|
||||
{offsetof(tic_ram, gfx.map), "MAP"},
|
||||
{offsetof(tic_ram, persistent), "PERSISTENT MEMORY"},
|
||||
{offsetof(tic_ram, registers), "SOUND REGISTERS"},
|
||||
{offsetof(tic_ram, sound.sfx.waveform), "WAVEFORMS"},
|
||||
{offsetof(tic_ram, sound.sfx.data), "SFX"},
|
||||
{offsetof(tic_ram, sound.music.patterns.data), "MUSIC PATTERNS"},
|
||||
{offsetof(tic_ram, sound.music.tracks.data), "MUSIC TRACKS"},
|
||||
{offsetof(tic_ram, music_pos), "MUSIC POS"},
|
||||
{TIC_RAM_SIZE, "..."},
|
||||
};
|
||||
|
||||
#undef ADDR_RECORD
|
||||
|
||||
enum{Last = COUNT_OF(Layout)-1};
|
||||
|
||||
for(s32 i = 0; i < Last; i++)
|
||||
|
@ -1832,6 +2181,8 @@ static const struct
|
|||
{"demo", NULL, "install demo carts", onConsoleInstallDemosCommand},
|
||||
{"config", NULL, "edit TIC config", onConsoleConfigCommand},
|
||||
{"keymap", NULL, "configure keyboard mapping", onConsoleKeymapCommand},
|
||||
{"version", NULL, "show the current version", onConsoleVersionCommand},
|
||||
{"edit", NULL, "open cart editor", onConsoleCodeCommand},
|
||||
{"surf", NULL, "open carts browser", onConsoleSurfCommand},
|
||||
};
|
||||
|
||||
|
@ -2242,11 +2593,12 @@ static void tick(Console* console)
|
|||
printLine(console);
|
||||
commandDone(console);
|
||||
console->active = true;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
if(console->cursor.delay)
|
||||
console->cursor.delay--;
|
||||
|
||||
|
@ -2256,6 +2608,12 @@ static void tick(Console* console)
|
|||
}
|
||||
|
||||
console->tickCounter++;
|
||||
|
||||
if(console->startSurf)
|
||||
{
|
||||
console->startSurf = false;
|
||||
gotoSurf();
|
||||
}
|
||||
}
|
||||
|
||||
static void cmdLoadCart(Console* console, const char* name)
|
||||
|
@ -2265,9 +2623,24 @@ static void cmdLoadCart(Console* console, const char* name)
|
|||
|
||||
if(data)
|
||||
{
|
||||
loadCart(console->tic, &embed.file, data, size, true);
|
||||
embed.yes = true;
|
||||
#if defined(TIC80_PRO)
|
||||
if(hasProjectExt(name))
|
||||
{
|
||||
loadProject(console, name, data, size, &embed.file);
|
||||
strcpy(console->romName, fsFilename(name));
|
||||
embed.yes = true;
|
||||
embed.fast = true;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if(hasExt(name, CART_EXT))
|
||||
{
|
||||
loadCart(console->tic, &embed.file, data, size, true);
|
||||
strcpy(console->romName, fsFilename(name));
|
||||
embed.yes = true;
|
||||
}
|
||||
|
||||
SDL_free(data);
|
||||
}
|
||||
}
|
||||
|
@ -2292,9 +2665,6 @@ static bool loadFileIntoBuffer(Console* console, char* buffer, const char* fileN
|
|||
memcpy(buffer, contents, SDL_min(size, TIC_CODE_SIZE-1));
|
||||
SDL_free(contents);
|
||||
|
||||
embed.yes = true;
|
||||
embed.fast = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2408,6 +2778,14 @@ void initConsole(Console* console, tic_mem* tic, FileSystem* fs, Config* config,
|
|||
.tic = tic,
|
||||
.config = config,
|
||||
.load = onConsoleLoadCommandConfirmed,
|
||||
|
||||
#if defined(TIC80_PRO)
|
||||
.loadProject = loadProject,
|
||||
.updateProject = updateProject,
|
||||
#else
|
||||
.loadProject = NULL,
|
||||
.updateProject = NULL,
|
||||
#endif
|
||||
.error = error,
|
||||
.trace = trace,
|
||||
.tick = tick,
|
||||
|
@ -2433,6 +2811,7 @@ void initConsole(Console* console, tic_mem* tic, FileSystem* fs, Config* config,
|
|||
.colorBuffer = console->colorBuffer,
|
||||
.fs = fs,
|
||||
.showGameMenu = false,
|
||||
.startSurf = false,
|
||||
};
|
||||
|
||||
memset(console->buffer, 0, CONSOLE_BUFFER_SIZE);
|
||||
|
@ -2476,6 +2855,14 @@ void initConsole(Console* console, tic_mem* tic, FileSystem* fs, Config* config,
|
|||
cmdInjectMap(console, argv[i], argv[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
for (s32 i = 1; i < argc; i++)
|
||||
{
|
||||
if(strcmp(argv[i], "-nosound") == 0)
|
||||
config->data.noSound = true;
|
||||
else if(strcmp(argv[i], "-surf") == 0)
|
||||
console->startSurf = true;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
|
|
|
@ -88,8 +88,11 @@ struct Console
|
|||
u32 tickCounter;
|
||||
bool active;
|
||||
bool showGameMenu;
|
||||
bool startSurf;
|
||||
|
||||
void(*load)(Console*, const char* name);
|
||||
bool(*loadProject)(Console*, const char* name, const char* data, s32 size, tic_cartridge* dst);
|
||||
void(*updateProject)(Console*);
|
||||
void(*error)(Console*, const char*);
|
||||
void(*trace)(Console*, const char*, u8 color);
|
||||
void(*tick)(Console*);
|
||||
|
|
|
@ -191,13 +191,6 @@ void file_dialog_save(file_dialog_save_callback callback, const char* name, cons
|
|||
|
||||
#elif defined(__LINUX__)
|
||||
|
||||
#if defined(__ARM_LINUX__)
|
||||
|
||||
void file_dialog_load(file_dialog_load_callback callback, void* data) {}
|
||||
void file_dialog_save(file_dialog_save_callback callback, const char* name, const u8* buffer, size_t size, void* data, u32 mode) {}
|
||||
|
||||
#else
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
@ -306,8 +299,6 @@ void file_dialog_save(file_dialog_save_callback callback, const char* name, cons
|
|||
callback(false, data);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#elif defined(__MACOSX__)
|
||||
|
||||
#include <string.h>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,97 @@
|
|||
/*****************************************************************************
|
||||
|
||||
gif_err.c - handle error reporting for the GIF library.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "gif_lib.h"
|
||||
#include "gif_lib_private.h"
|
||||
|
||||
/*****************************************************************************
|
||||
Return a string description of the last GIF error
|
||||
*****************************************************************************/
|
||||
const char *
|
||||
GifErrorString(int ErrorCode)
|
||||
{
|
||||
const char *Err;
|
||||
|
||||
switch (ErrorCode) {
|
||||
case E_GIF_ERR_OPEN_FAILED:
|
||||
Err = "Failed to open given file";
|
||||
break;
|
||||
case E_GIF_ERR_WRITE_FAILED:
|
||||
Err = "Failed to write to given file";
|
||||
break;
|
||||
case E_GIF_ERR_HAS_SCRN_DSCR:
|
||||
Err = "Screen descriptor has already been set";
|
||||
break;
|
||||
case E_GIF_ERR_HAS_IMAG_DSCR:
|
||||
Err = "Image descriptor is still active";
|
||||
break;
|
||||
case E_GIF_ERR_NO_COLOR_MAP:
|
||||
Err = "Neither global nor local color map";
|
||||
break;
|
||||
case E_GIF_ERR_DATA_TOO_BIG:
|
||||
Err = "Number of pixels bigger than width * height";
|
||||
break;
|
||||
case E_GIF_ERR_NOT_ENOUGH_MEM:
|
||||
Err = "Failed to allocate required memory";
|
||||
break;
|
||||
case E_GIF_ERR_DISK_IS_FULL:
|
||||
Err = "Write failed (disk full?)";
|
||||
break;
|
||||
case E_GIF_ERR_CLOSE_FAILED:
|
||||
Err = "Failed to close given file";
|
||||
break;
|
||||
case E_GIF_ERR_NOT_WRITEABLE:
|
||||
Err = "Given file was not opened for write";
|
||||
break;
|
||||
case D_GIF_ERR_OPEN_FAILED:
|
||||
Err = "Failed to open given file";
|
||||
break;
|
||||
case D_GIF_ERR_READ_FAILED:
|
||||
Err = "Failed to read from given file";
|
||||
break;
|
||||
case D_GIF_ERR_NOT_GIF_FILE:
|
||||
Err = "Data is not in GIF format";
|
||||
break;
|
||||
case D_GIF_ERR_NO_SCRN_DSCR:
|
||||
Err = "No screen descriptor detected";
|
||||
break;
|
||||
case D_GIF_ERR_NO_IMAG_DSCR:
|
||||
Err = "No Image Descriptor detected";
|
||||
break;
|
||||
case D_GIF_ERR_NO_COLOR_MAP:
|
||||
Err = "Neither global nor local color map";
|
||||
break;
|
||||
case D_GIF_ERR_WRONG_RECORD:
|
||||
Err = "Wrong record type detected";
|
||||
break;
|
||||
case D_GIF_ERR_DATA_TOO_BIG:
|
||||
Err = "Number of pixels bigger than width * height";
|
||||
break;
|
||||
case D_GIF_ERR_NOT_ENOUGH_MEM:
|
||||
Err = "Failed to allocate required memory";
|
||||
break;
|
||||
case D_GIF_ERR_CLOSE_FAILED:
|
||||
Err = "Failed to close given file";
|
||||
break;
|
||||
case D_GIF_ERR_NOT_READABLE:
|
||||
Err = "Given file was not opened for read";
|
||||
break;
|
||||
case D_GIF_ERR_IMAGE_DEFECT:
|
||||
Err = "Image is defective, decoding aborted";
|
||||
break;
|
||||
case D_GIF_ERR_EOF_TOO_SOON:
|
||||
Err = "Image EOF detected before image complete";
|
||||
break;
|
||||
default:
|
||||
Err = NULL;
|
||||
break;
|
||||
}
|
||||
return Err;
|
||||
}
|
||||
|
||||
/* end */
|
|
@ -0,0 +1,259 @@
|
|||
/*****************************************************************************
|
||||
|
||||
gif_font.c - utility font handling and simple drawing for the GIF library
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gif_lib.h"
|
||||
|
||||
/*****************************************************************************
|
||||
Ascii 8 by 8 regular font - only first 128 characters are supported.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Each array entry holds the bits for 8 horizontal scan lines, topmost
|
||||
* first. The most significant bit of each constant is the leftmost bit of
|
||||
* the scan line.
|
||||
*/
|
||||
/*@+charint@*/
|
||||
const unsigned char GifAsciiTable8x8[][GIF_FONT_WIDTH] = {
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Ascii 0 */
|
||||
{0x3c, 0x42, 0xa5, 0x81, 0xbd, 0x42, 0x3c, 0x00}, /* Ascii 1 */
|
||||
{0x3c, 0x7e, 0xdb, 0xff, 0xc3, 0x7e, 0x3c, 0x00}, /* Ascii 2 */
|
||||
{0x00, 0xee, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00}, /* Ascii 3 */
|
||||
{0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00}, /* Ascii 4 */
|
||||
{0x00, 0x3c, 0x18, 0xff, 0xff, 0x08, 0x18, 0x00}, /* Ascii 5 */
|
||||
{0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x10, 0x38, 0x00}, /* Ascii 6 */
|
||||
{0x00, 0x00, 0x18, 0x3c, 0x18, 0x00, 0x00, 0x00}, /* Ascii 7 */
|
||||
{0xff, 0xff, 0xe7, 0xc3, 0xe7, 0xff, 0xff, 0xff}, /* Ascii 8 */
|
||||
{0x00, 0x3c, 0x42, 0x81, 0x81, 0x42, 0x3c, 0x00}, /* Ascii 9 */
|
||||
{0xff, 0xc3, 0xbd, 0x7e, 0x7e, 0xbd, 0xc3, 0xff}, /* Ascii 10 */
|
||||
{0x1f, 0x07, 0x0d, 0x7c, 0xc6, 0xc6, 0x7c, 0x00}, /* Ascii 11 */
|
||||
{0x00, 0x7e, 0xc3, 0xc3, 0x7e, 0x18, 0x7e, 0x18}, /* Ascii 12 */
|
||||
{0x04, 0x06, 0x07, 0x04, 0x04, 0xfc, 0xf8, 0x00}, /* Ascii 13 */
|
||||
{0x0c, 0x0a, 0x0d, 0x0b, 0xf9, 0xf9, 0x1f, 0x1f}, /* Ascii 14 */
|
||||
{0x00, 0x92, 0x7c, 0x44, 0xc6, 0x7c, 0x92, 0x00}, /* Ascii 15 */
|
||||
{0x00, 0x00, 0x60, 0x78, 0x7e, 0x78, 0x60, 0x00}, /* Ascii 16 */
|
||||
{0x00, 0x00, 0x06, 0x1e, 0x7e, 0x1e, 0x06, 0x00}, /* Ascii 17 */
|
||||
{0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x18}, /* Ascii 18 */
|
||||
{0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00}, /* Ascii 19 */
|
||||
{0xff, 0xb6, 0x76, 0x36, 0x36, 0x36, 0x36, 0x00}, /* Ascii 20 */
|
||||
{0x7e, 0xc1, 0xdc, 0x22, 0x22, 0x1f, 0x83, 0x7e}, /* Ascii 21 */
|
||||
{0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00}, /* Ascii 22 */
|
||||
{0x18, 0x7e, 0x18, 0x18, 0x7e, 0x18, 0x00, 0xff}, /* Ascii 23 */
|
||||
{0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00}, /* Ascii 24 */
|
||||
{0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x00}, /* Ascii 25 */
|
||||
{0x00, 0x04, 0x06, 0xff, 0x06, 0x04, 0x00, 0x00}, /* Ascii 26 */
|
||||
{0x00, 0x20, 0x60, 0xff, 0x60, 0x20, 0x00, 0x00}, /* Ascii 27 */
|
||||
{0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0x00}, /* Ascii 28 */
|
||||
{0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00}, /* Ascii 29 */
|
||||
{0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x00, 0x00}, /* Ascii 30 */
|
||||
{0x00, 0x00, 0x00, 0xfe, 0x7c, 0x38, 0x10, 0x00}, /* Ascii 31 */
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* */
|
||||
{0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x30, 0x00}, /* ! */
|
||||
{0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* " */
|
||||
{0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00}, /* # */
|
||||
{0x10, 0x7c, 0xd2, 0x7c, 0x86, 0x7c, 0x10, 0x00}, /* $ */
|
||||
{0xf0, 0x96, 0xfc, 0x18, 0x3e, 0x72, 0xde, 0x00}, /* % */
|
||||
{0x30, 0x48, 0x30, 0x78, 0xce, 0xcc, 0x78, 0x00}, /* & */
|
||||
{0x0c, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ' */
|
||||
{0x10, 0x60, 0xc0, 0xc0, 0xc0, 0x60, 0x10, 0x00}, /* ( */
|
||||
{0x10, 0x0c, 0x06, 0x06, 0x06, 0x0c, 0x10, 0x00}, /* ) */
|
||||
{0x00, 0x54, 0x38, 0xfe, 0x38, 0x54, 0x00, 0x00}, /* * */
|
||||
{0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00}, /* + */
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x70}, /* , */
|
||||
{0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00}, /* - */
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00}, /* . */
|
||||
{0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00}, /* / */
|
||||
{0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00}, /* 0 */
|
||||
{0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x3c, 0x00}, /* 1 */
|
||||
{0x7c, 0xc6, 0x06, 0x0c, 0x30, 0x60, 0xfe, 0x00}, /* 2 */
|
||||
{0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00}, /* 3 */
|
||||
{0x0e, 0x1e, 0x36, 0x66, 0xfe, 0x06, 0x06, 0x00}, /* 4 */
|
||||
{0xfe, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xfc, 0x00}, /* 5 */
|
||||
{0x7c, 0xc6, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x00}, /* 6 */
|
||||
{0xfe, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x60, 0x00}, /* 7 */
|
||||
{0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0x00}, /* 8 */
|
||||
{0x7c, 0xc6, 0xc6, 0x7e, 0x06, 0xc6, 0x7c, 0x00}, /* 9 */
|
||||
{0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00}, /* : */
|
||||
{0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x20, 0x00}, /* }, */
|
||||
{0x00, 0x1c, 0x30, 0x60, 0x30, 0x1c, 0x00, 0x00}, /* < */
|
||||
{0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00}, /* = */
|
||||
{0x00, 0x70, 0x18, 0x0c, 0x18, 0x70, 0x00, 0x00}, /* > */
|
||||
{0x7c, 0xc6, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00}, /* ? */
|
||||
{0x7c, 0x82, 0x9a, 0xaa, 0xaa, 0x9e, 0x7c, 0x00}, /* @ */
|
||||
{0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00}, /* A */
|
||||
{0xfc, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, 0x00}, /* B */
|
||||
{0x7c, 0xc6, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00}, /* C */
|
||||
{0xf8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0xf8, 0x00}, /* D */
|
||||
{0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xfe, 0x00}, /* E */
|
||||
{0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0x00}, /* F */
|
||||
{0x7c, 0xc6, 0xc0, 0xce, 0xc6, 0xc6, 0x7e, 0x00}, /* G */
|
||||
{0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00}, /* H */
|
||||
{0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00}, /* I */
|
||||
{0x1e, 0x06, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00}, /* J */
|
||||
{0xc6, 0xcc, 0xd8, 0xf0, 0xd8, 0xcc, 0xc6, 0x00}, /* K */
|
||||
{0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00}, /* L */
|
||||
{0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0x00}, /* M */
|
||||
{0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00}, /* N */
|
||||
{0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00}, /* O */
|
||||
{0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0x00}, /* P */
|
||||
{0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x06}, /* Q */
|
||||
{0xfc, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xc6, 0x00}, /* R */
|
||||
{0x78, 0xcc, 0x60, 0x30, 0x18, 0xcc, 0x78, 0x00}, /* S */
|
||||
{0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00}, /* T */
|
||||
{0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00}, /* U */
|
||||
{0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00}, /* V */
|
||||
{0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00}, /* W */
|
||||
{0xc6, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0xc6, 0x00}, /* X */
|
||||
{0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00}, /* Y */
|
||||
{0xfe, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xfe, 0x00}, /* Z */
|
||||
{0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00}, /* [ */
|
||||
{0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x00}, /* \ */
|
||||
{0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00}, /* ] */
|
||||
{0x00, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00}, /* ^ */
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}, /* _ */
|
||||
{0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ` */
|
||||
{0x00, 0x00, 0x7c, 0x06, 0x7e, 0xc6, 0x7e, 0x00}, /* a */
|
||||
{0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xe6, 0xdc, 0x00}, /* b */
|
||||
{0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0x7e, 0x00}, /* c */
|
||||
{0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xce, 0x76, 0x00}, /* d */
|
||||
{0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7e, 0x00}, /* e */
|
||||
{0x1e, 0x30, 0x7c, 0x30, 0x30, 0x30, 0x30, 0x00}, /* f */
|
||||
{0x00, 0x00, 0x7e, 0xc6, 0xce, 0x76, 0x06, 0x7c}, /* g */
|
||||
{0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x00}, /* */
|
||||
{0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00}, /* i */
|
||||
{0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0xf0}, /* j */
|
||||
{0xc0, 0xc0, 0xcc, 0xd8, 0xf0, 0xd8, 0xcc, 0x00}, /* k */
|
||||
{0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00}, /* l */
|
||||
{0x00, 0x00, 0xcc, 0xfe, 0xd6, 0xc6, 0xc6, 0x00}, /* m */
|
||||
{0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x00}, /* n */
|
||||
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00}, /* o */
|
||||
{0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xe6, 0xdc, 0xc0}, /* p */
|
||||
{0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xce, 0x76, 0x06}, /* q */
|
||||
{0x00, 0x00, 0x6e, 0x70, 0x60, 0x60, 0x60, 0x00}, /* r */
|
||||
{0x00, 0x00, 0x7c, 0xc0, 0x7c, 0x06, 0xfc, 0x00}, /* s */
|
||||
{0x30, 0x30, 0x7c, 0x30, 0x30, 0x30, 0x1c, 0x00}, /* t */
|
||||
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00}, /* u */
|
||||
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00}, /* v */
|
||||
{0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xfe, 0x6c, 0x00}, /* w */
|
||||
{0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00}, /* x */
|
||||
{0x00, 0x00, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0x7c}, /* y */
|
||||
{0x00, 0x00, 0xfc, 0x18, 0x30, 0x60, 0xfc, 0x00}, /* z */
|
||||
{0x0e, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0e, 0x00}, /* { */
|
||||
{0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, /* | */
|
||||
{0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00}, /* } */
|
||||
{0x00, 0x00, 0x70, 0x9a, 0x0e, 0x00, 0x00, 0x00}, /* ~ */
|
||||
{0x00, 0x00, 0x18, 0x3c, 0x66, 0xff, 0x00, 0x00} /* Ascii 127 */
|
||||
};
|
||||
/*@=charint@*/
|
||||
|
||||
void
|
||||
GifDrawText8x8(SavedImage *Image,
|
||||
const int x, const int y,
|
||||
const char *legend,
|
||||
const int color)
|
||||
{
|
||||
int i, j;
|
||||
int base;
|
||||
const char *cp;
|
||||
|
||||
for (i = 0; i < GIF_FONT_HEIGHT; i++) {
|
||||
base = Image->ImageDesc.Width * (y + i) + x;
|
||||
|
||||
for (cp = legend; *cp; cp++)
|
||||
for (j = 0; j < GIF_FONT_WIDTH; j++) {
|
||||
if (GifAsciiTable8x8[(short)(*cp)][i] & (1 << (GIF_FONT_WIDTH - j)))
|
||||
Image->RasterBits[base] = color;
|
||||
base++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GifDrawBox(SavedImage *Image,
|
||||
const int x, const int y,
|
||||
const int w, const int d,
|
||||
const int color)
|
||||
{
|
||||
int j, base = Image->ImageDesc.Width * y + x;
|
||||
|
||||
for (j = 0; j < w; j++)
|
||||
Image->RasterBits[base + j] =
|
||||
Image->RasterBits[base + (d * Image->ImageDesc.Width) + j] = color;
|
||||
|
||||
for (j = 0; j < d; j++)
|
||||
Image->RasterBits[base + j * Image->ImageDesc.Width] =
|
||||
Image->RasterBits[base + j * Image->ImageDesc.Width + w] = color;
|
||||
}
|
||||
|
||||
void
|
||||
GifDrawRectangle(SavedImage *Image,
|
||||
const int x, const int y,
|
||||
const int w, const int d,
|
||||
const int color)
|
||||
{
|
||||
unsigned char *bp = Image->RasterBits + Image->ImageDesc.Width * y + x;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < d; i++)
|
||||
memset(bp + (i * Image->ImageDesc.Width), color, (size_t)w);
|
||||
}
|
||||
|
||||
void
|
||||
GifDrawBoxedText8x8(SavedImage *Image,
|
||||
const int x, const int y,
|
||||
const char *legend,
|
||||
const int border,
|
||||
const int bg, const int fg)
|
||||
{
|
||||
int j = 0, LineCount = 0, TextWidth = 0;
|
||||
const char *cp;
|
||||
char *dup;
|
||||
|
||||
/* compute size of text to box */
|
||||
for (cp = legend; *cp; cp++)
|
||||
if (*cp == '\r') {
|
||||
if (j > TextWidth)
|
||||
TextWidth = j;
|
||||
j = 0;
|
||||
LineCount++;
|
||||
} else if (*cp != '\t')
|
||||
++j;
|
||||
LineCount++; /* count last line */
|
||||
if (j > TextWidth) /* last line might be longer than any previous */
|
||||
TextWidth = j;
|
||||
|
||||
/* draw the text */
|
||||
dup = malloc(strlen(legend)+1);
|
||||
/* FIXME: should return bad status, but that would require API change */
|
||||
if (dup != NULL) {
|
||||
int i = 0;
|
||||
/* fill the box */
|
||||
GifDrawRectangle(Image, x + 1, y + 1,
|
||||
border + TextWidth * GIF_FONT_WIDTH + border - 1,
|
||||
border + LineCount * GIF_FONT_HEIGHT + border - 1, bg);
|
||||
(void)strcpy(dup, (char *)legend);
|
||||
cp = strtok((char *)dup, "\r\n");
|
||||
do {
|
||||
int leadspace = 0;
|
||||
|
||||
if (cp[0] == '\t')
|
||||
leadspace = (TextWidth - strlen(++cp)) / 2;
|
||||
|
||||
GifDrawText8x8(Image, x + border + (leadspace * GIF_FONT_WIDTH),
|
||||
y + border + (GIF_FONT_HEIGHT * i++), cp, fg);
|
||||
cp = strtok((char *)NULL, "\r\n");
|
||||
} while (cp);
|
||||
(void)free((void *)dup);
|
||||
|
||||
/* outline the box */
|
||||
GifDrawBox(Image, x, y, border + TextWidth * GIF_FONT_WIDTH + border,
|
||||
border + LineCount * GIF_FONT_HEIGHT + border, fg);
|
||||
}
|
||||
}
|
||||
|
||||
/* end */
|
|
@ -0,0 +1,131 @@
|
|||
/*****************************************************************************
|
||||
|
||||
gif_hash.c -- module to support the following operations:
|
||||
|
||||
1. InitHashTable - initialize hash table.
|
||||
2. ClearHashTable - clear the hash table to an empty state.
|
||||
2. InsertHashTable - insert one item into data structure.
|
||||
3. ExistsHashTable - test if item exists in data structure.
|
||||
|
||||
This module is used to hash the GIF codes during encoding.
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gif_lib.h"
|
||||
#include "gif_hash.h"
|
||||
#include "gif_lib_private.h"
|
||||
|
||||
/* #define DEBUG_HIT_RATE Debug number of misses per hash Insert/Exists. */
|
||||
|
||||
#ifdef DEBUG_HIT_RATE
|
||||
static long NumberOfTests = 0,
|
||||
NumberOfMisses = 0;
|
||||
#endif /* DEBUG_HIT_RATE */
|
||||
|
||||
static int KeyItem(uint32_t Item);
|
||||
|
||||
/******************************************************************************
|
||||
Initialize HashTable - allocate the memory needed and clear it. *
|
||||
******************************************************************************/
|
||||
GifHashTableType *_InitHashTable(void)
|
||||
{
|
||||
GifHashTableType *HashTable;
|
||||
|
||||
if ((HashTable = (GifHashTableType *) malloc(sizeof(GifHashTableType)))
|
||||
== NULL)
|
||||
return NULL;
|
||||
|
||||
_ClearHashTable(HashTable);
|
||||
|
||||
return HashTable;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Routine to clear the HashTable to an empty state. *
|
||||
This part is a little machine depended. Use the commented part otherwise. *
|
||||
******************************************************************************/
|
||||
void _ClearHashTable(GifHashTableType *HashTable)
|
||||
{
|
||||
memset(HashTable -> HTable, 0xFF, HT_SIZE * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Routine to insert a new Item into the HashTable. The data is assumed to be *
|
||||
new one. *
|
||||
******************************************************************************/
|
||||
void _InsertHashTable(GifHashTableType *HashTable, uint32_t Key, int Code)
|
||||
{
|
||||
int HKey = KeyItem(Key);
|
||||
uint32_t *HTable = HashTable -> HTable;
|
||||
|
||||
#ifdef DEBUG_HIT_RATE
|
||||
NumberOfTests++;
|
||||
NumberOfMisses++;
|
||||
#endif /* DEBUG_HIT_RATE */
|
||||
|
||||
while (HT_GET_KEY(HTable[HKey]) != 0xFFFFFL) {
|
||||
#ifdef DEBUG_HIT_RATE
|
||||
NumberOfMisses++;
|
||||
#endif /* DEBUG_HIT_RATE */
|
||||
HKey = (HKey + 1) & HT_KEY_MASK;
|
||||
}
|
||||
HTable[HKey] = HT_PUT_KEY(Key) | HT_PUT_CODE(Code);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Routine to test if given Key exists in HashTable and if so returns its code *
|
||||
Returns the Code if key was found, -1 if not. *
|
||||
******************************************************************************/
|
||||
int _ExistsHashTable(GifHashTableType *HashTable, uint32_t Key)
|
||||
{
|
||||
int HKey = KeyItem(Key);
|
||||
uint32_t *HTable = HashTable -> HTable, HTKey;
|
||||
|
||||
#ifdef DEBUG_HIT_RATE
|
||||
NumberOfTests++;
|
||||
NumberOfMisses++;
|
||||
#endif /* DEBUG_HIT_RATE */
|
||||
|
||||
while ((HTKey = HT_GET_KEY(HTable[HKey])) != 0xFFFFFL) {
|
||||
#ifdef DEBUG_HIT_RATE
|
||||
NumberOfMisses++;
|
||||
#endif /* DEBUG_HIT_RATE */
|
||||
if (Key == HTKey) return HT_GET_CODE(HTable[HKey]);
|
||||
HKey = (HKey + 1) & HT_KEY_MASK;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Routine to generate an HKey for the hashtable out of the given unique key. *
|
||||
The given Key is assumed to be 20 bits as follows: lower 8 bits are the *
|
||||
new postfix character, while the upper 12 bits are the prefix code. *
|
||||
Because the average hit ratio is only 2 (2 hash references per entry), *
|
||||
evaluating more complex keys (such as twin prime keys) does not worth it! *
|
||||
******************************************************************************/
|
||||
static int KeyItem(uint32_t Item)
|
||||
{
|
||||
return ((Item >> 12) ^ Item) & HT_KEY_MASK;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_HIT_RATE
|
||||
/******************************************************************************
|
||||
Debugging routine to print the hit ratio - number of times the hash table *
|
||||
was tested per operation. This routine was used to test the KeyItem routine *
|
||||
******************************************************************************/
|
||||
void HashTablePrintHitRatio(void)
|
||||
{
|
||||
printf("Hash Table Hit Ratio is %ld/%ld = %ld%%.\n",
|
||||
NumberOfMisses, NumberOfTests,
|
||||
NumberOfMisses * 100 / NumberOfTests);
|
||||
}
|
||||
#endif /* DEBUG_HIT_RATE */
|
||||
|
||||
/* end */
|
|
@ -0,0 +1,39 @@
|
|||
/******************************************************************************
|
||||
|
||||
gif_hash.h - magfic constants and declarations for GIF LZW
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _GIF_HASH_H_
|
||||
#define _GIF_HASH_H_
|
||||
|
||||
//#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */
|
||||
#define HT_KEY_MASK 0x1FFF /* 13bits keys */
|
||||
#define HT_KEY_NUM_BITS 13 /* 13bits keys */
|
||||
#define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */
|
||||
#define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
|
||||
|
||||
/* The 32 bits of the long are divided into two parts for the key & code: */
|
||||
/* 1. The code is 12 bits as our compression algorithm is limited to 12bits */
|
||||
/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */
|
||||
/* The key is the upper 20 bits. The code is the lower 12. */
|
||||
#define HT_GET_KEY(l) (l >> 12)
|
||||
#define HT_GET_CODE(l) (l & 0x0FFF)
|
||||
#define HT_PUT_KEY(l) (l << 12)
|
||||
#define HT_PUT_CODE(l) (l & 0x0FFF)
|
||||
|
||||
typedef struct GifHashTableType {
|
||||
uint32_t HTable[HT_SIZE];
|
||||
} GifHashTableType;
|
||||
|
||||
GifHashTableType *_InitHashTable(void);
|
||||
void _ClearHashTable(GifHashTableType *HashTable);
|
||||
void _InsertHashTable(GifHashTableType *HashTable, uint32_t Key, int Code);
|
||||
int _ExistsHashTable(GifHashTableType *HashTable, uint32_t Key);
|
||||
|
||||
#endif /* _GIF_HASH_H_ */
|
||||
|
||||
/* end */
|
|
@ -0,0 +1,312 @@
|
|||
/******************************************************************************
|
||||
|
||||
gif_lib.h - service library for decoding and encoding GIF images
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _GIF_LIB_H_
|
||||
#define _GIF_LIB_H_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define GIFLIB_MAJOR 5
|
||||
#define GIFLIB_MINOR 1
|
||||
#define GIFLIB_RELEASE 4
|
||||
|
||||
#define GIF_ERROR 0
|
||||
#define GIF_OK 1
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */
|
||||
#define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1
|
||||
#define GIF_VERSION_POS 3 /* Version first character in stamp. */
|
||||
#define GIF87_STAMP "GIF87a" /* First chars in file - GIF stamp. */
|
||||
#define GIF89_STAMP "GIF89a" /* First chars in file - GIF stamp. */
|
||||
|
||||
typedef unsigned char GifPixelType;
|
||||
typedef unsigned char *GifRowType;
|
||||
typedef unsigned char GifByteType;
|
||||
typedef unsigned int GifPrefixType;
|
||||
typedef int GifWord;
|
||||
|
||||
typedef struct GifColorType {
|
||||
GifByteType Red, Green, Blue;
|
||||
} GifColorType;
|
||||
|
||||
typedef struct ColorMapObject {
|
||||
int ColorCount;
|
||||
int BitsPerPixel;
|
||||
bool SortFlag;
|
||||
GifColorType *Colors; /* on malloc(3) heap */
|
||||
} ColorMapObject;
|
||||
|
||||
typedef struct GifImageDesc {
|
||||
GifWord Left, Top, Width, Height; /* Current image dimensions. */
|
||||
bool Interlace; /* Sequential/Interlaced lines. */
|
||||
ColorMapObject *ColorMap; /* The local color map */
|
||||
} GifImageDesc;
|
||||
|
||||
typedef struct ExtensionBlock {
|
||||
int ByteCount;
|
||||
GifByteType *Bytes; /* on malloc(3) heap */
|
||||
int Function; /* The block function code */
|
||||
#define CONTINUE_EXT_FUNC_CODE 0x00 /* continuation subblock */
|
||||
#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */
|
||||
#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control (GIF89) */
|
||||
#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */
|
||||
#define APPLICATION_EXT_FUNC_CODE 0xff /* application block */
|
||||
} ExtensionBlock;
|
||||
|
||||
typedef struct SavedImage {
|
||||
GifImageDesc ImageDesc;
|
||||
GifByteType *RasterBits; /* on malloc(3) heap */
|
||||
int ExtensionBlockCount; /* Count of extensions before image */
|
||||
ExtensionBlock *ExtensionBlocks; /* Extensions before image */
|
||||
} SavedImage;
|
||||
|
||||
typedef struct GifFileType {
|
||||
GifWord SWidth, SHeight; /* Size of virtual canvas */
|
||||
GifWord SColorResolution; /* How many colors can we generate? */
|
||||
GifWord SBackGroundColor; /* Background color for virtual canvas */
|
||||
GifByteType AspectByte; /* Used to compute pixel aspect ratio */
|
||||
ColorMapObject *SColorMap; /* Global colormap, NULL if nonexistent. */
|
||||
int ImageCount; /* Number of current image (both APIs) */
|
||||
GifImageDesc Image; /* Current image (low-level API) */
|
||||
SavedImage *SavedImages; /* Image sequence (high-level API) */
|
||||
int ExtensionBlockCount; /* Count extensions past last image */
|
||||
ExtensionBlock *ExtensionBlocks; /* Extensions past last image */
|
||||
int Error; /* Last error condition reported */
|
||||
void *UserData; /* hook to attach user data (TVT) */
|
||||
void *Private; /* Don't mess with this! */
|
||||
} GifFileType;
|
||||
|
||||
#define GIF_ASPECT_RATIO(n) ((n)+15.0/64.0)
|
||||
|
||||
typedef enum {
|
||||
UNDEFINED_RECORD_TYPE,
|
||||
SCREEN_DESC_RECORD_TYPE,
|
||||
IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */
|
||||
EXTENSION_RECORD_TYPE, /* Begin with '!' */
|
||||
TERMINATE_RECORD_TYPE /* Begin with ';' */
|
||||
} GifRecordType;
|
||||
|
||||
/* func type to read gif data from arbitrary sources (TVT) */
|
||||
typedef int (*InputFunc) (GifFileType *, GifByteType *, int);
|
||||
|
||||
/* func type to write gif data to arbitrary targets.
|
||||
* Returns count of bytes written. (MRB)
|
||||
*/
|
||||
typedef int (*OutputFunc) (GifFileType *, const GifByteType *, int);
|
||||
|
||||
/******************************************************************************
|
||||
GIF89 structures
|
||||
******************************************************************************/
|
||||
|
||||
typedef struct GraphicsControlBlock {
|
||||
int DisposalMode;
|
||||
#define DISPOSAL_UNSPECIFIED 0 /* No disposal specified. */
|
||||
#define DISPOSE_DO_NOT 1 /* Leave image in place */
|
||||
#define DISPOSE_BACKGROUND 2 /* Set area too background color */
|
||||
#define DISPOSE_PREVIOUS 3 /* Restore to previous content */
|
||||
bool UserInputFlag; /* User confirmation required before disposal */
|
||||
int DelayTime; /* pre-display delay in 0.01sec units */
|
||||
int TransparentColor; /* Palette index for transparency, -1 if none */
|
||||
#define NO_TRANSPARENT_COLOR -1
|
||||
} GraphicsControlBlock;
|
||||
|
||||
/******************************************************************************
|
||||
GIF encoding routines
|
||||
******************************************************************************/
|
||||
|
||||
/* Main entry points */
|
||||
GifFileType *EGifOpenFileName(const char *GifFileName,
|
||||
const bool GifTestExistence, int *Error);
|
||||
GifFileType *EGifOpenFileHandle(const int GifFileHandle, int *Error);
|
||||
GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc, int *Error);
|
||||
int EGifSpew(GifFileType * GifFile);
|
||||
const char *EGifGetGifVersion(GifFileType *GifFile); /* new in 5.x */
|
||||
int EGifCloseFile(GifFileType *GifFile, int *ErrorCode);
|
||||
|
||||
#define E_GIF_SUCCEEDED 0
|
||||
#define E_GIF_ERR_OPEN_FAILED 1 /* And EGif possible errors. */
|
||||
#define E_GIF_ERR_WRITE_FAILED 2
|
||||
#define E_GIF_ERR_HAS_SCRN_DSCR 3
|
||||
#define E_GIF_ERR_HAS_IMAG_DSCR 4
|
||||
#define E_GIF_ERR_NO_COLOR_MAP 5
|
||||
#define E_GIF_ERR_DATA_TOO_BIG 6
|
||||
#define E_GIF_ERR_NOT_ENOUGH_MEM 7
|
||||
#define E_GIF_ERR_DISK_IS_FULL 8
|
||||
#define E_GIF_ERR_CLOSE_FAILED 9
|
||||
#define E_GIF_ERR_NOT_WRITEABLE 10
|
||||
|
||||
/* These are legacy. You probably do not want to call them directly */
|
||||
int EGifPutScreenDesc(GifFileType *GifFile,
|
||||
const int GifWidth, const int GifHeight,
|
||||
const int GifColorRes,
|
||||
const int GifBackGround,
|
||||
const ColorMapObject *GifColorMap);
|
||||
int EGifPutImageDesc(GifFileType *GifFile,
|
||||
const int GifLeft, const int GifTop,
|
||||
const int GifWidth, const int GifHeight,
|
||||
const bool GifInterlace,
|
||||
const ColorMapObject *GifColorMap);
|
||||
void EGifSetGifVersion(GifFileType *GifFile, const bool gif89);
|
||||
int EGifPutLine(GifFileType *GifFile, GifPixelType *GifLine,
|
||||
int GifLineLen);
|
||||
int EGifPutPixel(GifFileType *GifFile, const GifPixelType GifPixel);
|
||||
int EGifPutComment(GifFileType *GifFile, const char *GifComment);
|
||||
int EGifPutExtensionLeader(GifFileType *GifFile, const int GifExtCode);
|
||||
int EGifPutExtensionBlock(GifFileType *GifFile,
|
||||
const int GifExtLen, const void *GifExtension);
|
||||
int EGifPutExtensionTrailer(GifFileType *GifFile);
|
||||
int EGifPutExtension(GifFileType *GifFile, const int GifExtCode,
|
||||
const int GifExtLen,
|
||||
const void *GifExtension);
|
||||
int EGifPutCode(GifFileType *GifFile, int GifCodeSize,
|
||||
const GifByteType *GifCodeBlock);
|
||||
int EGifPutCodeNext(GifFileType *GifFile,
|
||||
const GifByteType *GifCodeBlock);
|
||||
|
||||
/******************************************************************************
|
||||
GIF decoding routines
|
||||
******************************************************************************/
|
||||
|
||||
/* Main entry points */
|
||||
GifFileType *DGifOpenFileName(const char *GifFileName, int *Error);
|
||||
GifFileType *DGifOpenFileHandle(int GifFileHandle, int *Error);
|
||||
int DGifSlurp(GifFileType * GifFile);
|
||||
GifFileType *DGifOpen(void *userPtr, InputFunc readFunc, int *Error); /* new one (TVT) */
|
||||
int DGifCloseFile(GifFileType * GifFile, int *ErrorCode);
|
||||
|
||||
#define D_GIF_SUCCEEDED 0
|
||||
#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */
|
||||
#define D_GIF_ERR_READ_FAILED 102
|
||||
#define D_GIF_ERR_NOT_GIF_FILE 103
|
||||
#define D_GIF_ERR_NO_SCRN_DSCR 104
|
||||
#define D_GIF_ERR_NO_IMAG_DSCR 105
|
||||
#define D_GIF_ERR_NO_COLOR_MAP 106
|
||||
#define D_GIF_ERR_WRONG_RECORD 107
|
||||
#define D_GIF_ERR_DATA_TOO_BIG 108
|
||||
#define D_GIF_ERR_NOT_ENOUGH_MEM 109
|
||||
#define D_GIF_ERR_CLOSE_FAILED 110
|
||||
#define D_GIF_ERR_NOT_READABLE 111
|
||||
#define D_GIF_ERR_IMAGE_DEFECT 112
|
||||
#define D_GIF_ERR_EOF_TOO_SOON 113
|
||||
|
||||
/* These are legacy. You probably do not want to call them directly */
|
||||
int DGifGetScreenDesc(GifFileType *GifFile);
|
||||
int DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType);
|
||||
int DGifGetImageDesc(GifFileType *GifFile);
|
||||
int DGifGetLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen);
|
||||
int DGifGetPixel(GifFileType *GifFile, GifPixelType GifPixel);
|
||||
int DGifGetComment(GifFileType *GifFile, char *GifComment);
|
||||
int DGifGetExtension(GifFileType *GifFile, int *GifExtCode,
|
||||
GifByteType **GifExtension);
|
||||
int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **GifExtension);
|
||||
int DGifGetCode(GifFileType *GifFile, int *GifCodeSize,
|
||||
GifByteType **GifCodeBlock);
|
||||
int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock);
|
||||
int DGifGetLZCodes(GifFileType *GifFile, int *GifCode);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
Color table quantization (deprecated)
|
||||
******************************************************************************/
|
||||
int GifQuantizeBuffer(unsigned int Width, unsigned int Height,
|
||||
int *ColorMapSize, GifByteType * RedInput,
|
||||
GifByteType * GreenInput, GifByteType * BlueInput,
|
||||
GifByteType * OutputBuffer,
|
||||
GifColorType * OutputColorMap);
|
||||
|
||||
/******************************************************************************
|
||||
Error handling and reporting.
|
||||
******************************************************************************/
|
||||
extern const char *GifErrorString(int ErrorCode); /* new in 2012 - ESR */
|
||||
|
||||
/*****************************************************************************
|
||||
Everything below this point is new after version 1.2, supporting `slurp
|
||||
mode' for doing I/O in two big belts with all the image-bashing in core.
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
Color map handling from gif_alloc.c
|
||||
******************************************************************************/
|
||||
|
||||
extern ColorMapObject *GifMakeMapObject(int ColorCount,
|
||||
const GifColorType *ColorMap);
|
||||
extern void GifFreeMapObject(ColorMapObject *Object);
|
||||
extern ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1,
|
||||
const ColorMapObject *ColorIn2,
|
||||
GifPixelType ColorTransIn2[]);
|
||||
extern int GifBitSize(int n);
|
||||
|
||||
extern void *
|
||||
reallocarray(void *optr, size_t nmemb, size_t size);
|
||||
|
||||
/******************************************************************************
|
||||
Support for the in-core structures allocation (slurp mode).
|
||||
******************************************************************************/
|
||||
|
||||
extern void GifApplyTranslation(SavedImage *Image, GifPixelType Translation[]);
|
||||
extern int GifAddExtensionBlock(int *ExtensionBlock_Count,
|
||||
ExtensionBlock **ExtensionBlocks,
|
||||
int Function,
|
||||
unsigned int Len, unsigned char ExtData[]);
|
||||
extern void GifFreeExtensions(int *ExtensionBlock_Count,
|
||||
ExtensionBlock **ExtensionBlocks);
|
||||
extern SavedImage *GifMakeSavedImage(GifFileType *GifFile,
|
||||
const SavedImage *CopyFrom);
|
||||
extern void GifFreeSavedImages(GifFileType *GifFile);
|
||||
|
||||
/******************************************************************************
|
||||
5.x functions for GIF89 graphics control blocks
|
||||
******************************************************************************/
|
||||
|
||||
int DGifExtensionToGCB(const size_t GifExtensionLength,
|
||||
const GifByteType *GifExtension,
|
||||
GraphicsControlBlock *GCB);
|
||||
size_t EGifGCBToExtension(const GraphicsControlBlock *GCB,
|
||||
GifByteType *GifExtension);
|
||||
|
||||
int DGifSavedExtensionToGCB(GifFileType *GifFile,
|
||||
int ImageIndex,
|
||||
GraphicsControlBlock *GCB);
|
||||
int EGifGCBToSavedExtension(const GraphicsControlBlock *GCB,
|
||||
GifFileType *GifFile,
|
||||
int ImageIndex);
|
||||
|
||||
/******************************************************************************
|
||||
The library's internal utility font
|
||||
******************************************************************************/
|
||||
|
||||
#define GIF_FONT_WIDTH 8
|
||||
#define GIF_FONT_HEIGHT 8
|
||||
extern const unsigned char GifAsciiTable8x8[][GIF_FONT_WIDTH];
|
||||
|
||||
extern void GifDrawText8x8(SavedImage *Image,
|
||||
const int x, const int y,
|
||||
const char *legend, const int color);
|
||||
|
||||
extern void GifDrawBox(SavedImage *Image,
|
||||
const int x, const int y,
|
||||
const int w, const int d, const int color);
|
||||
|
||||
extern void GifDrawRectangle(SavedImage *Image,
|
||||
const int x, const int y,
|
||||
const int w, const int d, const int color);
|
||||
|
||||
extern void GifDrawBoxedText8x8(SavedImage *Image,
|
||||
const int x, const int y,
|
||||
const char *legend,
|
||||
const int border, const int bg, const int fg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* _GIF_LIB_H */
|
||||
|
||||
/* end */
|
|
@ -0,0 +1,59 @@
|
|||
/****************************************************************************
|
||||
|
||||
gif_lib_private.h - internal giflib routines and structures
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _GIF_LIB_PRIVATE_H
|
||||
#define _GIF_LIB_PRIVATE_H
|
||||
|
||||
#include "gif_lib.h"
|
||||
#include "gif_hash.h"
|
||||
|
||||
#define EXTENSION_INTRODUCER 0x21
|
||||
#define DESCRIPTOR_INTRODUCER 0x2c
|
||||
#define TERMINATOR_INTRODUCER 0x3b
|
||||
|
||||
#define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
|
||||
#define LZ_BITS 12
|
||||
|
||||
#define FLUSH_OUTPUT 4096 /* Impossible code, to signal flush. */
|
||||
#define FIRST_CODE 4097 /* Impossible code, to signal first. */
|
||||
#define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */
|
||||
|
||||
#define FILE_STATE_WRITE 0x01
|
||||
#define FILE_STATE_SCREEN 0x02
|
||||
#define FILE_STATE_IMAGE 0x04
|
||||
#define FILE_STATE_READ 0x08
|
||||
|
||||
#define IS_READABLE(Private) (Private->FileState & FILE_STATE_READ)
|
||||
#define IS_WRITEABLE(Private) (Private->FileState & FILE_STATE_WRITE)
|
||||
|
||||
typedef struct GifFilePrivateType {
|
||||
GifWord FileState, FileHandle, /* Where all this data goes to! */
|
||||
BitsPerPixel, /* Bits per pixel (Codes uses at least this + 1). */
|
||||
ClearCode, /* The CLEAR LZ code. */
|
||||
EOFCode, /* The EOF LZ code. */
|
||||
RunningCode, /* The next code algorithm can generate. */
|
||||
RunningBits, /* The number of bits required to represent RunningCode. */
|
||||
MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */
|
||||
LastCode, /* The code before the current code. */
|
||||
CrntCode, /* Current algorithm code. */
|
||||
StackPtr, /* For character stack (see below). */
|
||||
CrntShiftState; /* Number of bits in CrntShiftDWord. */
|
||||
unsigned long CrntShiftDWord; /* For bytes decomposition into codes. */
|
||||
unsigned long PixelCount; /* Number of pixels in image. */
|
||||
FILE *File; /* File as stream. */
|
||||
InputFunc Read; /* function to read gif input (TVT) */
|
||||
OutputFunc Write; /* function to write gif output (MRB) */
|
||||
GifByteType Buf[256]; /* Compressed input is buffered here. */
|
||||
GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */
|
||||
GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */
|
||||
GifPrefixType Prefix[LZ_MAX_CODE + 1];
|
||||
GifHashTableType *HashTable;
|
||||
bool gif89;
|
||||
} GifFilePrivateType;
|
||||
|
||||
#endif /* _GIF_LIB_PRIVATE_H */
|
||||
|
||||
/* end */
|
|
@ -0,0 +1,412 @@
|
|||
/*****************************************************************************
|
||||
|
||||
GIF construction tools
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gif_lib.h"
|
||||
|
||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
|
||||
/******************************************************************************
|
||||
Miscellaneous utility functions
|
||||
******************************************************************************/
|
||||
|
||||
/* return smallest bitfield size n will fit in */
|
||||
int
|
||||
GifBitSize(int n)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 1; i <= 8; i++)
|
||||
if ((1 << i) >= n)
|
||||
break;
|
||||
return (i);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Color map object functions
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* Allocate a color map of given size; initialize with contents of
|
||||
* ColorMap if that pointer is non-NULL.
|
||||
*/
|
||||
ColorMapObject *
|
||||
GifMakeMapObject(int ColorCount, const GifColorType *ColorMap)
|
||||
{
|
||||
ColorMapObject *Object;
|
||||
|
||||
/*** FIXME: Our ColorCount has to be a power of two. Is it necessary to
|
||||
* make the user know that or should we automatically round up instead? */
|
||||
if (ColorCount != (1 << GifBitSize(ColorCount))) {
|
||||
return ((ColorMapObject *) NULL);
|
||||
}
|
||||
|
||||
Object = (ColorMapObject *)malloc(sizeof(ColorMapObject));
|
||||
if (Object == (ColorMapObject *) NULL) {
|
||||
return ((ColorMapObject *) NULL);
|
||||
}
|
||||
|
||||
Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType));
|
||||
if (Object->Colors == (GifColorType *) NULL) {
|
||||
free(Object);
|
||||
return ((ColorMapObject *) NULL);
|
||||
}
|
||||
|
||||
Object->ColorCount = ColorCount;
|
||||
Object->BitsPerPixel = GifBitSize(ColorCount);
|
||||
Object->SortFlag = false;
|
||||
|
||||
if (ColorMap != NULL) {
|
||||
memcpy((char *)Object->Colors,
|
||||
(char *)ColorMap, ColorCount * sizeof(GifColorType));
|
||||
}
|
||||
|
||||
return (Object);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Free a color map object
|
||||
*******************************************************************************/
|
||||
void
|
||||
GifFreeMapObject(ColorMapObject *Object)
|
||||
{
|
||||
if (Object != NULL) {
|
||||
(void)free(Object->Colors);
|
||||
(void)free(Object);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
DumpColorMap(ColorMapObject *Object,
|
||||
FILE * fp)
|
||||
{
|
||||
if (Object != NULL) {
|
||||
int i, j, Len = Object->ColorCount;
|
||||
|
||||
for (i = 0; i < Len; i += 4) {
|
||||
for (j = 0; j < 4 && j < Len; j++) {
|
||||
(void)fprintf(fp, "%3d: %02x %02x %02x ", i + j,
|
||||
Object->Colors[i + j].Red,
|
||||
Object->Colors[i + j].Green,
|
||||
Object->Colors[i + j].Blue);
|
||||
}
|
||||
(void)fprintf(fp, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*******************************************************************************
|
||||
Compute the union of two given color maps and return it. If result can't
|
||||
fit into 256 colors, NULL is returned, the allocated union otherwise.
|
||||
ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are
|
||||
copied iff they didn't exist before. ColorTransIn2 maps the old
|
||||
ColorIn2 into the ColorUnion color map table./
|
||||
*******************************************************************************/
|
||||
ColorMapObject *
|
||||
GifUnionColorMap(const ColorMapObject *ColorIn1,
|
||||
const ColorMapObject *ColorIn2,
|
||||
GifPixelType ColorTransIn2[])
|
||||
{
|
||||
int i, j, CrntSlot, RoundUpTo, NewGifBitSize;
|
||||
ColorMapObject *ColorUnion;
|
||||
|
||||
/*
|
||||
* We don't worry about duplicates within either color map; if
|
||||
* the caller wants to resolve those, he can perform unions
|
||||
* with an empty color map.
|
||||
*/
|
||||
|
||||
/* Allocate table which will hold the result for sure. */
|
||||
ColorUnion = GifMakeMapObject(MAX(ColorIn1->ColorCount,
|
||||
ColorIn2->ColorCount) * 2, NULL);
|
||||
|
||||
if (ColorUnion == NULL)
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* Copy ColorIn1 to ColorUnion.
|
||||
*/
|
||||
for (i = 0; i < ColorIn1->ColorCount; i++)
|
||||
ColorUnion->Colors[i] = ColorIn1->Colors[i];
|
||||
CrntSlot = ColorIn1->ColorCount;
|
||||
|
||||
/*
|
||||
* Potentially obnoxious hack:
|
||||
*
|
||||
* Back CrntSlot down past all contiguous {0, 0, 0} slots at the end
|
||||
* of table 1. This is very useful if your display is limited to
|
||||
* 16 colors.
|
||||
*/
|
||||
while (ColorIn1->Colors[CrntSlot - 1].Red == 0
|
||||
&& ColorIn1->Colors[CrntSlot - 1].Green == 0
|
||||
&& ColorIn1->Colors[CrntSlot - 1].Blue == 0)
|
||||
CrntSlot--;
|
||||
|
||||
/* Copy ColorIn2 to ColorUnion (use old colors if they exist): */
|
||||
for (i = 0; i < ColorIn2->ColorCount && CrntSlot <= 256; i++) {
|
||||
/* Let's see if this color already exists: */
|
||||
for (j = 0; j < ColorIn1->ColorCount; j++)
|
||||
if (memcmp (&ColorIn1->Colors[j], &ColorIn2->Colors[i],
|
||||
sizeof(GifColorType)) == 0)
|
||||
break;
|
||||
|
||||
if (j < ColorIn1->ColorCount)
|
||||
ColorTransIn2[i] = j; /* color exists in Color1 */
|
||||
else {
|
||||
/* Color is new - copy it to a new slot: */
|
||||
ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i];
|
||||
ColorTransIn2[i] = CrntSlot++;
|
||||
}
|
||||
}
|
||||
|
||||
if (CrntSlot > 256) {
|
||||
GifFreeMapObject(ColorUnion);
|
||||
return ((ColorMapObject *) NULL);
|
||||
}
|
||||
|
||||
NewGifBitSize = GifBitSize(CrntSlot);
|
||||
RoundUpTo = (1 << NewGifBitSize);
|
||||
|
||||
if (RoundUpTo != ColorUnion->ColorCount) {
|
||||
register GifColorType *Map = ColorUnion->Colors;
|
||||
|
||||
/*
|
||||
* Zero out slots up to next power of 2.
|
||||
* We know these slots exist because of the way ColorUnion's
|
||||
* start dimension was computed.
|
||||
*/
|
||||
for (j = CrntSlot; j < RoundUpTo; j++)
|
||||
Map[j].Red = Map[j].Green = Map[j].Blue = 0;
|
||||
|
||||
/* perhaps we can shrink the map? */
|
||||
if (RoundUpTo < ColorUnion->ColorCount) {
|
||||
GifColorType *new_map = (GifColorType *)reallocarray(Map,
|
||||
RoundUpTo, sizeof(GifColorType));
|
||||
if( new_map == NULL ) {
|
||||
GifFreeMapObject(ColorUnion);
|
||||
return ((ColorMapObject *) NULL);
|
||||
}
|
||||
ColorUnion->Colors = new_map;
|
||||
}
|
||||
}
|
||||
|
||||
ColorUnion->ColorCount = RoundUpTo;
|
||||
ColorUnion->BitsPerPixel = NewGifBitSize;
|
||||
|
||||
return (ColorUnion);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Apply a given color translation to the raster bits of an image
|
||||
*******************************************************************************/
|
||||
void
|
||||
GifApplyTranslation(SavedImage *Image, GifPixelType Translation[])
|
||||
{
|
||||
register int i;
|
||||
register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width;
|
||||
|
||||
for (i = 0; i < RasterSize; i++)
|
||||
Image->RasterBits[i] = Translation[Image->RasterBits[i]];
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Extension record functions
|
||||
******************************************************************************/
|
||||
int
|
||||
GifAddExtensionBlock(int *ExtensionBlockCount,
|
||||
ExtensionBlock **ExtensionBlocks,
|
||||
int Function,
|
||||
unsigned int Len,
|
||||
unsigned char ExtData[])
|
||||
{
|
||||
ExtensionBlock *ep;
|
||||
|
||||
if (*ExtensionBlocks == NULL)
|
||||
*ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock));
|
||||
else {
|
||||
ExtensionBlock* ep_new = (ExtensionBlock *)reallocarray
|
||||
(*ExtensionBlocks, (*ExtensionBlockCount + 1),
|
||||
sizeof(ExtensionBlock));
|
||||
if( ep_new == NULL )
|
||||
return (GIF_ERROR);
|
||||
*ExtensionBlocks = ep_new;
|
||||
}
|
||||
|
||||
if (*ExtensionBlocks == NULL)
|
||||
return (GIF_ERROR);
|
||||
|
||||
ep = &(*ExtensionBlocks)[(*ExtensionBlockCount)++];
|
||||
|
||||
ep->Function = Function;
|
||||
ep->ByteCount=Len;
|
||||
ep->Bytes = (GifByteType *)malloc(ep->ByteCount);
|
||||
if (ep->Bytes == NULL)
|
||||
return (GIF_ERROR);
|
||||
|
||||
if (ExtData != NULL) {
|
||||
memcpy(ep->Bytes, ExtData, Len);
|
||||
}
|
||||
|
||||
return (GIF_OK);
|
||||
}
|
||||
|
||||
void
|
||||
GifFreeExtensions(int *ExtensionBlockCount,
|
||||
ExtensionBlock **ExtensionBlocks)
|
||||
{
|
||||
ExtensionBlock *ep;
|
||||
|
||||
if (*ExtensionBlocks == NULL)
|
||||
return;
|
||||
|
||||
for (ep = *ExtensionBlocks;
|
||||
ep < (*ExtensionBlocks + *ExtensionBlockCount);
|
||||
ep++)
|
||||
(void)free((char *)ep->Bytes);
|
||||
(void)free((char *)*ExtensionBlocks);
|
||||
*ExtensionBlocks = NULL;
|
||||
*ExtensionBlockCount = 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Image block allocation functions
|
||||
******************************************************************************/
|
||||
|
||||
/* Private Function:
|
||||
* Frees the last image in the GifFile->SavedImages array
|
||||
*/
|
||||
void
|
||||
FreeLastSavedImage(GifFileType *GifFile)
|
||||
{
|
||||
SavedImage *sp;
|
||||
|
||||
if ((GifFile == NULL) || (GifFile->SavedImages == NULL))
|
||||
return;
|
||||
|
||||
/* Remove one SavedImage from the GifFile */
|
||||
GifFile->ImageCount--;
|
||||
sp = &GifFile->SavedImages[GifFile->ImageCount];
|
||||
|
||||
/* Deallocate its Colormap */
|
||||
if (sp->ImageDesc.ColorMap != NULL) {
|
||||
GifFreeMapObject(sp->ImageDesc.ColorMap);
|
||||
sp->ImageDesc.ColorMap = NULL;
|
||||
}
|
||||
|
||||
/* Deallocate the image data */
|
||||
if (sp->RasterBits != NULL)
|
||||
free((char *)sp->RasterBits);
|
||||
|
||||
/* Deallocate any extensions */
|
||||
GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks);
|
||||
|
||||
/*** FIXME: We could realloc the GifFile->SavedImages structure but is
|
||||
* there a point to it? Saves some memory but we'd have to do it every
|
||||
* time. If this is used in GifFreeSavedImages then it would be inefficient
|
||||
* (The whole array is going to be deallocated.) If we just use it when
|
||||
* we want to free the last Image it's convenient to do it here.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Append an image block to the SavedImages array
|
||||
*/
|
||||
SavedImage *
|
||||
GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
|
||||
{
|
||||
if (GifFile->SavedImages == NULL)
|
||||
GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
|
||||
else
|
||||
GifFile->SavedImages = (SavedImage *)reallocarray(GifFile->SavedImages,
|
||||
(GifFile->ImageCount + 1), sizeof(SavedImage));
|
||||
|
||||
if (GifFile->SavedImages == NULL)
|
||||
return ((SavedImage *)NULL);
|
||||
else {
|
||||
SavedImage *sp = &GifFile->SavedImages[GifFile->ImageCount++];
|
||||
memset((char *)sp, '\0', sizeof(SavedImage));
|
||||
|
||||
if (CopyFrom != NULL) {
|
||||
memcpy((char *)sp, CopyFrom, sizeof(SavedImage));
|
||||
|
||||
/*
|
||||
* Make our own allocated copies of the heap fields in the
|
||||
* copied record. This guards against potential aliasing
|
||||
* problems.
|
||||
*/
|
||||
|
||||
/* first, the local color map */
|
||||
if (sp->ImageDesc.ColorMap != NULL) {
|
||||
sp->ImageDesc.ColorMap = GifMakeMapObject(
|
||||
CopyFrom->ImageDesc.ColorMap->ColorCount,
|
||||
CopyFrom->ImageDesc.ColorMap->Colors);
|
||||
if (sp->ImageDesc.ColorMap == NULL) {
|
||||
FreeLastSavedImage(GifFile);
|
||||
return (SavedImage *)(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* next, the raster */
|
||||
sp->RasterBits = (unsigned char *)reallocarray(NULL,
|
||||
(CopyFrom->ImageDesc.Height *
|
||||
CopyFrom->ImageDesc.Width),
|
||||
sizeof(GifPixelType));
|
||||
if (sp->RasterBits == NULL) {
|
||||
FreeLastSavedImage(GifFile);
|
||||
return (SavedImage *)(NULL);
|
||||
}
|
||||
memcpy(sp->RasterBits, CopyFrom->RasterBits,
|
||||
sizeof(GifPixelType) * CopyFrom->ImageDesc.Height *
|
||||
CopyFrom->ImageDesc.Width);
|
||||
|
||||
/* finally, the extension blocks */
|
||||
if (sp->ExtensionBlocks != NULL) {
|
||||
sp->ExtensionBlocks = (ExtensionBlock *)reallocarray(NULL,
|
||||
CopyFrom->ExtensionBlockCount,
|
||||
sizeof(ExtensionBlock));
|
||||
if (sp->ExtensionBlocks == NULL) {
|
||||
FreeLastSavedImage(GifFile);
|
||||
return (SavedImage *)(NULL);
|
||||
}
|
||||
memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks,
|
||||
sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount);
|
||||
}
|
||||
}
|
||||
|
||||
return (sp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GifFreeSavedImages(GifFileType *GifFile)
|
||||
{
|
||||
SavedImage *sp;
|
||||
|
||||
if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
|
||||
return;
|
||||
}
|
||||
for (sp = GifFile->SavedImages;
|
||||
sp < GifFile->SavedImages + GifFile->ImageCount; sp++) {
|
||||
if (sp->ImageDesc.ColorMap != NULL) {
|
||||
GifFreeMapObject(sp->ImageDesc.ColorMap);
|
||||
sp->ImageDesc.ColorMap = NULL;
|
||||
}
|
||||
|
||||
if (sp->RasterBits != NULL)
|
||||
free((char *)sp->RasterBits);
|
||||
|
||||
GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks);
|
||||
}
|
||||
free((char *)GifFile->SavedImages);
|
||||
GifFile->SavedImages = NULL;
|
||||
}
|
||||
|
||||
/* end */
|
|
@ -0,0 +1,42 @@
|
|||
/* $OpenBSD: reallocarray.c,v 1.1 2014/05/08 21:43:49 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX ((size_t) - 1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
|
||||
* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
|
||||
*/
|
||||
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
|
||||
|
||||
void *
|
||||
reallocarray(void *optr, size_t nmemb, size_t size)
|
||||
{
|
||||
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
|
||||
nmemb > 0 && SIZE_MAX / nmemb < size) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
return realloc(optr, size * nmemb);
|
||||
}
|
|
@ -0,0 +1,330 @@
|
|||
/*****************************************************************************
|
||||
|
||||
quantize.c - quantize a high resolution image into lower one
|
||||
|
||||
Based on: "Color Image Quantization for frame buffer Display", by
|
||||
Paul Heckbert SIGGRAPH 1982 page 297-307.
|
||||
|
||||
This doesn't really belong in the core library, was undocumented,
|
||||
and was removed in 4.2. Then it turned out some client apps were
|
||||
actually using it, so it was restored in 5.0.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "gif_lib.h"
|
||||
#include "gif_lib_private.h"
|
||||
|
||||
#define ABS(x) ((x) > 0 ? (x) : (-(x)))
|
||||
|
||||
#define COLOR_ARRAY_SIZE 32768
|
||||
#define BITS_PER_PRIM_COLOR 5
|
||||
#define MAX_PRIM_COLOR 0x1f
|
||||
|
||||
static int SortRGBAxis;
|
||||
|
||||
typedef struct QuantizedColorType {
|
||||
GifByteType RGB[3];
|
||||
GifByteType NewColorIndex;
|
||||
long Count;
|
||||
struct QuantizedColorType *Pnext;
|
||||
} QuantizedColorType;
|
||||
|
||||
typedef struct NewColorMapType {
|
||||
GifByteType RGBMin[3], RGBWidth[3];
|
||||
unsigned int NumEntries; /* # of QuantizedColorType in linked list below */
|
||||
unsigned long Count; /* Total number of pixels in all the entries */
|
||||
QuantizedColorType *QuantizedColors;
|
||||
} NewColorMapType;
|
||||
|
||||
static int SubdivColorMap(NewColorMapType * NewColorSubdiv,
|
||||
unsigned int ColorMapSize,
|
||||
unsigned int *NewColorMapSize);
|
||||
static int SortCmpRtn(const void *Entry1, const void *Entry2);
|
||||
|
||||
/******************************************************************************
|
||||
Quantize high resolution image into lower one. Input image consists of a
|
||||
2D array for each of the RGB colors with size Width by Height. There is no
|
||||
Color map for the input. Output is a quantized image with 2D array of
|
||||
indexes into the output color map.
|
||||
Note input image can be 24 bits at the most (8 for red/green/blue) and
|
||||
the output has 256 colors at the most (256 entries in the color map.).
|
||||
ColorMapSize specifies size of color map up to 256 and will be updated to
|
||||
real size before returning.
|
||||
Also non of the parameter are allocated by this routine.
|
||||
This function returns GIF_OK if successful, GIF_ERROR otherwise.
|
||||
******************************************************************************/
|
||||
int
|
||||
GifQuantizeBuffer(unsigned int Width,
|
||||
unsigned int Height,
|
||||
int *ColorMapSize,
|
||||
GifByteType * RedInput,
|
||||
GifByteType * GreenInput,
|
||||
GifByteType * BlueInput,
|
||||
GifByteType * OutputBuffer,
|
||||
GifColorType * OutputColorMap) {
|
||||
|
||||
unsigned int Index, NumOfEntries;
|
||||
int i, j, MaxRGBError[3];
|
||||
unsigned int NewColorMapSize;
|
||||
long Red, Green, Blue;
|
||||
NewColorMapType NewColorSubdiv[256];
|
||||
QuantizedColorType *ColorArrayEntries, *QuantizedColor;
|
||||
|
||||
ColorArrayEntries = (QuantizedColorType *)malloc(
|
||||
sizeof(QuantizedColorType) * COLOR_ARRAY_SIZE);
|
||||
if (ColorArrayEntries == NULL) {
|
||||
return GIF_ERROR;
|
||||
}
|
||||
|
||||
for (i = 0; i < COLOR_ARRAY_SIZE; i++) {
|
||||
ColorArrayEntries[i].RGB[0] = i >> (2 * BITS_PER_PRIM_COLOR);
|
||||
ColorArrayEntries[i].RGB[1] = (i >> BITS_PER_PRIM_COLOR) &
|
||||
MAX_PRIM_COLOR;
|
||||
ColorArrayEntries[i].RGB[2] = i & MAX_PRIM_COLOR;
|
||||
ColorArrayEntries[i].Count = 0;
|
||||
}
|
||||
|
||||
/* Sample the colors and their distribution: */
|
||||
for (i = 0; i < (int)(Width * Height); i++) {
|
||||
Index = ((RedInput[i] >> (8 - BITS_PER_PRIM_COLOR)) <<
|
||||
(2 * BITS_PER_PRIM_COLOR)) +
|
||||
((GreenInput[i] >> (8 - BITS_PER_PRIM_COLOR)) <<
|
||||
BITS_PER_PRIM_COLOR) +
|
||||
(BlueInput[i] >> (8 - BITS_PER_PRIM_COLOR));
|
||||
ColorArrayEntries[Index].Count++;
|
||||
}
|
||||
|
||||
/* Put all the colors in the first entry of the color map, and call the
|
||||
* recursive subdivision process. */
|
||||
for (i = 0; i < 256; i++) {
|
||||
NewColorSubdiv[i].QuantizedColors = NULL;
|
||||
NewColorSubdiv[i].Count = NewColorSubdiv[i].NumEntries = 0;
|
||||
for (j = 0; j < 3; j++) {
|
||||
NewColorSubdiv[i].RGBMin[j] = 0;
|
||||
NewColorSubdiv[i].RGBWidth[j] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the non empty entries in the color table and chain them: */
|
||||
for (i = 0; i < COLOR_ARRAY_SIZE; i++)
|
||||
if (ColorArrayEntries[i].Count > 0)
|
||||
break;
|
||||
QuantizedColor = NewColorSubdiv[0].QuantizedColors = &ColorArrayEntries[i];
|
||||
NumOfEntries = 1;
|
||||
while (++i < COLOR_ARRAY_SIZE)
|
||||
if (ColorArrayEntries[i].Count > 0) {
|
||||
QuantizedColor->Pnext = &ColorArrayEntries[i];
|
||||
QuantizedColor = &ColorArrayEntries[i];
|
||||
NumOfEntries++;
|
||||
}
|
||||
QuantizedColor->Pnext = NULL;
|
||||
|
||||
NewColorSubdiv[0].NumEntries = NumOfEntries; /* Different sampled colors */
|
||||
NewColorSubdiv[0].Count = ((long)Width) * Height; /* Pixels */
|
||||
NewColorMapSize = 1;
|
||||
if (SubdivColorMap(NewColorSubdiv, *ColorMapSize, &NewColorMapSize) !=
|
||||
GIF_OK) {
|
||||
free((char *)ColorArrayEntries);
|
||||
return GIF_ERROR;
|
||||
}
|
||||
if (NewColorMapSize < *ColorMapSize) {
|
||||
/* And clear rest of color map: */
|
||||
for (i = NewColorMapSize; i < *ColorMapSize; i++)
|
||||
OutputColorMap[i].Red = OutputColorMap[i].Green =
|
||||
OutputColorMap[i].Blue = 0;
|
||||
}
|
||||
|
||||
/* Average the colors in each entry to be the color to be used in the
|
||||
* output color map, and plug it into the output color map itself. */
|
||||
for (i = 0; i < NewColorMapSize; i++) {
|
||||
if ((j = NewColorSubdiv[i].NumEntries) > 0) {
|
||||
QuantizedColor = NewColorSubdiv[i].QuantizedColors;
|
||||
Red = Green = Blue = 0;
|
||||
while (QuantizedColor) {
|
||||
QuantizedColor->NewColorIndex = i;
|
||||
Red += QuantizedColor->RGB[0];
|
||||
Green += QuantizedColor->RGB[1];
|
||||
Blue += QuantizedColor->RGB[2];
|
||||
QuantizedColor = QuantizedColor->Pnext;
|
||||
}
|
||||
OutputColorMap[i].Red = (Red << (8 - BITS_PER_PRIM_COLOR)) / j;
|
||||
OutputColorMap[i].Green = (Green << (8 - BITS_PER_PRIM_COLOR)) / j;
|
||||
OutputColorMap[i].Blue = (Blue << (8 - BITS_PER_PRIM_COLOR)) / j;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally scan the input buffer again and put the mapped index in the
|
||||
* output buffer. */
|
||||
MaxRGBError[0] = MaxRGBError[1] = MaxRGBError[2] = 0;
|
||||
for (i = 0; i < (int)(Width * Height); i++) {
|
||||
Index = ((RedInput[i] >> (8 - BITS_PER_PRIM_COLOR)) <<
|
||||
(2 * BITS_PER_PRIM_COLOR)) +
|
||||
((GreenInput[i] >> (8 - BITS_PER_PRIM_COLOR)) <<
|
||||
BITS_PER_PRIM_COLOR) +
|
||||
(BlueInput[i] >> (8 - BITS_PER_PRIM_COLOR));
|
||||
Index = ColorArrayEntries[Index].NewColorIndex;
|
||||
OutputBuffer[i] = Index;
|
||||
if (MaxRGBError[0] < ABS(OutputColorMap[Index].Red - RedInput[i]))
|
||||
MaxRGBError[0] = ABS(OutputColorMap[Index].Red - RedInput[i]);
|
||||
if (MaxRGBError[1] < ABS(OutputColorMap[Index].Green - GreenInput[i]))
|
||||
MaxRGBError[1] = ABS(OutputColorMap[Index].Green - GreenInput[i]);
|
||||
if (MaxRGBError[2] < ABS(OutputColorMap[Index].Blue - BlueInput[i]))
|
||||
MaxRGBError[2] = ABS(OutputColorMap[Index].Blue - BlueInput[i]);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,
|
||||
"Quantization L(0) errors: Red = %d, Green = %d, Blue = %d.\n",
|
||||
MaxRGBError[0], MaxRGBError[1], MaxRGBError[2]);
|
||||
#endif /* DEBUG */
|
||||
|
||||
free((char *)ColorArrayEntries);
|
||||
|
||||
*ColorMapSize = NewColorMapSize;
|
||||
|
||||
return GIF_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Routine to subdivide the RGB space recursively using median cut in each
|
||||
axes alternatingly until ColorMapSize different cubes exists.
|
||||
The biggest cube in one dimension is subdivide unless it has only one entry.
|
||||
Returns GIF_ERROR if failed, otherwise GIF_OK.
|
||||
*******************************************************************************/
|
||||
static int
|
||||
SubdivColorMap(NewColorMapType * NewColorSubdiv,
|
||||
unsigned int ColorMapSize,
|
||||
unsigned int *NewColorMapSize) {
|
||||
|
||||
int MaxSize;
|
||||
unsigned int i, j, Index = 0, NumEntries, MinColor, MaxColor;
|
||||
long Sum, Count;
|
||||
QuantizedColorType *QuantizedColor, **SortArray;
|
||||
|
||||
while (ColorMapSize > *NewColorMapSize) {
|
||||
/* Find candidate for subdivision: */
|
||||
MaxSize = -1;
|
||||
for (i = 0; i < *NewColorMapSize; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
if ((((int)NewColorSubdiv[i].RGBWidth[j]) > MaxSize) &&
|
||||
(NewColorSubdiv[i].NumEntries > 1)) {
|
||||
MaxSize = NewColorSubdiv[i].RGBWidth[j];
|
||||
Index = i;
|
||||
SortRGBAxis = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (MaxSize == -1)
|
||||
return GIF_OK;
|
||||
|
||||
/* Split the entry Index into two along the axis SortRGBAxis: */
|
||||
|
||||
/* Sort all elements in that entry along the given axis and split at
|
||||
* the median. */
|
||||
SortArray = (QuantizedColorType **)malloc(
|
||||
sizeof(QuantizedColorType *) *
|
||||
NewColorSubdiv[Index].NumEntries);
|
||||
if (SortArray == NULL)
|
||||
return GIF_ERROR;
|
||||
for (j = 0, QuantizedColor = NewColorSubdiv[Index].QuantizedColors;
|
||||
j < NewColorSubdiv[Index].NumEntries && QuantizedColor != NULL;
|
||||
j++, QuantizedColor = QuantizedColor->Pnext)
|
||||
SortArray[j] = QuantizedColor;
|
||||
|
||||
/*
|
||||
* Because qsort isn't stable, this can produce differing
|
||||
* results for the order of tuples depending on platform
|
||||
* details of how qsort() is implemented.
|
||||
*
|
||||
* We mitigate this problem by sorting on all three axes rather
|
||||
* than only the one specied by SortRGBAxis; that way the instability
|
||||
* can only become an issue if there are multiple color indices
|
||||
* referring to identical RGB tuples. Older versions of this
|
||||
* sorted on only the one axis.
|
||||
*/
|
||||
qsort(SortArray, NewColorSubdiv[Index].NumEntries,
|
||||
sizeof(QuantizedColorType *), SortCmpRtn);
|
||||
|
||||
/* Relink the sorted list into one: */
|
||||
for (j = 0; j < NewColorSubdiv[Index].NumEntries - 1; j++)
|
||||
SortArray[j]->Pnext = SortArray[j + 1];
|
||||
SortArray[NewColorSubdiv[Index].NumEntries - 1]->Pnext = NULL;
|
||||
NewColorSubdiv[Index].QuantizedColors = QuantizedColor = SortArray[0];
|
||||
free((char *)SortArray);
|
||||
|
||||
/* Now simply add the Counts until we have half of the Count: */
|
||||
Sum = NewColorSubdiv[Index].Count / 2 - QuantizedColor->Count;
|
||||
NumEntries = 1;
|
||||
Count = QuantizedColor->Count;
|
||||
while (QuantizedColor->Pnext != NULL &&
|
||||
(Sum -= QuantizedColor->Pnext->Count) >= 0 &&
|
||||
QuantizedColor->Pnext->Pnext != NULL) {
|
||||
QuantizedColor = QuantizedColor->Pnext;
|
||||
NumEntries++;
|
||||
Count += QuantizedColor->Count;
|
||||
}
|
||||
/* Save the values of the last color of the first half, and first
|
||||
* of the second half so we can update the Bounding Boxes later.
|
||||
* Also as the colors are quantized and the BBoxes are full 0..255,
|
||||
* they need to be rescaled.
|
||||
*/
|
||||
MaxColor = QuantizedColor->RGB[SortRGBAxis]; /* Max. of first half */
|
||||
/* coverity[var_deref_op] */
|
||||
MinColor = QuantizedColor->Pnext->RGB[SortRGBAxis]; /* of second */
|
||||
MaxColor <<= (8 - BITS_PER_PRIM_COLOR);
|
||||
MinColor <<= (8 - BITS_PER_PRIM_COLOR);
|
||||
|
||||
/* Partition right here: */
|
||||
NewColorSubdiv[*NewColorMapSize].QuantizedColors =
|
||||
QuantizedColor->Pnext;
|
||||
QuantizedColor->Pnext = NULL;
|
||||
NewColorSubdiv[*NewColorMapSize].Count = Count;
|
||||
NewColorSubdiv[Index].Count -= Count;
|
||||
NewColorSubdiv[*NewColorMapSize].NumEntries =
|
||||
NewColorSubdiv[Index].NumEntries - NumEntries;
|
||||
NewColorSubdiv[Index].NumEntries = NumEntries;
|
||||
for (j = 0; j < 3; j++) {
|
||||
NewColorSubdiv[*NewColorMapSize].RGBMin[j] =
|
||||
NewColorSubdiv[Index].RGBMin[j];
|
||||
NewColorSubdiv[*NewColorMapSize].RGBWidth[j] =
|
||||
NewColorSubdiv[Index].RGBWidth[j];
|
||||
}
|
||||
NewColorSubdiv[*NewColorMapSize].RGBWidth[SortRGBAxis] =
|
||||
NewColorSubdiv[*NewColorMapSize].RGBMin[SortRGBAxis] +
|
||||
NewColorSubdiv[*NewColorMapSize].RGBWidth[SortRGBAxis] - MinColor;
|
||||
NewColorSubdiv[*NewColorMapSize].RGBMin[SortRGBAxis] = MinColor;
|
||||
|
||||
NewColorSubdiv[Index].RGBWidth[SortRGBAxis] =
|
||||
MaxColor - NewColorSubdiv[Index].RGBMin[SortRGBAxis];
|
||||
|
||||
(*NewColorMapSize)++;
|
||||
}
|
||||
|
||||
return GIF_OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Routine called by qsort to compare two entries.
|
||||
*****************************************************************************/
|
||||
|
||||
static int
|
||||
SortCmpRtn(const void *Entry1,
|
||||
const void *Entry2) {
|
||||
QuantizedColorType *entry1 = (*((QuantizedColorType **) Entry1));
|
||||
QuantizedColorType *entry2 = (*((QuantizedColorType **) Entry2));
|
||||
|
||||
/* sort on all axes of the color space! */
|
||||
int hash1 = entry1->RGB[SortRGBAxis] * 256 * 256
|
||||
+ entry1->RGB[(SortRGBAxis+1) % 3] * 256
|
||||
+ entry1->RGB[(SortRGBAxis+2) % 3];
|
||||
int hash2 = entry2->RGB[SortRGBAxis] * 256 * 256
|
||||
+ entry2->RGB[(SortRGBAxis+1) % 3] * 256
|
||||
+ entry2->RGB[(SortRGBAxis+2) % 3];
|
||||
|
||||
return hash1 - hash2;
|
||||
}
|
||||
|
||||
/* end */
|
|
@ -0,0 +1,96 @@
|
|||
HISTORY for LPeg 1.0
|
||||
|
||||
* Changes from version 0.12 to 1.0
|
||||
---------------------------------
|
||||
+ group "names" can be any Lua value
|
||||
+ some bugs fixed
|
||||
+ other small improvements
|
||||
|
||||
* Changes from version 0.11 to 0.12
|
||||
---------------------------------
|
||||
+ no "unsigned short" limit for pattern sizes
|
||||
+ mathtime captures considered nullable
|
||||
+ some bugs fixed
|
||||
|
||||
* Changes from version 0.10 to 0.11
|
||||
-------------------------------
|
||||
+ complete reimplementation of the code generator
|
||||
+ new syntax for table captures
|
||||
+ new functions in module 're'
|
||||
+ other small improvements
|
||||
|
||||
* Changes from version 0.9 to 0.10
|
||||
-------------------------------
|
||||
+ backtrack stack has configurable size
|
||||
+ better error messages
|
||||
+ Notation for non-terminals in 're' back to A instead o <A>
|
||||
+ experimental look-behind pattern
|
||||
+ support for external extensions
|
||||
+ works with Lua 5.2
|
||||
+ consumes less C stack
|
||||
|
||||
- "and" predicates do not keep captures
|
||||
|
||||
* Changes from version 0.8 to 0.9
|
||||
-------------------------------
|
||||
+ The accumulator capture was replaced by a fold capture;
|
||||
programs that used the old 'lpeg.Ca' will need small changes.
|
||||
+ Some support for character classes from old C locales.
|
||||
+ A new named-group capture.
|
||||
|
||||
* Changes from version 0.7 to 0.8
|
||||
-------------------------------
|
||||
+ New "match-time" capture.
|
||||
+ New "argument capture" that allows passing arguments into the pattern.
|
||||
+ Better documentation for 're'.
|
||||
+ Several small improvements for 're'.
|
||||
+ The 're' module has an incompatibility with previous versions:
|
||||
now, any use of a non-terminal must be enclosed in angle brackets
|
||||
(like <B>).
|
||||
|
||||
* Changes from version 0.6 to 0.7
|
||||
-------------------------------
|
||||
+ Several improvements in module 're':
|
||||
- better documentation;
|
||||
- support for most captures (all but accumulator);
|
||||
- limited repetitions p{n,m}.
|
||||
+ Small improvements in efficiency.
|
||||
+ Several small bugs corrected (special thanks to Hans Hagen
|
||||
and Taco Hoekwater).
|
||||
|
||||
* Changes from version 0.5 to 0.6
|
||||
-------------------------------
|
||||
+ Support for non-numeric indices in grammars.
|
||||
+ Some bug fixes (thanks to the luatex team).
|
||||
+ Some new optimizations; (thanks to Mike Pall).
|
||||
+ A new page layout (thanks to Andre Carregal).
|
||||
+ Minimal documentation for module 're'.
|
||||
|
||||
* Changes from version 0.4 to 0.5
|
||||
-------------------------------
|
||||
+ Several optimizations.
|
||||
+ lpeg.P now accepts booleans.
|
||||
+ Some new examples.
|
||||
+ A proper license.
|
||||
+ Several small improvements.
|
||||
|
||||
* Changes from version 0.3 to 0.4
|
||||
-------------------------------
|
||||
+ Static check for loops in repetitions and grammars.
|
||||
+ Removed label option in captures.
|
||||
+ The implementation of captures uses less memory.
|
||||
|
||||
* Changes from version 0.2 to 0.3
|
||||
-------------------------------
|
||||
+ User-defined patterns in Lua.
|
||||
+ Several new captures.
|
||||
|
||||
* Changes from version 0.1 to 0.2
|
||||
-------------------------------
|
||||
+ Several small corrections.
|
||||
+ Handles embedded zeros like any other character.
|
||||
+ Capture "name" can be any Lua value.
|
||||
+ Unlimited number of captures.
|
||||
+ Match gets an optional initial position.
|
||||
|
||||
(end of HISTORY)
|
|
@ -0,0 +1,537 @@
|
|||
/*
|
||||
** $Id: lpcap.c,v 1.6 2015/06/15 16:09:57 roberto Exp $
|
||||
** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license)
|
||||
*/
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
#include "lpcap.h"
|
||||
#include "lptypes.h"
|
||||
|
||||
|
||||
#define captype(cap) ((cap)->kind)
|
||||
|
||||
#define isclosecap(cap) (captype(cap) == Cclose)
|
||||
|
||||
#define closeaddr(c) ((c)->s + (c)->siz - 1)
|
||||
|
||||
#define isfullcap(cap) ((cap)->siz != 0)
|
||||
|
||||
#define getfromktable(cs,v) lua_rawgeti((cs)->L, ktableidx((cs)->ptop), v)
|
||||
|
||||
#define pushluaval(cs) getfromktable(cs, (cs)->cap->idx)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Put at the cache for Lua values the value indexed by 'v' in ktable
|
||||
** of the running pattern (if it is not there yet); returns its index.
|
||||
*/
|
||||
static int updatecache (CapState *cs, int v) {
|
||||
int idx = cs->ptop + 1; /* stack index of cache for Lua values */
|
||||
if (v != cs->valuecached) { /* not there? */
|
||||
getfromktable(cs, v); /* get value from 'ktable' */
|
||||
lua_replace(cs->L, idx); /* put it at reserved stack position */
|
||||
cs->valuecached = v; /* keep track of what is there */
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
static int pushcapture (CapState *cs);
|
||||
|
||||
|
||||
/*
|
||||
** Goes back in a list of captures looking for an open capture
|
||||
** corresponding to a close
|
||||
*/
|
||||
static Capture *findopen (Capture *cap) {
|
||||
int n = 0; /* number of closes waiting an open */
|
||||
for (;;) {
|
||||
cap--;
|
||||
if (isclosecap(cap)) n++; /* one more open to skip */
|
||||
else if (!isfullcap(cap))
|
||||
if (n-- == 0) return cap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Go to the next capture
|
||||
*/
|
||||
static void nextcap (CapState *cs) {
|
||||
Capture *cap = cs->cap;
|
||||
if (!isfullcap(cap)) { /* not a single capture? */
|
||||
int n = 0; /* number of opens waiting a close */
|
||||
for (;;) { /* look for corresponding close */
|
||||
cap++;
|
||||
if (isclosecap(cap)) {
|
||||
if (n-- == 0) break;
|
||||
}
|
||||
else if (!isfullcap(cap)) n++;
|
||||
}
|
||||
}
|
||||
cs->cap = cap + 1; /* + 1 to skip last close (or entire single capture) */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Push on the Lua stack all values generated by nested captures inside
|
||||
** the current capture. Returns number of values pushed. 'addextra'
|
||||
** makes it push the entire match after all captured values. The
|
||||
** entire match is pushed also if there are no other nested values,
|
||||
** so the function never returns zero.
|
||||
*/
|
||||
static int pushnestedvalues (CapState *cs, int addextra) {
|
||||
Capture *co = cs->cap;
|
||||
if (isfullcap(cs->cap++)) { /* no nested captures? */
|
||||
lua_pushlstring(cs->L, co->s, co->siz - 1); /* push whole match */
|
||||
return 1; /* that is it */
|
||||
}
|
||||
else {
|
||||
int n = 0;
|
||||
while (!isclosecap(cs->cap)) /* repeat for all nested patterns */
|
||||
n += pushcapture(cs);
|
||||
if (addextra || n == 0) { /* need extra? */
|
||||
lua_pushlstring(cs->L, co->s, cs->cap->s - co->s); /* push whole match */
|
||||
n++;
|
||||
}
|
||||
cs->cap++; /* skip close entry */
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Push only the first value generated by nested captures
|
||||
*/
|
||||
static void pushonenestedvalue (CapState *cs) {
|
||||
int n = pushnestedvalues(cs, 0);
|
||||
if (n > 1)
|
||||
lua_pop(cs->L, n - 1); /* pop extra values */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Try to find a named group capture with the name given at the top of
|
||||
** the stack; goes backward from 'cap'.
|
||||
*/
|
||||
static Capture *findback (CapState *cs, Capture *cap) {
|
||||
lua_State *L = cs->L;
|
||||
while (cap-- > cs->ocap) { /* repeat until end of list */
|
||||
if (isclosecap(cap))
|
||||
cap = findopen(cap); /* skip nested captures */
|
||||
else if (!isfullcap(cap))
|
||||
continue; /* opening an enclosing capture: skip and get previous */
|
||||
if (captype(cap) == Cgroup) {
|
||||
getfromktable(cs, cap->idx); /* get group name */
|
||||
if (lp_equal(L, -2, -1)) { /* right group? */
|
||||
lua_pop(L, 2); /* remove reference name and group name */
|
||||
return cap;
|
||||
}
|
||||
else lua_pop(L, 1); /* remove group name */
|
||||
}
|
||||
}
|
||||
luaL_error(L, "back reference '%s' not found", lua_tostring(L, -1));
|
||||
return NULL; /* to avoid warnings */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Back-reference capture. Return number of values pushed.
|
||||
*/
|
||||
static int backrefcap (CapState *cs) {
|
||||
int n;
|
||||
Capture *curr = cs->cap;
|
||||
pushluaval(cs); /* reference name */
|
||||
cs->cap = findback(cs, curr); /* find corresponding group */
|
||||
n = pushnestedvalues(cs, 0); /* push group's values */
|
||||
cs->cap = curr + 1;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Table capture: creates a new table and populates it with nested
|
||||
** captures.
|
||||
*/
|
||||
static int tablecap (CapState *cs) {
|
||||
lua_State *L = cs->L;
|
||||
int n = 0;
|
||||
lua_newtable(L);
|
||||
if (isfullcap(cs->cap++))
|
||||
return 1; /* table is empty */
|
||||
while (!isclosecap(cs->cap)) {
|
||||
if (captype(cs->cap) == Cgroup && cs->cap->idx != 0) { /* named group? */
|
||||
pushluaval(cs); /* push group name */
|
||||
pushonenestedvalue(cs);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
else { /* not a named group */
|
||||
int i;
|
||||
int k = pushcapture(cs);
|
||||
for (i = k; i > 0; i--) /* store all values into table */
|
||||
lua_rawseti(L, -(i + 1), n + i);
|
||||
n += k;
|
||||
}
|
||||
}
|
||||
cs->cap++; /* skip close entry */
|
||||
return 1; /* number of values pushed (only the table) */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Table-query capture
|
||||
*/
|
||||
static int querycap (CapState *cs) {
|
||||
int idx = cs->cap->idx;
|
||||
pushonenestedvalue(cs); /* get nested capture */
|
||||
lua_gettable(cs->L, updatecache(cs, idx)); /* query cap. value at table */
|
||||
if (!lua_isnil(cs->L, -1))
|
||||
return 1;
|
||||
else { /* no value */
|
||||
lua_pop(cs->L, 1); /* remove nil */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Fold capture
|
||||
*/
|
||||
static int foldcap (CapState *cs) {
|
||||
int n;
|
||||
lua_State *L = cs->L;
|
||||
int idx = cs->cap->idx;
|
||||
if (isfullcap(cs->cap++) || /* no nested captures? */
|
||||
isclosecap(cs->cap) || /* no nested captures (large subject)? */
|
||||
(n = pushcapture(cs)) == 0) /* nested captures with no values? */
|
||||
return luaL_error(L, "no initial value for fold capture");
|
||||
if (n > 1)
|
||||
lua_pop(L, n - 1); /* leave only one result for accumulator */
|
||||
while (!isclosecap(cs->cap)) {
|
||||
lua_pushvalue(L, updatecache(cs, idx)); /* get folding function */
|
||||
lua_insert(L, -2); /* put it before accumulator */
|
||||
n = pushcapture(cs); /* get next capture's values */
|
||||
lua_call(L, n + 1, 1); /* call folding function */
|
||||
}
|
||||
cs->cap++; /* skip close entry */
|
||||
return 1; /* only accumulator left on the stack */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Function capture
|
||||
*/
|
||||
static int functioncap (CapState *cs) {
|
||||
int n;
|
||||
int top = lua_gettop(cs->L);
|
||||
pushluaval(cs); /* push function */
|
||||
n = pushnestedvalues(cs, 0); /* push nested captures */
|
||||
lua_call(cs->L, n, LUA_MULTRET); /* call function */
|
||||
return lua_gettop(cs->L) - top; /* return function's results */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Select capture
|
||||
*/
|
||||
static int numcap (CapState *cs) {
|
||||
int idx = cs->cap->idx; /* value to select */
|
||||
if (idx == 0) { /* no values? */
|
||||
nextcap(cs); /* skip entire capture */
|
||||
return 0; /* no value produced */
|
||||
}
|
||||
else {
|
||||
int n = pushnestedvalues(cs, 0);
|
||||
if (n < idx) /* invalid index? */
|
||||
return luaL_error(cs->L, "no capture '%d'", idx);
|
||||
else {
|
||||
lua_pushvalue(cs->L, -(n - idx + 1)); /* get selected capture */
|
||||
lua_replace(cs->L, -(n + 1)); /* put it in place of 1st capture */
|
||||
lua_pop(cs->L, n - 1); /* remove other captures */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Return the stack index of the first runtime capture in the given
|
||||
** list of captures (or zero if no runtime captures)
|
||||
*/
|
||||
int finddyncap (Capture *cap, Capture *last) {
|
||||
for (; cap < last; cap++) {
|
||||
if (cap->kind == Cruntime)
|
||||
return cap->idx; /* stack position of first capture */
|
||||
}
|
||||
return 0; /* no dynamic captures in this segment */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Calls a runtime capture. Returns number of captures removed by
|
||||
** the call, including the initial Cgroup. (Captures to be added are
|
||||
** on the Lua stack.)
|
||||
*/
|
||||
int runtimecap (CapState *cs, Capture *close, const char *s, int *rem) {
|
||||
int n, id;
|
||||
lua_State *L = cs->L;
|
||||
int otop = lua_gettop(L);
|
||||
Capture *open = findopen(close);
|
||||
assert(captype(open) == Cgroup);
|
||||
id = finddyncap(open, close); /* get first dynamic capture argument */
|
||||
close->kind = Cclose; /* closes the group */
|
||||
close->s = s;
|
||||
cs->cap = open; cs->valuecached = 0; /* prepare capture state */
|
||||
luaL_checkstack(L, 4, "too many runtime captures");
|
||||
pushluaval(cs); /* push function to be called */
|
||||
lua_pushvalue(L, SUBJIDX); /* push original subject */
|
||||
lua_pushinteger(L, s - cs->s + 1); /* push current position */
|
||||
n = pushnestedvalues(cs, 0); /* push nested captures */
|
||||
lua_call(L, n + 2, LUA_MULTRET); /* call dynamic function */
|
||||
if (id > 0) { /* are there old dynamic captures to be removed? */
|
||||
int i;
|
||||
for (i = id; i <= otop; i++)
|
||||
lua_remove(L, id); /* remove old dynamic captures */
|
||||
*rem = otop - id + 1; /* total number of dynamic captures removed */
|
||||
}
|
||||
else
|
||||
*rem = 0; /* no dynamic captures removed */
|
||||
return close - open; /* number of captures of all kinds removed */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Auxiliary structure for substitution and string captures: keep
|
||||
** information about nested captures for future use, avoiding to push
|
||||
** string results into Lua
|
||||
*/
|
||||
typedef struct StrAux {
|
||||
int isstring; /* whether capture is a string */
|
||||
union {
|
||||
Capture *cp; /* if not a string, respective capture */
|
||||
struct { /* if it is a string... */
|
||||
const char *s; /* ... starts here */
|
||||
const char *e; /* ... ends here */
|
||||
} s;
|
||||
} u;
|
||||
} StrAux;
|
||||
|
||||
#define MAXSTRCAPS 10
|
||||
|
||||
/*
|
||||
** Collect values from current capture into array 'cps'. Current
|
||||
** capture must be Cstring (first call) or Csimple (recursive calls).
|
||||
** (In first call, fills %0 with whole match for Cstring.)
|
||||
** Returns number of elements in the array that were filled.
|
||||
*/
|
||||
static int getstrcaps (CapState *cs, StrAux *cps, int n) {
|
||||
int k = n++;
|
||||
cps[k].isstring = 1; /* get string value */
|
||||
cps[k].u.s.s = cs->cap->s; /* starts here */
|
||||
if (!isfullcap(cs->cap++)) { /* nested captures? */
|
||||
while (!isclosecap(cs->cap)) { /* traverse them */
|
||||
if (n >= MAXSTRCAPS) /* too many captures? */
|
||||
nextcap(cs); /* skip extra captures (will not need them) */
|
||||
else if (captype(cs->cap) == Csimple) /* string? */
|
||||
n = getstrcaps(cs, cps, n); /* put info. into array */
|
||||
else {
|
||||
cps[n].isstring = 0; /* not a string */
|
||||
cps[n].u.cp = cs->cap; /* keep original capture */
|
||||
nextcap(cs);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
cs->cap++; /* skip close */
|
||||
}
|
||||
cps[k].u.s.e = closeaddr(cs->cap - 1); /* ends here */
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** add next capture value (which should be a string) to buffer 'b'
|
||||
*/
|
||||
static int addonestring (luaL_Buffer *b, CapState *cs, const char *what);
|
||||
|
||||
|
||||
/*
|
||||
** String capture: add result to buffer 'b' (instead of pushing
|
||||
** it into the stack)
|
||||
*/
|
||||
static void stringcap (luaL_Buffer *b, CapState *cs) {
|
||||
StrAux cps[MAXSTRCAPS];
|
||||
int n;
|
||||
size_t len, i;
|
||||
const char *fmt; /* format string */
|
||||
fmt = lua_tolstring(cs->L, updatecache(cs, cs->cap->idx), &len);
|
||||
n = getstrcaps(cs, cps, 0) - 1; /* collect nested captures */
|
||||
for (i = 0; i < len; i++) { /* traverse them */
|
||||
if (fmt[i] != '%') /* not an escape? */
|
||||
luaL_addchar(b, fmt[i]); /* add it to buffer */
|
||||
else if (fmt[++i] < '0' || fmt[i] > '9') /* not followed by a digit? */
|
||||
luaL_addchar(b, fmt[i]); /* add to buffer */
|
||||
else {
|
||||
int l = fmt[i] - '0'; /* capture index */
|
||||
if (l > n)
|
||||
luaL_error(cs->L, "invalid capture index (%d)", l);
|
||||
else if (cps[l].isstring)
|
||||
luaL_addlstring(b, cps[l].u.s.s, cps[l].u.s.e - cps[l].u.s.s);
|
||||
else {
|
||||
Capture *curr = cs->cap;
|
||||
cs->cap = cps[l].u.cp; /* go back to evaluate that nested capture */
|
||||
if (!addonestring(b, cs, "capture"))
|
||||
luaL_error(cs->L, "no values in capture index %d", l);
|
||||
cs->cap = curr; /* continue from where it stopped */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Substitution capture: add result to buffer 'b'
|
||||
*/
|
||||
static void substcap (luaL_Buffer *b, CapState *cs) {
|
||||
const char *curr = cs->cap->s;
|
||||
if (isfullcap(cs->cap)) /* no nested captures? */
|
||||
luaL_addlstring(b, curr, cs->cap->siz - 1); /* keep original text */
|
||||
else {
|
||||
cs->cap++; /* skip open entry */
|
||||
while (!isclosecap(cs->cap)) { /* traverse nested captures */
|
||||
const char *next = cs->cap->s;
|
||||
luaL_addlstring(b, curr, next - curr); /* add text up to capture */
|
||||
if (addonestring(b, cs, "replacement"))
|
||||
curr = closeaddr(cs->cap - 1); /* continue after match */
|
||||
else /* no capture value */
|
||||
curr = next; /* keep original text in final result */
|
||||
}
|
||||
luaL_addlstring(b, curr, cs->cap->s - curr); /* add last piece of text */
|
||||
}
|
||||
cs->cap++; /* go to next capture */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Evaluates a capture and adds its first value to buffer 'b'; returns
|
||||
** whether there was a value
|
||||
*/
|
||||
static int addonestring (luaL_Buffer *b, CapState *cs, const char *what) {
|
||||
switch (captype(cs->cap)) {
|
||||
case Cstring:
|
||||
stringcap(b, cs); /* add capture directly to buffer */
|
||||
return 1;
|
||||
case Csubst:
|
||||
substcap(b, cs); /* add capture directly to buffer */
|
||||
return 1;
|
||||
default: {
|
||||
lua_State *L = cs->L;
|
||||
int n = pushcapture(cs);
|
||||
if (n > 0) {
|
||||
if (n > 1) lua_pop(L, n - 1); /* only one result */
|
||||
if (!lua_isstring(L, -1))
|
||||
luaL_error(L, "invalid %s value (a %s)", what, luaL_typename(L, -1));
|
||||
luaL_addvalue(b);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Push all values of the current capture into the stack; returns
|
||||
** number of values pushed
|
||||
*/
|
||||
static int pushcapture (CapState *cs) {
|
||||
lua_State *L = cs->L;
|
||||
luaL_checkstack(L, 4, "too many captures");
|
||||
switch (captype(cs->cap)) {
|
||||
case Cposition: {
|
||||
lua_pushinteger(L, cs->cap->s - cs->s + 1);
|
||||
cs->cap++;
|
||||
return 1;
|
||||
}
|
||||
case Cconst: {
|
||||
pushluaval(cs);
|
||||
cs->cap++;
|
||||
return 1;
|
||||
}
|
||||
case Carg: {
|
||||
int arg = (cs->cap++)->idx;
|
||||
if (arg + FIXEDARGS > cs->ptop)
|
||||
return luaL_error(L, "reference to absent extra argument #%d", arg);
|
||||
lua_pushvalue(L, arg + FIXEDARGS);
|
||||
return 1;
|
||||
}
|
||||
case Csimple: {
|
||||
int k = pushnestedvalues(cs, 1);
|
||||
lua_insert(L, -k); /* make whole match be first result */
|
||||
return k;
|
||||
}
|
||||
case Cruntime: {
|
||||
lua_pushvalue(L, (cs->cap++)->idx); /* value is in the stack */
|
||||
return 1;
|
||||
}
|
||||
case Cstring: {
|
||||
luaL_Buffer b;
|
||||
luaL_buffinit(L, &b);
|
||||
stringcap(&b, cs);
|
||||
luaL_pushresult(&b);
|
||||
return 1;
|
||||
}
|
||||
case Csubst: {
|
||||
luaL_Buffer b;
|
||||
luaL_buffinit(L, &b);
|
||||
substcap(&b, cs);
|
||||
luaL_pushresult(&b);
|
||||
return 1;
|
||||
}
|
||||
case Cgroup: {
|
||||
if (cs->cap->idx == 0) /* anonymous group? */
|
||||
return pushnestedvalues(cs, 0); /* add all nested values */
|
||||
else { /* named group: add no values */
|
||||
nextcap(cs); /* skip capture */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
case Cbackref: return backrefcap(cs);
|
||||
case Ctable: return tablecap(cs);
|
||||
case Cfunction: return functioncap(cs);
|
||||
case Cnum: return numcap(cs);
|
||||
case Cquery: return querycap(cs);
|
||||
case Cfold: return foldcap(cs);
|
||||
default: assert(0); return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Prepare a CapState structure and traverse the entire list of
|
||||
** captures in the stack pushing its results. 's' is the subject
|
||||
** string, 'r' is the final position of the match, and 'ptop'
|
||||
** the index in the stack where some useful values were pushed.
|
||||
** Returns the number of results pushed. (If the list produces no
|
||||
** results, push the final position of the match.)
|
||||
*/
|
||||
int getcaptures (lua_State *L, const char *s, const char *r, int ptop) {
|
||||
Capture *capture = (Capture *)lua_touserdata(L, caplistidx(ptop));
|
||||
int n = 0;
|
||||
if (!isclosecap(capture)) { /* is there any capture? */
|
||||
CapState cs;
|
||||
cs.ocap = cs.cap = capture; cs.L = L;
|
||||
cs.s = s; cs.valuecached = 0; cs.ptop = ptop;
|
||||
do { /* collect their values */
|
||||
n += pushcapture(&cs);
|
||||
} while (!isclosecap(cs.cap));
|
||||
}
|
||||
if (n == 0) { /* no capture values? */
|
||||
lua_pushinteger(L, r - s + 1); /* return only end position */
|
||||
n = 1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
** $Id: lpcap.h,v 1.3 2016/09/13 17:45:58 roberto Exp $
|
||||
*/
|
||||
|
||||
#if !defined(lpcap_h)
|
||||
#define lpcap_h
|
||||
|
||||
|
||||
#include "lptypes.h"
|
||||
|
||||
|
||||
/* kinds of captures */
|
||||
typedef enum CapKind {
|
||||
Cclose, /* not used in trees */
|
||||
Cposition,
|
||||
Cconst, /* ktable[key] is Lua constant */
|
||||
Cbackref, /* ktable[key] is "name" of group to get capture */
|
||||
Carg, /* 'key' is arg's number */
|
||||
Csimple, /* next node is pattern */
|
||||
Ctable, /* next node is pattern */
|
||||
Cfunction, /* ktable[key] is function; next node is pattern */
|
||||
Cquery, /* ktable[key] is table; next node is pattern */
|
||||
Cstring, /* ktable[key] is string; next node is pattern */
|
||||
Cnum, /* numbered capture; 'key' is number of value to return */
|
||||
Csubst, /* substitution capture; next node is pattern */
|
||||
Cfold, /* ktable[key] is function; next node is pattern */
|
||||
Cruntime, /* not used in trees (is uses another type for tree) */
|
||||
Cgroup /* ktable[key] is group's "name" */
|
||||
} CapKind;
|
||||
|
||||
|
||||
typedef struct Capture {
|
||||
const char *s; /* subject position */
|
||||
unsigned short idx; /* extra info (group name, arg index, etc.) */
|
||||
byte kind; /* kind of capture */
|
||||
byte siz; /* size of full capture + 1 (0 = not a full capture) */
|
||||
} Capture;
|
||||
|
||||
|
||||
typedef struct CapState {
|
||||
Capture *cap; /* current capture */
|
||||
Capture *ocap; /* (original) capture list */
|
||||
lua_State *L;
|
||||
int ptop; /* index of last argument to 'match' */
|
||||
const char *s; /* original string */
|
||||
int valuecached; /* value stored in cache slot */
|
||||
} CapState;
|
||||
|
||||
|
||||
int runtimecap (CapState *cs, Capture *close, const char *s, int *rem);
|
||||
int getcaptures (lua_State *L, const char *s, const char *r, int ptop);
|
||||
int finddyncap (Capture *cap, Capture *last);
|
||||
|
||||
#endif
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
** $Id: lpcode.h,v 1.8 2016/09/15 17:46:13 roberto Exp $
|
||||
*/
|
||||
|
||||
#if !defined(lpcode_h)
|
||||
#define lpcode_h
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lptypes.h"
|
||||
#include "lptree.h"
|
||||
#include "lpvm.h"
|
||||
|
||||
int tocharset (TTree *tree, Charset *cs);
|
||||
int checkaux (TTree *tree, int pred);
|
||||
int fixedlen (TTree *tree);
|
||||
int hascaptures (TTree *tree);
|
||||
int lp_gc (lua_State *L);
|
||||
Instruction *compile (lua_State *L, Pattern *p);
|
||||
void realloccode (lua_State *L, Pattern *p, int nsize);
|
||||
int sizei (const Instruction *i);
|
||||
|
||||
|
||||
#define PEnullable 0
|
||||
#define PEnofail 1
|
||||
|
||||
/*
|
||||
** nofail(t) implies that 't' cannot fail with any input
|
||||
*/
|
||||
#define nofail(t) checkaux(t, PEnofail)
|
||||
|
||||
/*
|
||||
** (not nullable(t)) implies 't' cannot match without consuming
|
||||
** something
|
||||
*/
|
||||
#define nullable(t) checkaux(t, PEnullable)
|
||||
|
||||
|
||||
|
||||
#endif
|
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
** $Id: lpprint.c,v 1.10 2016/09/13 16:06:03 roberto Exp $
|
||||
** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license)
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "lptypes.h"
|
||||
#include "lpprint.h"
|
||||
#include "lpcode.h"
|
||||
|
||||
|
||||
#if defined(LPEG_DEBUG)
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Printing patterns (for debugging)
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
void printcharset (const byte *st) {
|
||||
int i;
|
||||
printf("[");
|
||||
for (i = 0; i <= UCHAR_MAX; i++) {
|
||||
int first = i;
|
||||
while (testchar(st, i) && i <= UCHAR_MAX) i++;
|
||||
if (i - 1 == first) /* unary range? */
|
||||
printf("(%02x)", first);
|
||||
else if (i - 1 > first) /* non-empty range? */
|
||||
printf("(%02x-%02x)", first, i - 1);
|
||||
}
|
||||
printf("]");
|
||||
}
|
||||
|
||||
|
||||
static const char *capkind (int kind) {
|
||||
const char *const modes[] = {
|
||||
"close", "position", "constant", "backref",
|
||||
"argument", "simple", "table", "function",
|
||||
"query", "string", "num", "substitution", "fold",
|
||||
"runtime", "group"};
|
||||
return modes[kind];
|
||||
}
|
||||
|
||||
|
||||
static void printjmp (const Instruction *op, const Instruction *p) {
|
||||
printf("-> %d", (int)(p + (p + 1)->offset - op));
|
||||
}
|
||||
|
||||
|
||||
void printinst (const Instruction *op, const Instruction *p) {
|
||||
const char *const names[] = {
|
||||
"any", "char", "set",
|
||||
"testany", "testchar", "testset",
|
||||
"span", "behind",
|
||||
"ret", "end",
|
||||
"choice", "jmp", "call", "open_call",
|
||||
"commit", "partial_commit", "back_commit", "failtwice", "fail", "giveup",
|
||||
"fullcapture", "opencapture", "closecapture", "closeruntime"
|
||||
};
|
||||
printf("%02ld: %s ", (long)(p - op), names[p->i.code]);
|
||||
switch ((Opcode)p->i.code) {
|
||||
case IChar: {
|
||||
printf("'%c'", p->i.aux);
|
||||
break;
|
||||
}
|
||||
case ITestChar: {
|
||||
printf("'%c'", p->i.aux); printjmp(op, p);
|
||||
break;
|
||||
}
|
||||
case IFullCapture: {
|
||||
printf("%s (size = %d) (idx = %d)",
|
||||
capkind(getkind(p)), getoff(p), p->i.key);
|
||||
break;
|
||||
}
|
||||
case IOpenCapture: {
|
||||
printf("%s (idx = %d)", capkind(getkind(p)), p->i.key);
|
||||
break;
|
||||
}
|
||||
case ISet: {
|
||||
printcharset((p+1)->buff);
|
||||
break;
|
||||
}
|
||||
case ITestSet: {
|
||||
printcharset((p+2)->buff); printjmp(op, p);
|
||||
break;
|
||||
}
|
||||
case ISpan: {
|
||||
printcharset((p+1)->buff);
|
||||
break;
|
||||
}
|
||||
case IOpenCall: {
|
||||
printf("-> %d", (p + 1)->offset);
|
||||
break;
|
||||
}
|
||||
case IBehind: {
|
||||
printf("%d", p->i.aux);
|
||||
break;
|
||||
}
|
||||
case IJmp: case ICall: case ICommit: case IChoice:
|
||||
case IPartialCommit: case IBackCommit: case ITestAny: {
|
||||
printjmp(op, p);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
void printpatt (Instruction *p, int n) {
|
||||
Instruction *op = p;
|
||||
while (p < op + n) {
|
||||
printinst(op, p);
|
||||
p += sizei(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(LPEG_DEBUG)
|
||||
static void printcap (Capture *cap) {
|
||||
printf("%s (idx: %d - size: %d) -> %p\n",
|
||||
capkind(cap->kind), cap->idx, cap->siz, cap->s);
|
||||
}
|
||||
|
||||
|
||||
void printcaplist (Capture *cap, Capture *limit) {
|
||||
printf(">======\n");
|
||||
for (; cap->s && (limit == NULL || cap < limit); cap++)
|
||||
printcap(cap);
|
||||
printf("=======\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Printing trees (for debugging)
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
static const char *tagnames[] = {
|
||||
"char", "set", "any",
|
||||
"true", "false",
|
||||
"rep",
|
||||
"seq", "choice",
|
||||
"not", "and",
|
||||
"call", "opencall", "rule", "grammar",
|
||||
"behind",
|
||||
"capture", "run-time"
|
||||
};
|
||||
|
||||
|
||||
void printtree (TTree *tree, int ident) {
|
||||
int i;
|
||||
for (i = 0; i < ident; i++) printf(" ");
|
||||
printf("%s", tagnames[tree->tag]);
|
||||
switch (tree->tag) {
|
||||
case TChar: {
|
||||
int c = tree->u.n;
|
||||
if (isprint(c))
|
||||
printf(" '%c'\n", c);
|
||||
else
|
||||
printf(" (%02X)\n", c);
|
||||
break;
|
||||
}
|
||||
case TSet: {
|
||||
printcharset(treebuffer(tree));
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
case TOpenCall: case TCall: {
|
||||
assert(sib2(tree)->tag == TRule);
|
||||
printf(" key: %d (rule: %d)\n", tree->key, sib2(tree)->cap);
|
||||
break;
|
||||
}
|
||||
case TBehind: {
|
||||
printf(" %d\n", tree->u.n);
|
||||
printtree(sib1(tree), ident + 2);
|
||||
break;
|
||||
}
|
||||
case TCapture: {
|
||||
printf(" kind: '%s' key: %d\n", capkind(tree->cap), tree->key);
|
||||
printtree(sib1(tree), ident + 2);
|
||||
break;
|
||||
}
|
||||
case TRule: {
|
||||
printf(" n: %d key: %d\n", tree->cap, tree->key);
|
||||
printtree(sib1(tree), ident + 2);
|
||||
break; /* do not print next rule as a sibling */
|
||||
}
|
||||
case TGrammar: {
|
||||
TTree *rule = sib1(tree);
|
||||
printf(" %d\n", tree->u.n); /* number of rules */
|
||||
for (i = 0; i < tree->u.n; i++) {
|
||||
printtree(rule, ident + 2);
|
||||
rule = sib2(rule);
|
||||
}
|
||||
assert(rule->tag == TTrue); /* sentinel */
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
int sibs = numsiblings[tree->tag];
|
||||
printf("\n");
|
||||
if (sibs >= 1) {
|
||||
printtree(sib1(tree), ident + 2);
|
||||
if (sibs >= 2)
|
||||
printtree(sib2(tree), ident + 2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printktable (lua_State *L, int idx) {
|
||||
int n, i;
|
||||
lua_getuservalue(L, idx);
|
||||
if (lua_isnil(L, -1)) /* no ktable? */
|
||||
return;
|
||||
n = lua_rawlen(L, -1);
|
||||
printf("[");
|
||||
for (i = 1; i <= n; i++) {
|
||||
printf("%d = ", i);
|
||||
lua_rawgeti(L, -1, i);
|
||||
if (lua_isstring(L, -1))
|
||||
printf("%s ", lua_tostring(L, -1));
|
||||
else
|
||||
printf("%s ", lua_typename(L, lua_type(L, -1)));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
printf("]\n");
|
||||
/* leave ktable at the stack */
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
** $Id: lpprint.h,v 1.2 2015/06/12 18:18:08 roberto Exp $
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(lpprint_h)
|
||||
#define lpprint_h
|
||||
|
||||
|
||||
#include "lptree.h"
|
||||
#include "lpvm.h"
|
||||
|
||||
|
||||
#if defined(LPEG_DEBUG)
|
||||
|
||||
void printpatt (Instruction *p, int n);
|
||||
void printtree (TTree *tree, int ident);
|
||||
void printktable (lua_State *L, int idx);
|
||||
void printcharset (const byte *st);
|
||||
void printcaplist (Capture *cap, Capture *limit);
|
||||
void printinst (const Instruction *op, const Instruction *p);
|
||||
|
||||
#else
|
||||
|
||||
#define printktable(L,idx) \
|
||||
luaL_error(L, "function only implemented in debug mode")
|
||||
#define printtree(tree,i) \
|
||||
luaL_error(L, "function only implemented in debug mode")
|
||||
#define printpatt(p,n) \
|
||||
luaL_error(L, "function only implemented in debug mode")
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
** $Id: lptree.h,v 1.3 2016/09/13 18:07:51 roberto Exp $
|
||||
*/
|
||||
|
||||
#if !defined(lptree_h)
|
||||
#define lptree_h
|
||||
|
||||
|
||||
#include "lptypes.h"
|
||||
|
||||
|
||||
/*
|
||||
** types of trees
|
||||
*/
|
||||
typedef enum TTag {
|
||||
TChar = 0, /* 'n' = char */
|
||||
TSet, /* the set is stored in next CHARSETSIZE bytes */
|
||||
TAny,
|
||||
TTrue,
|
||||
TFalse,
|
||||
TRep, /* 'sib1'* */
|
||||
TSeq, /* 'sib1' 'sib2' */
|
||||
TChoice, /* 'sib1' / 'sib2' */
|
||||
TNot, /* !'sib1' */
|
||||
TAnd, /* &'sib1' */
|
||||
TCall, /* ktable[key] is rule's key; 'sib2' is rule being called */
|
||||
TOpenCall, /* ktable[key] is rule's key */
|
||||
TRule, /* ktable[key] is rule's key (but key == 0 for unused rules);
|
||||
'sib1' is rule's pattern;
|
||||
'sib2' is next rule; 'cap' is rule's sequential number */
|
||||
TGrammar, /* 'sib1' is initial (and first) rule */
|
||||
TBehind, /* 'sib1' is pattern, 'n' is how much to go back */
|
||||
TCapture, /* captures: 'cap' is kind of capture (enum 'CapKind');
|
||||
ktable[key] is Lua value associated with capture;
|
||||
'sib1' is capture body */
|
||||
TRunTime /* run-time capture: 'key' is Lua function;
|
||||
'sib1' is capture body */
|
||||
} TTag;
|
||||
|
||||
|
||||
/*
|
||||
** Tree trees
|
||||
** The first child of a tree (if there is one) is immediately after
|
||||
** the tree. A reference to a second child (ps) is its position
|
||||
** relative to the position of the tree itself.
|
||||
*/
|
||||
typedef struct TTree {
|
||||
byte tag;
|
||||
byte cap; /* kind of capture (if it is a capture) */
|
||||
unsigned short key; /* key in ktable for Lua data (0 if no key) */
|
||||
union {
|
||||
int ps; /* occasional second child */
|
||||
int n; /* occasional counter */
|
||||
} u;
|
||||
} TTree;
|
||||
|
||||
|
||||
/*
|
||||
** A complete pattern has its tree plus, if already compiled,
|
||||
** its corresponding code
|
||||
*/
|
||||
typedef struct Pattern {
|
||||
union Instruction *code;
|
||||
int codesize;
|
||||
TTree tree[1];
|
||||
} Pattern;
|
||||
|
||||
|
||||
/* number of children for each tree */
|
||||
extern const byte numsiblings[];
|
||||
|
||||
/* access to children */
|
||||
#define sib1(t) ((t) + 1)
|
||||
#define sib2(t) ((t) + (t)->u.ps)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
** $Id: lptypes.h,v 1.16 2017/01/13 13:33:17 roberto Exp $
|
||||
** LPeg - PEG pattern matching for Lua
|
||||
** Copyright 2007-2017, Lua.org & PUC-Rio (see 'lpeg.html' for license)
|
||||
** written by Roberto Ierusalimschy
|
||||
*/
|
||||
|
||||
#if !defined(lptypes_h)
|
||||
#define lptypes_h
|
||||
|
||||
|
||||
#if !defined(LPEG_DEBUG)
|
||||
#define NDEBUG
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
|
||||
#define VERSION "1.0.1"
|
||||
|
||||
|
||||
#define PATTERN_T "lpeg-pattern"
|
||||
#define MAXSTACKIDX "lpeg-maxstack"
|
||||
|
||||
|
||||
/*
|
||||
** compatibility with Lua 5.1
|
||||
*/
|
||||
#if (LUA_VERSION_NUM == 501)
|
||||
|
||||
#define lp_equal lua_equal
|
||||
|
||||
#define lua_getuservalue lua_getfenv
|
||||
#define lua_setuservalue lua_setfenv
|
||||
|
||||
#define lua_rawlen lua_objlen
|
||||
|
||||
#define luaL_setfuncs(L,f,n) luaL_register(L,NULL,f)
|
||||
#define luaL_newlib(L,f) luaL_register(L,"lpeg",f)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(lp_equal)
|
||||
#define lp_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ)
|
||||
#endif
|
||||
|
||||
|
||||
/* default maximum size for call/backtrack stack */
|
||||
#if !defined(MAXBACK)
|
||||
#define MAXBACK 400
|
||||
#endif
|
||||
|
||||
|
||||
/* maximum number of rules in a grammar (limited by 'unsigned char') */
|
||||
#if !defined(MAXRULES)
|
||||
#define MAXRULES 250
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* initial size for capture's list */
|
||||
#define INITCAPSIZE 32
|
||||
|
||||
|
||||
/* index, on Lua stack, for subject */
|
||||
#define SUBJIDX 2
|
||||
|
||||
/* number of fixed arguments to 'match' (before capture arguments) */
|
||||
#define FIXEDARGS 3
|
||||
|
||||
/* index, on Lua stack, for capture list */
|
||||
#define caplistidx(ptop) ((ptop) + 2)
|
||||
|
||||
/* index, on Lua stack, for pattern's ktable */
|
||||
#define ktableidx(ptop) ((ptop) + 3)
|
||||
|
||||
/* index, on Lua stack, for backtracking stack */
|
||||
#define stackidx(ptop) ((ptop) + 4)
|
||||
|
||||
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
|
||||
#define BITSPERCHAR 8
|
||||
|
||||
#define CHARSETSIZE ((UCHAR_MAX/BITSPERCHAR) + 1)
|
||||
|
||||
|
||||
|
||||
typedef struct Charset {
|
||||
byte cs[CHARSETSIZE];
|
||||
} Charset;
|
||||
|
||||
|
||||
|
||||
#define loopset(v,b) { int v; for (v = 0; v < CHARSETSIZE; v++) {b;} }
|
||||
|
||||
/* access to charset */
|
||||
#define treebuffer(t) ((byte *)((t) + 1))
|
||||
|
||||
/* number of slots needed for 'n' bytes */
|
||||
#define bytes2slots(n) (((n) - 1) / sizeof(TTree) + 1)
|
||||
|
||||
/* set 'b' bit in charset 'cs' */
|
||||
#define setchar(cs,b) ((cs)[(b) >> 3] |= (1 << ((b) & 7)))
|
||||
|
||||
|
||||
/*
|
||||
** in capture instructions, 'kind' of capture and its offset are
|
||||
** packed in field 'aux', 4 bits for each
|
||||
*/
|
||||
#define getkind(op) ((op)->i.aux & 0xF)
|
||||
#define getoff(op) (((op)->i.aux >> 4) & 0xF)
|
||||
#define joinkindoff(k,o) ((k) | ((o) << 4))
|
||||
|
||||
#define MAXOFF 0xF
|
||||
#define MAXAUX 0xFF
|
||||
|
||||
|
||||
/* maximum number of bytes to look behind */
|
||||
#define MAXBEHIND MAXAUX
|
||||
|
||||
|
||||
/* maximum size (in elements) for a pattern */
|
||||
#define MAXPATTSIZE (SHRT_MAX - 10)
|
||||
|
||||
|
||||
/* size (in elements) for an instruction plus extra l bytes */
|
||||
#define instsize(l) (((l) + sizeof(Instruction) - 1)/sizeof(Instruction) + 1)
|
||||
|
||||
|
||||
/* size (in elements) for a ISet instruction */
|
||||
#define CHARSETINSTSIZE instsize(CHARSETSIZE)
|
||||
|
||||
/* size (in elements) for a IFunc instruction */
|
||||
#define funcinstsize(p) ((p)->i.aux + 2)
|
||||
|
||||
|
||||
|
||||
#define testchar(st,c) (((int)(st)[((c) >> 3)] & (1 << ((c) & 7))))
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
** $Id: lpvm.c,v 1.9 2016/06/03 20:11:18 roberto Exp $
|
||||
** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license)
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
#include "lpcap.h"
|
||||
#include "lptypes.h"
|
||||
#include "lpvm.h"
|
||||
#include "lpprint.h"
|
||||
|
||||
|
||||
/* initial size for call/backtrack stack */
|
||||
#if !defined(INITBACK)
|
||||
#define INITBACK MAXBACK
|
||||
#endif
|
||||
|
||||
|
||||
#define getoffset(p) (((p) + 1)->offset)
|
||||
|
||||
static const Instruction giveup = {{IGiveup, 0, 0}};
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Virtual Machine
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
typedef struct Stack {
|
||||
const char *s; /* saved position (or NULL for calls) */
|
||||
const Instruction *p; /* next instruction */
|
||||
int caplevel;
|
||||
} Stack;
|
||||
|
||||
|
||||
#define getstackbase(L, ptop) ((Stack *)lua_touserdata(L, stackidx(ptop)))
|
||||
|
||||
|
||||
/*
|
||||
** Make the size of the array of captures 'cap' twice as large as needed
|
||||
** (which is 'captop'). ('n' is the number of new elements.)
|
||||
*/
|
||||
static Capture *doublecap (lua_State *L, Capture *cap, int captop,
|
||||
int n, int ptop) {
|
||||
Capture *newc;
|
||||
if (captop >= INT_MAX/((int)sizeof(Capture) * 2))
|
||||
luaL_error(L, "too many captures");
|
||||
newc = (Capture *)lua_newuserdata(L, captop * 2 * sizeof(Capture));
|
||||
memcpy(newc, cap, (captop - n) * sizeof(Capture));
|
||||
lua_replace(L, caplistidx(ptop));
|
||||
return newc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Double the size of the stack
|
||||
*/
|
||||
static Stack *doublestack (lua_State *L, Stack **stacklimit, int ptop) {
|
||||
Stack *stack = getstackbase(L, ptop);
|
||||
Stack *newstack;
|
||||
int n = *stacklimit - stack; /* current stack size */
|
||||
int max, newn;
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, MAXSTACKIDX);
|
||||
max = lua_tointeger(L, -1); /* maximum allowed size */
|
||||
lua_pop(L, 1);
|
||||
if (n >= max) /* already at maximum size? */
|
||||
luaL_error(L, "backtrack stack overflow (current limit is %d)", max);
|
||||
newn = 2 * n; /* new size */
|
||||
if (newn > max) newn = max;
|
||||
newstack = (Stack *)lua_newuserdata(L, newn * sizeof(Stack));
|
||||
memcpy(newstack, stack, n * sizeof(Stack));
|
||||
lua_replace(L, stackidx(ptop));
|
||||
*stacklimit = newstack + newn;
|
||||
return newstack + n; /* return next position */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Interpret the result of a dynamic capture: false -> fail;
|
||||
** true -> keep current position; number -> next position.
|
||||
** Return new subject position. 'fr' is stack index where
|
||||
** is the result; 'curr' is current subject position; 'limit'
|
||||
** is subject's size.
|
||||
*/
|
||||
static int resdyncaptures (lua_State *L, int fr, int curr, int limit) {
|
||||
lua_Integer res;
|
||||
if (!lua_toboolean(L, fr)) { /* false value? */
|
||||
lua_settop(L, fr - 1); /* remove results */
|
||||
return -1; /* and fail */
|
||||
}
|
||||
else if (lua_isboolean(L, fr)) /* true? */
|
||||
res = curr; /* keep current position */
|
||||
else {
|
||||
res = lua_tointeger(L, fr) - 1; /* new position */
|
||||
if (res < curr || res > limit)
|
||||
luaL_error(L, "invalid position returned by match-time capture");
|
||||
}
|
||||
lua_remove(L, fr); /* remove first result (offset) */
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Add capture values returned by a dynamic capture to the capture list
|
||||
** 'base', nested inside a group capture. 'fd' indexes the first capture
|
||||
** value, 'n' is the number of values (at least 1).
|
||||
*/
|
||||
static void adddyncaptures (const char *s, Capture *base, int n, int fd) {
|
||||
int i;
|
||||
base[0].kind = Cgroup; /* create group capture */
|
||||
base[0].siz = 0;
|
||||
base[0].idx = 0; /* make it an anonymous group */
|
||||
for (i = 1; i <= n; i++) { /* add runtime captures */
|
||||
base[i].kind = Cruntime;
|
||||
base[i].siz = 1; /* mark it as closed */
|
||||
base[i].idx = fd + i - 1; /* stack index of capture value */
|
||||
base[i].s = s;
|
||||
}
|
||||
base[i].kind = Cclose; /* close group */
|
||||
base[i].siz = 1;
|
||||
base[i].s = s;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Remove dynamic captures from the Lua stack (called in case of failure)
|
||||
*/
|
||||
static int removedyncap (lua_State *L, Capture *capture,
|
||||
int level, int last) {
|
||||
int id = finddyncap(capture + level, capture + last); /* index of 1st cap. */
|
||||
int top = lua_gettop(L);
|
||||
if (id == 0) return 0; /* no dynamic captures? */
|
||||
lua_settop(L, id - 1); /* remove captures */
|
||||
return top - id + 1; /* number of values removed */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Opcode interpreter
|
||||
*/
|
||||
const char *match (lua_State *L, const char *o, const char *s, const char *e,
|
||||
Instruction *op, Capture *capture, int ptop) {
|
||||
Stack stackbase[INITBACK];
|
||||
Stack *stacklimit = stackbase + INITBACK;
|
||||
Stack *stack = stackbase; /* point to first empty slot in stack */
|
||||
int capsize = INITCAPSIZE;
|
||||
int captop = 0; /* point to first empty slot in captures */
|
||||
int ndyncap = 0; /* number of dynamic captures (in Lua stack) */
|
||||
const Instruction *p = op; /* current instruction */
|
||||
stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack++;
|
||||
lua_pushlightuserdata(L, stackbase);
|
||||
for (;;) {
|
||||
#if defined(DEBUG)
|
||||
printf("-------------------------------------\n");
|
||||
printcaplist(capture, capture + captop);
|
||||
printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ",
|
||||
s, (int)(stack - getstackbase(L, ptop)), ndyncap, captop);
|
||||
printinst(op, p);
|
||||
#endif
|
||||
assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop);
|
||||
switch ((Opcode)p->i.code) {
|
||||
case IEnd: {
|
||||
assert(stack == getstackbase(L, ptop) + 1);
|
||||
capture[captop].kind = Cclose;
|
||||
capture[captop].s = NULL;
|
||||
return s;
|
||||
}
|
||||
case IGiveup: {
|
||||
assert(stack == getstackbase(L, ptop));
|
||||
return NULL;
|
||||
}
|
||||
case IRet: {
|
||||
assert(stack > getstackbase(L, ptop) && (stack - 1)->s == NULL);
|
||||
p = (--stack)->p;
|
||||
continue;
|
||||
}
|
||||
case IAny: {
|
||||
if (s < e) { p++; s++; }
|
||||
else goto fail;
|
||||
continue;
|
||||
}
|
||||
case ITestAny: {
|
||||
if (s < e) p += 2;
|
||||
else p += getoffset(p);
|
||||
continue;
|
||||
}
|
||||
case IChar: {
|
||||
if ((byte)*s == p->i.aux && s < e) { p++; s++; }
|
||||
else goto fail;
|
||||
continue;
|
||||
}
|
||||
case ITestChar: {
|
||||
if ((byte)*s == p->i.aux && s < e) p += 2;
|
||||
else p += getoffset(p);
|
||||
continue;
|
||||
}
|
||||
case ISet: {
|
||||
int c = (byte)*s;
|
||||
if (testchar((p+1)->buff, c) && s < e)
|
||||
{ p += CHARSETINSTSIZE; s++; }
|
||||
else goto fail;
|
||||
continue;
|
||||
}
|
||||
case ITestSet: {
|
||||
int c = (byte)*s;
|
||||
if (testchar((p + 2)->buff, c) && s < e)
|
||||
p += 1 + CHARSETINSTSIZE;
|
||||
else p += getoffset(p);
|
||||
continue;
|
||||
}
|
||||
case IBehind: {
|
||||
int n = p->i.aux;
|
||||
if (n > s - o) goto fail;
|
||||
s -= n; p++;
|
||||
continue;
|
||||
}
|
||||
case ISpan: {
|
||||
for (; s < e; s++) {
|
||||
int c = (byte)*s;
|
||||
if (!testchar((p+1)->buff, c)) break;
|
||||
}
|
||||
p += CHARSETINSTSIZE;
|
||||
continue;
|
||||
}
|
||||
case IJmp: {
|
||||
p += getoffset(p);
|
||||
continue;
|
||||
}
|
||||
case IChoice: {
|
||||
if (stack == stacklimit)
|
||||
stack = doublestack(L, &stacklimit, ptop);
|
||||
stack->p = p + getoffset(p);
|
||||
stack->s = s;
|
||||
stack->caplevel = captop;
|
||||
stack++;
|
||||
p += 2;
|
||||
continue;
|
||||
}
|
||||
case ICall: {
|
||||
if (stack == stacklimit)
|
||||
stack = doublestack(L, &stacklimit, ptop);
|
||||
stack->s = NULL;
|
||||
stack->p = p + 2; /* save return address */
|
||||
stack++;
|
||||
p += getoffset(p);
|
||||
continue;
|
||||
}
|
||||
case ICommit: {
|
||||
assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL);
|
||||
stack--;
|
||||
p += getoffset(p);
|
||||
continue;
|
||||
}
|
||||
case IPartialCommit: {
|
||||
assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL);
|
||||
(stack - 1)->s = s;
|
||||
(stack - 1)->caplevel = captop;
|
||||
p += getoffset(p);
|
||||
continue;
|
||||
}
|
||||
case IBackCommit: {
|
||||
assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL);
|
||||
s = (--stack)->s;
|
||||
captop = stack->caplevel;
|
||||
p += getoffset(p);
|
||||
continue;
|
||||
}
|
||||
case IFailTwice:
|
||||
assert(stack > getstackbase(L, ptop));
|
||||
stack--;
|
||||
/* go through */
|
||||
case IFail:
|
||||
fail: { /* pattern failed: try to backtrack */
|
||||
do { /* remove pending calls */
|
||||
assert(stack > getstackbase(L, ptop));
|
||||
s = (--stack)->s;
|
||||
} while (s == NULL);
|
||||
if (ndyncap > 0) /* is there matchtime captures? */
|
||||
ndyncap -= removedyncap(L, capture, stack->caplevel, captop);
|
||||
captop = stack->caplevel;
|
||||
p = stack->p;
|
||||
#if defined(DEBUG)
|
||||
printf("**FAIL**\n");
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
case ICloseRunTime: {
|
||||
CapState cs;
|
||||
int rem, res, n;
|
||||
int fr = lua_gettop(L) + 1; /* stack index of first result */
|
||||
cs.s = o; cs.L = L; cs.ocap = capture; cs.ptop = ptop;
|
||||
n = runtimecap(&cs, capture + captop, s, &rem); /* call function */
|
||||
captop -= n; /* remove nested captures */
|
||||
ndyncap -= rem; /* update number of dynamic captures */
|
||||
fr -= rem; /* 'rem' items were popped from Lua stack */
|
||||
res = resdyncaptures(L, fr, s - o, e - o); /* get result */
|
||||
if (res == -1) /* fail? */
|
||||
goto fail;
|
||||
s = o + res; /* else update current position */
|
||||
n = lua_gettop(L) - fr + 1; /* number of new captures */
|
||||
ndyncap += n; /* update number of dynamic captures */
|
||||
if (n > 0) { /* any new capture? */
|
||||
if (fr + n >= SHRT_MAX)
|
||||
luaL_error(L, "too many results in match-time capture");
|
||||
if ((captop += n + 2) >= capsize) {
|
||||
capture = doublecap(L, capture, captop, n + 2, ptop);
|
||||
capsize = 2 * captop;
|
||||
}
|
||||
/* add new captures to 'capture' list */
|
||||
adddyncaptures(s, capture + captop - n - 2, n, fr);
|
||||
}
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
case ICloseCapture: {
|
||||
const char *s1 = s;
|
||||
assert(captop > 0);
|
||||
/* if possible, turn capture into a full capture */
|
||||
if (capture[captop - 1].siz == 0 &&
|
||||
s1 - capture[captop - 1].s < UCHAR_MAX) {
|
||||
capture[captop - 1].siz = s1 - capture[captop - 1].s + 1;
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
capture[captop].siz = 1; /* mark entry as closed */
|
||||
capture[captop].s = s;
|
||||
goto pushcapture;
|
||||
}
|
||||
}
|
||||
case IOpenCapture:
|
||||
capture[captop].siz = 0; /* mark entry as open */
|
||||
capture[captop].s = s;
|
||||
goto pushcapture;
|
||||
case IFullCapture:
|
||||
capture[captop].siz = getoff(p) + 1; /* save capture size */
|
||||
capture[captop].s = s - getoff(p);
|
||||
/* goto pushcapture; */
|
||||
pushcapture: {
|
||||
capture[captop].idx = p->i.key;
|
||||
capture[captop].kind = getkind(p);
|
||||
if (++captop >= capsize) {
|
||||
capture = doublecap(L, capture, captop, 0, ptop);
|
||||
capsize = 2 * captop;
|
||||
}
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
default: assert(0); return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
** $Id: lpvm.h,v 1.3 2014/02/21 13:06:41 roberto Exp $
|
||||
*/
|
||||
|
||||
#if !defined(lpvm_h)
|
||||
#define lpvm_h
|
||||
|
||||
#include "lpcap.h"
|
||||
|
||||
|
||||
/* Virtual Machine's instructions */
|
||||
typedef enum Opcode {
|
||||
IAny, /* if no char, fail */
|
||||
IChar, /* if char != aux, fail */
|
||||
ISet, /* if char not in buff, fail */
|
||||
ITestAny, /* in no char, jump to 'offset' */
|
||||
ITestChar, /* if char != aux, jump to 'offset' */
|
||||
ITestSet, /* if char not in buff, jump to 'offset' */
|
||||
ISpan, /* read a span of chars in buff */
|
||||
IBehind, /* walk back 'aux' characters (fail if not possible) */
|
||||
IRet, /* return from a rule */
|
||||
IEnd, /* end of pattern */
|
||||
IChoice, /* stack a choice; next fail will jump to 'offset' */
|
||||
IJmp, /* jump to 'offset' */
|
||||
ICall, /* call rule at 'offset' */
|
||||
IOpenCall, /* call rule number 'key' (must be closed to a ICall) */
|
||||
ICommit, /* pop choice and jump to 'offset' */
|
||||
IPartialCommit, /* update top choice to current position and jump */
|
||||
IBackCommit, /* "fails" but jump to its own 'offset' */
|
||||
IFailTwice, /* pop one choice and then fail */
|
||||
IFail, /* go back to saved state on choice and jump to saved offset */
|
||||
IGiveup, /* internal use */
|
||||
IFullCapture, /* complete capture of last 'off' chars */
|
||||
IOpenCapture, /* start a capture */
|
||||
ICloseCapture,
|
||||
ICloseRunTime
|
||||
} Opcode;
|
||||
|
||||
|
||||
|
||||
typedef union Instruction {
|
||||
struct Inst {
|
||||
byte code;
|
||||
byte aux;
|
||||
short key;
|
||||
} i;
|
||||
int offset;
|
||||
byte buff[1];
|
||||
} Instruction;
|
||||
|
||||
|
||||
void printpatt (Instruction *p, int n);
|
||||
const char *match (lua_State *L, const char *o, const char *s, const char *e,
|
||||
Instruction *op, Capture *capture, int ptop);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
LIBNAME = lpeg
|
||||
LUADIR = ../lua/
|
||||
|
||||
COPT = -O2
|
||||
# COPT = -DLPEG_DEBUG -g
|
||||
|
||||
CWARNS = -Wall -Wextra -pedantic \
|
||||
-Waggregate-return \
|
||||
-Wcast-align \
|
||||
-Wcast-qual \
|
||||
-Wdisabled-optimization \
|
||||
-Wpointer-arith \
|
||||
-Wshadow \
|
||||
-Wsign-compare \
|
||||
-Wundef \
|
||||
-Wwrite-strings \
|
||||
-Wbad-function-cast \
|
||||
-Wdeclaration-after-statement \
|
||||
-Wmissing-prototypes \
|
||||
-Wnested-externs \
|
||||
-Wstrict-prototypes \
|
||||
# -Wunreachable-code \
|
||||
|
||||
|
||||
CFLAGS = $(CWARNS) $(COPT) -std=c99 -I$(LUADIR) -fPIC
|
||||
CC = gcc
|
||||
|
||||
FILES = lpvm.o lpcap.o lptree.o lpcode.o lpprint.o
|
||||
|
||||
# For Linux
|
||||
linux:
|
||||
make lpeg.so "DLLFLAGS = -shared -fPIC"
|
||||
|
||||
# For Mac OS
|
||||
macosx:
|
||||
make lpeg.so "DLLFLAGS = -bundle -undefined dynamic_lookup"
|
||||
|
||||
lpeg.so: $(FILES)
|
||||
env $(CC) $(DLLFLAGS) $(FILES) -o lpeg.so
|
||||
|
||||
$(FILES): makefile
|
||||
|
||||
test: test.lua re.lua lpeg.so
|
||||
./test.lua
|
||||
|
||||
clean:
|
||||
rm -f $(FILES) lpeg.so
|
||||
|
||||
|
||||
lpcap.o: lpcap.c lpcap.h lptypes.h
|
||||
lpcode.o: lpcode.c lptypes.h lpcode.h lptree.h lpvm.h lpcap.h
|
||||
lpprint.o: lpprint.c lptypes.h lpprint.h lptree.h lpvm.h lpcap.h
|
||||
lptree.o: lptree.c lptypes.h lpcap.h lpcode.h lptree.h lpvm.h lpprint.h
|
||||
lpvm.o: lpvm.c lpcap.h lptypes.h lpvm.h lpprint.h lptree.h
|
||||
|
|
@ -0,0 +1,498 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>LPeg.re - Regex syntax for LPEG</title>
|
||||
<link rel="stylesheet"
|
||||
href="http://www.inf.puc-rio.br/~roberto/lpeg/doc.css"
|
||||
type="text/css"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- $Id: re.html,v 1.24 2016/09/20 17:41:27 roberto Exp $ -->
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo">
|
||||
<a href="http://www.inf.puc-rio.br/~roberto/lpeg/">
|
||||
<img alt="LPeg logo" src="lpeg-128.gif"/>
|
||||
</a>
|
||||
</div>
|
||||
<div id="product_name"><big><strong>LPeg.re</strong></big></div>
|
||||
<div id="product_description">
|
||||
Regex syntax for LPEG
|
||||
</div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="navigation">
|
||||
<h1>re</h1>
|
||||
|
||||
<ul>
|
||||
<li><a href="#basic">Basic Constructions</a></li>
|
||||
<li><a href="#func">Functions</a></li>
|
||||
<li><a href="#ex">Some Examples</a></li>
|
||||
<li><a href="#license">License</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div> <!-- id="navigation" -->
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h2><a name="basic"></a>The <code>re</code> Module</h2>
|
||||
|
||||
<p>
|
||||
The <code>re</code> module
|
||||
(provided by file <code>re.lua</code> in the distribution)
|
||||
supports a somewhat conventional regex syntax
|
||||
for pattern usage within <a href="lpeg.html">LPeg</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The next table summarizes <code>re</code>'s syntax.
|
||||
A <code>p</code> represents an arbitrary pattern;
|
||||
<code>num</code> represents a number (<code>[0-9]+</code>);
|
||||
<code>name</code> represents an identifier
|
||||
(<code>[a-zA-Z][a-zA-Z0-9_]*</code>).
|
||||
Constructions are listed in order of decreasing precedence.
|
||||
<table border="1">
|
||||
<tbody><tr><td><b>Syntax</b></td><td><b>Description</b></td></tr>
|
||||
<tr><td><code>( p )</code></td> <td>grouping</td></tr>
|
||||
<tr><td><code>'string'</code></td> <td>literal string</td></tr>
|
||||
<tr><td><code>"string"</code></td> <td>literal string</td></tr>
|
||||
<tr><td><code>[class]</code></td> <td>character class</td></tr>
|
||||
<tr><td><code>.</code></td> <td>any character</td></tr>
|
||||
<tr><td><code>%name</code></td>
|
||||
<td>pattern <code>defs[name]</code> or a pre-defined pattern</td></tr>
|
||||
<tr><td><code>name</code></td><td>non terminal</td></tr>
|
||||
<tr><td><code><name></code></td><td>non terminal</td></tr>
|
||||
<tr><td><code>{}</code></td> <td>position capture</td></tr>
|
||||
<tr><td><code>{ p }</code></td> <td>simple capture</td></tr>
|
||||
<tr><td><code>{: p :}</code></td> <td>anonymous group capture</td></tr>
|
||||
<tr><td><code>{:name: p :}</code></td> <td>named group capture</td></tr>
|
||||
<tr><td><code>{~ p ~}</code></td> <td>substitution capture</td></tr>
|
||||
<tr><td><code>{| p |}</code></td> <td>table capture</td></tr>
|
||||
<tr><td><code>=name</code></td> <td>back reference
|
||||
</td></tr>
|
||||
<tr><td><code>p ?</code></td> <td>optional match</td></tr>
|
||||
<tr><td><code>p *</code></td> <td>zero or more repetitions</td></tr>
|
||||
<tr><td><code>p +</code></td> <td>one or more repetitions</td></tr>
|
||||
<tr><td><code>p^num</code></td> <td>exactly <code>n</code> repetitions</td></tr>
|
||||
<tr><td><code>p^+num</code></td>
|
||||
<td>at least <code>n</code> repetitions</td></tr>
|
||||
<tr><td><code>p^-num</code></td>
|
||||
<td>at most <code>n</code> repetitions</td></tr>
|
||||
<tr><td><code>p -> 'string'</code></td> <td>string capture</td></tr>
|
||||
<tr><td><code>p -> "string"</code></td> <td>string capture</td></tr>
|
||||
<tr><td><code>p -> num</code></td> <td>numbered capture</td></tr>
|
||||
<tr><td><code>p -> name</code></td> <td>function/query/string capture
|
||||
equivalent to <code>p / defs[name]</code></td></tr>
|
||||
<tr><td><code>p => name</code></td> <td>match-time capture
|
||||
equivalent to <code>lpeg.Cmt(p, defs[name])</code></td></tr>
|
||||
<tr><td><code>& p</code></td> <td>and predicate</td></tr>
|
||||
<tr><td><code>! p</code></td> <td>not predicate</td></tr>
|
||||
<tr><td><code>p1 p2</code></td> <td>concatenation</td></tr>
|
||||
<tr><td><code>p1 / p2</code></td> <td>ordered choice</td></tr>
|
||||
<tr><td>(<code>name <- p</code>)<sup>+</sup></td> <td>grammar</td></tr>
|
||||
</tbody></table>
|
||||
<p>
|
||||
Any space appearing in a syntax description can be
|
||||
replaced by zero or more space characters and Lua-style comments
|
||||
(<code>--</code> until end of line).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Character classes define sets of characters.
|
||||
An initial <code>^</code> complements the resulting set.
|
||||
A range <em>x</em><code>-</code><em>y</em> includes in the set
|
||||
all characters with codes between the codes of <em>x</em> and <em>y</em>.
|
||||
A pre-defined class <code>%</code><em>name</em> includes all
|
||||
characters of that class.
|
||||
A simple character includes itself in the set.
|
||||
The only special characters inside a class are <code>^</code>
|
||||
(special only if it is the first character);
|
||||
<code>]</code>
|
||||
(can be included in the set as the first character,
|
||||
after the optional <code>^</code>);
|
||||
<code>%</code> (special only if followed by a letter);
|
||||
and <code>-</code>
|
||||
(can be included in the set as the first or the last character).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Currently the pre-defined classes are similar to those from the
|
||||
Lua's string library
|
||||
(<code>%a</code> for letters,
|
||||
<code>%A</code> for non letters, etc.).
|
||||
There is also a class <code>%nl</code>
|
||||
containing only the newline character,
|
||||
which is particularly handy for grammars written inside long strings,
|
||||
as long strings do not interpret escape sequences like <code>\n</code>.
|
||||
</p>
|
||||
|
||||
|
||||
<h2><a name="func">Functions</a></h2>
|
||||
|
||||
<h3><code>re.compile (string, [, defs])</code></h3>
|
||||
<p>
|
||||
Compiles the given string and
|
||||
returns an equivalent LPeg pattern.
|
||||
The given string may define either an expression or a grammar.
|
||||
The optional <code>defs</code> table provides extra Lua values
|
||||
to be used by the pattern.
|
||||
</p>
|
||||
|
||||
<h3><code>re.find (subject, pattern [, init])</code></h3>
|
||||
<p>
|
||||
Searches the given pattern in the given subject.
|
||||
If it finds a match,
|
||||
returns the index where this occurrence starts and
|
||||
the index where it ends.
|
||||
Otherwise, returns nil.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
An optional numeric argument <code>init</code> makes the search
|
||||
starts at that position in the subject string.
|
||||
As usual in Lua libraries,
|
||||
a negative value counts from the end.
|
||||
</p>
|
||||
|
||||
<h3><code>re.gsub (subject, pattern, replacement)</code></h3>
|
||||
<p>
|
||||
Does a <em>global substitution</em>,
|
||||
replacing all occurrences of <code>pattern</code>
|
||||
in the given <code>subject</code> by <code>replacement</code>.
|
||||
|
||||
<h3><code>re.match (subject, pattern)</code></h3>
|
||||
<p>
|
||||
Matches the given pattern against the given subject,
|
||||
returning all captures.
|
||||
</p>
|
||||
|
||||
<h3><code>re.updatelocale ()</code></h3>
|
||||
<p>
|
||||
Updates the pre-defined character classes to the current locale.
|
||||
</p>
|
||||
|
||||
|
||||
<h2><a name="ex">Some Examples</a></h2>
|
||||
|
||||
<h3>A complete simple program</h3>
|
||||
<p>
|
||||
The next code shows a simple complete Lua program using
|
||||
the <code>re</code> module:
|
||||
</p>
|
||||
<pre class="example">
|
||||
local re = require"re"
|
||||
|
||||
-- find the position of the first numeral in a string
|
||||
print(re.find("the number 423 is odd", "[0-9]+")) --> 12 14
|
||||
|
||||
-- returns all words in a string
|
||||
print(re.match("the number 423 is odd", "({%a+} / .)*"))
|
||||
--> the number is odd
|
||||
|
||||
-- returns the first numeral in a string
|
||||
print(re.match("the number 423 is odd", "s <- {%d+} / . s"))
|
||||
--> 423
|
||||
|
||||
print(re.gsub("hello World", "[aeiou]", "."))
|
||||
--> h.ll. W.rld
|
||||
</pre>
|
||||
|
||||
|
||||
<h3>Balanced parentheses</h3>
|
||||
<p>
|
||||
The following call will produce the same pattern produced by the
|
||||
Lua expression in the
|
||||
<a href="lpeg.html#balanced">balanced parentheses</a> example:
|
||||
</p>
|
||||
<pre class="example">
|
||||
b = re.compile[[ balanced <- "(" ([^()] / balanced)* ")" ]]
|
||||
</pre>
|
||||
|
||||
<h3>String reversal</h3>
|
||||
<p>
|
||||
The next example reverses a string:
|
||||
</p>
|
||||
<pre class="example">
|
||||
rev = re.compile[[ R <- (!.) -> '' / ({.} R) -> '%2%1']]
|
||||
print(rev:match"0123456789") --> 9876543210
|
||||
</pre>
|
||||
|
||||
<h3>CSV decoder</h3>
|
||||
<p>
|
||||
The next example replicates the <a href="lpeg.html#CSV">CSV decoder</a>:
|
||||
</p>
|
||||
<pre class="example">
|
||||
record = re.compile[[
|
||||
record <- {| field (',' field)* |} (%nl / !.)
|
||||
field <- escaped / nonescaped
|
||||
nonescaped <- { [^,"%nl]* }
|
||||
escaped <- '"' {~ ([^"] / '""' -> '"')* ~} '"'
|
||||
]]
|
||||
</pre>
|
||||
|
||||
<h3>Lua's long strings</h3>
|
||||
<p>
|
||||
The next example matches Lua long strings:
|
||||
</p>
|
||||
<pre class="example">
|
||||
c = re.compile([[
|
||||
longstring <- ('[' {:eq: '='* :} '[' close)
|
||||
close <- ']' =eq ']' / . close
|
||||
]])
|
||||
|
||||
print(c:match'[==[]]===]]]]==]===[]') --> 17
|
||||
</pre>
|
||||
|
||||
<h3>Abstract Syntax Trees</h3>
|
||||
<p>
|
||||
This example shows a simple way to build an
|
||||
abstract syntax tree (AST) for a given grammar.
|
||||
To keep our example simple,
|
||||
let us consider the following grammar
|
||||
for lists of names:
|
||||
</p>
|
||||
<pre class="example">
|
||||
p = re.compile[[
|
||||
listname <- (name s)*
|
||||
name <- [a-z][a-z]*
|
||||
s <- %s*
|
||||
]]
|
||||
</pre>
|
||||
<p>
|
||||
Now, we will add captures to build a corresponding AST.
|
||||
As a first step, the pattern will build a table to
|
||||
represent each non terminal;
|
||||
terminals will be represented by their corresponding strings:
|
||||
</p>
|
||||
<pre class="example">
|
||||
c = re.compile[[
|
||||
listname <- {| (name s)* |}
|
||||
name <- {| {[a-z][a-z]*} |}
|
||||
s <- %s*
|
||||
]]
|
||||
</pre>
|
||||
<p>
|
||||
Now, a match against <code>"hi hello bye"</code>
|
||||
results in the table
|
||||
<code>{{"hi"}, {"hello"}, {"bye"}}</code>.
|
||||
</p>
|
||||
<p>
|
||||
For such a simple grammar,
|
||||
this AST is more than enough;
|
||||
actually, the tables around each single name
|
||||
are already overkilling.
|
||||
More complex grammars,
|
||||
however, may need some more structure.
|
||||
Specifically,
|
||||
it would be useful if each table had
|
||||
a <code>tag</code> field telling what non terminal
|
||||
that table represents.
|
||||
We can add such a tag using
|
||||
<a href="lpeg.html#cap-g">named group captures</a>:
|
||||
</p>
|
||||
<pre class="example">
|
||||
x = re.compile[[
|
||||
listname <- {| {:tag: '' -> 'list':} (name s)* |}
|
||||
name <- {| {:tag: '' -> 'id':} {[a-z][a-z]*} |}
|
||||
s <- ' '*
|
||||
]]
|
||||
</pre>
|
||||
<p>
|
||||
With these group captures,
|
||||
a match against <code>"hi hello bye"</code>
|
||||
results in the following table:
|
||||
</p>
|
||||
<pre class="example">
|
||||
{tag="list",
|
||||
{tag="id", "hi"},
|
||||
{tag="id", "hello"},
|
||||
{tag="id", "bye"}
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
<h3>Indented blocks</h3>
|
||||
<p>
|
||||
This example breaks indented blocks into tables,
|
||||
respecting the indentation:
|
||||
</p>
|
||||
<pre class="example">
|
||||
p = re.compile[[
|
||||
block <- {| {:ident:' '*:} line
|
||||
((=ident !' ' line) / &(=ident ' ') block)* |}
|
||||
line <- {[^%nl]*} %nl
|
||||
]]
|
||||
</pre>
|
||||
<p>
|
||||
As an example,
|
||||
consider the following text:
|
||||
</p>
|
||||
<pre class="example">
|
||||
t = p:match[[
|
||||
first line
|
||||
subline 1
|
||||
subline 2
|
||||
second line
|
||||
third line
|
||||
subline 3.1
|
||||
subline 3.1.1
|
||||
subline 3.2
|
||||
]]
|
||||
</pre>
|
||||
<p>
|
||||
The resulting table <code>t</code> will be like this:
|
||||
</p>
|
||||
<pre class="example">
|
||||
{'first line'; {'subline 1'; 'subline 2'; ident = ' '};
|
||||
'second line';
|
||||
'third line'; { 'subline 3.1'; {'subline 3.1.1'; ident = ' '};
|
||||
'subline 3.2'; ident = ' '};
|
||||
ident = ''}
|
||||
</pre>
|
||||
|
||||
<h3>Macro expander</h3>
|
||||
<p>
|
||||
This example implements a simple macro expander.
|
||||
Macros must be defined as part of the pattern,
|
||||
following some simple rules:
|
||||
</p>
|
||||
<pre class="example">
|
||||
p = re.compile[[
|
||||
text <- {~ item* ~}
|
||||
item <- macro / [^()] / '(' item* ')'
|
||||
arg <- ' '* {~ (!',' item)* ~}
|
||||
args <- '(' arg (',' arg)* ')'
|
||||
-- now we define some macros
|
||||
macro <- ('apply' args) -> '%1(%2)'
|
||||
/ ('add' args) -> '%1 + %2'
|
||||
/ ('mul' args) -> '%1 * %2'
|
||||
]]
|
||||
|
||||
print(p:match"add(mul(a,b), apply(f,x))") --> a * b + f(x)
|
||||
</pre>
|
||||
<p>
|
||||
A <code>text</code> is a sequence of items,
|
||||
wherein we apply a substitution capture to expand any macros.
|
||||
An <code>item</code> is either a macro,
|
||||
any character different from parentheses,
|
||||
or a parenthesized expression.
|
||||
A macro argument (<code>arg</code>) is a sequence
|
||||
of items different from a comma.
|
||||
(Note that a comma may appear inside an item,
|
||||
e.g., inside a parenthesized expression.)
|
||||
Again we do a substitution capture to expand any macro
|
||||
in the argument before expanding the outer macro.
|
||||
<code>args</code> is a list of arguments separated by commas.
|
||||
Finally we define the macros.
|
||||
Each macro is a string substitution;
|
||||
it replaces the macro name and its arguments by its corresponding string,
|
||||
with each <code>%</code><em>n</em> replaced by the <em>n</em>-th argument.
|
||||
</p>
|
||||
|
||||
<h3>Patterns</h3>
|
||||
<p>
|
||||
This example shows the complete syntax
|
||||
of patterns accepted by <code>re</code>.
|
||||
</p>
|
||||
<pre class="example">
|
||||
p = [=[
|
||||
|
||||
pattern <- exp !.
|
||||
exp <- S (grammar / alternative)
|
||||
|
||||
alternative <- seq ('/' S seq)*
|
||||
seq <- prefix*
|
||||
prefix <- '&' S prefix / '!' S prefix / suffix
|
||||
suffix <- primary S (([+*?]
|
||||
/ '^' [+-]? num
|
||||
/ '->' S (string / '{}' / name)
|
||||
/ '=>' S name) S)*
|
||||
|
||||
primary <- '(' exp ')' / string / class / defined
|
||||
/ '{:' (name ':')? exp ':}'
|
||||
/ '=' name
|
||||
/ '{}'
|
||||
/ '{~' exp '~}'
|
||||
/ '{' exp '}'
|
||||
/ '.'
|
||||
/ name S !arrow
|
||||
/ '<' name '>' -- old-style non terminals
|
||||
|
||||
grammar <- definition+
|
||||
definition <- name S arrow exp
|
||||
|
||||
class <- '[' '^'? item (!']' item)* ']'
|
||||
item <- defined / range / .
|
||||
range <- . '-' [^]]
|
||||
|
||||
S <- (%s / '--' [^%nl]*)* -- spaces and comments
|
||||
name <- [A-Za-z][A-Za-z0-9_]*
|
||||
arrow <- '<-'
|
||||
num <- [0-9]+
|
||||
string <- '"' [^"]* '"' / "'" [^']* "'"
|
||||
defined <- '%' name
|
||||
|
||||
]=]
|
||||
|
||||
print(re.match(p, p)) -- a self description must match itself
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
<h2><a name="license">License</a></h2>
|
||||
|
||||
<p>
|
||||
Copyright © 2008-2015 Lua.org, PUC-Rio.
|
||||
</p>
|
||||
<p>
|
||||
Permission is hereby granted, free of charge,
|
||||
to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction,
|
||||
including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is
|
||||
furnished to do so,
|
||||
subject to the following conditions:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions of the Software.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
</p>
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
|
||||
</div> <!-- id="main" -->
|
||||
|
||||
<div id="about">
|
||||
<p><small>
|
||||
$Id: re.html,v 1.24 2016/09/20 17:41:27 roberto Exp $
|
||||
</small></p>
|
||||
</div> <!-- id="about" -->
|
||||
|
||||
</div> <!-- id="container" -->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,259 @@
|
|||
-- $Id: re.lua,v 1.44 2013/03/26 20:11:40 roberto Exp $
|
||||
|
||||
-- imported functions and modules
|
||||
local tonumber, type, print, error = tonumber, type, print, error
|
||||
local setmetatable = setmetatable
|
||||
local m = require"lpeg"
|
||||
|
||||
-- 'm' will be used to parse expressions, and 'mm' will be used to
|
||||
-- create expressions; that is, 're' runs on 'm', creating patterns
|
||||
-- on 'mm'
|
||||
local mm = m
|
||||
|
||||
-- pattern's metatable
|
||||
local mt = getmetatable(mm.P(0))
|
||||
|
||||
|
||||
|
||||
-- No more global accesses after this point
|
||||
local version = _VERSION
|
||||
if version == "Lua 5.2" then _ENV = nil end
|
||||
|
||||
|
||||
local any = m.P(1)
|
||||
|
||||
|
||||
-- Pre-defined names
|
||||
local Predef = { nl = m.P"\n" }
|
||||
|
||||
|
||||
local mem
|
||||
local fmem
|
||||
local gmem
|
||||
|
||||
|
||||
local function updatelocale ()
|
||||
mm.locale(Predef)
|
||||
Predef.a = Predef.alpha
|
||||
Predef.c = Predef.cntrl
|
||||
Predef.d = Predef.digit
|
||||
Predef.g = Predef.graph
|
||||
Predef.l = Predef.lower
|
||||
Predef.p = Predef.punct
|
||||
Predef.s = Predef.space
|
||||
Predef.u = Predef.upper
|
||||
Predef.w = Predef.alnum
|
||||
Predef.x = Predef.xdigit
|
||||
Predef.A = any - Predef.a
|
||||
Predef.C = any - Predef.c
|
||||
Predef.D = any - Predef.d
|
||||
Predef.G = any - Predef.g
|
||||
Predef.L = any - Predef.l
|
||||
Predef.P = any - Predef.p
|
||||
Predef.S = any - Predef.s
|
||||
Predef.U = any - Predef.u
|
||||
Predef.W = any - Predef.w
|
||||
Predef.X = any - Predef.x
|
||||
mem = {} -- restart memoization
|
||||
fmem = {}
|
||||
gmem = {}
|
||||
local mt = {__mode = "v"}
|
||||
setmetatable(mem, mt)
|
||||
setmetatable(fmem, mt)
|
||||
setmetatable(gmem, mt)
|
||||
end
|
||||
|
||||
|
||||
updatelocale()
|
||||
|
||||
|
||||
|
||||
local I = m.P(function (s,i) print(i, s:sub(1, i-1)); return i end)
|
||||
|
||||
|
||||
local function getdef (id, defs)
|
||||
local c = defs and defs[id]
|
||||
if not c then error("undefined name: " .. id) end
|
||||
return c
|
||||
end
|
||||
|
||||
|
||||
local function patt_error (s, i)
|
||||
local msg = (#s < i + 20) and s:sub(i)
|
||||
or s:sub(i,i+20) .. "..."
|
||||
msg = ("pattern error near '%s'"):format(msg)
|
||||
error(msg, 2)
|
||||
end
|
||||
|
||||
local function mult (p, n)
|
||||
local np = mm.P(true)
|
||||
while n >= 1 do
|
||||
if n%2 >= 1 then np = np * p end
|
||||
p = p * p
|
||||
n = n/2
|
||||
end
|
||||
return np
|
||||
end
|
||||
|
||||
local function equalcap (s, i, c)
|
||||
if type(c) ~= "string" then return nil end
|
||||
local e = #c + i
|
||||
if s:sub(i, e - 1) == c then return e else return nil end
|
||||
end
|
||||
|
||||
|
||||
local S = (Predef.space + "--" * (any - Predef.nl)^0)^0
|
||||
|
||||
local name = m.R("AZ", "az", "__") * m.R("AZ", "az", "__", "09")^0
|
||||
|
||||
local arrow = S * "<-"
|
||||
|
||||
local seq_follow = m.P"/" + ")" + "}" + ":}" + "~}" + "|}" + (name * arrow) + -1
|
||||
|
||||
name = m.C(name)
|
||||
|
||||
|
||||
-- a defined name only have meaning in a given environment
|
||||
local Def = name * m.Carg(1)
|
||||
|
||||
local num = m.C(m.R"09"^1) * S / tonumber
|
||||
|
||||
local String = "'" * m.C((any - "'")^0) * "'" +
|
||||
'"' * m.C((any - '"')^0) * '"'
|
||||
|
||||
|
||||
local defined = "%" * Def / function (c,Defs)
|
||||
local cat = Defs and Defs[c] or Predef[c]
|
||||
if not cat then error ("name '" .. c .. "' undefined") end
|
||||
return cat
|
||||
end
|
||||
|
||||
local Range = m.Cs(any * (m.P"-"/"") * (any - "]")) / mm.R
|
||||
|
||||
local item = defined + Range + m.C(any)
|
||||
|
||||
local Class =
|
||||
"["
|
||||
* (m.C(m.P"^"^-1)) -- optional complement symbol
|
||||
* m.Cf(item * (item - "]")^0, mt.__add) /
|
||||
function (c, p) return c == "^" and any - p or p end
|
||||
* "]"
|
||||
|
||||
local function adddef (t, k, exp)
|
||||
if t[k] then
|
||||
error("'"..k.."' already defined as a rule")
|
||||
else
|
||||
t[k] = exp
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
local function firstdef (n, r) return adddef({n}, n, r) end
|
||||
|
||||
|
||||
local function NT (n, b)
|
||||
if not b then
|
||||
error("rule '"..n.."' used outside a grammar")
|
||||
else return mm.V(n)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local exp = m.P{ "Exp",
|
||||
Exp = S * ( m.V"Grammar"
|
||||
+ m.Cf(m.V"Seq" * ("/" * S * m.V"Seq")^0, mt.__add) );
|
||||
Seq = m.Cf(m.Cc(m.P"") * m.V"Prefix"^0 , mt.__mul)
|
||||
* (#seq_follow + patt_error);
|
||||
Prefix = "&" * S * m.V"Prefix" / mt.__len
|
||||
+ "!" * S * m.V"Prefix" / mt.__unm
|
||||
+ m.V"Suffix";
|
||||
Suffix = m.Cf(m.V"Primary" * S *
|
||||
( ( m.P"+" * m.Cc(1, mt.__pow)
|
||||
+ m.P"*" * m.Cc(0, mt.__pow)
|
||||
+ m.P"?" * m.Cc(-1, mt.__pow)
|
||||
+ "^" * ( m.Cg(num * m.Cc(mult))
|
||||
+ m.Cg(m.C(m.S"+-" * m.R"09"^1) * m.Cc(mt.__pow))
|
||||
)
|
||||
+ "->" * S * ( m.Cg((String + num) * m.Cc(mt.__div))
|
||||
+ m.P"{}" * m.Cc(nil, m.Ct)
|
||||
+ m.Cg(Def / getdef * m.Cc(mt.__div))
|
||||
)
|
||||
+ "=>" * S * m.Cg(Def / getdef * m.Cc(m.Cmt))
|
||||
) * S
|
||||
)^0, function (a,b,f) return f(a,b) end );
|
||||
Primary = "(" * m.V"Exp" * ")"
|
||||
+ String / mm.P
|
||||
+ Class
|
||||
+ defined
|
||||
+ "{:" * (name * ":" + m.Cc(nil)) * m.V"Exp" * ":}" /
|
||||
function (n, p) return mm.Cg(p, n) end
|
||||
+ "=" * name / function (n) return mm.Cmt(mm.Cb(n), equalcap) end
|
||||
+ m.P"{}" / mm.Cp
|
||||
+ "{~" * m.V"Exp" * "~}" / mm.Cs
|
||||
+ "{|" * m.V"Exp" * "|}" / mm.Ct
|
||||
+ "{" * m.V"Exp" * "}" / mm.C
|
||||
+ m.P"." * m.Cc(any)
|
||||
+ (name * -arrow + "<" * name * ">") * m.Cb("G") / NT;
|
||||
Definition = name * arrow * m.V"Exp";
|
||||
Grammar = m.Cg(m.Cc(true), "G") *
|
||||
m.Cf(m.V"Definition" / firstdef * m.Cg(m.V"Definition")^0,
|
||||
adddef) / mm.P
|
||||
}
|
||||
|
||||
local pattern = S * m.Cg(m.Cc(false), "G") * exp / mm.P * (-any + patt_error)
|
||||
|
||||
|
||||
local function compile (p, defs)
|
||||
if mm.type(p) == "pattern" then return p end -- already compiled
|
||||
local cp = pattern:match(p, 1, defs)
|
||||
if not cp then error("incorrect pattern", 3) end
|
||||
return cp
|
||||
end
|
||||
|
||||
local function match (s, p, i)
|
||||
local cp = mem[p]
|
||||
if not cp then
|
||||
cp = compile(p)
|
||||
mem[p] = cp
|
||||
end
|
||||
return cp:match(s, i or 1)
|
||||
end
|
||||
|
||||
local function find (s, p, i)
|
||||
local cp = fmem[p]
|
||||
if not cp then
|
||||
cp = compile(p) / 0
|
||||
cp = mm.P{ mm.Cp() * cp * mm.Cp() + 1 * mm.V(1) }
|
||||
fmem[p] = cp
|
||||
end
|
||||
local i, e = cp:match(s, i or 1)
|
||||
if i then return i, e - 1
|
||||
else return i
|
||||
end
|
||||
end
|
||||
|
||||
local function gsub (s, p, rep)
|
||||
local g = gmem[p] or {} -- ensure gmem[p] is not collected while here
|
||||
gmem[p] = g
|
||||
local cp = g[rep]
|
||||
if not cp then
|
||||
cp = compile(p)
|
||||
cp = mm.Cs((cp / rep + 1)^0)
|
||||
g[rep] = cp
|
||||
end
|
||||
return cp:match(s)
|
||||
end
|
||||
|
||||
|
||||
-- exported names
|
||||
local re = {
|
||||
compile = compile,
|
||||
match = match,
|
||||
find = find,
|
||||
gsub = gsub,
|
||||
updatelocale = updatelocale,
|
||||
}
|
||||
|
||||
if version == "Lua 5.1" then _G.re = re end
|
||||
|
||||
return re
|
File diff suppressed because it is too large
Load Diff
178
src/fs.c
178
src/fs.c
|
@ -29,12 +29,11 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if !defined(__WINRT__) && !defined(__WINDOWS__)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(__WINRT__) || defined(__WINDOWS__)
|
||||
#include <direct.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
|
@ -540,18 +539,95 @@ static void makeDir(const char* name)
|
|||
#endif
|
||||
}
|
||||
|
||||
bool fsExistsFile(FileSystem* fs, const char* name)
|
||||
const char* fsFilename(const char *path)
|
||||
{
|
||||
const char* path = getFilePath(fs, name);
|
||||
FILE* file = tic_fopen(UTF8ToString(path), UTF8ToString("rb"));
|
||||
const char* full = fsFullname(path);
|
||||
const char* base = fsBasename(path);
|
||||
|
||||
return base ? full + strlen(fsBasename(path)) : NULL;
|
||||
}
|
||||
|
||||
const char* fsFullname(const char *path)
|
||||
{
|
||||
char* result = NULL;
|
||||
|
||||
#if defined(__WINDOWS__) || defined(__WINRT__)
|
||||
static wchar_t wpath[FILENAME_MAX];
|
||||
GetFullPathNameW(UTF8ToString(path), sizeof(wpath), wpath, NULL);
|
||||
|
||||
result = StringToUTF8(wpath);
|
||||
#else
|
||||
|
||||
result = realpath(path, NULL);
|
||||
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* fsBasename(const char *path)
|
||||
{
|
||||
char* result = NULL;
|
||||
|
||||
#if defined(__WINDOWS__) || defined(__WINRT__)
|
||||
#define SEP "\\"
|
||||
#else
|
||||
#define SEP "/"
|
||||
#endif
|
||||
|
||||
if(file)
|
||||
{
|
||||
fclose(file);
|
||||
return true;
|
||||
char* full = (char*)fsFullname(path);
|
||||
|
||||
struct tic_stat_struct s;
|
||||
if(tic_stat(UTF8ToString(full), &s) == 0)
|
||||
{
|
||||
result = full;
|
||||
|
||||
if(S_ISREG(s.st_mode))
|
||||
{
|
||||
const char* ptr = result + strlen(result);
|
||||
|
||||
while(ptr >= result)
|
||||
{
|
||||
if(*ptr == SEP[0])
|
||||
{
|
||||
result[ptr-result] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
ptr--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
if(result && result[strlen(result)-1] != SEP[0])
|
||||
strcat(result, SEP);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool fsExists(const char* name)
|
||||
{
|
||||
struct tic_stat_struct s;
|
||||
return tic_stat(UTF8ToString(name), &s) == 0;
|
||||
}
|
||||
|
||||
bool fsExistsFile(FileSystem* fs, const char* name)
|
||||
{
|
||||
return fsExists(getFilePath(fs, name));
|
||||
}
|
||||
|
||||
u64 fsMDate(FileSystem* fs, const char* name)
|
||||
{
|
||||
struct tic_stat_struct s;
|
||||
|
||||
if(tic_stat(UTF8ToString(getFilePath(fs, name)), &s) == 0 && S_ISREG(s.st_mode))
|
||||
{
|
||||
return s.st_mtime;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool fsSaveFile(FileSystem* fs, const char* name, const void* data, size_t size, bool overwrite)
|
||||
|
@ -674,7 +750,7 @@ void fsMakeDir(FileSystem* fs, const char* name)
|
|||
|
||||
#if defined(__WINDOWS__) || defined(__LINUX__) || defined(__MACOSX__)
|
||||
|
||||
int fsOpenSystemPath(FileSystem* fs, const char* path)
|
||||
s32 fsOpenSystemPath(FileSystem* fs, const char* path)
|
||||
{
|
||||
char command[FILENAME_MAX];
|
||||
|
||||
|
@ -697,7 +773,10 @@ int fsOpenSystemPath(FileSystem* fs, const char* path)
|
|||
|
||||
#else
|
||||
|
||||
void fsOpenSystemPath(FileSystem* fs, const char* path) {}
|
||||
s32 fsOpenSystemPath(FileSystem* fs, const char* path)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -711,55 +790,64 @@ void fsOpenWorkingFolder(FileSystem* fs)
|
|||
fsOpenSystemPath(fs, path);
|
||||
}
|
||||
|
||||
void createFileSystem(void(*callback)(FileSystem*))
|
||||
void createFileSystem(const char* path, void(*callback)(FileSystem*))
|
||||
{
|
||||
FileSystem* fs = (FileSystem*)SDL_malloc(sizeof(FileSystem));
|
||||
memset(fs, 0, sizeof(FileSystem));
|
||||
|
||||
fs->net = createNet();
|
||||
|
||||
if(path)
|
||||
{
|
||||
strcpy(fs->dir, path);
|
||||
callback(fs);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
|
||||
strcpy(fs->dir, "/" TIC_PACKAGE "/" TIC_NAME "/");
|
||||
strcpy(fs->dir, "/" TIC_PACKAGE "/" TIC_NAME "/");
|
||||
|
||||
#elif defined(__ANDROID__)
|
||||
|
||||
strcpy(fs->dir, SDL_AndroidGetExternalStoragePath());
|
||||
const char AppFolder[] = "/" TIC_NAME "/";
|
||||
strcat(fs->dir, AppFolder);
|
||||
mkdir(fs->dir, 0700);
|
||||
strcpy(fs->dir, SDL_AndroidGetExternalStoragePath());
|
||||
const char AppFolder[] = "/" TIC_NAME "/";
|
||||
strcat(fs->dir, AppFolder);
|
||||
mkdir(fs->dir, 0700);
|
||||
|
||||
#else
|
||||
|
||||
char* path = SDL_GetPrefPath(TIC_PACKAGE, TIC_NAME);
|
||||
strcpy(fs->dir, path);
|
||||
SDL_free(path);
|
||||
char* path = SDL_GetPrefPath(TIC_PACKAGE, TIC_NAME);
|
||||
strcpy(fs->dir, path);
|
||||
SDL_free(path);
|
||||
|
||||
#endif
|
||||
|
||||
fs->net = createNet();
|
||||
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
EM_ASM_
|
||||
(
|
||||
{
|
||||
var dir = "";
|
||||
Module.Pointer_stringify($0).split("/").forEach(function(val)
|
||||
EM_ASM_
|
||||
(
|
||||
{
|
||||
if(val.length)
|
||||
var dir = "";
|
||||
Module.Pointer_stringify($0).split("/").forEach(function(val)
|
||||
{
|
||||
dir += "/" + val;
|
||||
FS.mkdir(dir);
|
||||
}
|
||||
});
|
||||
|
||||
FS.mount(IDBFS, {}, dir);
|
||||
FS.syncfs(true, function(error)
|
||||
{
|
||||
if(error) console.log(error);
|
||||
else Runtime.dynCall('vi', $1, [$2]);
|
||||
});
|
||||
}, fs->dir, callback, fs
|
||||
);
|
||||
if(val.length)
|
||||
{
|
||||
dir += "/" + val;
|
||||
FS.mkdir(dir);
|
||||
}
|
||||
});
|
||||
|
||||
FS.mount(IDBFS, {}, dir);
|
||||
FS.syncfs(true, function(error)
|
||||
{
|
||||
if(error) console.log(error);
|
||||
else Runtime.dynCall('vi', $1, [$2]);
|
||||
});
|
||||
}, fs->dir, callback, fs
|
||||
);
|
||||
#else
|
||||
callback(fs);
|
||||
callback(fs);
|
||||
#endif
|
||||
}
|
||||
}
|
9
src/fs.h
9
src/fs.h
|
@ -47,7 +47,7 @@ typedef void(*OpenCallback)(const char* name, const void* buffer, size_t size, v
|
|||
|
||||
typedef struct FileSystem FileSystem;
|
||||
|
||||
void createFileSystem(void(*callback)(FileSystem*));
|
||||
void createFileSystem(const char* path, void(*callback)(FileSystem*));
|
||||
|
||||
void fsEnumFiles(FileSystem* fs, ListCallback callback, void* data);
|
||||
void fsAddFile(FileSystem* fs, AddCallback callback, void* data);
|
||||
|
@ -60,14 +60,19 @@ void* fsLoadFile(FileSystem* fs, const char* name, s32* size);
|
|||
void* fsLoadRootFile(FileSystem* fs, const char* name, s32* size);
|
||||
void fsMakeDir(FileSystem* fs, const char* name);
|
||||
bool fsExistsFile(FileSystem* fs, const char* name);
|
||||
u64 fsMDate(FileSystem* fs, const char* name);
|
||||
|
||||
const char* fsBasename(const char *path);
|
||||
const char* fsFilename(const char *path);
|
||||
const char* fsFullname(const char *path);
|
||||
bool fsExists(const char* name);
|
||||
void* fsReadFile(const char* path, s32* size);
|
||||
bool fsWriteFile(const char* path, const void* data, s32 size);
|
||||
bool fsCopyFile(const char* src, const char* dst);
|
||||
void fsGetFileData(GetCallback callback, const char* name, void* buffer, size_t size, u32 mode, void* data);
|
||||
void fsOpenFileData(OpenCallback callback, void* data);
|
||||
void fsOpenWorkingFolder(FileSystem* fs);
|
||||
int fsOpenSystemPath(FileSystem* fs, const char* path);
|
||||
s32 fsOpenSystemPath(FileSystem* fs, const char* path);
|
||||
bool fsIsDir(FileSystem* fs, const char* dir);
|
||||
bool fsIsInPublicDir(FileSystem* fs);
|
||||
bool fsChangeDir(FileSystem* fs, const char* dir);
|
||||
|
|
18
src/jsapi.c
18
src/jsapi.c
|
@ -512,7 +512,7 @@ static duk_ret_t duk_pmem(duk_context* duk)
|
|||
|
||||
u32 index = duk_to_int(duk, 0);
|
||||
|
||||
if(index < TIC_PERSISTENT_SIZE)
|
||||
if(index >= 0 && index < TIC_PERSISTENT_SIZE)
|
||||
{
|
||||
s32 val = memory->ram.persistent.data[index];
|
||||
|
||||
|
@ -645,10 +645,10 @@ static duk_ret_t duk_tri(duk_context* duk)
|
|||
|
||||
static duk_ret_t duk_textri(duk_context* duk)
|
||||
{
|
||||
s32 pt[12];
|
||||
float pt[12];
|
||||
|
||||
for (s32 i = 0; i < COUNT_OF(pt); i++)
|
||||
pt[i] = duk_to_int(duk, i);
|
||||
pt[i] = (float)duk_to_number(duk, i);
|
||||
tic_mem* memory = (tic_mem*)getDukMachine(duk);
|
||||
bool use_map = duk_is_null_or_undefined(duk, 12) ? false : duk_to_boolean(duk, 12);
|
||||
u8 chroma = duk_is_null_or_undefined(duk, 13) ? 0xff : duk_to_int(duk, 13);
|
||||
|
@ -703,13 +703,10 @@ static duk_ret_t duk_sync(duk_context* duk)
|
|||
{
|
||||
tic_mem* memory = (tic_mem*)getDukMachine(duk);
|
||||
|
||||
memory->api.sync(memory, true);
|
||||
bool toCart = duk_is_null_or_undefined(duk, 0) ? true : duk_to_boolean(duk, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
memory->api.sync(memory, toCart);
|
||||
|
||||
static duk_ret_t duk_dofile(duk_context* duk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -771,11 +768,6 @@ static void initDuktape(tic_machine* machine)
|
|||
duk_push_c_function(machine->js, ApiFunc[i].func, ApiFunc[i].params);
|
||||
duk_put_global_string(machine->js, ApiKeywords[i]);
|
||||
}
|
||||
|
||||
{
|
||||
duk_push_c_function(machine->js, duk_dofile, 1);
|
||||
duk_put_global_string(machine->js, "dofile");
|
||||
}
|
||||
}
|
||||
|
||||
bool initJavascript(tic_machine* machine, const char* code)
|
||||
|
|
32
src/luaapi.c
32
src/luaapi.c
|
@ -299,7 +299,7 @@ static s32 lua_textri(lua_State* lua)
|
|||
float pt[12];
|
||||
|
||||
for (s32 i = 0; i < COUNT_OF(pt); i++)
|
||||
pt[i] = getLuaNumber(lua, i + 1);
|
||||
pt[i] = (float)lua_tonumber(lua, i + 1);
|
||||
|
||||
tic_mem* memory = (tic_mem*)getLuaMachine(lua);
|
||||
u8 chroma = 0xff;
|
||||
|
@ -745,7 +745,12 @@ static s32 lua_sync(lua_State* lua)
|
|||
{
|
||||
tic_mem* memory = (tic_mem*)getLuaMachine(lua);
|
||||
|
||||
memory->api.sync(memory, true);
|
||||
bool toCart = true;
|
||||
|
||||
if(lua_gettop(lua) >= 1)
|
||||
toCart = lua_toboolean(lua, 1);
|
||||
|
||||
memory->api.sync(memory, toCart);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -956,18 +961,21 @@ static s32 lua_pmem(lua_State *lua)
|
|||
if(top >= 1)
|
||||
{
|
||||
u32 index = getLuaNumber(lua, 1);
|
||||
index %= TIC_PERSISTENT_SIZE;
|
||||
|
||||
s32 val = memory->ram.persistent.data[index];
|
||||
|
||||
if(top >= 2)
|
||||
if(index >= 0 && index < TIC_PERSISTENT_SIZE)
|
||||
{
|
||||
memory->ram.persistent.data[index] = getLuaNumber(lua, 2);
|
||||
s32 val = memory->ram.persistent.data[index];
|
||||
|
||||
if(top >= 2)
|
||||
{
|
||||
memory->ram.persistent.data[index] = getLuaNumber(lua, 2);
|
||||
}
|
||||
|
||||
lua_pushinteger(lua, val);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pushinteger(lua, val);
|
||||
|
||||
return 1;
|
||||
luaL_error(lua, "invalid persistent memory index\n");
|
||||
}
|
||||
else luaL_error(lua, "invalid params, pmem(index [val]) -> val\n");
|
||||
|
||||
|
@ -1013,7 +1021,7 @@ static s32 lua_mouse(lua_State *lua)
|
|||
|
||||
static s32 lua_dofile(lua_State *lua)
|
||||
{
|
||||
luaL_error(lua, "you can use 'dofile' only on first line\n");
|
||||
luaL_error(lua, "unknown method: \"dofile\"\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -999,7 +999,7 @@ static void copyFromClipboard(Map* map)
|
|||
{
|
||||
u8* data = SDL_malloc(size);
|
||||
|
||||
str2buf(clipboard, data, true);
|
||||
str2buf(clipboard, strlen(clipboard), data, true);
|
||||
|
||||
if(data[0] * data[1] == size - 2)
|
||||
{
|
||||
|
|
|
@ -598,7 +598,7 @@ static void copyFromClipboard(Music* music)
|
|||
{
|
||||
u8* data = SDL_malloc(size);
|
||||
|
||||
str2buf(clipboard, data, true);
|
||||
str2buf(clipboard, strlen(clipboard), data, true);
|
||||
|
||||
ClipboardHeader header = {0};
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ static void tick(Run* run)
|
|||
return;
|
||||
|
||||
if(!run->init)
|
||||
{
|
||||
{
|
||||
run->tickData.start = run->tickData.counter(),
|
||||
run->init = true;
|
||||
}
|
||||
|
|
12
src/sprite.c
12
src/sprite.c
|
@ -637,6 +637,12 @@ static void drawRGBSlider(Sprite* sprite, s32 x, s32 y, u8* value)
|
|||
}
|
||||
}
|
||||
|
||||
static void pasteColor(Sprite* sprite)
|
||||
{
|
||||
fromClipboard(sprite->tic->cart.palette.data, sizeof(tic_palette), false);
|
||||
fromClipboard(&sprite->tic->cart.palette.colors[sprite->color], sizeof(tic_rgb), false);
|
||||
}
|
||||
|
||||
static void drawRGBTools(Sprite* sprite, s32 x, s32 y)
|
||||
{
|
||||
{
|
||||
|
@ -713,8 +719,7 @@ static void drawRGBTools(Sprite* sprite, s32 x, s32 y)
|
|||
|
||||
if(checkMouseClick(&rect, SDL_BUTTON_LEFT))
|
||||
{
|
||||
fromClipboard(sprite->tic->cart.palette.data, sizeof(tic_palette), false);
|
||||
sprite->tic->api.reset(sprite->tic);
|
||||
pasteColor(sprite);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1194,6 +1199,9 @@ static void cutToClipboard(Sprite* sprite)
|
|||
|
||||
static void copyFromClipboard(Sprite* sprite)
|
||||
{
|
||||
if(sprite->editPalette)
|
||||
pasteColor(sprite);
|
||||
|
||||
s32 size = sprite->size * sprite->size * TIC_PALETTE_BPP / BITS_IN_BYTE;
|
||||
u8* buffer = SDL_malloc(size);
|
||||
|
||||
|
|
340
src/studio.c
340
src/studio.c
|
@ -47,14 +47,16 @@
|
|||
#include "ext/md5.h"
|
||||
|
||||
#define STUDIO_UI_SCALE 3
|
||||
#define STUDIO_UI_BORDER 16
|
||||
|
||||
#define TEXTURE_SIZE (TIC80_FULLWIDTH)
|
||||
|
||||
#define MAX_CONTROLLERS 4
|
||||
#define STUDIO_PIXEL_FORMAT SDL_PIXELFORMAT_ARGB8888
|
||||
|
||||
#define MAX_OFFSET 128
|
||||
#define FULL_WIDTH (TIC80_WIDTH + MAX_OFFSET*2)
|
||||
#define FRAME_SIZE (TIC80_WIDTH * TIC80_HEIGHT * sizeof(u32))
|
||||
#define FRAME_SIZE (TIC80_FULLWIDTH * TIC80_FULLHEIGHT * sizeof(u32))
|
||||
|
||||
#define OFFSET_LEFT ((TIC80_FULLWIDTH-TIC80_WIDTH)/2)
|
||||
#define OFFSET_TOP ((TIC80_FULLHEIGHT-TIC80_HEIGHT)/2)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -76,12 +78,15 @@ static struct
|
|||
tic80_local* tic80local;
|
||||
tic_mem* tic;
|
||||
|
||||
CartHash hash;
|
||||
struct
|
||||
{
|
||||
CartHash hash;
|
||||
u64 mdate;
|
||||
}cart;
|
||||
|
||||
SDL_Window* window;
|
||||
SDL_Renderer* renderer;
|
||||
SDL_Texture* texture;
|
||||
SDL_Texture* borderTexture;
|
||||
|
||||
SDL_AudioSpec audioSpec;
|
||||
SDL_AudioDeviceID audioDevice;
|
||||
|
@ -196,9 +201,13 @@ static struct
|
|||
.window = NULL,
|
||||
.renderer = NULL,
|
||||
.texture = NULL,
|
||||
.borderTexture = NULL,
|
||||
.audioDevice = 0,
|
||||
|
||||
.cart =
|
||||
{
|
||||
.mdate = 0,
|
||||
},
|
||||
|
||||
.joysticks = {NULL, NULL, NULL, NULL},
|
||||
|
||||
.mode = TIC_START_MODE,
|
||||
|
@ -341,13 +350,11 @@ void toClipboard(const void* data, s32 size, bool flip)
|
|||
}
|
||||
}
|
||||
|
||||
void str2buf(const char* str, void* buf, bool flip)
|
||||
void str2buf(const char* str, s32 size, void* buf, bool flip)
|
||||
{
|
||||
char val[] = "0x00";
|
||||
const char* ptr = str;
|
||||
|
||||
s32 size = (s32)strlen(str);
|
||||
|
||||
for(s32 i = 0; i < size/2; i++)
|
||||
{
|
||||
if(flip)
|
||||
|
@ -377,7 +384,7 @@ bool fromClipboard(void* data, s32 size, bool flip)
|
|||
{
|
||||
bool valid = strlen(clipboard) == size * 2;
|
||||
|
||||
if(valid) str2buf(clipboard, data, flip);
|
||||
if(valid) str2buf(clipboard, strlen(clipboard), data, flip);
|
||||
|
||||
SDL_free(clipboard);
|
||||
|
||||
|
@ -720,6 +727,11 @@ void gotoSurf()
|
|||
setStudioMode(TIC_SURF_MODE);
|
||||
}
|
||||
|
||||
void gotoCode()
|
||||
{
|
||||
setStudioMode(TIC_CODE_MODE);
|
||||
}
|
||||
|
||||
static void initMenuMode()
|
||||
{
|
||||
initMenu(&studio.menu, studio.tic, studio.fs);
|
||||
|
@ -757,6 +769,8 @@ void exitFromGameMenu()
|
|||
{
|
||||
setStudioMode(TIC_CONSOLE_MODE);
|
||||
}
|
||||
|
||||
studio.console.showGameMenu = false;
|
||||
}
|
||||
|
||||
void setStudioMode(EditorMode mode)
|
||||
|
@ -884,7 +898,12 @@ void setCursor(SDL_SystemCursor id)
|
|||
|
||||
void hideDialog()
|
||||
{
|
||||
setStudioMode(studio.dialogMode);
|
||||
if(studio.dialogMode == TIC_RUN_MODE)
|
||||
{
|
||||
studio.tic->api.resume(studio.tic);
|
||||
studio.mode = TIC_RUN_MODE;
|
||||
}
|
||||
else setStudioMode(studio.dialogMode);
|
||||
}
|
||||
|
||||
void showDialog(const char** text, s32 rows, DialogCallback callback, void* data)
|
||||
|
@ -909,7 +928,12 @@ static void initModules()
|
|||
|
||||
static void updateHash()
|
||||
{
|
||||
md5(&studio.tic->cart, sizeof(tic_cartridge), studio.hash.data);
|
||||
md5(&studio.tic->cart, sizeof(tic_cartridge), studio.cart.hash.data);
|
||||
}
|
||||
|
||||
static void updateMDate()
|
||||
{
|
||||
studio.cart.mdate = fsMDate(studio.console.fs, studio.console.romName);
|
||||
}
|
||||
|
||||
static void updateTitle()
|
||||
|
@ -926,6 +950,7 @@ void studioRomSaved()
|
|||
{
|
||||
updateTitle();
|
||||
updateHash();
|
||||
updateMDate();
|
||||
}
|
||||
|
||||
void studioRomLoaded()
|
||||
|
@ -934,6 +959,7 @@ void studioRomLoaded()
|
|||
|
||||
updateTitle();
|
||||
updateHash();
|
||||
updateMDate();
|
||||
}
|
||||
|
||||
bool studioCartChanged()
|
||||
|
@ -941,7 +967,7 @@ bool studioCartChanged()
|
|||
CartHash hash;
|
||||
md5(&studio.tic->cart, sizeof(tic_cartridge), hash.data);
|
||||
|
||||
return memcmp(hash.data, studio.hash.data, sizeof(CartHash)) != 0;
|
||||
return memcmp(hash.data, studio.cart.hash.data, sizeof(CartHash)) != 0;
|
||||
}
|
||||
|
||||
static void updateGamepadParts();
|
||||
|
@ -957,7 +983,9 @@ static void calcTextureRect(SDL_Rect* rect)
|
|||
|
||||
rect->x = (rect->w - discreteWidth) / 2;
|
||||
|
||||
rect->y = rect->w > rect->h ? (rect->h - discreteHeight) / 2 : 0;
|
||||
rect->y = rect->w > rect->h
|
||||
? (rect->h - discreteHeight) / 2
|
||||
: OFFSET_LEFT*discreteWidth/TIC80_WIDTH;
|
||||
|
||||
rect->w = discreteWidth;
|
||||
rect->h = discreteHeight;
|
||||
|
@ -1401,78 +1429,38 @@ static u32* paletteBlit()
|
|||
return srcPaletteBlit(studio.tic->ram.vram.palette.data);
|
||||
}
|
||||
|
||||
static void blit(u32* out, u32* bgOut, s32 pitch, s32 bgPitch)
|
||||
static void screen2buffer(u32* buffer, const u32* pixels, SDL_Rect rect)
|
||||
{
|
||||
const s32 pitchWidth = pitch/sizeof *out;
|
||||
const s32 bgPitchWidth = bgPitch/sizeof *bgOut;
|
||||
u32* row = out;
|
||||
const u32* pal = paletteBlit();
|
||||
pixels += rect.y * TIC80_FULLWIDTH;
|
||||
|
||||
void(*scanline)(tic_mem* memory, s32 row) = NULL;
|
||||
|
||||
switch(studio.mode)
|
||||
for(s32 i = 0; i < rect.h; i++)
|
||||
{
|
||||
case TIC_RUN_MODE:
|
||||
scanline = studio.tic->api.scanline;
|
||||
break;
|
||||
case TIC_SPRITE_MODE:
|
||||
scanline = studio.sprite.scanline;
|
||||
break;
|
||||
case TIC_MAP_MODE:
|
||||
scanline = studio.map.scanline;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for(s32 r = 0, pos = 0; r < TIC80_HEIGHT; r++, row += pitchWidth)
|
||||
{
|
||||
if(scanline)
|
||||
{
|
||||
scanline(studio.tic, r);
|
||||
pal = paletteBlit();
|
||||
}
|
||||
|
||||
if(bgOut)
|
||||
{
|
||||
u8 border = tic_tool_peek4(studio.tic->ram.vram.mapping, studio.tic->ram.vram.vars.border & 0xf);
|
||||
SDL_memset4(bgOut, pal[border], TIC80_WIDTH);
|
||||
bgOut += bgPitchWidth;
|
||||
}
|
||||
|
||||
SDL_memset4(row, 0, pitchWidth);
|
||||
|
||||
for(u32* ptr = row + MAX_OFFSET + studio.tic->ram.vram.vars.offset.x, c = 0; c < TIC80_WIDTH; c++, ptr++)
|
||||
*ptr = pal[tic_tool_peek4(studio.tic->ram.vram.screen.data, pos++)];
|
||||
}
|
||||
}
|
||||
|
||||
static void screen2buffer(u32* buffer, const u8* pixels, s32 pitch)
|
||||
{
|
||||
for(s32 i = 0; i < TIC80_HEIGHT; i++)
|
||||
{
|
||||
SDL_memcpy(buffer, pixels+MAX_OFFSET * sizeof(u32), TIC80_WIDTH * sizeof(u32));
|
||||
pixels += pitch;
|
||||
buffer += TIC80_WIDTH;
|
||||
SDL_memcpy(buffer, pixels + rect.x, rect.w * sizeof(pixels[0]));
|
||||
pixels += TIC80_FULLWIDTH;
|
||||
buffer += rect.w;
|
||||
}
|
||||
}
|
||||
|
||||
static void setCoverImage()
|
||||
{
|
||||
tic_mem* tic = studio.tic;
|
||||
|
||||
if(studio.mode == TIC_RUN_MODE)
|
||||
{
|
||||
enum {Pitch = FULL_WIDTH*sizeof(u32)};
|
||||
u32* pixels = SDL_malloc(Pitch * TIC80_HEIGHT);
|
||||
enum {Pitch = TIC80_FULLWIDTH*sizeof(u32)};
|
||||
u32* pixels = SDL_malloc(Pitch * TIC80_FULLHEIGHT);
|
||||
|
||||
if(pixels)
|
||||
{
|
||||
blit(pixels, NULL, Pitch, 0);
|
||||
tic->api.blit(tic, pixels, tic->api.scanline);
|
||||
|
||||
u32* buffer = SDL_malloc(TIC80_WIDTH * TIC80_HEIGHT * sizeof(u32));
|
||||
|
||||
if(buffer)
|
||||
{
|
||||
screen2buffer(buffer, (const u8*)pixels, Pitch);
|
||||
SDL_Rect rect = {OFFSET_LEFT, OFFSET_TOP, TIC80_WIDTH, TIC80_HEIGHT};
|
||||
|
||||
screen2buffer(buffer, pixels, rect);
|
||||
|
||||
gif_write_animation(studio.tic->cart.cover.data, &studio.tic->cart.cover.size,
|
||||
TIC80_WIDTH, TIC80_HEIGHT, (const u8*)buffer, 1, TIC_FRAMERATE, 1);
|
||||
|
@ -1503,7 +1491,7 @@ static void stopVideoRecord()
|
|||
s32 size = 0;
|
||||
u8* data = SDL_malloc(FRAME_SIZE * studio.video.frame);
|
||||
|
||||
gif_write_animation(data, &size, TIC80_WIDTH, TIC80_HEIGHT, (const u8*)studio.video.buffer, studio.video.frame, TIC_FRAMERATE, getConfig()->gifScale);
|
||||
gif_write_animation(data, &size, TIC80_FULLWIDTH, TIC80_FULLHEIGHT, (const u8*)studio.video.buffer, studio.video.frame, TIC_FRAMERATE, getConfig()->gifScale);
|
||||
|
||||
fsGetFileData(onVideoExported, "screen.gif", data, size, DEFAULT_CHMOD, NULL);
|
||||
}
|
||||
|
@ -1710,6 +1698,16 @@ static void processMouseInput()
|
|||
studio.tic->ram.vram.input.gamepad.pressed = studio.mouse.state->down ? 1 : 0;
|
||||
}
|
||||
|
||||
#if defined(TIC80_PRO)
|
||||
|
||||
static void reloadConfirm(bool yes, void* data)
|
||||
{
|
||||
if(yes)
|
||||
studio.console.updateProject(&studio.console);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
SDL_Event* pollEvent()
|
||||
{
|
||||
static SDL_Event event;
|
||||
|
@ -1751,9 +1749,38 @@ SDL_Event* pollEvent()
|
|||
{
|
||||
case SDL_WINDOWEVENT_RESIZED: updateGamepadParts(); break;
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||
|
||||
#if defined(TIC80_PRO)
|
||||
|
||||
if(studio.mode != TIC_START_MODE)
|
||||
{
|
||||
studio.console.codeLiveReload.reload(&studio.console,studio.code.data);
|
||||
if(studio.code.update)
|
||||
Console* console = &studio.console;
|
||||
|
||||
u64 mdate = fsMDate(console->fs, console->romName);
|
||||
|
||||
if(mdate > studio.cart.mdate)
|
||||
{
|
||||
if(studioCartChanged())
|
||||
{
|
||||
static const char* Rows[] =
|
||||
{
|
||||
"",
|
||||
"CART HAS CHANGED!",
|
||||
"",
|
||||
"DO YOU WANT",
|
||||
"TO RELOAD IT?"
|
||||
};
|
||||
|
||||
showDialog(Rows, COUNT_OF(Rows), reloadConfirm, NULL);
|
||||
}
|
||||
else console->updateProject(console);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
{
|
||||
studio.console.codeLiveReload.reload(&studio.console, studio.code.data);
|
||||
if(studio.console.codeLiveReload.active && studio.code.update)
|
||||
studio.code.update(&studio.code);
|
||||
}
|
||||
break;
|
||||
|
@ -1830,6 +1857,7 @@ static void blitSound()
|
|||
{
|
||||
s32 samples = studio.audioSpec.freq / TIC_FRAMERATE;
|
||||
|
||||
// TODO: use SDL_ConvertAudio to covert format
|
||||
if(studio.audioSpec.format == AUDIO_F32)
|
||||
{
|
||||
if(!studio.floatSamples)
|
||||
|
@ -1847,7 +1875,7 @@ static void blitSound()
|
|||
SDL_QueueAudio(studio.audioDevice, studio.tic->samples.buffer, studio.tic->samples.size);
|
||||
}
|
||||
|
||||
static void drawRecordLabel(u8* frame, s32 pitch, s32 sx, s32 sy, const u32* color)
|
||||
static void drawRecordLabel(u32* frame, s32 pitch, s32 sx, s32 sy, const u32* color)
|
||||
{
|
||||
static const u16 RecLabel[] =
|
||||
{
|
||||
|
@ -1863,23 +1891,24 @@ static void drawRecordLabel(u8* frame, s32 pitch, s32 sx, s32 sy, const u32* col
|
|||
for(s32 x = 0; x < sizeof RecLabel[0]*BITS_IN_BYTE; x++)
|
||||
{
|
||||
if(RecLabel[y] & (1 << x))
|
||||
memcpy(&frame[((MAX_OFFSET + sx) + 15 - x + (y+sy)*(pitch/4))*4], color, sizeof *color);
|
||||
memcpy(&frame[sx + 15 - x + (y+sy)*TIC80_FULLWIDTH], color, sizeof *color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void recordFrame(u8* pixels, s32 pitch)
|
||||
static void recordFrame(u32* pixels)
|
||||
{
|
||||
if(studio.video.record)
|
||||
{
|
||||
if(studio.video.frame < studio.video.frames)
|
||||
{
|
||||
screen2buffer(studio.video.buffer + (TIC80_WIDTH*TIC80_HEIGHT) * studio.video.frame, pixels, pitch);
|
||||
SDL_Rect rect = {0, 0, TIC80_FULLWIDTH, TIC80_FULLHEIGHT};
|
||||
screen2buffer(studio.video.buffer + (TIC80_FULLWIDTH*TIC80_FULLHEIGHT) * studio.video.frame, pixels, rect);
|
||||
|
||||
if(studio.video.frame % TIC_FRAMERATE < TIC_FRAMERATE / 2)
|
||||
{
|
||||
const u32* pal = srcPaletteBlit(studio.tic->config.palette.data);
|
||||
drawRecordLabel(pixels, pitch, TIC80_WIDTH-24, 8, &pal[tic_color_red]);
|
||||
drawRecordLabel(pixels, TIC80_FULLWIDTH, TIC80_WIDTH-24, 8, &pal[tic_color_red]);
|
||||
}
|
||||
|
||||
studio.video.frame++;
|
||||
|
@ -1894,43 +1923,74 @@ static void recordFrame(u8* pixels, s32 pitch)
|
|||
|
||||
static void blitTexture()
|
||||
{
|
||||
tic_mem* tic = studio.tic;
|
||||
SDL_Rect rect = {0, 0, 0, 0};
|
||||
calcTextureRect(&rect);
|
||||
|
||||
const s32 Pixel = rect.w / TIC80_WIDTH;
|
||||
rect.x -= MAX_OFFSET * Pixel;
|
||||
rect.w = rect.w * FULL_WIDTH / TIC80_WIDTH;
|
||||
|
||||
void* pixels = NULL;
|
||||
s32 pitch = 0;
|
||||
SDL_LockTexture(studio.texture, NULL, &pixels, &pitch);
|
||||
|
||||
if(studio.mode == TIC_RUN_MODE)
|
||||
tic_scanline scanline = NULL;
|
||||
|
||||
switch(studio.mode)
|
||||
{
|
||||
rect.y += studio.tic->ram.vram.vars.offset.y * Pixel;
|
||||
|
||||
{
|
||||
void* bgPixels = NULL;
|
||||
s32 bgPitch = 0;
|
||||
SDL_LockTexture(studio.borderTexture, NULL, &bgPixels, &bgPitch);
|
||||
blit(pixels, bgPixels, pitch, bgPitch);
|
||||
SDL_UnlockTexture(studio.borderTexture);
|
||||
|
||||
{
|
||||
SDL_Rect srcRect = {0, 0, TIC80_WIDTH, TIC80_HEIGHT};
|
||||
SDL_RenderCopy(studio.renderer, studio.borderTexture, &srcRect, NULL);
|
||||
}
|
||||
}
|
||||
case TIC_RUN_MODE:
|
||||
scanline = tic->api.scanline;
|
||||
break;
|
||||
case TIC_SPRITE_MODE:
|
||||
scanline = studio.sprite.scanline;
|
||||
break;
|
||||
case TIC_MAP_MODE:
|
||||
scanline = studio.map.scanline;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else blit(pixels, NULL, pitch, 0);
|
||||
|
||||
recordFrame(pixels, pitch);
|
||||
tic->api.blit(tic, pixels, scanline);
|
||||
|
||||
recordFrame(pixels);
|
||||
|
||||
SDL_UnlockTexture(studio.texture);
|
||||
|
||||
{
|
||||
SDL_Rect srcRect = {0, 0, FULL_WIDTH, TIC80_HEIGHT};
|
||||
SDL_RenderCopy(studio.renderer, studio.texture, &srcRect, &rect);
|
||||
enum {Header = OFFSET_TOP};
|
||||
SDL_Rect srcRect = {0, 0, TIC80_FULLWIDTH, Header};
|
||||
SDL_Rect dstRect = {0};
|
||||
SDL_GetWindowSize(studio.window, &dstRect.w, &dstRect.h);
|
||||
dstRect.h = rect.y;
|
||||
SDL_RenderCopy(studio.renderer, studio.texture, &srcRect, &dstRect);
|
||||
}
|
||||
|
||||
{
|
||||
enum {Header = OFFSET_TOP};
|
||||
SDL_Rect srcRect = {0, TIC80_FULLHEIGHT - Header, TIC80_FULLWIDTH, Header};
|
||||
SDL_Rect dstRect = {0};
|
||||
SDL_GetWindowSize(studio.window, &dstRect.w, &dstRect.h);
|
||||
dstRect.y = rect.y + rect.h;
|
||||
dstRect.h = rect.y;
|
||||
SDL_RenderCopy(studio.renderer, studio.texture, &srcRect, &dstRect);
|
||||
}
|
||||
|
||||
{
|
||||
enum {Header = OFFSET_TOP};
|
||||
enum {Left = OFFSET_LEFT};
|
||||
SDL_Rect srcRect = {0, Header, Left, TIC80_HEIGHT};
|
||||
SDL_Rect dstRect = {0};
|
||||
SDL_GetWindowSize(studio.window, &dstRect.w, &dstRect.h);
|
||||
dstRect.y = rect.y;
|
||||
dstRect.h = rect.h;
|
||||
SDL_RenderCopy(studio.renderer, studio.texture, &srcRect, &dstRect);
|
||||
}
|
||||
|
||||
{
|
||||
enum {Top = OFFSET_TOP};
|
||||
enum {Left = OFFSET_LEFT};
|
||||
|
||||
SDL_Rect srcRect = {Left, Top, TIC80_WIDTH, TIC80_HEIGHT};
|
||||
|
||||
SDL_RenderCopy(studio.renderer, studio.texture, &srcRect, &rect);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2012,6 +2072,8 @@ static void useSystemPalette()
|
|||
|
||||
static void renderStudio()
|
||||
{
|
||||
tic_mem* tic = studio.tic;
|
||||
|
||||
showTooltip("");
|
||||
|
||||
studio.gesture.active = false;
|
||||
|
@ -2067,6 +2129,9 @@ static void renderStudio()
|
|||
TIC80_HEIGHT - TIC_FONT_HEIGHT, (tic_color_white));
|
||||
}
|
||||
|
||||
if(getConfig()->noSound)
|
||||
SDL_memset(tic->ram.registers, 0, sizeof tic->ram.registers);
|
||||
|
||||
studio.tic->api.tick_end(studio.tic);
|
||||
|
||||
blitSound();
|
||||
|
@ -2175,11 +2240,6 @@ static void tick()
|
|||
SDL_SystemCursor cursor = studio.mouse.system;
|
||||
studio.mouse.system = SDL_SYSTEM_CURSOR_ARROW;
|
||||
|
||||
{
|
||||
const u8* pal = (u8*)(paletteBlit() + tic_tool_peek4(studio.tic->ram.vram.mapping, studio.tic->ram.vram.vars.border & 0xf));
|
||||
SDL_SetRenderDrawColor(studio.renderer, pal[2], pal[1], pal[0], SDL_ALPHA_OPAQUE);
|
||||
}
|
||||
|
||||
SDL_RenderClear(studio.renderer);
|
||||
|
||||
renderStudio();
|
||||
|
@ -2212,14 +2272,6 @@ static void initSound()
|
|||
SDL_PauseAudioDevice(studio.audioDevice, 0);
|
||||
}
|
||||
|
||||
static s32 textureLog2(s32 val)
|
||||
{
|
||||
u32 rom = 0;
|
||||
while( val >>= 1 ) rom++;
|
||||
|
||||
return 1 << ++rom;
|
||||
}
|
||||
|
||||
static void initTouchGamepad()
|
||||
{
|
||||
if (!studio.renderer)
|
||||
|
@ -2229,8 +2281,7 @@ static void initTouchGamepad()
|
|||
|
||||
if(!studio.gamepad.texture)
|
||||
{
|
||||
studio.gamepad.texture = SDL_CreateTexture(studio.renderer, STUDIO_PIXEL_FORMAT, SDL_TEXTUREACCESS_STREAMING,
|
||||
textureLog2(TIC80_WIDTH), textureLog2(TIC80_HEIGHT));
|
||||
studio.gamepad.texture = SDL_CreateTexture(studio.renderer, STUDIO_PIXEL_FORMAT, SDL_TEXTUREACCESS_STREAMING, TEXTURE_SIZE, TEXTURE_SIZE);
|
||||
SDL_SetTextureBlendMode(studio.gamepad.texture, SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
|
||||
|
@ -2329,13 +2380,13 @@ static void onFSInitialized(FileSystem* fs)
|
|||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
|
||||
|
||||
studio.window = SDL_CreateWindow( TIC_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
(TIC80_WIDTH+STUDIO_UI_BORDER) * STUDIO_UI_SCALE,
|
||||
(TIC80_HEIGHT+STUDIO_UI_BORDER) * STUDIO_UI_SCALE,
|
||||
(TIC80_FULLWIDTH) * STUDIO_UI_SCALE,
|
||||
(TIC80_FULLHEIGHT) * STUDIO_UI_SCALE,
|
||||
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE
|
||||
#if defined(__ARM_LINUX__)
|
||||
| SDL_WINDOW_FULLSCREEN_DESKTOP
|
||||
#if defined(__CHIP__)
|
||||
| SDL_WINDOW_FULLSCREEN_DESKTOP
|
||||
#endif
|
||||
);
|
||||
);
|
||||
|
||||
initSound();
|
||||
|
||||
|
@ -2363,22 +2414,15 @@ static void onFSInitialized(FileSystem* fs)
|
|||
// set the window icon before renderer is created (issues on Linux)
|
||||
setWindowIcon();
|
||||
|
||||
#if defined(__ARM_LINUX__)
|
||||
s32 renderFlags = SDL_RENDERER_SOFTWARE;
|
||||
studio.renderer = SDL_CreateRenderer(studio.window, -1,
|
||||
#if defined(__CHIP__)
|
||||
SDL_RENDERER_SOFTWARE
|
||||
#else
|
||||
s32 renderFlags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC;
|
||||
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
|
||||
#endif
|
||||
);
|
||||
|
||||
studio.renderer = SDL_CreateRenderer(studio.window, -1, renderFlags);
|
||||
studio.texture = SDL_CreateTexture(studio.renderer, STUDIO_PIXEL_FORMAT, SDL_TEXTUREACCESS_STREAMING,
|
||||
textureLog2(FULL_WIDTH), textureLog2(TIC80_HEIGHT));
|
||||
|
||||
#if !defined(__ARM_LINUX__)
|
||||
SDL_SetTextureBlendMode(studio.texture, SDL_BLENDMODE_BLEND);
|
||||
#endif
|
||||
|
||||
studio.borderTexture = SDL_CreateTexture(studio.renderer, STUDIO_PIXEL_FORMAT, SDL_TEXTUREACCESS_STREAMING,
|
||||
textureLog2(TIC80_WIDTH), textureLog2(TIC80_HEIGHT));
|
||||
studio.texture = SDL_CreateTexture(studio.renderer, STUDIO_PIXEL_FORMAT, SDL_TEXTUREACCESS_STREAMING, TEXTURE_SIZE, TEXTURE_SIZE);
|
||||
|
||||
initTouchGamepad();
|
||||
}
|
||||
|
@ -2390,7 +2434,7 @@ static void onFSInitialized(FileSystem* fs)
|
|||
void onEmscriptenWget(const char* file)
|
||||
{
|
||||
studio.argv[1] = DEFAULT_CART;
|
||||
createFileSystem(onFSInitialized);
|
||||
createFileSystem(NULL, onFSInitialized);
|
||||
}
|
||||
|
||||
void onEmscriptenWgetError(const char* error) {}
|
||||
|
@ -2417,29 +2461,30 @@ s32 main(s32 argc, char **argv)
|
|||
{
|
||||
emscripten_async_wget(studio.argv[1], DEFAULT_CART, onEmscriptenWget, onEmscriptenWgetError);
|
||||
}
|
||||
else createFileSystem(onFSInitialized);
|
||||
else createFileSystem(NULL, onFSInitialized);
|
||||
|
||||
emscripten_set_main_loop(tick, TIC_FRAMERATE == 60 ? 0 : TIC_FRAMERATE, 1);
|
||||
#else
|
||||
|
||||
createFileSystem(onFSInitialized);
|
||||
createFileSystem(argc > 1 && fsExists(argv[1]) ? fsBasename(argv[1]) : NULL, onFSInitialized);
|
||||
|
||||
u64 nextTick = SDL_GetPerformanceCounter();
|
||||
const u64 Delta = SDL_GetPerformanceFrequency() / TIC_FRAMERATE;
|
||||
|
||||
while (!studio.quitFlag)
|
||||
{
|
||||
nextTick += Delta;
|
||||
tick();
|
||||
u64 nextTick = SDL_GetPerformanceCounter();
|
||||
const u64 Delta = SDL_GetPerformanceFrequency() / TIC_FRAMERATE;
|
||||
|
||||
while (!studio.quitFlag)
|
||||
{
|
||||
nextTick += Delta;
|
||||
tick();
|
||||
|
||||
s64 delay = nextTick - SDL_GetPerformanceCounter();
|
||||
s64 delay = nextTick - SDL_GetPerformanceCounter();
|
||||
|
||||
if(delay > 0)
|
||||
SDL_Delay((u32)(delay * 1000 / SDL_GetPerformanceFrequency()));
|
||||
else nextTick -= delay;
|
||||
if(delay > 0)
|
||||
SDL_Delay((u32)(delay * 1000 / SDL_GetPerformanceFrequency()));
|
||||
else nextTick -= delay;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
if(studio.tic80local)
|
||||
|
@ -2450,7 +2495,6 @@ s32 main(s32 argc, char **argv)
|
|||
|
||||
SDL_DestroyTexture(studio.gamepad.texture);
|
||||
SDL_DestroyTexture(studio.texture);
|
||||
SDL_DestroyTexture(studio.borderTexture);
|
||||
|
||||
if(studio.mouse.texture)
|
||||
SDL_DestroyTexture(studio.mouse.texture);
|
||||
|
|
|
@ -60,6 +60,11 @@
|
|||
#define KEYMAP_DAT "keymap.dat"
|
||||
#define KEYMAP_DAT_PATH TIC_LOCAL KEYMAP_DAT
|
||||
|
||||
#define CART_EXT ".tic"
|
||||
#define PROJECT_LUA_EXT ".lua"
|
||||
#define PROJECT_MOON_EXT ".moon"
|
||||
#define PROJECT_JS_EXT ".js"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
|
@ -100,6 +105,7 @@ typedef struct
|
|||
s32 gifLength;
|
||||
|
||||
bool checkNewVersion;
|
||||
bool noSound;
|
||||
|
||||
} StudioConfig;
|
||||
|
||||
|
@ -146,7 +152,7 @@ EditorMode getStudioMode();
|
|||
void exitStudio();
|
||||
u32 unzip(u8** dest, const u8* source, size_t size);
|
||||
|
||||
void str2buf(const char* str, void* buf, bool flip);
|
||||
void str2buf(const char* str, s32 size, void* buf, bool flip);
|
||||
void toClipboard(const void* data, s32 size, bool flip);
|
||||
bool fromClipboard(void* data, s32 size, bool flip);
|
||||
|
||||
|
@ -189,6 +195,7 @@ bool studioCartChanged();
|
|||
void playSystemSfx(s32 id);
|
||||
|
||||
void runGameFromSurf();
|
||||
void gotoCode();
|
||||
void gotoSurf();
|
||||
void exitFromGameMenu();
|
||||
void runProject();
|
||||
|
|
62
src/surf.c
62
src/surf.c
|
@ -38,7 +38,7 @@
|
|||
#define COVER_Y 5
|
||||
#define COVER_X (TIC80_WIDTH - COVER_WIDTH - COVER_Y)
|
||||
|
||||
#if defined(__WINDOWS__) || (defined(__LINUX__) && !defined(__ARM_LINUX__)) || defined(__MACOSX__)
|
||||
#if defined(__WINDOWS__) || defined(__LINUX__) || defined(__MACOSX__)
|
||||
#define CAN_OPEN_URL 1
|
||||
#endif
|
||||
|
||||
|
@ -155,6 +155,7 @@ struct MenuItem
|
|||
s32 id;
|
||||
tic_screen* cover;
|
||||
bool dir;
|
||||
bool project;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
|
@ -372,18 +373,35 @@ static void replace(char* src, const char* what, const char* with)
|
|||
}
|
||||
}
|
||||
|
||||
static bool hasExt(const char* name, const char* ext)
|
||||
{
|
||||
return strcmp(name + strlen(name) - strlen(ext), ext) == 0;
|
||||
}
|
||||
|
||||
static void cutExt(char* name, const char* ext)
|
||||
{
|
||||
name[strlen(name)-strlen(ext)] = '\0';
|
||||
}
|
||||
|
||||
static bool addMenuItem(const char* name, const char* info, s32 id, void* ptr, bool dir)
|
||||
{
|
||||
AddMenuItem* data = (AddMenuItem*)ptr;
|
||||
|
||||
static const char CartExt[] = ".tic";
|
||||
static const char CartExt[] = CART_EXT;
|
||||
|
||||
if(dir || (strstr(name, CartExt) == name + strlen(name) - sizeof(CartExt)+1))
|
||||
if(dir
|
||||
|| hasExt(name, CartExt)
|
||||
#if defined(TIC80_PRO)
|
||||
|| hasExt(name, PROJECT_LUA_EXT)
|
||||
|| hasExt(name, PROJECT_MOON_EXT)
|
||||
|| hasExt(name, PROJECT_JS_EXT)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
MenuItem* item = &data->items[data->count++];
|
||||
|
||||
item->name = SDL_strdup(name);
|
||||
|
||||
bool project = false;
|
||||
if(dir)
|
||||
{
|
||||
char folder[FILENAME_MAX];
|
||||
|
@ -394,7 +412,14 @@ static bool addMenuItem(const char* name, const char* info, s32 id, void* ptr, b
|
|||
{
|
||||
|
||||
item->label = SDL_strdup(name);
|
||||
item->label[strlen(item->label)-sizeof(CartExt)+1] = '\0';
|
||||
|
||||
if(hasExt(name, CartExt))
|
||||
cutExt(item->label, CartExt);
|
||||
else
|
||||
{
|
||||
project = true;
|
||||
}
|
||||
|
||||
|
||||
replace(item->label, "&", "&");
|
||||
replace(item->label, "'", "'");
|
||||
|
@ -404,6 +429,7 @@ static bool addMenuItem(const char* name, const char* info, s32 id, void* ptr, b
|
|||
item->id = id;
|
||||
item->dir = dir;
|
||||
item->cover = NULL;
|
||||
item->project = project;
|
||||
}
|
||||
|
||||
return data->count < MAX_CARTS;
|
||||
|
@ -509,7 +535,10 @@ static void loadCover(Surf* surf)
|
|||
|
||||
if(cart)
|
||||
{
|
||||
tic->api.load(cart, data, size, true);
|
||||
if(hasExt(item->name, PROJECT_LUA_EXT))
|
||||
surf->console->loadProject(surf->console, item->name, data, size, cart);
|
||||
else
|
||||
tic->api.load(cart, data, size, true);
|
||||
|
||||
if(cart->cover.size)
|
||||
updateMenuItemCover(surf, cart->cover.data, cart->cover.size);
|
||||
|
@ -617,7 +646,26 @@ static void onPlayCart(Surf* surf)
|
|||
{
|
||||
MenuItem* item = &surf->menu.items[surf->menu.pos];
|
||||
|
||||
surf->console->load(surf->console, item->name);
|
||||
if(item->project)
|
||||
{
|
||||
tic_cartridge* cart = SDL_malloc(sizeof(tic_cartridge));
|
||||
|
||||
if(cart)
|
||||
{
|
||||
s32 size = 0;
|
||||
void* data = fsLoadFile(surf->fs, item->name, &size);
|
||||
|
||||
surf->console->loadProject(surf->console, item->name, data, size, cart);
|
||||
|
||||
SDL_memcpy(&surf->tic->cart, cart, sizeof(tic_cartridge));
|
||||
|
||||
studioRomLoaded();
|
||||
|
||||
SDL_free(cart);
|
||||
}
|
||||
}
|
||||
else
|
||||
surf->console->load(surf->console, item->name);
|
||||
|
||||
runGameFromSurf();
|
||||
}
|
||||
|
|
269
src/tic.c
269
src/tic.c
|
@ -53,7 +53,7 @@ typedef enum
|
|||
CHUNK_TEMP3, // 8
|
||||
CHUNK_SOUND, // 9
|
||||
CHUNK_WAVEFORM, // 10
|
||||
CHUNK_OLDMUSIC, // 11
|
||||
CHUNK_TEMP4, // 11
|
||||
CHUNK_PALETTE, // 12
|
||||
CHUNK_PATTERNS, // 13
|
||||
CHUNK_MUSIC, // 14
|
||||
|
@ -83,17 +83,17 @@ static void update_amp(blip_buffer_t* blip, tic_sound_register_data* data, s32 n
|
|||
blip_add_delta( blip, data->time, delta );
|
||||
}
|
||||
|
||||
inline s32 freq2note(double freq)
|
||||
static inline s32 freq2note(double freq)
|
||||
{
|
||||
return (s32)round((double)NOTES * log2(freq / BASE_NOTE_FREQ)) + BASE_NOTE_POS;
|
||||
}
|
||||
|
||||
inline double note2freq(s32 note)
|
||||
static inline double note2freq(s32 note)
|
||||
{
|
||||
return pow(2, (note - BASE_NOTE_POS) / (double)NOTES) * BASE_NOTE_FREQ;
|
||||
}
|
||||
|
||||
inline s32 freq2period(double freq)
|
||||
static inline s32 freq2period(double freq)
|
||||
{
|
||||
if(freq == 0.0) return MAX_PERIOD_VALUE;
|
||||
|
||||
|
@ -106,7 +106,7 @@ inline s32 freq2period(double freq)
|
|||
return period;
|
||||
}
|
||||
|
||||
inline s32 getAmp(const tic_sound_register* reg, s32 amp)
|
||||
static inline s32 getAmp(const tic_sound_register* reg, s32 amp)
|
||||
{
|
||||
enum {MaxAmp = (u16)-1 / (MAX_VOLUME * TIC_SOUND_CHANNELS)};
|
||||
|
||||
|
@ -149,18 +149,18 @@ static void resetPalette(tic_mem* memory)
|
|||
memory->ram.vram.vars.mask.data = TIC_GAMEPAD_MASK;
|
||||
}
|
||||
|
||||
static void setPixel(tic_machine* machine, s32 x, s32 y, u8 color)
|
||||
static inline void setPixel(tic_machine* machine, s32 x, s32 y, u8 color)
|
||||
{
|
||||
if(x < machine->state.clip.l || y < machine->state.clip.t || x >= machine->state.clip.r || y >= machine->state.clip.b) return;
|
||||
|
||||
tic_tool_poke4(machine->memory.ram.vram.screen.data, y * TIC80_WIDTH + x, tic_tool_peek4(machine->memory.ram.vram.mapping, color));
|
||||
tic_tool_poke4(machine->memory.ram.vram.screen.data, y * TIC80_WIDTH + x, tic_tool_peek4(machine->memory.ram.vram.mapping, color & 0xf));
|
||||
}
|
||||
|
||||
static u8 getPixel(tic_machine* machine, s32 x, s32 y)
|
||||
{
|
||||
if(x < 0 || y < 0 || x >= TIC80_WIDTH || y >= TIC80_HEIGHT) return 0;
|
||||
|
||||
return tic_tool_peek4(machine->memory.ram.vram.mapping, tic_tool_peek4(machine->memory.ram.vram.screen.data, y * TIC80_WIDTH + x));
|
||||
return tic_tool_peek4(machine->memory.ram.vram.screen.data, y * TIC80_WIDTH + x);
|
||||
}
|
||||
|
||||
static void drawHLine(tic_machine* machine, s32 x, s32 y, s32 width, u8 color)
|
||||
|
@ -200,62 +200,63 @@ static void drawRectBorder(tic_machine* machine, s32 x, s32 y, s32 width, s32 he
|
|||
drawVLine(machine, x + width - 1, y, height, color);
|
||||
}
|
||||
|
||||
static void drawRectRev(tic_machine* machine, s32 y, s32 x, s32 height, s32 width, u8 color)
|
||||
{
|
||||
drawRect(machine, x, y, width, height, color);
|
||||
}
|
||||
|
||||
static void drawTile(tic_machine* machine, const tic_tile* buffer, s32 x, s32 y, u8* colors, s32 count, s32 scale, tic_flip flip, tic_rotate rotate)
|
||||
{
|
||||
static u8 transparent[TIC_PALETTE_SIZE];
|
||||
memset(transparent, 0, sizeof(transparent));
|
||||
for (s32 i = 0; i < count; i++) transparent[colors[i]] = 1;
|
||||
|
||||
flip &= 0b11;
|
||||
rotate &= 0b11;
|
||||
|
||||
s32 a = flip & tic_horz_flip ? -scale : scale;
|
||||
s32 b = flip & tic_vert_flip ? -scale : scale;
|
||||
if (flip == 0 && rotate == 0 && scale == 1) {
|
||||
// the most common path
|
||||
s32 i = 0;
|
||||
for(s32 py=0; py < TIC_SPRITESIZE; py++, y++)
|
||||
{
|
||||
s32 xx = x;
|
||||
for(s32 px=0; px < TIC_SPRITESIZE; px++, xx++)
|
||||
{
|
||||
u8 color = tic_tool_peek4(buffer, i++);
|
||||
if(!transparent[color]) setPixel(machine, xx, y, color);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void(*drawRectFunc)(tic_machine*, s32, s32, s32, s32, u8) = drawRect;
|
||||
s32 a = flip & tic_horz_flip ? -1 : 1;
|
||||
s32 b = flip & tic_vert_flip ? -1 : 1;
|
||||
|
||||
if(rotate == tic_90_rotate) a = -a;
|
||||
else if(rotate == tic_180_rotate) a = -a, b = -b;
|
||||
else if(rotate == tic_270_rotate) b = -b;
|
||||
|
||||
x += (scale - a) * (TIC_SPRITESIZE - 1) >> 1;
|
||||
y += (scale - b) * (TIC_SPRITESIZE - 1) >> 1;
|
||||
bool swap_axis = (rotate == tic_90_rotate || rotate == tic_270_rotate);
|
||||
|
||||
if(rotate == tic_90_rotate || rotate == tic_270_rotate)
|
||||
for(s32 py=0; py < TIC_SPRITESIZE; py++, y+=scale)
|
||||
{
|
||||
s32 t = a; a = b; b = t;
|
||||
t = x; x = y; y = t;
|
||||
drawRectFunc = drawRectRev;
|
||||
}
|
||||
|
||||
for(s32 i = 0, px = 0, xx = x; i < TIC_SPRITESIZE * TIC_SPRITESIZE; px++, xx += a, i++)
|
||||
{
|
||||
if(px == TIC_SPRITESIZE) px = 0, xx = x, y += b;
|
||||
|
||||
u8 color = tic_tool_peek4(buffer, i);
|
||||
|
||||
if(count == 1)
|
||||
s32 xx = x;
|
||||
for(s32 px=0; px < TIC_SPRITESIZE; px++, xx+=scale)
|
||||
{
|
||||
if(*colors != color)
|
||||
drawRectFunc(machine, xx, y, scale, scale, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool draw = true;
|
||||
for(s32 i = 0; i < count; i++)
|
||||
{
|
||||
if(color == colors[i])
|
||||
{
|
||||
draw = false;
|
||||
break;
|
||||
s32 i;
|
||||
s32 ix, iy;
|
||||
ix = a == 1 ? px : TIC_SPRITESIZE - px - 1;
|
||||
iy = b == 1 ? py : TIC_SPRITESIZE - py - 1;
|
||||
if(swap_axis) {
|
||||
i = ix * TIC_SPRITESIZE + iy;
|
||||
} else {
|
||||
i = iy * TIC_SPRITESIZE + ix;
|
||||
}
|
||||
u8 color = tic_tool_peek4(buffer, i);
|
||||
if(!transparent[color]) {
|
||||
if (scale == 1) {
|
||||
setPixel(machine, xx, y, color);
|
||||
} else {
|
||||
drawRect(machine, xx, y, scale, scale, color);
|
||||
}
|
||||
}
|
||||
|
||||
if(draw)
|
||||
drawRectFunc(machine, xx, y, scale, scale, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void drawMap(tic_machine* machine, const tic_gfx* src, s32 x, s32 y, s32 width, s32 height, s32 sx, s32 sy, u8 chromakey, s32 scale, RemapFunc remap, void* data)
|
||||
|
@ -493,6 +494,8 @@ static void api_clear(tic_mem* memory, u8 color)
|
|||
{
|
||||
api_rect(memory, machine->state.clip.l, machine->state.clip.t, machine->state.clip.r - machine->state.clip.l, machine->state.clip.b - machine->state.clip.t, color);
|
||||
}
|
||||
|
||||
memory->ram.vram.vars.bg = color & 0xf;
|
||||
}
|
||||
|
||||
static s32 drawChar(tic_mem* memory, u8 symbol, s32 x, s32 y, s32 width, s32 height, u8 color, s32 scale)
|
||||
|
@ -846,6 +849,7 @@ static void ticTexLine(tic_mem* memory, TexVert *v0, TexVert *v1)
|
|||
|
||||
float dy = bot->y - top->y;
|
||||
if ((s32)dy == 0) return;
|
||||
if ((s32)dy > TIC80_HEIGHT) return; // reject large polys
|
||||
|
||||
float step_x = (bot->x - top->x) / dy;
|
||||
float step_u = (bot->u - top->u) / dy;
|
||||
|
@ -864,7 +868,7 @@ static void ticTexLine(tic_mem* memory, TexVert *v0, TexVert *v1)
|
|||
}
|
||||
}
|
||||
|
||||
static void api_textri(tic_mem* memory, s32 x1, s32 y1, s32 x2, s32 y2, s32 x3, s32 y3, s32 u1, s32 v1, s32 u2, s32 v2, s32 u3, s32 v3,bool use_map,u8 chroma)
|
||||
static void api_textri(tic_mem* memory, float x1, float y1, float x2, float y2, float x3, float y3, float u1, float v1, float u2, float v2, float u3, float v3, bool use_map, u8 chroma)
|
||||
{
|
||||
tic_machine* machine = (tic_machine*)memory;
|
||||
TexVert V0, V1, V2;
|
||||
|
@ -1375,77 +1379,15 @@ static void api_tick(tic_mem* memory, tic_tick_data* data)
|
|||
{
|
||||
cart2ram(memory);
|
||||
|
||||
char* code = machine->memory.cart.code.data;
|
||||
if(code && strlen(code))
|
||||
const char* code = machine->memory.cart.code.data;
|
||||
|
||||
if(strlen(code))
|
||||
{
|
||||
static const char DoFileTag[] = "dofile(";
|
||||
enum {Size = sizeof DoFileTag - 1};
|
||||
|
||||
if (memcmp(code, DoFileTag, Size) == 0)
|
||||
{
|
||||
const char* start = code + Size;
|
||||
const char* end = strchr(start, ')');
|
||||
|
||||
if(end && *start == *(end-1) && (*start == '"' || *start == '\''))
|
||||
{
|
||||
char filename[FILENAME_MAX] = {0};
|
||||
memcpy(filename, start + 1, end - start - 2);
|
||||
|
||||
FILE* file = fopen(filename, "rb");
|
||||
|
||||
if(file)
|
||||
{
|
||||
fseek(file, 0, SEEK_END);
|
||||
s32 size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
if(size > 0)
|
||||
{
|
||||
if(size > TIC_CODE_SIZE)
|
||||
{
|
||||
char buffer[256];
|
||||
sprintf(buffer, "code is larger than %i symbols", TIC_CODE_SIZE);
|
||||
machine->data->error(machine->data->data, buffer);
|
||||
|
||||
fclose(file);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
void* buffer = malloc(size+1);
|
||||
|
||||
if(buffer)
|
||||
{
|
||||
memset(buffer, 0, size+1);
|
||||
|
||||
if(fread(buffer, size, 1, file)) {}
|
||||
|
||||
code = buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
char buffer[256];
|
||||
sprintf(buffer, "dofile: file '%s' not found", filename);
|
||||
machine->data->error(machine->data->data, buffer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memory->input = compareMetatag(code, "input", "mouse") ? tic_mouse_input : tic_gamepad_input;
|
||||
|
||||
|
||||
if(memory->input == tic_mouse_input)
|
||||
memory->ram.vram.vars.mask.data = 0;
|
||||
|
||||
//////////////////////////
|
||||
|
||||
memory->script = tic_script_lua;
|
||||
|
||||
if (isMoonscript(code))
|
||||
|
@ -1465,13 +1407,13 @@ static void api_tick(tic_mem* memory, tic_tick_data* data)
|
|||
else if(!initLua(machine, code))
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: possible memory leak if script not initialozed
|
||||
if(code != machine->memory.cart.code.data)
|
||||
free(code);
|
||||
else
|
||||
{
|
||||
machine->data->error(machine->data->data, "the code is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
machine->state.scanline = memory->script == tic_script_js ? callJavascriptScanline : callLuaScanline;
|
||||
|
||||
machine->state.initialized = true;
|
||||
}
|
||||
|
||||
|
@ -1637,6 +1579,96 @@ static s32 api_save(const tic_cartridge* cart, u8* buffer)
|
|||
return (s32)(buffer - start);
|
||||
}
|
||||
|
||||
// copied from SDL2
|
||||
static inline void memset4(void *dst, u32 val, u32 dwords)
|
||||
{
|
||||
#if defined(__GNUC__) && defined(i386)
|
||||
s32 u0, u1, u2;
|
||||
__asm__ __volatile__ (
|
||||
"cld \n\t"
|
||||
"rep ; stosl \n\t"
|
||||
: "=&D" (u0), "=&a" (u1), "=&c" (u2)
|
||||
: "0" (dst), "1" (val), "2" (dwords)
|
||||
: "memory"
|
||||
);
|
||||
#else
|
||||
u32 _n = (dwords + 3) / 4;
|
||||
u32 *_p = (u32*)dst;
|
||||
u32 _val = (val);
|
||||
if (dwords == 0)
|
||||
return;
|
||||
switch (dwords % 4)
|
||||
{
|
||||
case 0: do { *_p++ = _val;
|
||||
case 3: *_p++ = _val;
|
||||
case 2: *_p++ = _val;
|
||||
case 1: *_p++ = _val;
|
||||
} while ( --_n );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static u32* paletteBlit(tic_mem* tic)
|
||||
{
|
||||
static u32 pal[TIC_PALETTE_SIZE] = {0};
|
||||
|
||||
const u8* src = tic->ram.vram.palette.data;
|
||||
|
||||
memset(pal, 0xff, sizeof pal);
|
||||
|
||||
u8* dst = (u8*)pal;
|
||||
const u8* end = src + sizeof(tic_palette);
|
||||
|
||||
enum{RGB = sizeof(tic_rgb)};
|
||||
|
||||
for(; src != end; dst++, src+=RGB)
|
||||
for(s32 j = 0; j < RGB; j++)
|
||||
*dst++ = *(src+(RGB-1)-j);
|
||||
|
||||
return pal;
|
||||
}
|
||||
|
||||
static void api_blit(tic_mem* tic, u32* out, tic_scanline scanline)
|
||||
{
|
||||
const u32* pal = paletteBlit(tic);
|
||||
|
||||
if(scanline)
|
||||
{
|
||||
scanline(tic, 0);
|
||||
pal = paletteBlit(tic);
|
||||
}
|
||||
|
||||
enum {Top = (TIC80_FULLHEIGHT-TIC80_HEIGHT)/2, Bottom = Top};
|
||||
enum {Left = (TIC80_FULLWIDTH-TIC80_WIDTH)/2, Right = Left};
|
||||
|
||||
memset4(&out[0 * TIC80_FULLWIDTH], pal[tic->ram.vram.vars.border], TIC80_FULLWIDTH*Top);
|
||||
|
||||
u32* rowPtr = out + Top*TIC80_FULLWIDTH;
|
||||
|
||||
for(s32 r = 0, y = tic->ram.vram.vars.offset.y; r < TIC80_HEIGHT; r++, y++, rowPtr += TIC80_FULLWIDTH)
|
||||
{
|
||||
memset4(rowPtr, pal[tic->ram.vram.vars.border], Left);
|
||||
memset4(rowPtr + Left, pal[tic->ram.vram.vars.bg], TIC80_WIDTH);
|
||||
|
||||
u32* colPtr = rowPtr + Left;
|
||||
|
||||
if(y >= 0 && y < TIC80_HEIGHT)
|
||||
for(s32 c = 0, x = tic->ram.vram.vars.offset.x, index = y * TIC80_WIDTH + x; c < TIC80_WIDTH; c++, colPtr++, x++, index++)
|
||||
if(x >= 0 && x < TIC80_WIDTH)
|
||||
*colPtr = pal[tic_tool_peek4(tic->ram.vram.screen.data, index)];
|
||||
|
||||
memset4(rowPtr + (TIC80_FULLWIDTH-Right), pal[tic->ram.vram.vars.border], Right);
|
||||
|
||||
if(scanline && (r < TIC80_HEIGHT-1))
|
||||
{
|
||||
scanline(tic, r+1);
|
||||
pal = paletteBlit(tic);
|
||||
}
|
||||
}
|
||||
|
||||
memset4(&out[(TIC80_FULLHEIGHT-Bottom) * TIC80_FULLWIDTH], pal[tic->ram.vram.vars.border], TIC80_FULLWIDTH*Bottom);
|
||||
}
|
||||
|
||||
static void initApi(tic_api* api)
|
||||
{
|
||||
#define INIT_API(func) api->func = api_##func
|
||||
|
@ -1681,6 +1713,7 @@ static void initApi(tic_api* api)
|
|||
INIT_API(save);
|
||||
INIT_API(tick_start);
|
||||
INIT_API(tick_end);
|
||||
INIT_API(blit);
|
||||
|
||||
#undef INIT_API
|
||||
}
|
||||
|
|
23
src/tic.h
23
src/tic.h
|
@ -27,17 +27,23 @@
|
|||
#include "defines.h"
|
||||
|
||||
#define TIC_VERSION_MAJOR 0
|
||||
#define TIC_VERSION_MINOR 47
|
||||
#define TIC_VERSION_MINOR 50
|
||||
#define TIC_VERSION_PATCH 0
|
||||
#define TIC_VERSION_STATUS ""
|
||||
|
||||
#if defined(TIC80_PRO)
|
||||
#define TIC_VERSION_POST " Pro"
|
||||
#else
|
||||
#define TIC_VERSION_POST ""
|
||||
#endif
|
||||
|
||||
#define TIC_MAKE_VERSION(major, minor, patch) ((major) * 10000 + (minor) * 100 + (patch))
|
||||
#define TIC_VERSION TIC_MAKE_VERSION(MYPROJ_VERSION_MAJOR, MYPROJ_VERSION_MINOR, MYPROJ_VERSION_PATCH)
|
||||
|
||||
#define DEF2STR2(x) #x
|
||||
#define DEF2STR(x) DEF2STR2(x)
|
||||
|
||||
#define TIC_VERSION_LABEL DEF2STR(TIC_VERSION_MAJOR) "." DEF2STR(TIC_VERSION_MINOR) "." DEF2STR(TIC_VERSION_PATCH) TIC_VERSION_STATUS
|
||||
#define TIC_VERSION_LABEL DEF2STR(TIC_VERSION_MAJOR) "." DEF2STR(TIC_VERSION_MINOR) "." DEF2STR(TIC_VERSION_PATCH) TIC_VERSION_STATUS TIC_VERSION_POST
|
||||
#define TIC_PACKAGE "com.nesbox.tic"
|
||||
#define TIC_NAME "TIC-80"
|
||||
#define TIC_NAME_FULL TIC_NAME " tiny computer"
|
||||
|
@ -302,8 +308,8 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
u8 data [TIC80_WIDTH * TIC80_HEIGHT * sizeof(u32)];
|
||||
s32 size;
|
||||
u8 data [TIC80_WIDTH * TIC80_HEIGHT * sizeof(u32)];
|
||||
} tic_cover_image;
|
||||
|
||||
typedef struct
|
||||
|
@ -355,7 +361,16 @@ typedef union
|
|||
|
||||
struct
|
||||
{
|
||||
u8 border;
|
||||
union
|
||||
{
|
||||
u8 colors;
|
||||
|
||||
struct
|
||||
{
|
||||
u8 border:TIC_PALETTE_BPP;
|
||||
u8 bg:TIC_PALETTE_BPP;
|
||||
};
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
|
|
48
src/tic80.c
48
src/tic80.c
|
@ -111,52 +111,6 @@ TIC80_API void tic80_load(tic80* tic, void* cart, s32 size)
|
|||
}
|
||||
}
|
||||
|
||||
static u32* srcPaletteBlit(const u8* src)
|
||||
{
|
||||
static u32 pal[TIC_PALETTE_SIZE] = { 0 };
|
||||
|
||||
memset(pal, 0xff, sizeof pal);
|
||||
|
||||
u8* dst = (u8*)pal;
|
||||
const u8* end = src + sizeof(tic_palette);
|
||||
|
||||
enum { RGB = sizeof(tic_rgb) };
|
||||
|
||||
for (; src != end; dst++, src += RGB)
|
||||
for (s32 j = 0; j < RGB; j++)
|
||||
*dst++ = *(src + (RGB - 1) - j);
|
||||
|
||||
return pal;
|
||||
}
|
||||
|
||||
static u32* paletteBlit(tic_mem* memory)
|
||||
{
|
||||
return srcPaletteBlit(memory->ram.vram.palette.data);
|
||||
}
|
||||
|
||||
static void blit(tic80* tic)
|
||||
{
|
||||
tic80_local* tic80 = (tic80_local*)tic;
|
||||
|
||||
u32* screen = tic->screen;
|
||||
u32* border = tic->border;
|
||||
|
||||
tic->offset.x = tic80->memory->ram.vram.vars.offset.x;
|
||||
tic->offset.y = tic80->memory->ram.vram.vars.offset.y;
|
||||
|
||||
for (s32 r = 0, pos = 0; r < TIC80_HEIGHT; r++, screen += TIC80_WIDTH)
|
||||
{
|
||||
tic80->memory->api.scanline(tic80->memory, r);
|
||||
const u32* pal = paletteBlit(tic80->memory);
|
||||
|
||||
tic->offset.rows[r] = tic80->memory->ram.vram.vars.offset.x;
|
||||
|
||||
*border++ = pal[tic_tool_peek4(tic80->memory->ram.vram.mapping, tic80->memory->ram.vram.vars.border & 0xf)];
|
||||
for (u32* ptr = screen, c = 0; c < TIC80_WIDTH; c++, ptr++)
|
||||
*ptr = pal[tic_tool_peek4(tic80->memory->ram.vram.screen.data, pos++)];
|
||||
}
|
||||
}
|
||||
|
||||
TIC80_API void tic80_tick(tic80* tic, tic80_input input)
|
||||
{
|
||||
tic80_local* tic80 = (tic80_local*)tic;
|
||||
|
@ -167,7 +121,7 @@ TIC80_API void tic80_tick(tic80* tic, tic80_input input)
|
|||
tic80->memory->api.tick(tic80->memory, &tic80->tickData);
|
||||
tic80->memory->api.tick_end(tic80->memory);
|
||||
|
||||
blit(tic);
|
||||
tic80->memory->api.blit(tic80->memory, tic->screen, tic80->memory->api.scanline);
|
||||
|
||||
TickCounter++;
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ typedef struct
|
|||
} tic_tick_data;
|
||||
|
||||
typedef struct tic_mem tic_mem;
|
||||
typedef void(*tic_scanline)(tic_mem* memory, s32 row);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -82,7 +83,7 @@ typedef struct
|
|||
void (*circle) (tic_mem* memory, s32 x, s32 y, u32 radius, u8 color);
|
||||
void (*circle_border) (tic_mem* memory, s32 x, s32 y, u32 radius, u8 color);
|
||||
void (*tri) (tic_mem* memory, s32 x1, s32 y1, s32 x2, s32 y2, s32 x3, s32 y3, u8 color);
|
||||
void (*textri) (tic_mem* memory, s32 x1, s32 y1, s32 x2, s32 y2, s32 x3, s32 y3, s32 u1, s32 v1, s32 u2, s32 v2, s32 u3, s32 v3 ,bool use_map,u8 chroma);
|
||||
void(*textri) (tic_mem* memory, float x1, float y1, float x2, float y2, float x3, float y3, float u1, float v1, float u2, float v2, float u3, float v3, bool use_map, u8 chroma);
|
||||
void (*clip) (tic_mem* memory, s32 x, s32 y, s32 width, s32 height);
|
||||
void (*sfx) (tic_mem* memory, s32 index, s32 note, s32 octave, s32 duration, s32 channel);
|
||||
void (*sfx_stop) (tic_mem* memory, s32 channel);
|
||||
|
@ -104,6 +105,7 @@ typedef struct
|
|||
|
||||
void (*tick_start) (tic_mem* memory, const tic_sound* src);
|
||||
void (*tick_end) (tic_mem* memory);
|
||||
void (*blit) (tic_mem* tic, u32* out, tic_scanline scanline);
|
||||
|
||||
tic_script_lang (*get_script)(tic_mem* memory);
|
||||
} tic_api;
|
||||
|
|
24
src/tools.c
24
src/tools.c
|
@ -25,28 +25,8 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
void tic_tool_poke4(void* addr, u32 index, u8 value)
|
||||
{
|
||||
u8* val = (u8*)addr + (index >> 1);
|
||||
|
||||
if(index & 1)
|
||||
{
|
||||
*val &= 0x0f;
|
||||
*val |= (value << 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
*val &= 0xf0;
|
||||
*val |= value & 0x0f;
|
||||
}
|
||||
}
|
||||
|
||||
u8 tic_tool_peek4(const void* addr, u32 index)
|
||||
{
|
||||
u8 val = ((u8*)addr)[index >> 1];
|
||||
|
||||
return index & 1 ? val >> 4 : val & 0xf;
|
||||
}
|
||||
extern void tic_tool_poke4(void* addr, u32 index, u8 value);
|
||||
extern u8 tic_tool_peek4(const void* addr, u32 index);
|
||||
|
||||
s32 tic_tool_get_pattern_id(const tic_track* track, s32 frame, s32 channel)
|
||||
{
|
||||
|
|
25
src/tools.h
25
src/tools.h
|
@ -24,8 +24,29 @@
|
|||
|
||||
#include "tic.h"
|
||||
|
||||
void tic_tool_poke4(void* addr, u32 index, u8 value);
|
||||
u8 tic_tool_peek4(const void* addr, u32 index);
|
||||
inline void tic_tool_poke4(void* addr, u32 index, u8 value)
|
||||
{
|
||||
u8* val = (u8*)addr + (index >> 1);
|
||||
|
||||
if(index & 1)
|
||||
{
|
||||
*val &= 0x0f;
|
||||
*val |= (value << 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
*val &= 0xf0;
|
||||
*val |= value & 0x0f;
|
||||
}
|
||||
}
|
||||
|
||||
inline u8 tic_tool_peek4(const void* addr, u32 index)
|
||||
{
|
||||
u8 val = ((u8*)addr)[index >> 1];
|
||||
|
||||
return index & 1 ? val >> 4 : val & 0xf;
|
||||
}
|
||||
|
||||
bool tic_tool_parse_note(const char* noteStr, s32* note, s32* octave);
|
||||
s32 tic_tool_get_pattern_id(const tic_track* track, s32 frame, s32 channel);
|
||||
void tic_tool_set_pattern_id(tic_track* track, s32 frame, s32 channel, s32 id);
|
||||
|
|
Loading…
Reference in New Issue