.50 version

This commit is contained in:
BADIM-PC\Vadim 2017-11-24 14:26:48 +03:00
parent 92214f13b3
commit f7de8f0d61
80 changed files with 13829 additions and 912 deletions

17
.gitignore vendored
View File

@ -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/

View File

@ -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

View File

@ -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 -->

View File

@ -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>

View File

@ -1,4 +1,4 @@
APPNAME=tic
APPNAME=tic80
APPBUNDLE=$(APPNAME).app
APPBUNDLECONTENTS=$(APPBUNDLE)/Contents
APPBUNDLEEXE=$(APPBUNDLECONTENTS)/MacOS

BIN
build/macosx/tic80Icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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" />

View File

@ -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.

View File

@ -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>

View File

@ -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>

Binary file not shown.

BIN
demos/benchmark.tic Normal file

Binary file not shown.

View File

@ -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;

View File

@ -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

BIN
lib/linux64/libSDL2.a Normal file

Binary file not shown.

BIN
lib/linux64/libgif.a Normal file

Binary file not shown.

BIN
lib/linux64/liblua.a Normal file

Binary file not shown.

BIN
lib/linux64/libz.a Normal file

Binary file not shown.

Binary file not shown.

334
makefile
View File

@ -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)

View File

@ -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)

View File

@ -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[] =
{

View File

@ -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__)

View File

@ -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*);

View File

@ -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>

1198
src/ext/gif/dgif_lib.c Normal file

File diff suppressed because it is too large Load Diff

1159
src/ext/gif/egif_lib.c Normal file

File diff suppressed because it is too large Load Diff

97
src/ext/gif/gif_err.c Normal file
View File

@ -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 */

259
src/ext/gif/gif_font.c Normal file
View File

@ -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 */

131
src/ext/gif/gif_hash.c Normal file
View File

@ -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 */

39
src/ext/gif/gif_hash.h Normal file
View File

@ -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 */

312
src/ext/gif/gif_lib.h Normal file
View File

@ -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 */

View File

@ -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 */

412
src/ext/gif/gifalloc.c Normal file
View File

@ -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 */

View File

@ -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);
}

330
src/ext/gif/quantize.c Normal file
View File

@ -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 */

96
src/ext/lpeg/HISTORY Normal file
View File

@ -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)

537
src/ext/lpeg/lpcap.c Normal file
View File

@ -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;
}

56
src/ext/lpeg/lpcap.h Normal file
View File

@ -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

1014
src/ext/lpeg/lpcode.c Normal file

File diff suppressed because it is too large Load Diff

40
src/ext/lpeg/lpcode.h Normal file
View File

@ -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

BIN
src/ext/lpeg/lpeg-128.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

1445
src/ext/lpeg/lpeg.html Normal file

File diff suppressed because it is too large Load Diff

244
src/ext/lpeg/lpprint.c Normal file
View File

@ -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

36
src/ext/lpeg/lpprint.h Normal file
View File

@ -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

1303
src/ext/lpeg/lptree.c Normal file

File diff suppressed because it is too large Load Diff

82
src/ext/lpeg/lptree.h Normal file
View File

@ -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

149
src/ext/lpeg/lptypes.h Normal file
View File

@ -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

364
src/ext/lpeg/lpvm.c Normal file
View File

@ -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;
}
}
}
/* }====================================================== */

58
src/ext/lpeg/lpvm.h Normal file
View File

@ -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

55
src/ext/lpeg/makefile Normal file
View File

@ -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

498
src/ext/lpeg/re.html Normal file
View File

