stripped a lot of files out
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
||||
[submodule "Toy"]
|
||||
path = Toy
|
||||
url = https://github.com/Ratstail91/Toy
|
||||
58
Airport.sln
58
Airport.sln
@@ -1,58 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.4.33213.308
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Box", "Box.vcxproj", "{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{26360002-CC2A-469A-9B28-BA0C1AF41657} = {26360002-CC2A-469A-9B28-BA0C1AF41657}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Toy", "Toy\Toy.vcxproj", "{26360002-CC2A-469A-9B28-BA0C1AF41657}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Airport", "Airport.vcxproj", "{97F823E5-3AB8-47EF-B142-C15DD7CADF76}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{26360002-CC2A-469A-9B28-BA0C1AF41657} = {26360002-CC2A-469A-9B28-BA0C1AF41657}
|
||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79} = {348A36D9-181E-46AD-BEEB-8A3FFAA50E79}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Debug|x64.Build.0 = Debug|x64
|
||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Debug|x86.Build.0 = Debug|Win32
|
||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Release|x64.ActiveCfg = Release|x64
|
||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Release|x64.Build.0 = Release|x64
|
||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Release|x86.ActiveCfg = Release|Win32
|
||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Release|x86.Build.0 = Release|Win32
|
||||
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Debug|x64.Build.0 = Debug|x64
|
||||
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Debug|x86.Build.0 = Debug|Win32
|
||||
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Release|x64.ActiveCfg = Release|x64
|
||||
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Release|x64.Build.0 = Release|x64
|
||||
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Release|x86.ActiveCfg = Release|Win32
|
||||
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Release|x86.Build.0 = Release|Win32
|
||||
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Debug|x64.Build.0 = Debug|x64
|
||||
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Debug|x86.Build.0 = Debug|Win32
|
||||
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Release|x64.ActiveCfg = Release|x64
|
||||
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Release|x64.Build.0 = Release|x64
|
||||
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Release|x86.ActiveCfg = Release|Win32
|
||||
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {11A7E1C9-DA78-4754-9B70-3B328B0B5471}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
161
Airport.vcxproj
161
Airport.vcxproj
@@ -1,161 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="source\main.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="assets\scripts\demo\scene.toy" />
|
||||
<None Include="assets\scripts\demo\tilemap\layer-background.toy" />
|
||||
<None Include="assets\scripts\demo\tilemap\layer-walls.toy" />
|
||||
<None Include="assets\scripts\demo\tilemap\tilemap.toy" />
|
||||
<None Include="assets\scripts\empty.toy" />
|
||||
<None Include="assets\scripts\airplane.toy" />
|
||||
<None Include="assets\scripts\gameplay\drone.toy" />
|
||||
<None Include="assets\scripts\gameplay\lejana.toy" />
|
||||
<None Include="assets\scripts\gameplay\scene.toy" />
|
||||
<None Include="assets\scripts\gameplay\step-counter.toy" />
|
||||
<None Include="assets\scripts\gameplay\text.toy" />
|
||||
<None Include="assets\scripts\gameplay\tilemap.toy" />
|
||||
<None Include="assets\scripts\init.toy" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<ProjectGuid>{97F823E5-3AB8-47EF-B142-C15DD7CADF76}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<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 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 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 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>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IgnoreImportLibrary>false</IgnoreImportLibrary>
|
||||
<OutDir>$(SolutionDir)out\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)out\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Link>
|
||||
<AdditionalDependencies>SDL2main.lib;SDL2.lib;SDL2_image.lib;Toy.lib;Box.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;$(SolutionDir)box;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||
<PreprocessorDefinitions>TOY_DISABLE_REPL</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||
<PreprocessorDefinitions>TOY_DISABLE_REPL</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;$(SolutionDir)box;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>SDL2main.lib;SDL2.lib;SDL2_image.lib;Toy.lib;Box.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
170
Box.vcxproj
170
Box.vcxproj
@@ -1,170 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<ProjectGuid>{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<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 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 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 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>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)out\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)out\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;BOX_EXPORTS;BOX_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;BOX_EXPORTS;BOX_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||
<PreprocessorDefinitions>TOY_DISABLE_REPL;BOX_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;Toy.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)Toy\repl\lib*.*" "$(SolutionDir)box" /Y /I /E
|
||||
xcopy "$(SolutionDir)Toy\repl\repl_tools.*" "$(SolutionDir)box" /Y /I /E</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||
<PreprocessorDefinitions>TOY_DISABLE_REPL;BOX_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;Toy.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)Toy\repl\lib*.*" "$(SolutionDir)box" /Y /I /E
|
||||
xcopy "$(SolutionDir)Toy\repl\repl_tools.*" "$(SolutionDir)box" /Y /I /E</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="box\box_common.c" />
|
||||
<ClCompile Include="box\box_engine.c" />
|
||||
<ClCompile Include="box\box_node.c" />
|
||||
<ClCompile Include="box\dbg_profiler.c" />
|
||||
<ClCompile Include="box\lib_about.c" />
|
||||
<ClCompile Include="box\lib_engine.c" />
|
||||
<ClCompile Include="box\lib_input.c" />
|
||||
<ClCompile Include="box\lib_node.c" />
|
||||
<ClCompile Include="box\lib_random.c" />
|
||||
<ClCompile Include="box\lib_runner.c" />
|
||||
<ClCompile Include="box\lib_standard.c" />
|
||||
<ClCompile Include="box\repl_tools.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="box\box_common.h" />
|
||||
<ClInclude Include="box\box_engine.h" />
|
||||
<ClInclude Include="box\box_node.h" />
|
||||
<ClInclude Include="box\dbg_profiler.h" />
|
||||
<ClInclude Include="box\lib_about.h" />
|
||||
<ClInclude Include="box\lib_engine.h" />
|
||||
<ClInclude Include="box\lib_input.h" />
|
||||
<ClInclude Include="box\lib_node.h" />
|
||||
<ClInclude Include="box\lib_random.h" />
|
||||
<ClInclude Include="box\lib_runner.h" />
|
||||
<ClInclude Include="box\lib_standard.h" />
|
||||
<ClInclude Include="box\repl_tools.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
20
README.md
20
README.md
@@ -2,27 +2,21 @@
|
||||
|
||||
The best way to build a game engine, is to build a game first.
|
||||
|
||||
This project has now been adapted into a roguelike for the 7 day roguelike jam.
|
||||
This game utilizes the [Box Game Engine](https://github.com/Ratstail91/Box) the [Toy Programming Language](https://toylang.com).
|
||||
|
||||
This game/engine utilizes the [Toy programming langauge](https://toylang.com).
|
||||
|
||||
## Cloning
|
||||
# Cloning
|
||||
|
||||
Either clone recursively, or run `git submodule update --init` after cloning.
|
||||
|
||||
## Building
|
||||
# Building
|
||||
|
||||
We're now using Visual Studio - define the following environment variables to point to the root of each SDL2 lib:
|
||||
WIP
|
||||
|
||||
* `SDL2Dir`
|
||||
* `SDL2ImageDir`
|
||||
* `SDL2TTFDir`
|
||||
|
||||
## Running
|
||||
# Running
|
||||
|
||||
Make sure the program can see the `assets` folder (symbolic links can help), and all of the required DLLs are present.
|
||||
|
||||
## Dependencies
|
||||
# Dependencies
|
||||
|
||||
* SDL2
|
||||
* SDL2_image
|
||||
@@ -32,6 +26,6 @@ Make sure the program can see the `assets` folder (symbolic links can help), and
|
||||
|
||||
* Art - Evan Hartshorn
|
||||
* Coding - Kayne Ruse
|
||||
* Font - Ancient God (Koczman B<>lint)
|
||||
* Font - Ancient God (Koczman B<>lint)
|
||||
* Font - AlphaBeta (Brian Kent)
|
||||
|
||||
|
||||
1
Toy
1
Toy
Submodule Toy deleted from 0e41b00ef4
@@ -1,10 +0,0 @@
|
||||
#include "box_common.h"
|
||||
|
||||
STATIC_ASSERT(sizeof(char) == 1);
|
||||
STATIC_ASSERT(sizeof(short) == 2);
|
||||
STATIC_ASSERT(sizeof(int) == 4);
|
||||
STATIC_ASSERT(sizeof(float) == 4);
|
||||
STATIC_ASSERT(sizeof(unsigned char) == 1);
|
||||
STATIC_ASSERT(sizeof(unsigned short) == 2);
|
||||
STATIC_ASSERT(sizeof(unsigned int) == 4);
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define BOX_VERSION_MAJOR 0
|
||||
#define BOX_VERSION_MINOR 1
|
||||
#define BOX_VERSION_PATCH 0
|
||||
#define BOX_VERSION_BUILD __DATE__ " " __TIME__
|
||||
|
||||
//platform/compiler-specific instructions
|
||||
#if defined(__linux__) || defined(__MINGW32__) || defined(__GNUC__)
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#define BOX_API extern
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_image.h>
|
||||
#include <SDL_ttf.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <crtdbg.h>
|
||||
|
||||
#ifndef BOX_EXPORT
|
||||
#define BOX_API __declspec(dllimport)
|
||||
#else
|
||||
#define BOX_API __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
//TODO: figure out the sleep issue
|
||||
#define sleep Sleep
|
||||
|
||||
#else
|
||||
|
||||
#define BOX_API extern
|
||||
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
//test variable sizes based on platform
|
||||
#define STATIC_ASSERT(test_for_true) static_assert((test_for_true), "(" #test_for_true ") failed")
|
||||
|
||||
//debugging
|
||||
#include "dbg_profiler.h"
|
||||
482
box/box_engine.c
482
box/box_engine.c
@@ -1,482 +0,0 @@
|
||||
#include "box_engine.h"
|
||||
|
||||
#include "lib_about.h"
|
||||
#include "lib_standard.h"
|
||||
#include "lib_random.h"
|
||||
#include "lib_runner.h"
|
||||
#include "lib_engine.h"
|
||||
#include "lib_node.h"
|
||||
#include "lib_input.h"
|
||||
|
||||
#include "repl_tools.h"
|
||||
|
||||
#include "toy_memory.h"
|
||||
#include "toy_lexer.h"
|
||||
#include "toy_parser.h"
|
||||
#include "toy_compiler.h"
|
||||
#include "toy_interpreter.h"
|
||||
#include "toy_literal_array.h"
|
||||
#include "toy_literal_dictionary.h"
|
||||
|
||||
#include "toy_console_colors.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
//define the extern engine object
|
||||
Box_Engine engine;
|
||||
|
||||
//errors here should be fatal
|
||||
static void fatalError(char* message) {
|
||||
fprintf(stderr, TOY_CC_ERROR "%s" TOY_CC_RESET, message);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//exposed functions
|
||||
void Box_initEngine() {
|
||||
//clear
|
||||
engine.rootNode = NULL;
|
||||
engine.nextRootNodeFilename = TOY_TO_NULL_LITERAL;
|
||||
engine.running = false;
|
||||
engine.window = NULL;
|
||||
engine.renderer = NULL;
|
||||
|
||||
//init SDL
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||
fatalError("Failed to initialize SDL2");
|
||||
}
|
||||
|
||||
//init SDL_image
|
||||
int imageFlags = IMG_INIT_PNG | IMG_INIT_JPG;
|
||||
if (IMG_Init(imageFlags) != imageFlags) {
|
||||
fatalError("Failed to initialize SDL2_image");
|
||||
}
|
||||
|
||||
//init SDL_ttf
|
||||
if (TTF_Init() == -1) {
|
||||
fatalError("Failed to initialize SDL2_ttf");
|
||||
}
|
||||
|
||||
//init events
|
||||
Toy_initLiteralDictionary(&engine.symKeyDownEvents);
|
||||
Toy_initLiteralDictionary(&engine.symKeyUpEvents);
|
||||
|
||||
//init Toy
|
||||
Toy_initInterpreter(&engine.interpreter);
|
||||
Toy_injectNativeHook(&engine.interpreter, "about", Toy_hookAbout);
|
||||
Toy_injectNativeHook(&engine.interpreter, "standard", Toy_hookStandard);
|
||||
Toy_injectNativeHook(&engine.interpreter, "random", Toy_hookRandom);
|
||||
Toy_injectNativeHook(&engine.interpreter, "runner", Toy_hookRunner);
|
||||
Toy_injectNativeHook(&engine.interpreter, "engine", Box_hookEngine);
|
||||
Toy_injectNativeHook(&engine.interpreter, "node", Box_hookNode);
|
||||
Toy_injectNativeHook(&engine.interpreter, "input", Box_hookInput);
|
||||
|
||||
//run the init
|
||||
size_t size = 0;
|
||||
const unsigned char* source = Toy_readFile("./assets/scripts/init.toy", &size);
|
||||
|
||||
if (!source) {
|
||||
fatalError("Couldn't read /assets/scripts/init.toy");
|
||||
}
|
||||
|
||||
const unsigned char* tb = Toy_compileString((const char*)source, &size);
|
||||
free((void*)source);
|
||||
|
||||
//A quirk of the setup is that anything defined in `init.toy` becomes a global object
|
||||
Toy_runInterpreter(&engine.interpreter, tb, size);
|
||||
}
|
||||
|
||||
void Box_freeEngine() {
|
||||
//clear existing root node
|
||||
if (engine.rootNode != NULL) {
|
||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onFree", NULL);
|
||||
Box_freeNode(engine.rootNode);
|
||||
engine.rootNode = NULL;
|
||||
}
|
||||
|
||||
if (!TOY_IS_NULL(engine.nextRootNodeFilename)) {
|
||||
Toy_freeLiteral(engine.nextRootNodeFilename);
|
||||
}
|
||||
|
||||
Toy_freeInterpreter(&engine.interpreter);
|
||||
|
||||
//free events
|
||||
Toy_freeLiteralDictionary(&engine.symKeyDownEvents);
|
||||
Toy_freeLiteralDictionary(&engine.symKeyUpEvents);
|
||||
|
||||
//free SDL
|
||||
SDL_DestroyRenderer(engine.renderer);
|
||||
SDL_DestroyWindow(engine.window);
|
||||
SDL_Quit();
|
||||
|
||||
engine.renderer = NULL;
|
||||
engine.window = NULL;
|
||||
}
|
||||
|
||||
static inline void execLoadRootNode() {
|
||||
//if a new root node is NOT needed, skip out
|
||||
if (TOY_IS_NULL(engine.nextRootNodeFilename)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//free the existing root node
|
||||
if (engine.rootNode != NULL) {
|
||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onFree", NULL);
|
||||
Box_freeNode(engine.rootNode);
|
||||
engine.rootNode = NULL;
|
||||
}
|
||||
|
||||
//compile the new root node
|
||||
size_t size = 0;
|
||||
const unsigned char* source = Toy_readFile(Toy_toCString(TOY_AS_STRING(engine.nextRootNodeFilename)), &size);
|
||||
const unsigned char* tb = Toy_compileString((const char*)source, &size);
|
||||
free((void*)source);
|
||||
|
||||
//allocate the new root node
|
||||
engine.rootNode = TOY_ALLOCATE(Box_Node, 1);
|
||||
|
||||
//BUGFIX: make an inner-interpreter
|
||||
Toy_Interpreter inner;
|
||||
|
||||
//init the inner interpreter manually
|
||||
Toy_initLiteralArray(&inner.literalCache);
|
||||
inner.scope = Toy_pushScope(engine.interpreter.scope);
|
||||
inner.bytecode = tb;
|
||||
inner.length = size;
|
||||
inner.count = 0;
|
||||
inner.codeStart = -1;
|
||||
inner.depth = engine.interpreter.depth + 1;
|
||||
inner.panic = false;
|
||||
Toy_initLiteralArray(&inner.stack);
|
||||
inner.hooks = engine.interpreter.hooks;
|
||||
Toy_setInterpreterPrint(&inner, engine.interpreter.printOutput);
|
||||
Toy_setInterpreterAssert(&inner, engine.interpreter.assertOutput);
|
||||
Toy_setInterpreterError(&inner, engine.interpreter.errorOutput);
|
||||
|
||||
Box_initNode(engine.rootNode, &inner, tb, size);
|
||||
|
||||
//immediately call onLoad() after running the script - for loading other nodes
|
||||
Box_callNode(engine.rootNode, &inner, "onLoad", NULL);
|
||||
|
||||
//cache the scope for later freeing
|
||||
engine.rootNode->scope = inner.scope;
|
||||
|
||||
//manual cleanup
|
||||
Toy_freeLiteralArray(&inner.stack);
|
||||
Toy_freeLiteralArray(&inner.literalCache);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(engine.nextRootNodeFilename);
|
||||
engine.nextRootNodeFilename = TOY_TO_NULL_LITERAL;
|
||||
|
||||
//init the new node-tree
|
||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onInit", NULL);
|
||||
}
|
||||
|
||||
static inline void execEvents() {
|
||||
Toy_LiteralArray args; //save some allocation by reusing this
|
||||
Toy_initLiteralArray(&args);
|
||||
|
||||
//poll all events
|
||||
SDL_Event event;
|
||||
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch(event.type) {
|
||||
//quit
|
||||
case SDL_QUIT: {
|
||||
engine.running = false;
|
||||
}
|
||||
break;
|
||||
|
||||
//window events are handled internally
|
||||
case SDL_WINDOWEVENT: {
|
||||
switch(event.window.event) {
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
//TODO: toy onWindowResized, setLogicalWindowSize, getLogicalWindowSize
|
||||
//engine.screenWidth = event.window.data1;
|
||||
//engine.screenHeight = event.window.data2;
|
||||
//SDL_RenderSetLogicalSize(engine.renderer, engine.screenWidth, engine.screenHeight);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//input
|
||||
case SDL_KEYDOWN: {
|
||||
//bugfix: ignore repeat messages
|
||||
if (event.key.repeat) {
|
||||
break;
|
||||
}
|
||||
|
||||
//determine the given keycode
|
||||
Toy_Literal keycodeLiteral = TOY_TO_INTEGER_LITERAL( (int)(event.key.keysym.sym) );
|
||||
if (!Toy_existsLiteralDictionary(&engine.symKeyDownEvents, keycodeLiteral)) {
|
||||
Toy_freeLiteral(keycodeLiteral);
|
||||
break;
|
||||
}
|
||||
|
||||
//get the event name
|
||||
Toy_Literal eventLiteral = Toy_getLiteralDictionary(&engine.symKeyDownEvents, keycodeLiteral);
|
||||
|
||||
//call the function
|
||||
Toy_pushLiteralArray(&args, eventLiteral);
|
||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onKeyDown", &args);
|
||||
Toy_freeLiteral(Toy_popLiteralArray(&args));
|
||||
|
||||
//push to the event list
|
||||
Toy_freeLiteral(eventLiteral);
|
||||
Toy_freeLiteral(keycodeLiteral);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_KEYUP: {
|
||||
//bugfix: ignore repeat messages
|
||||
if (event.key.repeat) {
|
||||
break;
|
||||
}
|
||||
|
||||
//determine the given keycode
|
||||
Toy_Literal keycodeLiteral = TOY_TO_INTEGER_LITERAL( (int)(event.key.keysym.sym) );
|
||||
if (!Toy_existsLiteralDictionary(&engine.symKeyUpEvents, keycodeLiteral)) {
|
||||
Toy_freeLiteral(keycodeLiteral);
|
||||
break;
|
||||
}
|
||||
|
||||
//get the event name
|
||||
Toy_Literal eventLiteral = Toy_getLiteralDictionary(&engine.symKeyUpEvents, keycodeLiteral);
|
||||
|
||||
//call the function
|
||||
Toy_pushLiteralArray(&args, eventLiteral);
|
||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onKeyUp", &args);
|
||||
Toy_freeLiteral(Toy_popLiteralArray(&args));
|
||||
|
||||
//push to the event list
|
||||
Toy_freeLiteral(eventLiteral);
|
||||
Toy_freeLiteral(keycodeLiteral);
|
||||
}
|
||||
break;
|
||||
|
||||
//mouse motion
|
||||
case SDL_MOUSEMOTION: {
|
||||
Toy_Literal mouseX = TOY_TO_INTEGER_LITERAL( (int)(event.motion.x) );
|
||||
Toy_Literal mouseY = TOY_TO_INTEGER_LITERAL( (int)(event.motion.y) );
|
||||
Toy_Literal mouseXRel = TOY_TO_INTEGER_LITERAL( (int)(event.motion.xrel) );
|
||||
Toy_Literal mouseYRel = TOY_TO_INTEGER_LITERAL( (int)(event.motion.yrel) );
|
||||
|
||||
Toy_pushLiteralArray(&args, mouseX);
|
||||
Toy_pushLiteralArray(&args, mouseY);
|
||||
Toy_pushLiteralArray(&args, mouseXRel);
|
||||
Toy_pushLiteralArray(&args, mouseYRel);
|
||||
|
||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onMouseMotion", &args);
|
||||
|
||||
Toy_freeLiteral(mouseX);
|
||||
Toy_freeLiteral(mouseY);
|
||||
Toy_freeLiteral(mouseXRel);
|
||||
Toy_freeLiteral(mouseYRel);
|
||||
|
||||
//hack: manual free
|
||||
for(int i = 0; i < args.count; i++) {
|
||||
Toy_freeLiteral(args.literals[i]);
|
||||
}
|
||||
args.count = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
//mouse button down
|
||||
case SDL_MOUSEBUTTONDOWN: {
|
||||
Toy_Literal mouseX = TOY_TO_INTEGER_LITERAL( (int)(event.button.x) );
|
||||
Toy_Literal mouseY = TOY_TO_INTEGER_LITERAL( (int)(event.button.y) );
|
||||
Toy_Literal mouseButton;
|
||||
|
||||
switch (event.button.button) {
|
||||
case SDL_BUTTON_LEFT:
|
||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("left"));
|
||||
break;
|
||||
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("middle"));
|
||||
break;
|
||||
|
||||
case SDL_BUTTON_RIGHT:
|
||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("right"));
|
||||
break;
|
||||
|
||||
case SDL_BUTTON_X1:
|
||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("x1"));
|
||||
break;
|
||||
|
||||
case SDL_BUTTON_X2:
|
||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("x2"));
|
||||
break;
|
||||
|
||||
default:
|
||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("unknown"));
|
||||
break;
|
||||
}
|
||||
|
||||
Toy_pushLiteralArray(&args, mouseX);
|
||||
Toy_pushLiteralArray(&args, mouseY);
|
||||
Toy_pushLiteralArray(&args, mouseButton);
|
||||
|
||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onMouseButtonDown", &args);
|
||||
|
||||
Toy_freeLiteral(mouseX);
|
||||
Toy_freeLiteral(mouseY);
|
||||
Toy_freeLiteral(mouseButton);
|
||||
|
||||
//hack: manual free
|
||||
for(int i = 0; i < args.count; i++) {
|
||||
Toy_freeLiteral(args.literals[i]);
|
||||
}
|
||||
args.count = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
//mouse button up
|
||||
case SDL_MOUSEBUTTONUP: {
|
||||
Toy_Literal mouseX = TOY_TO_INTEGER_LITERAL( (int)(event.button.x) );
|
||||
Toy_Literal mouseY = TOY_TO_INTEGER_LITERAL( (int)(event.button.y) );
|
||||
Toy_Literal mouseButton;
|
||||
|
||||
switch (event.button.button) {
|
||||
case SDL_BUTTON_LEFT:
|
||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("left"));
|
||||
break;
|
||||
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("middle"));
|
||||
break;
|
||||
|
||||
case SDL_BUTTON_RIGHT:
|
||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("right"));
|
||||
break;
|
||||
|
||||
case SDL_BUTTON_X1:
|
||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("x1"));
|
||||
break;
|
||||
|
||||
case SDL_BUTTON_X2:
|
||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("x2"));
|
||||
break;
|
||||
|
||||
default:
|
||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("unknown"));
|
||||
break;
|
||||
}
|
||||
|
||||
Toy_pushLiteralArray(&args, mouseX);
|
||||
Toy_pushLiteralArray(&args, mouseY);
|
||||
Toy_pushLiteralArray(&args, mouseButton);
|
||||
|
||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onMouseButtonUp", &args);
|
||||
|
||||
Toy_freeLiteral(mouseX);
|
||||
Toy_freeLiteral(mouseY);
|
||||
Toy_freeLiteral(mouseButton);
|
||||
|
||||
//hack: manual free
|
||||
for(int i = 0; i < args.count; i++) {
|
||||
Toy_freeLiteral(args.literals[i]);
|
||||
}
|
||||
args.count = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
//mouse wheel
|
||||
case SDL_MOUSEWHEEL: {
|
||||
Toy_Literal mouseX = TOY_TO_INTEGER_LITERAL( (int)(event.wheel.x) );
|
||||
Toy_Literal mouseY = TOY_TO_INTEGER_LITERAL( (int)(event.wheel.y) );
|
||||
Toy_pushLiteralArray(&args, mouseX);
|
||||
Toy_pushLiteralArray(&args, mouseY);
|
||||
|
||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onMouseWheel", &args);
|
||||
|
||||
Toy_freeLiteral(mouseX);
|
||||
Toy_freeLiteral(mouseY);
|
||||
|
||||
//hack: manual free
|
||||
for(int i = 0; i < args.count; i++) {
|
||||
Toy_freeLiteral(args.literals[i]);
|
||||
}
|
||||
args.count = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Toy_freeLiteralArray(&args);
|
||||
}
|
||||
|
||||
static inline void execStep() {
|
||||
if (engine.rootNode != NULL) {
|
||||
//steps
|
||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onStep", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
//the heart of the engine
|
||||
void Box_execEngine() {
|
||||
if (!engine.running) {
|
||||
fatalError("Can't execute the engine (did you forget to initialize the screen?)");
|
||||
}
|
||||
|
||||
//set up time
|
||||
engine.realTime = clock();
|
||||
engine.simTime = engine.realTime;
|
||||
clock_t delta = (double) CLOCKS_PER_SEC / 30.0;
|
||||
|
||||
Dbg_Timer dbgTimer;
|
||||
Dbg_FPSCounter fps;
|
||||
|
||||
Dbg_initTimer(&dbgTimer);
|
||||
Dbg_initFPSCounter(&fps);
|
||||
|
||||
while (engine.running) {
|
||||
Dbg_tickFPSCounter(&fps);
|
||||
|
||||
Dbg_clearConsole();
|
||||
Dbg_printTimerLog(&dbgTimer);
|
||||
Dbg_printFPSCounter(&fps);
|
||||
|
||||
Dbg_startTimer(&dbgTimer, "execLoadRootNode()");
|
||||
execLoadRootNode();
|
||||
Dbg_stopTimer(&dbgTimer);
|
||||
|
||||
Dbg_startTimer(&dbgTimer, "execEvents()");
|
||||
execEvents();
|
||||
Dbg_stopTimer(&dbgTimer);
|
||||
|
||||
//calc the time passed
|
||||
engine.realTime = clock();
|
||||
|
||||
Dbg_startTimer(&dbgTimer, "execStep() (variable)");
|
||||
//while not enough time has passed
|
||||
while(engine.simTime < engine.realTime) {
|
||||
//simulate the world
|
||||
execStep();
|
||||
|
||||
//calc the time simulation
|
||||
engine.simTime += delta;
|
||||
}
|
||||
Dbg_stopTimer(&dbgTimer);
|
||||
|
||||
//render the world
|
||||
Dbg_startTimer(&dbgTimer, "clear screen");
|
||||
SDL_SetRenderDrawColor(engine.renderer, 128, 128, 128, 255); //NOTE: This line can be disabled later
|
||||
SDL_RenderClear(engine.renderer); //NOTE: This line can be disabled later
|
||||
Dbg_stopTimer(&dbgTimer);
|
||||
|
||||
Dbg_startTimer(&dbgTimer, "onDraw() calls");
|
||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onDraw", NULL);
|
||||
Dbg_stopTimer(&dbgTimer);
|
||||
|
||||
Dbg_startTimer(&dbgTimer, "render screen");
|
||||
SDL_RenderPresent(engine.renderer);
|
||||
Dbg_stopTimer(&dbgTimer);
|
||||
}
|
||||
|
||||
Dbg_freeTimer(&dbgTimer);
|
||||
Dbg_freeFPSCounter(&fps);
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "box_common.h"
|
||||
#include "box_node.h"
|
||||
|
||||
#include "toy_interpreter.h"
|
||||
#include "toy_literal_array.h"
|
||||
#include "toy_literal_dictionary.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
//the base engine object, which represents the state of the game
|
||||
typedef struct Box_private_engine {
|
||||
//engine stuff
|
||||
Box_Node* rootNode;
|
||||
Toy_Literal nextRootNodeFilename;
|
||||
clock_t simTime;
|
||||
clock_t realTime;
|
||||
bool running;
|
||||
|
||||
//Toy stuff
|
||||
Toy_Interpreter interpreter;
|
||||
|
||||
//SDL stuff
|
||||
SDL_Window* window;
|
||||
SDL_Renderer* renderer;
|
||||
int screenWidth;
|
||||
int screenHeight;
|
||||
|
||||
//input syms mapped to events
|
||||
Toy_LiteralDictionary symKeyDownEvents; //keysym -> event names
|
||||
Toy_LiteralDictionary symKeyUpEvents; //keysym -> event names
|
||||
} Box_Engine;
|
||||
|
||||
//extern singleton - used by various libraries
|
||||
extern Box_Engine engine;
|
||||
|
||||
//APIs for running the engine in main()
|
||||
BOX_API void Box_initEngine();
|
||||
BOX_API void Box_execEngine();
|
||||
BOX_API void Box_freeEngine();
|
||||
|
||||
395
box/box_node.c
395
box/box_node.c
@@ -1,395 +0,0 @@
|
||||
#include "box_node.h"
|
||||
#include "box_engine.h"
|
||||
|
||||
#include "toy_memory.h"
|
||||
|
||||
void Box_initNode(Box_Node* node, Toy_Interpreter* interpreter, const unsigned char* tb, size_t size) {
|
||||
//init
|
||||
// node->freeMemory = freeMemory;
|
||||
node->functions = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
|
||||
node->parent = NULL;
|
||||
node->scope = NULL;
|
||||
node->tag = OPAQUE_TAG_NODE;
|
||||
node->children = NULL;
|
||||
node->capacity = 0;
|
||||
node->count = 0;
|
||||
node->childCount = 0;
|
||||
node->texture = NULL;
|
||||
node->rect = ((SDL_Rect) { 0, 0, 0, 0 });
|
||||
node->frames = 0;
|
||||
|
||||
Toy_initLiteralDictionary(node->functions);
|
||||
|
||||
//run bytecode
|
||||
Toy_runInterpreter(interpreter, tb, size);
|
||||
|
||||
//grab all top-level functions from the dirty interpreter
|
||||
Toy_LiteralDictionary* variablesPtr = &interpreter->scope->variables;
|
||||
|
||||
for (int i = 0; i < variablesPtr->capacity; i++) {
|
||||
//skip empties and tombstones
|
||||
if (TOY_IS_NULL(variablesPtr->entries[i].key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//if this variable is a function (this outmodes import and export)
|
||||
Toy_private_dictionary_entry* entry = &variablesPtr->entries[i];
|
||||
if (TOY_IS_FUNCTION(entry->value)) {
|
||||
//save a copy
|
||||
Toy_setLiteralDictionary(node->functions, entry->key, entry->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Box_pushNode(Box_Node* node, Box_Node* child) {
|
||||
//push to the array
|
||||
if (node->count + 1 > node->capacity) {
|
||||
int oldCapacity = node->capacity;
|
||||
|
||||
node->capacity = TOY_GROW_CAPACITY(oldCapacity);
|
||||
node->children = TOY_GROW_ARRAY(Box_Node*, node->children, oldCapacity, node->capacity);
|
||||
}
|
||||
|
||||
//assign
|
||||
node->children[node->count++] = child;
|
||||
|
||||
//reverse-assign
|
||||
child->parent = node;
|
||||
|
||||
//count
|
||||
node->childCount++;
|
||||
}
|
||||
|
||||
void Box_freeNode(Box_Node* node) {
|
||||
if (node == NULL) {
|
||||
return; //NO-OP
|
||||
}
|
||||
|
||||
//free this node's children
|
||||
for (int i = 0; i < node->count; i++) {
|
||||
Box_freeNode(node->children[i]);
|
||||
}
|
||||
|
||||
//free the pointer array to the children
|
||||
TOY_FREE_ARRAY(Box_Node*, node->children, node->capacity);
|
||||
|
||||
if (node->functions != NULL) {
|
||||
Toy_freeLiteralDictionary(node->functions);
|
||||
TOY_FREE(Toy_LiteralDictionary, node->functions);
|
||||
}
|
||||
|
||||
if (node->scope != NULL) {
|
||||
Toy_popScope(node->scope);
|
||||
}
|
||||
|
||||
if (node->texture != NULL) {
|
||||
Box_freeTextureNode(node);
|
||||
}
|
||||
|
||||
//free this node's memory
|
||||
TOY_FREE(Box_Node, node);
|
||||
}
|
||||
|
||||
Box_Node* Box_getChildNode(Box_Node* node, int index) {
|
||||
if (index < 0 || index > node->count) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return node->children[index];
|
||||
}
|
||||
|
||||
void Box_freeChildNode(Box_Node* node, int index) {
|
||||
//get the child node
|
||||
Box_Node* childNode = node->children[index];
|
||||
|
||||
//free the node
|
||||
if (childNode != NULL) {
|
||||
Box_freeNode(childNode);
|
||||
node->childCount--;
|
||||
}
|
||||
|
||||
node->children[index] = NULL;
|
||||
}
|
||||
|
||||
static void swapUtil(Box_Node** lhs, Box_Node** rhs) {
|
||||
Box_Node* tmp = *lhs;
|
||||
*lhs = *rhs;
|
||||
*rhs = tmp;
|
||||
}
|
||||
|
||||
//copied from lib_standard.c
|
||||
static void recursiveLiteralQuicksortUtil(Toy_Interpreter* interpreter, Box_Node** ptr, int count, Toy_Literal fnCompare) {
|
||||
//base case
|
||||
if (count <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
int runner = 0;
|
||||
|
||||
//iterate through the array
|
||||
for (int checker = 0; checker < count - 1; checker++) {
|
||||
//if node is null, it is always "sorted" to the end
|
||||
while (ptr[checker] == NULL && count > 0) {
|
||||
swapUtil(&ptr[checker], &ptr[count - 1]);
|
||||
count--;
|
||||
}
|
||||
|
||||
//base case
|
||||
if (count < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
Toy_LiteralArray arguments;
|
||||
Toy_LiteralArray returns;
|
||||
|
||||
Toy_initLiteralArray(&arguments);
|
||||
Toy_initLiteralArray(&returns);
|
||||
|
||||
Toy_pushLiteralArray(&arguments, TOY_TO_OPAQUE_LITERAL(ptr[checker], OPAQUE_TAG_NODE));
|
||||
Toy_pushLiteralArray(&arguments, TOY_TO_OPAQUE_LITERAL(ptr[count - 1], OPAQUE_TAG_NODE));
|
||||
|
||||
Toy_callLiteralFn(interpreter, fnCompare, &arguments, &returns);
|
||||
|
||||
Toy_Literal lessThan = Toy_popLiteralArray(&returns);
|
||||
|
||||
Toy_freeLiteralArray(&arguments);
|
||||
Toy_freeLiteralArray(&returns);
|
||||
|
||||
if (TOY_IS_TRUTHY(lessThan)) {
|
||||
swapUtil(&ptr[runner++], &ptr[checker]);
|
||||
}
|
||||
|
||||
Toy_freeLiteral(lessThan);
|
||||
}
|
||||
|
||||
//"shift everything up" so the pivot is in the middle
|
||||
swapUtil(&ptr[runner], &ptr[count - 1]);
|
||||
|
||||
//recurse on each end
|
||||
recursiveLiteralQuicksortUtil(interpreter, &ptr[0], runner, fnCompare);
|
||||
recursiveLiteralQuicksortUtil(interpreter, &ptr[runner + 1], count - runner - 1, fnCompare);
|
||||
}
|
||||
|
||||
BOX_API void Box_sortChildrenNode(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal fnCompare) {
|
||||
//check that this node's children aren't already sorted
|
||||
bool sorted = true;
|
||||
for (int checker = 0; checker < node->count - 1 && sorted; checker++) {
|
||||
//NULL (tombstone) is always considered unsorted
|
||||
if (node->children[checker] == NULL || node->children[checker + 1] == NULL) {
|
||||
sorted = false;
|
||||
break;
|
||||
}
|
||||
|
||||
Toy_LiteralArray arguments;
|
||||
Toy_LiteralArray returns;
|
||||
|
||||
Toy_initLiteralArray(&arguments);
|
||||
Toy_initLiteralArray(&returns);
|
||||
|
||||
Toy_pushLiteralArray(&arguments, TOY_TO_OPAQUE_LITERAL(node->children[checker], OPAQUE_TAG_NODE));
|
||||
Toy_pushLiteralArray(&arguments, TOY_TO_OPAQUE_LITERAL(node->children[checker + 1], OPAQUE_TAG_NODE));
|
||||
|
||||
Toy_callLiteralFn(interpreter, fnCompare, &arguments, &returns);
|
||||
|
||||
Toy_Literal lessThan = Toy_popLiteralArray(&returns);
|
||||
|
||||
Toy_freeLiteralArray(&arguments);
|
||||
Toy_freeLiteralArray(&returns);
|
||||
|
||||
if (!TOY_IS_TRUTHY(lessThan)) {
|
||||
sorted = false;
|
||||
}
|
||||
|
||||
Toy_freeLiteral(lessThan);
|
||||
}
|
||||
|
||||
//sort the children
|
||||
if (!sorted) {
|
||||
recursiveLiteralQuicksortUtil(interpreter, node->children, node->count, fnCompare);
|
||||
}
|
||||
|
||||
//re-count the newly-sorted children
|
||||
for (int i = node->count - 1; node->children[i] == NULL; i--) {
|
||||
node->count--;
|
||||
}
|
||||
}
|
||||
|
||||
Toy_Literal Box_callNodeLiteral(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal key, Toy_LiteralArray* args) {
|
||||
Toy_Literal ret = TOY_TO_NULL_LITERAL;
|
||||
|
||||
//if this fn exists
|
||||
if (Toy_existsLiteralDictionary(node->functions, key)) {
|
||||
Toy_Literal fn = Toy_getLiteralDictionary(node->functions, key);
|
||||
Toy_Literal n = TOY_TO_OPAQUE_LITERAL(node, node->tag);
|
||||
|
||||
Toy_LiteralArray arguments;
|
||||
Toy_LiteralArray returns;
|
||||
Toy_initLiteralArray(&arguments);
|
||||
Toy_initLiteralArray(&returns);
|
||||
|
||||
//feed the arguments in
|
||||
Toy_pushLiteralArray(&arguments, n);
|
||||
|
||||
if (args) {
|
||||
for (int i = 0; i < args->count; i++) {
|
||||
Toy_pushLiteralArray(&arguments, args->literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Toy_callLiteralFn(interpreter, fn, &arguments, &returns);
|
||||
|
||||
ret = Toy_popLiteralArray(&returns);
|
||||
|
||||
Toy_freeLiteralArray(&arguments);
|
||||
Toy_freeLiteralArray(&returns);
|
||||
|
||||
Toy_freeLiteral(n);
|
||||
Toy_freeLiteral(fn);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Toy_Literal Box_callNode(Box_Node* node, Toy_Interpreter* interpreter, const char* fnName, Toy_LiteralArray* args) {
|
||||
//call "fnName" on this node, and all children, if it exists
|
||||
Toy_Literal key = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString(fnName));
|
||||
|
||||
Toy_Literal ret = Box_callNodeLiteral(node, interpreter, key, args);
|
||||
|
||||
Toy_freeLiteral(key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Box_callRecursiveNodeLiteral(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal key, Toy_LiteralArray* args) {
|
||||
//if this fn exists
|
||||
if (Toy_existsLiteralDictionary(node->functions, key)) {
|
||||
Toy_Literal fn = Toy_getLiteralDictionary(node->functions, key);
|
||||
Toy_Literal n = TOY_TO_OPAQUE_LITERAL(node, node->tag);
|
||||
|
||||
Toy_LiteralArray arguments;
|
||||
Toy_LiteralArray returns;
|
||||
Toy_initLiteralArray(&arguments);
|
||||
Toy_initLiteralArray(&returns);
|
||||
|
||||
//feed the arguments in
|
||||
Toy_pushLiteralArray(&arguments, n);
|
||||
|
||||
if (args) {
|
||||
for (int i = 0; i < args->count; i++) {
|
||||
Toy_pushLiteralArray(&arguments, args->literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Toy_callLiteralFn(interpreter, fn, &arguments, &returns);
|
||||
|
||||
Toy_freeLiteralArray(&arguments);
|
||||
Toy_freeLiteralArray(&returns);
|
||||
|
||||
Toy_freeLiteral(n);
|
||||
Toy_freeLiteral(fn);
|
||||
}
|
||||
|
||||
//recurse to the (non-tombstone) children
|
||||
for (int i = 0; i < node->count; i++) {
|
||||
if (node->children[i] != NULL) {
|
||||
Box_callRecursiveNodeLiteral(node->children[i], interpreter, key, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Box_callRecursiveNode(Box_Node* node, Toy_Interpreter* interpreter, const char* fnName, Toy_LiteralArray* args) {
|
||||
//call "fnName" on this node, and all children, if it exists
|
||||
Toy_Literal key = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString(fnName));
|
||||
|
||||
Box_callRecursiveNodeLiteral(node, interpreter, key, args);
|
||||
|
||||
Toy_freeLiteral(key);
|
||||
}
|
||||
|
||||
int Box_getChildCountNode(Box_Node* node) {
|
||||
return node->childCount;
|
||||
}
|
||||
|
||||
int Box_loadTextureNode(Box_Node* node, const char* fname) {
|
||||
SDL_Surface* surface = IMG_Load(fname);
|
||||
|
||||
if (surface == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
node->texture = SDL_CreateTextureFromSurface(engine.renderer, surface);
|
||||
|
||||
if (node->texture == NULL) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
SDL_FreeSurface(surface);
|
||||
|
||||
int w, h;
|
||||
SDL_QueryTexture(node->texture, NULL, NULL, &w, &h);
|
||||
SDL_Rect r = { 0, 0, w, h };
|
||||
Box_setRectNode(node, r);
|
||||
Box_setFramesNode(node, 1); //default
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Box_freeTextureNode(Box_Node* node) {
|
||||
if (node->texture != NULL) {
|
||||
SDL_DestroyTexture(node->texture);
|
||||
node->texture = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Box_setRectNode(Box_Node* node, SDL_Rect rect) {
|
||||
node->rect = rect;
|
||||
}
|
||||
|
||||
SDL_Rect Box_getRectNode(Box_Node* node) {
|
||||
return node->rect;
|
||||
}
|
||||
|
||||
void Box_setFramesNode(Box_Node* node, int frames) {
|
||||
node->frames = frames;
|
||||
node->currentFrame = 0; //just in case
|
||||
}
|
||||
|
||||
int Box_getFramesNode(Box_Node* node) {
|
||||
return node->frames;
|
||||
}
|
||||
|
||||
void Box_setCurrentFrameNode(Box_Node* node, int currentFrame) {
|
||||
node->currentFrame = currentFrame;
|
||||
}
|
||||
|
||||
int Box_getCurrentFrameNode(Box_Node* node) {
|
||||
return node->currentFrame;
|
||||
}
|
||||
|
||||
void Box_incrementCurrentFrame(Box_Node* node) {
|
||||
node->currentFrame++;
|
||||
if (node->currentFrame >= node->frames) {
|
||||
node->currentFrame = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Box_setTextNode(Box_Node* node, TTF_Font* font, const char* text, SDL_Color color) {
|
||||
SDL_Surface* surface = TTF_RenderText_Solid(font, text, color);
|
||||
|
||||
node->texture = SDL_CreateTextureFromSurface(engine.renderer, surface);
|
||||
|
||||
node->rect = (SDL_Rect){ .x = 0, .y = 0, .w = surface->w, .h = surface->h };
|
||||
node->frames = 1;
|
||||
node->currentFrame = 0;
|
||||
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
|
||||
|
||||
void Box_drawNode(Box_Node* node, SDL_Rect dest) {
|
||||
if (!node->texture) return;
|
||||
SDL_Rect src = node->rect;
|
||||
src.x += src.w * node->currentFrame;
|
||||
SDL_RenderCopy(engine.renderer, node->texture, &src, &dest);
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "box_common.h"
|
||||
|
||||
#include "toy_literal_dictionary.h"
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
#define OPAQUE_TAG_NODE 1001
|
||||
|
||||
//forward declare
|
||||
typedef struct Box_private_node Box_Node;
|
||||
|
||||
//the node object, which forms a tree
|
||||
typedef struct Box_private_node {
|
||||
//toy functions, stored in a dict for flexibility
|
||||
Toy_LiteralDictionary* functions;
|
||||
|
||||
//point to the parent
|
||||
Box_Node* parent;
|
||||
|
||||
//BUGFIX: hold the node's scope so it can be popped
|
||||
Toy_Scope* scope;
|
||||
|
||||
//my opaque type tag
|
||||
int tag;
|
||||
|
||||
//use Toy's memory model
|
||||
Box_Node** children;
|
||||
int capacity;
|
||||
int count; //includes tombstones
|
||||
int childCount;
|
||||
|
||||
//rendering-specific features
|
||||
SDL_Texture* texture;
|
||||
SDL_Rect rect; //rendered rect
|
||||
int frames; //horizontal-strip based animations
|
||||
int currentFrame;
|
||||
} Box_Node;
|
||||
|
||||
BOX_API void Box_initNode(Box_Node* node, Toy_Interpreter* interpreter, const unsigned char* tb, size_t size); //run bytecode, then grab all top-level function literals
|
||||
BOX_API void Box_pushNode(Box_Node* node, Box_Node* child); //push to the array (prune tombstones when expanding/copying)
|
||||
BOX_API void Box_freeNode(Box_Node* node); //free this node and all children
|
||||
|
||||
BOX_API Box_Node* Box_getChildNode(Box_Node* node, int index);
|
||||
BOX_API void Box_freeChildNode(Box_Node* node, int index);
|
||||
|
||||
BOX_API void Box_sortChildrenNode(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal fnCompare);
|
||||
|
||||
BOX_API Toy_Literal Box_callNodeLiteral(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal key, Toy_LiteralArray* args);
|
||||
BOX_API Toy_Literal Box_callNode(Box_Node* node, Toy_Interpreter* interpreter, const char* fnName, Toy_LiteralArray* args); //call "fnName" on this node, and only this node, if it exists
|
||||
|
||||
//for calling various lifecycle functions
|
||||
BOX_API void Box_callRecursiveNodeLiteral(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal key, Toy_LiteralArray* args);
|
||||
BOX_API void Box_callRecursiveNode(Box_Node* node, Toy_Interpreter* interpreter, const char* fnName, Toy_LiteralArray* args); //call "fnName" on this node, and all children, if it exists
|
||||
|
||||
BOX_API int Box_getChildCountNode(Box_Node* node);
|
||||
|
||||
BOX_API int Box_loadTextureNode(Box_Node* node, const char* fname);
|
||||
BOX_API void Box_freeTextureNode(Box_Node* node);
|
||||
|
||||
BOX_API void Box_setRectNode(Box_Node* node, SDL_Rect rect);
|
||||
BOX_API SDL_Rect Box_getRectNode(Box_Node* node);
|
||||
|
||||
BOX_API void Box_setFramesNode(Box_Node* node, int frames);
|
||||
BOX_API int Box_getFramesNode(Box_Node* node);
|
||||
BOX_API void Box_setCurrentFrameNode(Box_Node* node, int currentFrame);
|
||||
BOX_API int Box_getCurrentFrameNode(Box_Node* node);
|
||||
BOX_API void Box_incrementCurrentFrame(Box_Node* node);
|
||||
|
||||
BOX_API void Box_setTextNode(Box_Node* node, TTF_Font* font, const char* text, SDL_Color color);
|
||||
|
||||
BOX_API void Box_drawNode(Box_Node* node, SDL_Rect dest);
|
||||
@@ -1,114 +0,0 @@
|
||||
#include "dbg_profiler.h"
|
||||
|
||||
#include "toy_memory.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
//https://stackoverflow.com/questions/2347770/how-do-you-clear-the-console-screen-in-c
|
||||
void Dbg_clearConsole()
|
||||
{
|
||||
HANDLE hStdOut;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
DWORD count;
|
||||
DWORD cellCount;
|
||||
COORD homeCoords = { 0, 0 };
|
||||
|
||||
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (hStdOut == INVALID_HANDLE_VALUE) return;
|
||||
|
||||
/* Get the number of cells in the current buffer */
|
||||
if (!GetConsoleScreenBufferInfo(hStdOut, &csbi)) return;
|
||||
cellCount = csbi.dwSize.X * csbi.dwSize.Y;
|
||||
|
||||
/* Fill the entire buffer with spaces */
|
||||
if (!FillConsoleOutputCharacter(
|
||||
hStdOut,
|
||||
(TCHAR)' ',
|
||||
cellCount,
|
||||
homeCoords,
|
||||
&count
|
||||
)) return;
|
||||
|
||||
/* Fill the entire buffer with the current colors and attributes */
|
||||
if (!FillConsoleOutputAttribute(
|
||||
hStdOut,
|
||||
csbi.wAttributes,
|
||||
cellCount,
|
||||
homeCoords,
|
||||
&count
|
||||
)) return;
|
||||
|
||||
/* Move the cursor home */
|
||||
SetConsoleCursorPosition(hStdOut, homeCoords);
|
||||
}
|
||||
|
||||
#else // !_WIN32
|
||||
#include <unistd.h>
|
||||
#include <term.h>
|
||||
|
||||
void Dbg_clearConsole()
|
||||
{
|
||||
if (!cur_term)
|
||||
{
|
||||
int result;
|
||||
setupterm(NULL, STDOUT_FILENO, &result);
|
||||
if (result <= 0) return;
|
||||
}
|
||||
|
||||
putp(tigetstr("clear"));
|
||||
}
|
||||
#endif
|
||||
|
||||
void Dbg_initTimer(Dbg_Timer* timer) {
|
||||
timer->name = NULL;
|
||||
timer->start = 0;
|
||||
memset(timer->log, 0, 2048);
|
||||
timer->logPos = 0;
|
||||
}
|
||||
|
||||
void Dbg_startTimer(Dbg_Timer* timer, const char* name) {
|
||||
timer->name = name;
|
||||
timer->start = clock();
|
||||
}
|
||||
|
||||
void Dbg_stopTimer(Dbg_Timer* timer) {
|
||||
double duration = (clock() - timer->start) / (double) CLOCKS_PER_SEC * 1000;
|
||||
timer->logPos += sprintf(&(timer->log[timer->logPos]), "%.3fms %s\n", duration, timer->name);
|
||||
}
|
||||
|
||||
void Dbg_printTimerLog(Dbg_Timer* timer) {
|
||||
printf("%.*s", timer->logPos, timer->log);
|
||||
timer->logPos = 0;
|
||||
}
|
||||
|
||||
void Dbg_freeTimer(Dbg_Timer* timer) {
|
||||
//
|
||||
}
|
||||
|
||||
void Dbg_initFPSCounter(Dbg_FPSCounter* counter) {
|
||||
counter->count = 0;
|
||||
counter->start = clock();
|
||||
memset(counter->log, 0, 256);
|
||||
}
|
||||
|
||||
void Dbg_tickFPSCounter(Dbg_FPSCounter* counter) {
|
||||
counter->count++;
|
||||
|
||||
if (clock() - counter->start > CLOCKS_PER_SEC) {
|
||||
sprintf(counter->log, "%d FPS", counter->count);
|
||||
counter->start = clock();
|
||||
counter->count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Dbg_printFPSCounter(Dbg_FPSCounter* counter) {
|
||||
printf("%s\n", counter->log);
|
||||
}
|
||||
|
||||
void Dbg_freeFPSCounter(Dbg_FPSCounter* counter) {
|
||||
//
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <time.h>
|
||||
|
||||
void Dbg_clearConsole();
|
||||
|
||||
typedef struct Dbg_Timer {
|
||||
const char* name;
|
||||
clock_t start;
|
||||
char log[2048];
|
||||
int logPos;
|
||||
} Dbg_Timer;
|
||||
|
||||
void Dbg_initTimer(Dbg_Timer*);
|
||||
void Dbg_startTimer(Dbg_Timer*, const char* name);
|
||||
void Dbg_stopTimer(Dbg_Timer*);
|
||||
void Dbg_printTimerLog(Dbg_Timer*);
|
||||
void Dbg_freeTimer(Dbg_Timer*);
|
||||
|
||||
typedef struct Dbg_FPSCounter {
|
||||
int count;
|
||||
clock_t start;
|
||||
char log[256];
|
||||
} Dbg_FPSCounter;
|
||||
|
||||
void Dbg_initFPSCounter(Dbg_FPSCounter*);
|
||||
void Dbg_tickFPSCounter(Dbg_FPSCounter*);
|
||||
void Dbg_printFPSCounter(Dbg_FPSCounter*);
|
||||
void Dbg_freeFPSCounter(Dbg_FPSCounter*);
|
||||
162
box/lib_about.c
162
box/lib_about.c
@@ -1,162 +0,0 @@
|
||||
#include "lib_about.h"
|
||||
|
||||
#include "toy_memory.h"
|
||||
|
||||
int Toy_hookAbout(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
||||
//the about keys
|
||||
Toy_Literal majorKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("major"));
|
||||
Toy_Literal minorKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("minor"));
|
||||
Toy_Literal patchKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("patch"));
|
||||
Toy_Literal buildKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("build"));
|
||||
Toy_Literal authorKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("author"));
|
||||
|
||||
//the about identifiers
|
||||
Toy_Literal majorIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("major"));
|
||||
Toy_Literal minorIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("minor"));
|
||||
Toy_Literal patchIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("patch"));
|
||||
Toy_Literal buildIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("build"));
|
||||
Toy_Literal authorIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("author"));
|
||||
|
||||
//the about values
|
||||
Toy_Literal majorLiteral = TOY_TO_INTEGER_LITERAL(TOY_VERSION_MAJOR);
|
||||
Toy_Literal minorLiteral = TOY_TO_INTEGER_LITERAL(TOY_VERSION_MINOR);
|
||||
Toy_Literal patchLiteral = TOY_TO_INTEGER_LITERAL(TOY_VERSION_PATCH);
|
||||
Toy_Literal buildLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString(TOY_VERSION_BUILD));
|
||||
Toy_Literal authorLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("Kayne Ruse, KR Game Studios"));
|
||||
|
||||
//store as an aliased dictionary
|
||||
if (!TOY_IS_NULL(alias)) {
|
||||
//make sure the name isn't taken
|
||||
if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
|
||||
interpreter->errorOutput("Can't override an existing variable\n");
|
||||
Toy_freeLiteral(alias);
|
||||
|
||||
Toy_freeLiteral(majorKeyLiteral);
|
||||
Toy_freeLiteral(minorKeyLiteral);
|
||||
Toy_freeLiteral(patchKeyLiteral);
|
||||
Toy_freeLiteral(buildKeyLiteral);
|
||||
Toy_freeLiteral(authorKeyLiteral);
|
||||
|
||||
Toy_freeLiteral(majorIdentifierLiteral);
|
||||
Toy_freeLiteral(minorIdentifierLiteral);
|
||||
Toy_freeLiteral(patchIdentifierLiteral);
|
||||
Toy_freeLiteral(buildIdentifierLiteral);
|
||||
Toy_freeLiteral(authorIdentifierLiteral);
|
||||
|
||||
Toy_freeLiteral(majorLiteral);
|
||||
Toy_freeLiteral(minorLiteral);
|
||||
Toy_freeLiteral(patchLiteral);
|
||||
Toy_freeLiteral(buildLiteral);
|
||||
Toy_freeLiteral(authorLiteral);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//create the dictionary to load up with values
|
||||
Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
|
||||
Toy_initLiteralDictionary(dictionary);
|
||||
|
||||
//set each key/value pair
|
||||
Toy_setLiteralDictionary(dictionary, majorKeyLiteral, majorLiteral);
|
||||
Toy_setLiteralDictionary(dictionary, minorKeyLiteral, minorLiteral);
|
||||
Toy_setLiteralDictionary(dictionary, patchKeyLiteral, patchLiteral);
|
||||
Toy_setLiteralDictionary(dictionary, buildKeyLiteral, buildLiteral);
|
||||
Toy_setLiteralDictionary(dictionary, authorKeyLiteral, authorLiteral);
|
||||
|
||||
//build the type
|
||||
Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true);
|
||||
Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
|
||||
Toy_Literal anyType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_ANY, true);
|
||||
TOY_TYPE_PUSH_SUBTYPE(&type, strType);
|
||||
TOY_TYPE_PUSH_SUBTYPE(&type, anyType);
|
||||
|
||||
//set scope
|
||||
Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
|
||||
Toy_declareScopeVariable(interpreter->scope, alias, type);
|
||||
Toy_setScopeVariable(interpreter->scope, alias, dict, false);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(dict);
|
||||
Toy_freeLiteral(type);
|
||||
}
|
||||
|
||||
//store globally
|
||||
else {
|
||||
//make sure the names aren't taken
|
||||
if (Toy_isDelcaredScopeVariable(interpreter->scope, majorKeyLiteral) ||
|
||||
Toy_isDelcaredScopeVariable(interpreter->scope, minorKeyLiteral) ||
|
||||
Toy_isDelcaredScopeVariable(interpreter->scope, patchKeyLiteral) ||
|
||||
Toy_isDelcaredScopeVariable(interpreter->scope, buildKeyLiteral) ||
|
||||
Toy_isDelcaredScopeVariable(interpreter->scope, authorKeyLiteral)) {
|
||||
interpreter->errorOutput("Can't override an existing variable\n");
|
||||
Toy_freeLiteral(alias);
|
||||
|
||||
Toy_freeLiteral(majorKeyLiteral);
|
||||
Toy_freeLiteral(minorKeyLiteral);
|
||||
Toy_freeLiteral(patchKeyLiteral);
|
||||
Toy_freeLiteral(buildKeyLiteral);
|
||||
Toy_freeLiteral(authorKeyLiteral);
|
||||
|
||||
Toy_freeLiteral(majorIdentifierLiteral);
|
||||
Toy_freeLiteral(minorIdentifierLiteral);
|
||||
Toy_freeLiteral(patchIdentifierLiteral);
|
||||
Toy_freeLiteral(buildIdentifierLiteral);
|
||||
Toy_freeLiteral(authorIdentifierLiteral);
|
||||
|
||||
Toy_freeLiteral(majorLiteral);
|
||||
Toy_freeLiteral(minorLiteral);
|
||||
Toy_freeLiteral(patchLiteral);
|
||||
Toy_freeLiteral(buildLiteral);
|
||||
Toy_freeLiteral(authorLiteral);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Literal intType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_INTEGER, true);
|
||||
Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
|
||||
|
||||
//major
|
||||
Toy_declareScopeVariable(interpreter->scope, majorIdentifierLiteral, intType);
|
||||
Toy_setScopeVariable(interpreter->scope, majorIdentifierLiteral, majorLiteral, false);
|
||||
|
||||
//minor
|
||||
Toy_declareScopeVariable(interpreter->scope, minorIdentifierLiteral, intType);
|
||||
Toy_setScopeVariable(interpreter->scope, minorIdentifierLiteral, minorLiteral, false);
|
||||
|
||||
//patch
|
||||
Toy_declareScopeVariable(interpreter->scope, patchIdentifierLiteral, intType);
|
||||
Toy_setScopeVariable(interpreter->scope, patchIdentifierLiteral, patchLiteral, false);
|
||||
|
||||
//build
|
||||
Toy_declareScopeVariable(interpreter->scope, buildIdentifierLiteral, strType);
|
||||
Toy_setScopeVariable(interpreter->scope, buildIdentifierLiteral, buildLiteral, false);
|
||||
|
||||
//author
|
||||
Toy_declareScopeVariable(interpreter->scope, authorIdentifierLiteral, strType);
|
||||
Toy_setScopeVariable(interpreter->scope, authorIdentifierLiteral, authorLiteral, false);
|
||||
|
||||
Toy_freeLiteral(intType);
|
||||
Toy_freeLiteral(strType);
|
||||
}
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(majorKeyLiteral);
|
||||
Toy_freeLiteral(minorKeyLiteral);
|
||||
Toy_freeLiteral(patchKeyLiteral);
|
||||
Toy_freeLiteral(buildKeyLiteral);
|
||||
Toy_freeLiteral(authorKeyLiteral);
|
||||
|
||||
Toy_freeLiteral(majorIdentifierLiteral);
|
||||
Toy_freeLiteral(minorIdentifierLiteral);
|
||||
Toy_freeLiteral(patchIdentifierLiteral);
|
||||
Toy_freeLiteral(buildIdentifierLiteral);
|
||||
Toy_freeLiteral(authorIdentifierLiteral);
|
||||
|
||||
Toy_freeLiteral(majorLiteral);
|
||||
Toy_freeLiteral(minorLiteral);
|
||||
Toy_freeLiteral(patchLiteral);
|
||||
Toy_freeLiteral(buildLiteral);
|
||||
Toy_freeLiteral(authorLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
int Toy_hookAbout(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
||||
|
||||
221
box/lib_engine.c
221
box/lib_engine.c
@@ -1,221 +0,0 @@
|
||||
#include "lib_engine.h"
|
||||
|
||||
#include "box_engine.h"
|
||||
|
||||
#include "repl_tools.h"
|
||||
#include "toy_memory.h"
|
||||
#include "toy_drive_system.h"
|
||||
#include "toy_literal_array.h"
|
||||
|
||||
#include "toy_console_colors.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
//errors here should be fatal
|
||||
static void fatalError(char* message) {
|
||||
fprintf(stderr, TOY_CC_ERROR "%s" TOY_CC_RESET, message);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//native functions to be called
|
||||
static int nativeInitWindow(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (engine.window != NULL) {
|
||||
fatalError("Can't re-initialize the window\n");
|
||||
}
|
||||
|
||||
if (arguments->count != 4) {
|
||||
fatalError("Incorrect number of arguments passed to initWindow\n");
|
||||
}
|
||||
|
||||
//extract the arguments
|
||||
Toy_Literal fscreen = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal screenHeight = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal screenWidth = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal caption = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal captionIdn = caption;
|
||||
if (TOY_IS_IDENTIFIER(caption) && Toy_parseIdentifierToValue(interpreter, &caption)) {
|
||||
Toy_freeLiteral(captionIdn);
|
||||
}
|
||||
|
||||
Toy_Literal screenWidthIdn = screenWidth;
|
||||
if (TOY_IS_IDENTIFIER(screenWidth) && Toy_parseIdentifierToValue(interpreter, &screenWidth)) {
|
||||
Toy_freeLiteral(screenWidthIdn);
|
||||
}
|
||||
|
||||
Toy_Literal screenHeightIdn = screenHeight;
|
||||
if (TOY_IS_IDENTIFIER(screenHeight) && Toy_parseIdentifierToValue(interpreter, &screenHeight)) {
|
||||
Toy_freeLiteral(screenHeightIdn);
|
||||
}
|
||||
|
||||
Toy_Literal fscreenIdn = fscreen;
|
||||
if (TOY_IS_IDENTIFIER(fscreen) && Toy_parseIdentifierToValue(interpreter, &fscreen)) {
|
||||
Toy_freeLiteral(fscreenIdn);
|
||||
}
|
||||
|
||||
//check argument types
|
||||
if (!TOY_IS_STRING(caption) || !TOY_IS_INTEGER(screenWidth) || !TOY_IS_INTEGER(screenHeight) || !TOY_IS_BOOLEAN(fscreen)) {
|
||||
fatalError("Incorrect argument type passed to initWindow\n");
|
||||
}
|
||||
|
||||
//init the window
|
||||
engine.window = SDL_CreateWindow(
|
||||
Toy_toCString(TOY_AS_STRING(caption)),
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
engine.screenWidth = TOY_AS_INTEGER(screenWidth),
|
||||
engine.screenHeight = TOY_AS_INTEGER(screenHeight),
|
||||
TOY_IS_TRUTHY(fscreen) ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE
|
||||
);
|
||||
|
||||
if (engine.window == NULL) {
|
||||
fatalError("Failed to initialize the window\n");
|
||||
}
|
||||
|
||||
//init the renderer
|
||||
// SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
|
||||
engine.renderer = SDL_CreateRenderer(engine.window, -1, SDL_RENDERER_ACCELERATED);
|
||||
|
||||
if (engine.renderer == NULL) {
|
||||
fatalError("Failed to initialize the renderer\n");
|
||||
}
|
||||
|
||||
SDL_RendererInfo rendererInfo;
|
||||
SDL_GetRendererInfo(engine.renderer, &rendererInfo);
|
||||
|
||||
printf("Renderer: %s (HW %s)\n", rendererInfo.name, rendererInfo.flags & SDL_RENDERER_ACCELERATED ? "yes" : "no");
|
||||
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
|
||||
SDL_RenderSetLogicalSize(engine.renderer, engine.screenWidth, engine.screenHeight);
|
||||
|
||||
//only run with a window
|
||||
engine.running = true;
|
||||
|
||||
Toy_freeLiteral(caption);
|
||||
Toy_freeLiteral(screenWidth);
|
||||
Toy_freeLiteral(screenHeight);
|
||||
Toy_freeLiteral(fscreen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nativeLoadRootNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments passed to loadRootNode\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//extract the arguments
|
||||
Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal drivePathLiteralIdn = drivePathLiteral;
|
||||
if (TOY_IS_IDENTIFIER(drivePathLiteral) && Toy_parseIdentifierToValue(interpreter, &drivePathLiteral)) {
|
||||
Toy_freeLiteral(drivePathLiteralIdn);
|
||||
}
|
||||
|
||||
//check argument types
|
||||
if (!TOY_IS_STRING(drivePathLiteral)) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to loadRootNode\n");
|
||||
Toy_freeLiteral(drivePathLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Literal filePathLiteral = Toy_getDrivePathLiteral(interpreter, &drivePathLiteral);
|
||||
|
||||
Toy_freeLiteral(drivePathLiteral); //not needed anymore
|
||||
|
||||
if (!TOY_IS_STRING(filePathLiteral)) {
|
||||
Toy_freeLiteral(filePathLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//set the signal that a new node is needed
|
||||
engine.nextRootNodeFilename = Toy_copyLiteral(filePathLiteral);
|
||||
|
||||
Toy_freeLiteral(filePathLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nativeGetRootNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 0) {
|
||||
interpreter->errorOutput("Incorrect number of arguments passed to getRootNode\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (engine.rootNode == NULL) {
|
||||
interpreter->errorOutput("Can't access root node until after initialization\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Literal resultLiteral = TOY_TO_OPAQUE_LITERAL(engine.rootNode, engine.rootNode->tag);
|
||||
|
||||
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//call the hook
|
||||
typedef struct Natives {
|
||||
char* name;
|
||||
Toy_NativeFn fn;
|
||||
} Natives;
|
||||
|
||||
int Box_hookEngine(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
||||
//build the natives list
|
||||
Natives natives[] = {
|
||||
{"initWindow", nativeInitWindow},
|
||||
{"loadRootNode", nativeLoadRootNode},
|
||||
{"getRootNode", nativeGetRootNode},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
//store the library in an aliased dictionary
|
||||
if (!TOY_IS_NULL(alias)) {
|
||||
//make sure the name isn't taken
|
||||
if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
|
||||
interpreter->errorOutput("Can't override an existing variable\n");
|
||||
Toy_freeLiteral(alias);
|
||||
return false;
|
||||
}
|
||||
|
||||
//create the dictionary to load up with functions
|
||||
Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
|
||||
Toy_initLiteralDictionary(dictionary);
|
||||
|
||||
//load the dict with functions
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name));
|
||||
Toy_Literal func = TOY_TO_FUNCTION_NATIVE_LITERAL(natives[i].fn);
|
||||
|
||||
Toy_setLiteralDictionary(dictionary, name, func);
|
||||
|
||||
Toy_freeLiteral(name);
|
||||
Toy_freeLiteral(func);
|
||||
}
|
||||
|
||||
//build the type
|
||||
Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true);
|
||||
Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
|
||||
Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true);
|
||||
TOY_TYPE_PUSH_SUBTYPE(&type, strType);
|
||||
TOY_TYPE_PUSH_SUBTYPE(&type, fnType);
|
||||
|
||||
//set scope
|
||||
Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
|
||||
Toy_declareScopeVariable(interpreter->scope, alias, type);
|
||||
Toy_setScopeVariable(interpreter->scope, alias, dict, false);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(dict);
|
||||
Toy_freeLiteral(type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//default
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
int Box_hookEngine(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
||||
|
||||
130
box/lib_input.c
130
box/lib_input.c
@@ -1,130 +0,0 @@
|
||||
#include "lib_input.h"
|
||||
|
||||
#include "box_common.h"
|
||||
#include "box_engine.h"
|
||||
|
||||
#include "toy_memory.h"
|
||||
|
||||
static int nativeMapInputEventToKey(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments, Toy_LiteralDictionary* symKeyEventsPtr, char* fnName) {
|
||||
//checks
|
||||
if (arguments->count != 2) {
|
||||
interpreter->errorOutput("Incorrect number of arguments passed to ");
|
||||
interpreter->errorOutput(fnName);
|
||||
interpreter->errorOutput("\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Literal symLiteral = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal evtLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal evtLiteralIdn = evtLiteral;
|
||||
if (TOY_IS_IDENTIFIER(evtLiteral) && Toy_parseIdentifierToValue(interpreter, &evtLiteral)) {
|
||||
Toy_freeLiteral(evtLiteralIdn);
|
||||
}
|
||||
|
||||
Toy_Literal symLiteralIdn = symLiteral;
|
||||
if (TOY_IS_IDENTIFIER(symLiteral) && Toy_parseIdentifierToValue(interpreter, &symLiteral)) {
|
||||
Toy_freeLiteral(symLiteralIdn);
|
||||
}
|
||||
|
||||
if (!TOY_IS_STRING(symLiteral) || !TOY_IS_STRING(evtLiteral)) {
|
||||
interpreter->errorOutput("Incorrect type of arguments passed to mapInputEventToKey\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//use the keycode for faster lookups
|
||||
SDL_Keycode keycode = SDL_GetKeyFromName( Toy_toCString(TOY_AS_STRING(symLiteral)) );
|
||||
|
||||
if (keycode == SDLK_UNKNOWN) {
|
||||
interpreter->errorOutput("Unknown key found: ");
|
||||
interpreter->errorOutput(SDL_GetError());
|
||||
interpreter->errorOutput("\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Literal keycodeLiteral = TOY_TO_INTEGER_LITERAL( (int)keycode );
|
||||
|
||||
//save the sym-event pair
|
||||
Toy_setLiteralDictionary(symKeyEventsPtr, keycodeLiteral, evtLiteral); //I could possibly map multiple events to one sym
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(symLiteral);
|
||||
Toy_freeLiteral(evtLiteral);
|
||||
Toy_freeLiteral(keycodeLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//dry wrappers
|
||||
static int nativeMapInputEventToKeyDown(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
return nativeMapInputEventToKey(interpreter, arguments, &engine.symKeyDownEvents, "mapInputEventToKeyDown");
|
||||
}
|
||||
|
||||
static int nativeMapInputEventToKeyUp(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
return nativeMapInputEventToKey(interpreter, arguments, &engine.symKeyUpEvents, "mapInputEventToKeyUp");
|
||||
}
|
||||
|
||||
//call the hook
|
||||
typedef struct Natives {
|
||||
char* name;
|
||||
Toy_NativeFn fn;
|
||||
} Natives;
|
||||
|
||||
int Box_hookInput(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
||||
//build the natives list
|
||||
Natives natives[] = {
|
||||
{"mapInputEventToKeyDown", nativeMapInputEventToKeyDown},
|
||||
{"mapInputEventToKeyUp", nativeMapInputEventToKeyUp},
|
||||
// {"mapInputEventToMouse", nativeMapInputEventToMouse},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
//store the library in an aliased dictionary
|
||||
if (!TOY_IS_NULL(alias)) {
|
||||
//make sure the name isn't taken
|
||||
if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
|
||||
interpreter->errorOutput("Can't override an existing variable\n");
|
||||
Toy_freeLiteral(alias);
|
||||
return false;
|
||||
}
|
||||
|
||||
//create the dictionary to load up with functions
|
||||
Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
|
||||
Toy_initLiteralDictionary(dictionary);
|
||||
|
||||
//load the dict with functions
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name));
|
||||
Toy_Literal func = TOY_TO_FUNCTION_NATIVE_LITERAL(natives[i].fn);
|
||||
|
||||
Toy_setLiteralDictionary(dictionary, name, func);
|
||||
|
||||
Toy_freeLiteral(name);
|
||||
Toy_freeLiteral(func);
|
||||
}
|
||||
|
||||
//build the type
|
||||
Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true);
|
||||
Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
|
||||
Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true);
|
||||
TOY_TYPE_PUSH_SUBTYPE(&type, strType);
|
||||
TOY_TYPE_PUSH_SUBTYPE(&type, fnType);
|
||||
|
||||
//set scope
|
||||
Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
|
||||
Toy_declareScopeVariable(interpreter->scope, alias, type);
|
||||
Toy_setScopeVariable(interpreter->scope, alias, dict, false);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(dict);
|
||||
Toy_freeLiteral(type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//default
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
int Box_hookInput(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
||||
|
||||
1209
box/lib_node.c
1209
box/lib_node.c
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
int Box_hookNode(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
||||
|
||||
196
box/lib_random.c
196
box/lib_random.c
@@ -1,196 +0,0 @@
|
||||
#include "lib_random.h"
|
||||
|
||||
#include "toy_memory.h"
|
||||
|
||||
static int hashInt(int x) {
|
||||
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
||||
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
||||
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
||||
x = (x >> 16) ^ x;
|
||||
return x;
|
||||
}
|
||||
|
||||
typedef struct Toy_RandomGenerator {
|
||||
int seed; //mutated with each call
|
||||
} Toy_RandomGenerator;
|
||||
|
||||
//Toy native functions
|
||||
static int nativeCreateRandomGenerator(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to createRandomGenerator\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the seed argument
|
||||
Toy_Literal seedLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal seedLiteralIdn = seedLiteral;
|
||||
if (TOY_IS_IDENTIFIER(seedLiteral) && Toy_parseIdentifierToValue(interpreter, &seedLiteral)) {
|
||||
Toy_freeLiteral(seedLiteralIdn);
|
||||
}
|
||||
|
||||
if (TOY_IS_IDENTIFIER(seedLiteral)) {
|
||||
Toy_freeLiteral(seedLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!TOY_IS_INTEGER(seedLiteral)) {
|
||||
interpreter->errorOutput("Incorrect literal type passed to createRandomGenerator");
|
||||
Toy_freeLiteral(seedLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//generate the generator object
|
||||
Toy_RandomGenerator* generator = TOY_ALLOCATE(Toy_RandomGenerator, 1);
|
||||
generator->seed = TOY_AS_INTEGER(seedLiteral);
|
||||
Toy_Literal generatorLiteral = TOY_TO_OPAQUE_LITERAL(generator, TOY_OPAQUE_TAG_RANDOM);
|
||||
|
||||
//return and cleanup
|
||||
Toy_pushLiteralArray(&interpreter->stack, generatorLiteral);
|
||||
|
||||
Toy_freeLiteral(seedLiteral);
|
||||
Toy_freeLiteral(generatorLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeGenerateRandomNumber(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to generateRandomNumber\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the runner object
|
||||
Toy_Literal generatorLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal generatorLiteralIdn = generatorLiteral;
|
||||
if (TOY_IS_IDENTIFIER(generatorLiteral) && Toy_parseIdentifierToValue(interpreter, &generatorLiteral)) {
|
||||
Toy_freeLiteral(generatorLiteralIdn);
|
||||
}
|
||||
|
||||
if (TOY_IS_IDENTIFIER(generatorLiteral)) {
|
||||
Toy_freeLiteral(generatorLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (TOY_GET_OPAQUE_TAG(generatorLiteral) != TOY_OPAQUE_TAG_RANDOM) {
|
||||
interpreter->errorOutput("Unrecognized opaque literal in generateRandomNumber\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_RandomGenerator* generator = TOY_AS_OPAQUE(generatorLiteral);
|
||||
|
||||
//generate the new value and package up the return
|
||||
generator->seed = hashInt(generator->seed);
|
||||
|
||||
Toy_Literal resultLiteral = TOY_TO_INTEGER_LITERAL(generator->seed);
|
||||
|
||||
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(generatorLiteral);
|
||||
Toy_freeLiteral(resultLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nativeFreeRandomGenerator(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to freeRandomGenerator\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the runner object
|
||||
Toy_Literal generatorLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal generatorLiteralIdn = generatorLiteral;
|
||||
if (TOY_IS_IDENTIFIER(generatorLiteral) && Toy_parseIdentifierToValue(interpreter, &generatorLiteral)) {
|
||||
Toy_freeLiteral(generatorLiteralIdn);
|
||||
}
|
||||
|
||||
if (TOY_IS_IDENTIFIER(generatorLiteral)) {
|
||||
Toy_freeLiteral(generatorLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (TOY_GET_OPAQUE_TAG(generatorLiteral) != TOY_OPAQUE_TAG_RANDOM) {
|
||||
interpreter->errorOutput("Unrecognized opaque literal in freeRandomGenerator\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_RandomGenerator* generator = TOY_AS_OPAQUE(generatorLiteral);
|
||||
|
||||
//clear out the runner object
|
||||
TOY_FREE(Toy_RandomGenerator, generator);
|
||||
Toy_freeLiteral(generatorLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//call the hook
|
||||
typedef struct Natives {
|
||||
const char* name;
|
||||
Toy_NativeFn fn;
|
||||
} Natives;
|
||||
|
||||
int Toy_hookRandom(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
||||
//build the natives list
|
||||
Natives natives[] = {
|
||||
{"createRandomGenerator", nativeCreateRandomGenerator},
|
||||
{"generateRandomNumber", nativeGenerateRandomNumber},
|
||||
{"freeRandomGenerator", nativeFreeRandomGenerator},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
//store the library in an aliased dictionary
|
||||
if (!TOY_IS_NULL(alias)) {
|
||||
//make sure the name isn't taken
|
||||
if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
|
||||
interpreter->errorOutput("Can't override an existing variable\n");
|
||||
Toy_freeLiteral(alias);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//create the dictionary to load up with functions
|
||||
Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
|
||||
Toy_initLiteralDictionary(dictionary);
|
||||
|
||||
//load the dict with functions
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name));
|
||||
Toy_Literal func = TOY_TO_FUNCTION_NATIVE_LITERAL(natives[i].fn);
|
||||
|
||||
Toy_setLiteralDictionary(dictionary, name, func);
|
||||
|
||||
Toy_freeLiteral(name);
|
||||
Toy_freeLiteral(func);
|
||||
}
|
||||
|
||||
//build the type
|
||||
Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true);
|
||||
Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
|
||||
Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true);
|
||||
TOY_TYPE_PUSH_SUBTYPE(&type, strType);
|
||||
TOY_TYPE_PUSH_SUBTYPE(&type, fnType);
|
||||
|
||||
//set scope
|
||||
Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
|
||||
Toy_declareScopeVariable(interpreter->scope, alias, type);
|
||||
Toy_setScopeVariable(interpreter->scope, alias, dict, false);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(dict);
|
||||
Toy_freeLiteral(type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//default
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
int Toy_hookRandom(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
||||
|
||||
#define TOY_OPAQUE_TAG_RANDOM 200
|
||||
553
box/lib_runner.c
553
box/lib_runner.c
@@ -1,553 +0,0 @@
|
||||
#include "lib_runner.h"
|
||||
|
||||
#include "toy_memory.h"
|
||||
#include "toy_drive_system.h"
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
#include "repl_tools.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct Toy_Runner {
|
||||
Toy_Interpreter interpreter;
|
||||
const unsigned char* bytecode;
|
||||
size_t size;
|
||||
|
||||
bool dirty;
|
||||
} Toy_Runner;
|
||||
|
||||
//Toy native functions
|
||||
static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to loadScript\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the file path literal with a handle
|
||||
Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal drivePathLiteralIdn = drivePathLiteral;
|
||||
if (TOY_IS_IDENTIFIER(drivePathLiteral) && Toy_parseIdentifierToValue(interpreter, &drivePathLiteral)) {
|
||||
Toy_freeLiteral(drivePathLiteralIdn);
|
||||
}
|
||||
|
||||
if (TOY_IS_IDENTIFIER(drivePathLiteral)) {
|
||||
Toy_freeLiteral(drivePathLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Literal filePathLiteral = Toy_getDrivePathLiteral(interpreter, &drivePathLiteral);
|
||||
|
||||
if (TOY_IS_NULL(filePathLiteral)) {
|
||||
Toy_freeLiteral(filePathLiteral);
|
||||
Toy_freeLiteral(drivePathLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_freeLiteral(drivePathLiteral);
|
||||
|
||||
//use raw types - easier
|
||||
const char* filePath = Toy_toCString(TOY_AS_STRING(filePathLiteral));
|
||||
size_t filePathLength = Toy_lengthRefString(TOY_AS_STRING(filePathLiteral));
|
||||
|
||||
//load and compile the bytecode
|
||||
size_t fileSize = 0;
|
||||
const char* source = (const char*)Toy_readFile(filePath, &fileSize);
|
||||
|
||||
if (!source) {
|
||||
interpreter->errorOutput("Failed to load source file\n");
|
||||
Toy_freeLiteral(filePathLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
const unsigned char* bytecode = Toy_compileString(source, &fileSize);
|
||||
free((void*)source);
|
||||
|
||||
if (!bytecode) {
|
||||
interpreter->errorOutput("Failed to compile source file\n");
|
||||
Toy_freeLiteral(filePathLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//build the runner object
|
||||
Toy_Runner* runner = TOY_ALLOCATE(Toy_Runner, 1);
|
||||
Toy_setInterpreterPrint(&runner->interpreter, interpreter->printOutput);
|
||||
Toy_setInterpreterAssert(&runner->interpreter, interpreter->assertOutput);
|
||||
Toy_setInterpreterError(&runner->interpreter, interpreter->errorOutput);
|
||||
runner->interpreter.hooks = interpreter->hooks;
|
||||
runner->interpreter.scope = NULL;
|
||||
Toy_resetInterpreter(&runner->interpreter);
|
||||
runner->bytecode = bytecode;
|
||||
runner->size = fileSize;
|
||||
runner->dirty = false;
|
||||
|
||||
//build the opaque object, and push it to the stack
|
||||
Toy_Literal runnerLiteral = TOY_TO_OPAQUE_LITERAL(runner, TOY_OPAQUE_TAG_RUNNER);
|
||||
Toy_pushLiteralArray(&interpreter->stack, runnerLiteral);
|
||||
|
||||
//free the drive path
|
||||
Toy_freeLiteral(filePathLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeLoadScriptBytecode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to loadScriptBytecode\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the argument
|
||||
Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal drivePathLiteralIdn = drivePathLiteral;
|
||||
if (TOY_IS_IDENTIFIER(drivePathLiteral) && Toy_parseIdentifierToValue(interpreter, &drivePathLiteral)) {
|
||||
Toy_freeLiteral(drivePathLiteralIdn);
|
||||
}
|
||||
|
||||
if (TOY_IS_IDENTIFIER(drivePathLiteral)) {
|
||||
Toy_freeLiteral(drivePathLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Literal filePathLiteral = Toy_getDrivePathLiteral(interpreter, &drivePathLiteral);
|
||||
|
||||
if (TOY_IS_NULL(filePathLiteral)) {
|
||||
Toy_freeLiteral(filePathLiteral);
|
||||
Toy_freeLiteral(drivePathLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_freeLiteral(drivePathLiteral);
|
||||
|
||||
//use raw types - easier
|
||||
const char* filePath = Toy_toCString(TOY_AS_STRING(filePathLiteral));
|
||||
size_t filePathLength = Toy_lengthRefString(TOY_AS_STRING(filePathLiteral));
|
||||
|
||||
//load the bytecode
|
||||
size_t fileSize = 0;
|
||||
unsigned char* bytecode = (unsigned char*)Toy_readFile(filePath, &fileSize);
|
||||
|
||||
if (!bytecode) {
|
||||
interpreter->errorOutput("Failed to load bytecode file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//build the runner object
|
||||
Toy_Runner* runner = TOY_ALLOCATE(Toy_Runner, 1);
|
||||
Toy_setInterpreterPrint(&runner->interpreter, interpreter->printOutput);
|
||||
Toy_setInterpreterAssert(&runner->interpreter, interpreter->assertOutput);
|
||||
Toy_setInterpreterError(&runner->interpreter, interpreter->errorOutput);
|
||||
runner->interpreter.hooks = interpreter->hooks;
|
||||
runner->interpreter.scope = NULL;
|
||||
Toy_resetInterpreter(&runner->interpreter);
|
||||
runner->bytecode = bytecode;
|
||||
runner->size = fileSize;
|
||||
runner->dirty = false;
|
||||
|
||||
//build the opaque object, and push it to the stack
|
||||
Toy_Literal runnerLiteral = TOY_TO_OPAQUE_LITERAL(runner, TOY_OPAQUE_TAG_RUNNER);
|
||||
Toy_pushLiteralArray(&interpreter->stack, runnerLiteral);
|
||||
|
||||
//free the drive path
|
||||
Toy_freeLiteral(filePathLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeRunScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to runScript\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the runner object
|
||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal runnerIdn = runnerLiteral;
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerIdn);
|
||||
}
|
||||
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
||||
interpreter->errorOutput("Unrecognized opaque literal in runScript\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
|
||||
|
||||
//run
|
||||
if (runner->dirty) {
|
||||
interpreter->errorOutput("Can't re-run a dirty script (try resetting it first)\n");
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned char* bytecodeCopy = TOY_ALLOCATE(unsigned char, runner->size);
|
||||
memcpy(bytecodeCopy, runner->bytecode, runner->size); //need a COPY of the bytecode, because the interpreter eats it
|
||||
|
||||
Toy_runInterpreter(&runner->interpreter, bytecodeCopy, runner->size);
|
||||
runner->dirty = true;
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nativeGetScriptVar(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 2) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to getScriptVar\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the runner object
|
||||
Toy_Literal varName = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal varNameIdn = varName;
|
||||
if (TOY_IS_IDENTIFIER(varName) && Toy_parseIdentifierToValue(interpreter, &varName)) {
|
||||
Toy_freeLiteral(varNameIdn);
|
||||
}
|
||||
|
||||
Toy_Literal runnerIdn = runnerLiteral;
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerIdn);
|
||||
}
|
||||
|
||||
if (TOY_IS_IDENTIFIER(varName) || TOY_IS_IDENTIFIER(runnerLiteral)) {
|
||||
Toy_freeLiteral(varName);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
||||
interpreter->errorOutput("Unrecognized opaque literal in getScriptVar\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
|
||||
|
||||
//dirty check
|
||||
if (!runner->dirty) {
|
||||
interpreter->errorOutput("Can't access variable from a non-dirty script (try running it first)\n");
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the desired variable
|
||||
Toy_Literal varIdn = TOY_TO_IDENTIFIER_LITERAL(Toy_copyRefString(TOY_AS_STRING(varName)));
|
||||
Toy_Literal result = TOY_TO_NULL_LITERAL;
|
||||
Toy_getScopeVariable(runner->interpreter.scope, varIdn, &result);
|
||||
|
||||
Toy_pushLiteralArray(&interpreter->stack, result);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(result);
|
||||
Toy_freeLiteral(varIdn);
|
||||
Toy_freeLiteral(varName);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeCallScriptFn(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count < 2) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to callScriptFn\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the rest args
|
||||
Toy_LiteralArray tmp;
|
||||
Toy_initLiteralArray(&tmp);
|
||||
|
||||
while (arguments->count > 2) {
|
||||
Toy_Literal lit = Toy_popLiteralArray(arguments);
|
||||
Toy_pushLiteralArray(&tmp, lit);
|
||||
Toy_freeLiteral(lit);
|
||||
}
|
||||
|
||||
Toy_LiteralArray rest;
|
||||
Toy_initLiteralArray(&rest);
|
||||
|
||||
while (tmp.count > 0) { //correct the order of the rest args
|
||||
Toy_Literal lit = Toy_popLiteralArray(&tmp);
|
||||
Toy_pushLiteralArray(&rest, lit);
|
||||
Toy_freeLiteral(lit);
|
||||
}
|
||||
|
||||
Toy_freeLiteralArray(&tmp);
|
||||
|
||||
//get the runner object
|
||||
Toy_Literal varName = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal varNameIdn = varName;
|
||||
if (TOY_IS_IDENTIFIER(varName) && Toy_parseIdentifierToValue(interpreter, &varName)) {
|
||||
Toy_freeLiteral(varNameIdn);
|
||||
}
|
||||
|
||||
Toy_Literal runnerIdn = runnerLiteral;
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerIdn);
|
||||
}
|
||||
|
||||
if (TOY_IS_IDENTIFIER(varName) || TOY_IS_IDENTIFIER(runnerLiteral)) {
|
||||
Toy_freeLiteral(varName);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
||||
interpreter->errorOutput("Unrecognized opaque literal in callScriptFn\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
|
||||
|
||||
//dirty check
|
||||
if (!runner->dirty) {
|
||||
interpreter->errorOutput("Can't access fn from a non-dirty script (try running it first)\n");
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
Toy_freeLiteralArray(&rest);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the desired variable
|
||||
Toy_Literal varIdn = TOY_TO_IDENTIFIER_LITERAL(Toy_copyRefString(TOY_AS_STRING(varName)));
|
||||
Toy_Literal fn = TOY_TO_NULL_LITERAL;
|
||||
Toy_getScopeVariable(runner->interpreter.scope, varIdn, &fn);
|
||||
|
||||
if (!TOY_IS_FUNCTION(fn)) {
|
||||
interpreter->errorOutput("Can't run a non-function literal\n");
|
||||
Toy_freeLiteral(fn);
|
||||
Toy_freeLiteral(varIdn);
|
||||
Toy_freeLiteral(varName);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
Toy_freeLiteralArray(&rest);
|
||||
}
|
||||
|
||||
//call
|
||||
Toy_LiteralArray resultArray;
|
||||
Toy_initLiteralArray(&resultArray);
|
||||
|
||||
Toy_callLiteralFn(interpreter, fn, &rest, &resultArray);
|
||||
|
||||
Toy_Literal result = TOY_TO_NULL_LITERAL;
|
||||
if (resultArray.count > 0) {
|
||||
result = Toy_popLiteralArray(&resultArray);
|
||||
}
|
||||
|
||||
Toy_pushLiteralArray(&interpreter->stack, result);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteralArray(&resultArray);
|
||||
Toy_freeLiteral(result);
|
||||
Toy_freeLiteral(fn);
|
||||
Toy_freeLiteral(varIdn);
|
||||
Toy_freeLiteral(varName);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
Toy_freeLiteralArray(&rest);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeResetScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to resetScript\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the runner object
|
||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal runnerIdn = runnerLiteral;
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerIdn);
|
||||
}
|
||||
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
||||
interpreter->errorOutput("Unrecognized opaque literal in resetScript\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
|
||||
|
||||
//reset
|
||||
if (!runner->dirty) {
|
||||
interpreter->errorOutput("Can't reset a non-dirty script (try running it first)\n");
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_resetInterpreter(&runner->interpreter);
|
||||
runner->dirty = false;
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nativeFreeScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to freeScript\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the runner object
|
||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal runnerIdn = runnerLiteral;
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerIdn);
|
||||
}
|
||||
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
||||
interpreter->errorOutput("Unrecognized opaque literal in freeScript\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
|
||||
|
||||
//clear out the runner object
|
||||
runner->interpreter.hooks = NULL;
|
||||
Toy_freeInterpreter(&runner->interpreter);
|
||||
TOY_FREE_ARRAY(unsigned char, runner->bytecode, runner->size);
|
||||
|
||||
TOY_FREE(Toy_Runner, runner);
|
||||
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nativeCheckScriptDirty(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to checkScriptDirty\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the runner object
|
||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
Toy_Literal runnerIdn = runnerLiteral;
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerIdn);
|
||||
}
|
||||
|
||||
if (TOY_IS_IDENTIFIER(runnerLiteral)) {
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
||||
interpreter->errorOutput("Unrecognized opaque literal in checkScriptDirty\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
|
||||
|
||||
//run
|
||||
Toy_Literal result = TOY_TO_BOOLEAN_LITERAL(runner->dirty);
|
||||
|
||||
Toy_pushLiteralArray(&interpreter->stack, result);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(result);
|
||||
Toy_freeLiteral(runnerLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//call the hook
|
||||
typedef struct Natives {
|
||||
const char* name;
|
||||
Toy_NativeFn fn;
|
||||
} Natives;
|
||||
|
||||
int Toy_hookRunner(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
||||
//build the natives list
|
||||
Natives natives[] = {
|
||||
{"loadScript", nativeLoadScript},
|
||||
{"loadScriptBytecode", nativeLoadScriptBytecode},
|
||||
{"runScript", nativeRunScript},
|
||||
{"getScriptVar", nativeGetScriptVar},
|
||||
{"callScriptFn", nativeCallScriptFn},
|
||||
{"resetScript", nativeResetScript},
|
||||
{"freeScript", nativeFreeScript},
|
||||
{"checkScriptDirty", nativeCheckScriptDirty},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
//store the library in an aliased dictionary
|
||||
if (!TOY_IS_NULL(alias)) {
|
||||
//make sure the name isn't taken
|
||||
if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
|
||||
interpreter->errorOutput("Can't override an existing variable\n");
|
||||
Toy_freeLiteral(alias);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//create the dictionary to load up with functions
|
||||
Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
|
||||
Toy_initLiteralDictionary(dictionary);
|
||||
|
||||
//load the dict with functions
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name));
|
||||
Toy_Literal func = TOY_TO_FUNCTION_NATIVE_LITERAL(natives[i].fn);
|
||||
|
||||
Toy_setLiteralDictionary(dictionary, name, func);
|
||||
|
||||
Toy_freeLiteral(name);
|
||||
Toy_freeLiteral(func);
|
||||
}
|
||||
|
||||
//build the type
|
||||
Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true);
|
||||
Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
|
||||
Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true);
|
||||
TOY_TYPE_PUSH_SUBTYPE(&type, strType);
|
||||
TOY_TYPE_PUSH_SUBTYPE(&type, fnType);
|
||||
|
||||
//set scope
|
||||
Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
|
||||
Toy_declareScopeVariable(interpreter->scope, alias, type);
|
||||
Toy_setScopeVariable(interpreter->scope, alias, dict, false);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(dict);
|
||||
Toy_freeLiteral(type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//default
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
int Toy_hookRunner(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
||||
|
||||
#define TOY_OPAQUE_TAG_RUNNER 100
|
||||
|
||||
2117
box/lib_standard.c
2117
box/lib_standard.c
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
||||
|
||||
51
box/makefile
51
box/makefile
@@ -1,51 +0,0 @@
|
||||
CC=gcc
|
||||
|
||||
IDIR+=. ../Toy/source
|
||||
CFLAGS+=$(addprefix -I,$(IDIR)) -g -Wall -W -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable
|
||||
LIBS+=-lSDL2 -lSDL2_image -ltoy
|
||||
|
||||
ODIR = obj
|
||||
SRC = $(wildcard *.c)
|
||||
OBJ = $(addprefix $(ODIR)/,$(SRC:.c=.o))
|
||||
|
||||
REPLLIBS = $(wildcard ../Toy/repl/lib*) $(wildcard ../Toy/repl/repl_tools.*)
|
||||
|
||||
OUTNAME=box
|
||||
|
||||
ifeq ($(findstring CYGWIN, $(shell uname)),CYGWIN)
|
||||
LIBLINE =-Wl,--out-implib=$(BOX_OUTDIR)/lib$(OUTNAME).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive $(OBJ) -Wl,--no-whole-archive
|
||||
OUT=$(BOX_OUTDIR)/$(OUTNAME).dll
|
||||
else ifeq ($(shell uname),Linux)
|
||||
LIBLINE=-Wl,--out-implib=./$(BOX_OUTDIR)/lib$(OUTNAME).a -Wl,--whole-archive $(OBJ) -Wl,--no-whole-archive
|
||||
OUT=./$(BOX_OUTDIR)/lib$(OUTNAME).so
|
||||
CFLAGS += -fPIC
|
||||
else ifeq ($(OS),Windows_NT)
|
||||
LIBLINE =-Wl,--out-implib=$(BOX_OUTDIR)/lib$(OUTNAME).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive $(OBJ) -Wl,--no-whole-archive
|
||||
OUT=$(BOX_OUTDIR)/$(OUTNAME).dll
|
||||
else
|
||||
@echo "Platform test failed - what platform is this?"
|
||||
exit 1
|
||||
endif
|
||||
|
||||
library: repllibs $(OBJ)
|
||||
$(CC) -DBOX_EXPORT $(CFLAGS) -shared -o $(OUT) $(LIBLINE) -L../$(LIBDIR) $(LIBS)
|
||||
|
||||
static: repllibs $(OBJ)
|
||||
ar crs $(BOX_OUTDIR)/lib$(OUTNAME).a $(OBJ) -L../$(LIBDIR) $(LIBS)
|
||||
|
||||
#copy the stuff from Toy/repl that is needed
|
||||
repllibs:
|
||||
cp $(REPLLIBS) .
|
||||
|
||||
$(OBJ): | $(ODIR)
|
||||
|
||||
$(ODIR):
|
||||
mkdir $(ODIR)
|
||||
|
||||
$(ODIR)/%.o: %.c
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean-repllibs:
|
||||
$(RM) $(notdir $(REPLLIBS))
|
||||
207
box/repl_tools.c
207
box/repl_tools.c
@@ -1,207 +0,0 @@
|
||||
#include "repl_tools.h"
|
||||
#include "lib_about.h"
|
||||
#include "lib_standard.h"
|
||||
#include "lib_random.h"
|
||||
#include "lib_runner.h"
|
||||
|
||||
#include "toy_console_colors.h"
|
||||
|
||||
#include "toy_lexer.h"
|
||||
#include "toy_parser.h"
|
||||
#include "toy_compiler.h"
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//IO functions
|
||||
const unsigned char* Toy_readFile(const char* path, size_t* fileSize) {
|
||||
FILE* file = fopen(path, "rb");
|
||||
|
||||
if (file == NULL) {
|
||||
fprintf(stderr, TOY_CC_ERROR "Could not open file \"%s\"\n" TOY_CC_RESET, path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fseek(file, 0L, SEEK_END);
|
||||
*fileSize = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
unsigned char* buffer = (unsigned char*)malloc(*fileSize + 1);
|
||||
|
||||
if (buffer == NULL) {
|
||||
fprintf(stderr, TOY_CC_ERROR "Not enough memory to read \"%s\"\n" TOY_CC_RESET, path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t bytesRead = fread(buffer, sizeof(unsigned char), *fileSize, file);
|
||||
|
||||
buffer[*fileSize] = '\0'; //NOTE: fread doesn't append this
|
||||
|
||||
if (bytesRead < *fileSize) {
|
||||
fprintf(stderr, TOY_CC_ERROR "Could not read file \"%s\"\n" TOY_CC_RESET, path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int Toy_writeFile(const char* path, const unsigned char* bytes, size_t size) {
|
||||
FILE* file = fopen(path, "wb");
|
||||
|
||||
if (file == NULL) {
|
||||
fprintf(stderr, TOY_CC_ERROR "Could not open file \"%s\"\n" TOY_CC_RESET, path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t written = fwrite(bytes, size, 1, file);
|
||||
|
||||
if (written != 1) {
|
||||
fprintf(stderr, TOY_CC_ERROR "Could not write file \"%s\"\n" TOY_CC_RESET, path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//repl functions
|
||||
const unsigned char* Toy_compileString(const char* source, size_t* size) {
|
||||
Toy_Lexer lexer;
|
||||
Toy_Parser parser;
|
||||
Toy_Compiler compiler;
|
||||
|
||||
Toy_initLexer(&lexer, source);
|
||||
Toy_initParser(&parser, &lexer);
|
||||
Toy_initCompiler(&compiler);
|
||||
|
||||
//step 1 - run the parser until the end of the source
|
||||
Toy_ASTNode* node = Toy_scanParser(&parser);
|
||||
while(node != NULL) {
|
||||
//on error, pack up and leave
|
||||
if (node->type == TOY_AST_NODE_ERROR) {
|
||||
Toy_freeASTNode(node);
|
||||
Toy_freeCompiler(&compiler);
|
||||
Toy_freeParser(&parser);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Toy_writeCompiler(&compiler, node);
|
||||
Toy_freeASTNode(node);
|
||||
node = Toy_scanParser(&parser);
|
||||
}
|
||||
|
||||
//step 2 - get the bytecode dump
|
||||
const unsigned char* tb = Toy_collateCompiler(&compiler, size);
|
||||
|
||||
//cleanup
|
||||
Toy_freeCompiler(&compiler);
|
||||
Toy_freeParser(&parser);
|
||||
//no lexer to clean up
|
||||
|
||||
//finally
|
||||
return tb;
|
||||
}
|
||||
|
||||
void Toy_runBinary(const unsigned char* tb, size_t size) {
|
||||
Toy_Interpreter interpreter;
|
||||
Toy_initInterpreter(&interpreter);
|
||||
|
||||
//inject the libs
|
||||
Toy_injectNativeHook(&interpreter, "about", Toy_hookAbout);
|
||||
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
||||
Toy_injectNativeHook(&interpreter, "random", Toy_hookRandom);
|
||||
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
||||
|
||||
Toy_runInterpreter(&interpreter, tb, (int)size);
|
||||
Toy_freeInterpreter(&interpreter);
|
||||
}
|
||||
|
||||
void Toy_runBinaryFile(const char* fname) {
|
||||
size_t size = 0; //not used
|
||||
const unsigned char* tb = Toy_readFile(fname, &size);
|
||||
if (!tb) {
|
||||
return;
|
||||
}
|
||||
Toy_runBinary(tb, size);
|
||||
//interpreter takes ownership of the binary data
|
||||
}
|
||||
|
||||
void Toy_runSource(const char* source) {
|
||||
size_t size = 0;
|
||||
const unsigned char* tb = Toy_compileString(source, &size);
|
||||
if (!tb) {
|
||||
return;
|
||||
}
|
||||
|
||||
Toy_runBinary(tb, size);
|
||||
}
|
||||
|
||||
void Toy_runSourceFile(const char* fname) {
|
||||
size_t size = 0; //not used
|
||||
const char* source = (const char*)Toy_readFile(fname, &size);
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
Toy_runSource(source);
|
||||
free((void*)source);
|
||||
}
|
||||
|
||||
//utils for debugging the header
|
||||
static unsigned char readByte(const unsigned char* tb, int* count) {
|
||||
unsigned char ret = *(unsigned char*)(tb + *count);
|
||||
*count += 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char* readString(const unsigned char* tb, int* count) {
|
||||
const unsigned char* ret = tb + *count;
|
||||
*count += strlen((char*)ret) + 1; //+1 for null character
|
||||
return (const char*)ret;
|
||||
}
|
||||
|
||||
void Toy_parseBinaryFileHeader(const char* fname) {
|
||||
size_t size = 0; //not used
|
||||
const unsigned char* tb = Toy_readFile(fname, &size);
|
||||
if (!tb || size < 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
|
||||
//header section
|
||||
const unsigned char major = readByte(tb, &count);
|
||||
const unsigned char minor = readByte(tb, &count);
|
||||
const unsigned char patch = readByte(tb, &count);
|
||||
|
||||
const char* build = readString(tb, &count);
|
||||
|
||||
printf("Toy Programming Language Interpreter Version %d.%d.%d (interpreter built on %s)\n\n", TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH, TOY_VERSION_BUILD);
|
||||
|
||||
printf("Toy Programming Language Bytecode Version ");
|
||||
|
||||
//print the output
|
||||
if (major == TOY_VERSION_MAJOR && minor == TOY_VERSION_MINOR && patch == TOY_VERSION_PATCH) {
|
||||
printf("%d.%d.%d", major, minor, patch);
|
||||
}
|
||||
else {
|
||||
printf(TOY_CC_FONT_YELLOW TOY_CC_BACK_BLACK "%d.%d.%d" TOY_CC_RESET, major, minor, patch);
|
||||
}
|
||||
|
||||
printf(" (interpreter built on ");
|
||||
|
||||
if (strncmp(build, TOY_VERSION_BUILD, strlen(TOY_VERSION_BUILD)) == 0) {
|
||||
printf("%s", build);
|
||||
}
|
||||
else {
|
||||
printf(TOY_CC_FONT_YELLOW TOY_CC_BACK_BLACK "%s" TOY_CC_RESET, build);
|
||||
}
|
||||
|
||||
printf(")\n");
|
||||
|
||||
//cleanup
|
||||
free((void*)tb);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "toy_common.h"
|
||||
|
||||
const unsigned char* Toy_readFile(const char* path, size_t* fileSize);
|
||||
int Toy_writeFile(const char* path, const unsigned char* bytes, size_t size);
|
||||
|
||||
const unsigned char* Toy_compileString(const char* source, size_t* size);
|
||||
|
||||
void Toy_runBinary(const unsigned char* tb, size_t size);
|
||||
void Toy_runBinaryFile(const char* fname);
|
||||
void Toy_runSource(const char* source);
|
||||
void Toy_runSourceFile(const char* fname);
|
||||
|
||||
void Toy_parseBinaryFileHeader(const char* fname);
|
||||
46
makefile
46
makefile
@@ -1,34 +1,19 @@
|
||||
export OUTDIR = out
|
||||
export LIBDIR = lib
|
||||
export TOY_OUTDIR = ../$(LIBDIR)
|
||||
export BOX_OUTDIR = ../$(LIBDIR)
|
||||
export BOX_OUTDIR = ../$(OUTDIR)
|
||||
export TOY_OUTDIR = ../../$(OUTDIR)
|
||||
|
||||
all: $(OUTDIR) $(LIBDIR) toy box
|
||||
all: $(OUTDIR) toy box
|
||||
$(MAKE) -j8 -C source
|
||||
ifeq ($(findstring CYGWIN, $(shell uname)),CYGWIN)
|
||||
cp $(LIBDIR)/*.dll $(OUTDIR)
|
||||
else ifeq ($(shell uname),Linux)
|
||||
cp $(LIBDIR)/*.so $(OUTDIR)
|
||||
else ifeq ($(OS),Windows_NT)
|
||||
cp $(LIBDIR)/*.dll $(OUTDIR)
|
||||
endif
|
||||
|
||||
test: clean $(OUTDIR) toy box
|
||||
$(MAKE) -C test
|
||||
|
||||
toy: $(LIBDIR)
|
||||
$(MAKE) -j8 -C Toy/source
|
||||
$(MAKE) -j8 -C Box/Toy/source
|
||||
|
||||
box: $(LIBDIR)
|
||||
$(MAKE) -j8 -C box repllibs
|
||||
$(MAKE) -j8 -C box library
|
||||
$(MAKE) -j8 -C Box/source
|
||||
|
||||
$(OUTDIR):
|
||||
mkdir $(OUTDIR)
|
||||
|
||||
$(LIBDIR):
|
||||
mkdir $(LIBDIR)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
@@ -56,24 +41,3 @@ else
|
||||
endif
|
||||
|
||||
rebuild: clean all
|
||||
|
||||
|
||||
#utils for the manual android build
|
||||
INCLUDEDIR=include
|
||||
|
||||
SOURCEDIR=bundle
|
||||
|
||||
$(INCLUDEDIR):
|
||||
mkdir $(INCLUDEDIR)
|
||||
|
||||
$(SOURCEDIR):
|
||||
mkdir $(SOURCEDIR)
|
||||
|
||||
sourcelist:
|
||||
@echo $(addprefix ../airport/,$(wildcard Toy/source/*.c) $(wildcard box/*.c) $(wildcard source/*.c)) > source.list
|
||||
|
||||
bundleincludes: $(INCLUDEDIR)
|
||||
cp $(addprefix ../airport/,$(wildcard Toy/source/*.h) $(wildcard box/*.h) $(wildcard source/*.h)) $(INCLUDEDIR)
|
||||
|
||||
bundlesource: $(SOURCEDIR)
|
||||
cp $(addprefix ../airport/,$(wildcard Toy/source/*.c) $(wildcard box/*.c) $(wildcard source/*.c)) $(SOURCEDIR)
|
||||
@@ -1,41 +0,0 @@
|
||||
CC=gcc
|
||||
|
||||
IDIR+=. ../Toy/source ../box
|
||||
CFLAGS+=$(addprefix -I,$(IDIR)) -DSDL_MAIN_HANDLED -g -Wall -W -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable
|
||||
LIBS+=-lSDL2 -lSDL2_image -ltoy -lbox
|
||||
|
||||
ODIR = obj
|
||||
TARGETS = $(wildcard ../box/*.c)
|
||||
TESTS = $(wildcard *.c)
|
||||
OBJ = $(addprefix $(ODIR)/,$(TARGETS:../box/%.c=%.o)) $(addprefix $(ODIR)/,$(TESTS:.c=.o))
|
||||
|
||||
.PRECIOUS: $(TESTS:%.c=../$(OUTDIR)/%.exe)
|
||||
|
||||
all: $(OBJ) $(TESTS:%.c=../$(OUTDIR)/%.exe)
|
||||
|
||||
../$(OUTDIR)/%.exe: $(ODIR)/%.o
|
||||
ifeq ($(shell uname),Linux)
|
||||
@$(CC) -o $@ $< $(TARGETS:../box/%.c=$(ODIR)/%.o) $(CFLAGS) -Wl,-rpath,../out -L../$(LIBDIR) $(LIBS)
|
||||
cp ../$(LIBDIR)/*.so ../$(OUTDIR)
|
||||
valgrind --leak-check=full --track-origins=yes $@
|
||||
else
|
||||
@$(CC) -o $@ $< $(TARGETS:../box/%.c=$(ODIR)/%.o) $(CFLAGS) -L../$(LIBDIR) $(LIBS)
|
||||
cp ../$(LIBDIR)/*.dll ../$(OUTDIR)
|
||||
$@
|
||||
endif
|
||||
|
||||
$(OBJ): | $(ODIR)
|
||||
|
||||
$(ODIR):
|
||||
mkdir $(ODIR)
|
||||
|
||||
$(ODIR)/%.o: %.c
|
||||
@$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
$(ODIR)/%.o: ../box/%.c
|
||||
@$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
$(RM) $(ODIR)
|
||||
@@ -1,14 +0,0 @@
|
||||
var tally: int = 0;
|
||||
|
||||
fn onInit(node: opaque) {
|
||||
print "child init called";
|
||||
}
|
||||
|
||||
fn onStep(node: opaque) {
|
||||
print "child step called";
|
||||
print ++tally;
|
||||
}
|
||||
|
||||
fn onFree(node: opaque) {
|
||||
print "child free called";
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fn onInit(node: opaque) {
|
||||
print "init called";
|
||||
}
|
||||
|
||||
fn onStep(node: opaque) {
|
||||
print "step called";
|
||||
}
|
||||
|
||||
fn onFree(node: opaque) {
|
||||
print "free called";
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
#include "box_engine_node.h"
|
||||
|
||||
#include "toy_lexer.h"
|
||||
#include "toy_parser.h"
|
||||
#include "toy_compiler.h"
|
||||
#include "toy_interpreter.h"
|
||||
#include "toy_console_colors.h"
|
||||
#include "toy_memory.h"
|
||||
|
||||
#include "repl_tools.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
//suppress the print keyword
|
||||
static void noPrintFn(const char* output) {
|
||||
//NO OP
|
||||
}
|
||||
|
||||
int main() {
|
||||
{
|
||||
//setup interpreter
|
||||
Toy_Interpreter interpreter;
|
||||
Toy_initInterpreter(&interpreter);
|
||||
Toy_setInterpreterPrint(&interpreter, noPrintFn);
|
||||
|
||||
size_t size = 0;
|
||||
|
||||
const char* source = Toy_readFile("./scripts/parent_engine_node.toy", &size);
|
||||
const unsigned char* tb = Toy_compileString(source, &size);
|
||||
|
||||
//create and test the engine node
|
||||
Box_EngineNode* node = TOY_ALLOCATE(Box_EngineNode, 1);
|
||||
|
||||
Box_initEngineNode(node, &interpreter, tb, size);
|
||||
|
||||
Toy_Literal nodeLiteral = TOY_TO_OPAQUE_LITERAL(node, OPAQUE_TAG_ENGINE_NODE);
|
||||
|
||||
//argument list to pass in the node
|
||||
Toy_LiteralArray arguments;
|
||||
Toy_initLiteralArray(&arguments);
|
||||
|
||||
//call each function
|
||||
Box_callRecursiveEngineNode(node, &interpreter, "onInit", &arguments);
|
||||
Box_callRecursiveEngineNode(node, &interpreter, "onStep", &arguments);
|
||||
Box_callRecursiveEngineNode(node, &interpreter, "onQuit", &arguments);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteralArray(&arguments);
|
||||
Box_freeEngineNode(node);
|
||||
free((void*)source);
|
||||
|
||||
Toy_freeInterpreter(&interpreter);
|
||||
}
|
||||
|
||||
{
|
||||
//setup interpreter
|
||||
Toy_Interpreter interpreter;
|
||||
Toy_initInterpreter(&interpreter);
|
||||
Toy_setInterpreterPrint(&interpreter, noPrintFn);
|
||||
|
||||
size_t size = 0;
|
||||
|
||||
const char* source = Toy_readFile("./scripts/parent_engine_node.toy", &size);
|
||||
const unsigned char* tb = Toy_compileString(source, &size);
|
||||
|
||||
//create and test the engine node
|
||||
Box_EngineNode* node = TOY_ALLOCATE(Box_EngineNode, 1);
|
||||
|
||||
Box_initEngineNode(node, &interpreter, tb, size);
|
||||
Toy_resetInterpreter(&interpreter);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
const char* source = Toy_readFile("./scripts/child_engine_node.toy", &size);
|
||||
const unsigned char* tb = Toy_compileString(source, &size);
|
||||
|
||||
Box_EngineNode* child = TOY_ALLOCATE(Box_EngineNode, 1);
|
||||
Box_initEngineNode(child, &interpreter, tb, size);
|
||||
Toy_resetInterpreter(&interpreter);
|
||||
|
||||
Box_pushEngineNode(node, child);
|
||||
|
||||
free((void*)source);
|
||||
}
|
||||
|
||||
//argument list to pass in each time
|
||||
Toy_LiteralArray arguments;
|
||||
Toy_initLiteralArray(&arguments);
|
||||
|
||||
//test the calls
|
||||
Box_callRecursiveEngineNode(node, &interpreter, "onInit", &arguments);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Box_callRecursiveEngineNode(node, &interpreter, "onStep", &arguments);
|
||||
}
|
||||
|
||||
Box_callRecursiveEngineNode(node, &interpreter, "onFree", &arguments);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteralArray(&arguments);
|
||||
Box_freeEngineNode(node); //frees all children
|
||||
free((void*)source);
|
||||
|
||||
Toy_freeInterpreter(&interpreter);
|
||||
}
|
||||
|
||||
printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user