@ -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>&lt;name&gt;</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 -&gt; 'string'</code></td> <td>string capture</td></tr>
<tr><td><code>p -&gt; "string"</code></td> <td>string capture</td></tr>
<tr><td><code>p -&gt; num</code></td> <td>numbered capture</td></tr>
<tr><td><code>p -&gt; name</code></td> <td>function/query/string capture
equivalent to <code>p / defs[name]</code></td></tr>
<tr><td><code>p =&gt; 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 &lt;- 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]+")) --&gt; 12 14
-- returns all words in a string
print(re.match("the number 423 is odd", "({%a+} / .)*"))
--&gt; the number is odd
-- returns the first numeral in a string
print(re.match("the number 423 is odd", "s <- {%d+} / . s"))
--&gt; 423
print(re.gsub("hello World", "[aeiou]", "."))
--&gt; 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 &lt;- "(" ([^()] / balanced)* ")" ]]
</pre>
<h3>String reversal</h3>
<p>
The next example reverses a string:
</p>
<pre class="example">
rev = re.compile[[ R &lt;- (!.) -&gt; '' / ({.} R) -&gt; '%2%1']]
print(rev:match"0123456789") --&gt; 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 &lt;- {| field (',' field)* |} (%nl / !.)
field &lt;- escaped / nonescaped
nonescaped &lt;- { [^,"%nl]* }
escaped &lt;- '"' {~ ([^"] / '""' -&gt; '"')* ~} '"'
]]
</pre>
<h3>Lua's long strings</h3>
<p>
The next example matches Lua long strings:
</p>
<pre class="example">
c = re.compile([[
longstring &lt;- ('[' {:eq: '='* :} '[' close)
close &lt;- ']' =eq ']' / . close
]])
print(c:match'[==[]]===]]]]==]===[]') --&gt; 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 &lt;- (name s)*
name &lt;- [a-z][a-z]*
s &lt;- %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 &lt;- {| (name s)* |}
name &lt;- {| {[a-z][a-z]*} |}
s &lt;- %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 &lt;- {| {:ident:' '*:} line
((=ident !' ' line) / &(=ident ' ') block)* |}
line &lt;- {[^%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 &lt;- {~ item* ~}
item &lt;- macro / [^()] / '(' item* ')'
arg &lt;- ' '* {~ (!',' item)* ~}
args &lt;- '(' arg (',' arg)* ')'
-- now we define some macros
macro &lt;- ('apply' args) -&gt; '%1(%2)'
/ ('add' args) -&gt; '%1 + %2'
/ ('mul' args) -&gt; '%1 * %2'
]]
print(p:match"add(mul(a,b), apply(f,x))") --&gt; 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 &lt;- exp !.
exp &lt;- S (grammar / alternative)
alternative &lt;- seq ('/' S seq)*
seq &lt;- prefix*
prefix &lt;- '&amp;' S prefix / '!' S prefix / suffix
suffix &lt;- primary S (([+*?]
/ '^' [+-]? num
/ '-&gt;' S (string / '{}' / name)
/ '=&gt;' S name) S)*
primary &lt;- '(' exp ')' / string / class / defined
/ '{:' (name ':')? exp ':}'
/ '=' name
/ '{}'
/ '{~' exp '~}'
/ '{' exp '}'
/ '.'
/ name S !arrow
/ '&lt;' name '&gt;' -- old-style non terminals
grammar &lt;- definition+
definition &lt;- name S arrow exp
class &lt;- '[' '^'? item (!']' item)* ']'
item &lt;- defined / range / .
range &lt;- . '-' [^]]
S &lt;- (%s / '--' [^%nl]*)* -- spaces and comments
name &lt;- [A-Za-z][A-Za-z0-9_]*
arrow &lt;- '&lt;-'
num &lt;- [0-9]+
string &lt;- '"' [^"]* '"' / "'" [^']* "'"
defined &lt;- '%' name
]=]
print(re.match(p, p)) -- a self description must match itself
</pre>
<h2><a name="license">License</a></h2>
<p>
Copyright &copy; 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>

259
src/ext/lpeg/re.lua Normal file
View File

@ -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

1503
src/ext/lpeg/test.lua Normal file

File diff suppressed because it is too large Load Diff

178
src/fs.c
View File

@ -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
}
}

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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};

View File

@ -95,7 +95,7 @@ static void tick(Run* run)
return;
if(!run->init)
{
{
run->tickData.start = run->tickData.counter(),
run->init = true;
}

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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, "&amp;", "&");
replace(item->label, "&#39;", "'");
@ -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
View File

@ -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
}

View File

@ -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
{

View File

@ -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++;
}

View File

@ -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;

View File

@ -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)
{

View File

@ -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);