Add project files.
This commit is contained in:
parent
3c7909c4d8
commit
d1f943df8e
2
Font.cc
Normal file
2
Font.cc
Normal file
@ -0,0 +1,2 @@
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#include "Font.h"
|
73
Font.h
Normal file
73
Font.h
Normal file
@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "stb_truetype.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "iAllocator.h"
|
||||
#include "Rasterbuffer.h"
|
||||
|
||||
namespace gj {
|
||||
|
||||
|
||||
class Font {
|
||||
public:
|
||||
Font() = delete;
|
||||
Font(Font&&) = delete;
|
||||
Font(const Font&) = delete;
|
||||
|
||||
Font& operator=(Font&&) = delete;
|
||||
Font& operator=(const Font&) = delete;
|
||||
|
||||
Font(iAllocator* alloc, const std::string& path) : alloc_(alloc) {
|
||||
std::ifstream ifs(path, std::ios::binary);
|
||||
if (!ifs) {
|
||||
Abort("failed to open: "+path);
|
||||
}
|
||||
|
||||
ifs.seekg(0, std::ios::end);
|
||||
const size_t size = ifs.tellg();
|
||||
ifs.seekg(0);
|
||||
|
||||
buf_ = alloc_->MakeUniqueArray<uint8_t>(size);
|
||||
ifs.read(reinterpret_cast<char*>(buf_.get()), size);
|
||||
|
||||
const int offset = stbtt_GetFontOffsetForIndex(buf_.get(), 0);
|
||||
if (!stbtt_InitFont(&stb_, buf_.get(), offset)) {
|
||||
Abort("invalid font: "+path);
|
||||
}
|
||||
}
|
||||
|
||||
Colorbuffer&& RenderGlyph(char16_t c, uint32_t fontsize = 32) {
|
||||
int w, h;
|
||||
|
||||
const float s = stbtt_ScaleForPixelHeight(&stb_, fontsize*1.f);
|
||||
|
||||
const uint8_t* src = stbtt_GetCodepointBitmap(&stb_, 0, s, c, &w, &h, 0, 0);
|
||||
|
||||
Colorbuffer ret(alloc_, w, h);
|
||||
float* dst = ret.ptr();
|
||||
|
||||
for (int y = 0; y < h; ++y) {
|
||||
for (int x = 0; x < w; ++x) {
|
||||
*dst = *src*1./UINT8_MAX;
|
||||
++dst, ++src;
|
||||
}
|
||||
}
|
||||
return std::move(ret);
|
||||
}
|
||||
|
||||
private:
|
||||
iAllocator* alloc_;
|
||||
|
||||
stbtt_fontinfo stb_;
|
||||
|
||||
iAllocator::UniquePtr<uint8_t> buf_;
|
||||
};
|
||||
|
||||
|
||||
}
|
31
GlyphsJuke.sln
Normal file
31
GlyphsJuke.sln
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31605.320
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GlyphsJuke", "GlyphsJuke.vcxproj", "{7AEB2CAE-89E0-4705-9020-26066ABDE274}"
|
||||
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
|
||||
{7AEB2CAE-89E0-4705-9020-26066ABDE274}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7AEB2CAE-89E0-4705-9020-26066ABDE274}.Debug|x64.Build.0 = Debug|x64
|
||||
{7AEB2CAE-89E0-4705-9020-26066ABDE274}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{7AEB2CAE-89E0-4705-9020-26066ABDE274}.Debug|x86.Build.0 = Debug|Win32
|
||||
{7AEB2CAE-89E0-4705-9020-26066ABDE274}.Release|x64.ActiveCfg = Release|x64
|
||||
{7AEB2CAE-89E0-4705-9020-26066ABDE274}.Release|x64.Build.0 = Release|x64
|
||||
{7AEB2CAE-89E0-4705-9020-26066ABDE274}.Release|x86.ActiveCfg = Release|Win32
|
||||
{7AEB2CAE-89E0-4705-9020-26066ABDE274}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {4FFC52B9-3723-4AEF-8A03-9DE3DC1BFB22}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
161
GlyphsJuke.vcxproj
Normal file
161
GlyphsJuke.vcxproj
Normal file
@ -0,0 +1,161 @@
|
||||
<?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>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{7aeb2cae-89e0-4705-9020-26066abde274}</ProjectGuid>
|
||||
<RootNamespace>GlyphsJuke</RootNamespace>
|
||||
<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>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</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>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Font.cc" />
|
||||
<ClCompile Include="main.cc" />
|
||||
<ClCompile Include="Win32Console.cc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="common.h" />
|
||||
<ClInclude Include="Font.h" />
|
||||
<ClInclude Include="Rasterbuffer.h" />
|
||||
<ClInclude Include="iConsole.h" />
|
||||
<ClInclude Include="iAllocator.h" />
|
||||
<ClInclude Include="LinearAllocator.h" />
|
||||
<ClInclude Include="StackAllocator.h" />
|
||||
<ClInclude Include="stb_truetype.h" />
|
||||
<ClInclude Include="Win32Console.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
57
GlyphsJuke.vcxproj.filters
Normal file
57
GlyphsJuke.vcxproj.filters
Normal file
@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cc">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Win32Console.cc">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Font.cc">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="iConsole.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="iAllocator.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="LinearAllocator.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="StackAllocator.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Rasterbuffer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Win32Console.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="stb_truetype.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Font.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
97
LinearAllocator.h
Normal file
97
LinearAllocator.h
Normal file
@ -0,0 +1,97 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "common.h"
|
||||
#include "iAllocator.h"
|
||||
|
||||
|
||||
namespace gj {
|
||||
|
||||
|
||||
class LinearAllocator : public iAllocator {
|
||||
public:
|
||||
using iAllocator::Alloc;
|
||||
using iAllocator::MakeUnique;
|
||||
|
||||
LinearAllocator() = delete;
|
||||
LinearAllocator(LinearAllocator&&) = delete;
|
||||
LinearAllocator(const LinearAllocator&) = delete;
|
||||
|
||||
LinearAllocator& operator=(LinearAllocator&&) = delete;
|
||||
LinearAllocator& operator=(const LinearAllocator&) = delete;
|
||||
|
||||
LinearAllocator(void* ptr, const size_t size) :
|
||||
ptr_(static_cast<uint8_t*>(ptr)) {
|
||||
assert(size >= sizeof(Header)*2);
|
||||
|
||||
auto head = reinterpret_cast<Header*>(ptr_);
|
||||
head->prev = 0;
|
||||
head->next = size - sizeof(Header);
|
||||
head->size = sizeof(Header);
|
||||
|
||||
auto tail = reinterpret_cast<Header*>(ptr_+head->next);
|
||||
tail->prev = head->next;
|
||||
tail->next = 0;
|
||||
tail->size = sizeof(Header);
|
||||
}
|
||||
|
||||
void* Alloc(const size_t size) override {
|
||||
const size_t aligned_size = (((size >> 3) + !!(size & 0b111))) << 3;
|
||||
const size_t whole_size = sizeof(Header) + aligned_size;
|
||||
assert(aligned_size >= size);
|
||||
|
||||
auto h = reinterpret_cast<Header*>(ptr_);
|
||||
|
||||
while (h->next) {
|
||||
const size_t remain = h->next - h->size;
|
||||
if (remain >= whole_size) {
|
||||
auto hprev = h;
|
||||
auto hnext = reinterpret_cast<Header*>(reinterpret_cast<uint8_t*>(hprev) + hprev->next);
|
||||
|
||||
h = reinterpret_cast<Header*>(reinterpret_cast<uint8_t*>(hprev) + hprev->size);
|
||||
h->prev = hprev->size;
|
||||
h->next = remain;
|
||||
h->size = whole_size;
|
||||
|
||||
hprev->next = h->prev;
|
||||
hnext->prev = h->next;
|
||||
|
||||
return h + 1;
|
||||
}
|
||||
h = reinterpret_cast<Header*>(reinterpret_cast<uint8_t*>(h) + h->next);
|
||||
}
|
||||
Abort("LinearAllocator Allocation Failure");
|
||||
}
|
||||
|
||||
void Free(void* ptr) override {
|
||||
if (!ptr) return;
|
||||
uint8_t* uptr = reinterpret_cast<uint8_t*>(ptr) - sizeof(Header);
|
||||
|
||||
auto h = reinterpret_cast<Header*>(uptr);
|
||||
auto hprev = reinterpret_cast<Header*>(uptr - h->prev);
|
||||
auto hnext = reinterpret_cast<Header*>(uptr + h->next);
|
||||
|
||||
hprev->next += h->next;
|
||||
hnext->prev += h->prev;
|
||||
}
|
||||
|
||||
private:
|
||||
/* |------prev--------||--------next--------| */
|
||||
/* |----size-----| */
|
||||
/* memory: HHAAAAAAAAAAAAAAAAUUHHAAAAAAAAAAAAAUUUUUUUHHAAAAA */
|
||||
/* H: header, A: allocated area, U: unused area */
|
||||
struct Header {
|
||||
size_t prev;
|
||||
size_t next;
|
||||
size_t size;
|
||||
};
|
||||
static_assert(sizeof(Header) == sizeof(size_t)*3, "padding detected in memory header");
|
||||
|
||||
uint8_t* const ptr_;
|
||||
};
|
||||
|
||||
|
||||
}
|
72
Rasterbuffer.h
Normal file
72
Rasterbuffer.h
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "iAllocator.h"
|
||||
|
||||
namespace gj {
|
||||
|
||||
|
||||
template <typename T>
|
||||
class Rasterbuffer {
|
||||
public:
|
||||
Rasterbuffer() = delete;
|
||||
Rasterbuffer(const Rasterbuffer&) = delete;
|
||||
Rasterbuffer& operator=(const Rasterbuffer&) = delete;
|
||||
|
||||
Rasterbuffer(iAllocator* alloc, uint32_t w, uint32_t h) :
|
||||
alloc_(alloc), w_(w), h_(h),
|
||||
buf_(alloc->Alloc<T>(static_cast<uint64_t>(w_)*h_)) {
|
||||
_ASSERT(buf_ != nullptr);
|
||||
}
|
||||
~Rasterbuffer() {
|
||||
alloc_->Free(buf_);
|
||||
}
|
||||
|
||||
Rasterbuffer(Rasterbuffer&& src) noexcept :
|
||||
alloc_(src.alloc_), w_(src.w_), h_(src.h_), buf_(src.buf_) {
|
||||
src.buf_ = nullptr;
|
||||
}
|
||||
Rasterbuffer& operator=(Rasterbuffer&& src) noexcept {
|
||||
if (this != &src) {
|
||||
alloc_ = src.alloc_;
|
||||
w_ = src.w_;
|
||||
h_ = src.h_;
|
||||
buf_ = src.buf_;
|
||||
src.buf_ = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void Clear() {
|
||||
memset(buf_, 0, static_cast<uint64_t>(w_) * h_ * sizeof(T));
|
||||
}
|
||||
|
||||
|
||||
uint32_t width() const {
|
||||
return w_;
|
||||
}
|
||||
uint32_t height() const {
|
||||
return h_;
|
||||
}
|
||||
T* ptr() {
|
||||
return buf_;
|
||||
}
|
||||
const T* ptr() const {
|
||||
return buf_;
|
||||
}
|
||||
|
||||
private:
|
||||
iAllocator* alloc_;
|
||||
|
||||
uint32_t w_, h_;
|
||||
T* buf_;
|
||||
};
|
||||
|
||||
using Colorbuffer = Rasterbuffer<float>;
|
||||
using Textbuffer = Rasterbuffer<char16_t>;
|
||||
|
||||
|
||||
}
|
63
StackAllocator.h
Normal file
63
StackAllocator.h
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "iAllocator.h"
|
||||
|
||||
|
||||
namespace gj {
|
||||
|
||||
|
||||
class StackAllocator : public iAllocator {
|
||||
public:
|
||||
using iAllocator::Alloc;
|
||||
using iAllocator::MakeUnique;
|
||||
|
||||
StackAllocator() = delete;
|
||||
StackAllocator(StackAllocator&&) = delete;
|
||||
StackAllocator(const StackAllocator&) = delete;
|
||||
|
||||
StackAllocator& operator=(StackAllocator&&) = delete;
|
||||
StackAllocator& operator=(const StackAllocator&) = delete;
|
||||
|
||||
StackAllocator(void* ptr, const size_t size) :
|
||||
begin_(static_cast<uint8_t*>(ptr)),
|
||||
end_ (begin_+size),
|
||||
next_ (begin_) {
|
||||
}
|
||||
~StackAllocator() {
|
||||
assert(refcnt_ == 0);
|
||||
}
|
||||
|
||||
void* Alloc(const size_t size) override {
|
||||
const size_t aligned_size = ((size >> 3) + !!(size & 0b111)) << 3;
|
||||
|
||||
void* ret = next_;
|
||||
next_ += aligned_size;
|
||||
if (next_ >= end_) {
|
||||
return nullptr;
|
||||
}
|
||||
++refcnt_;
|
||||
return ret;
|
||||
}
|
||||
void Free(void* ptr) override {
|
||||
if (!ptr) return;
|
||||
|
||||
assert(refcnt_);
|
||||
if (--refcnt_ == 0) {
|
||||
next_ = begin_;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t* const begin_;
|
||||
uint8_t* const end_;
|
||||
uint8_t* next_;
|
||||
|
||||
size_t refcnt_ = 0;
|
||||
};
|
||||
|
||||
|
||||
}
|
87
Win32Console.cc
Normal file
87
Win32Console.cc
Normal file
@ -0,0 +1,87 @@
|
||||
#include "Win32Console.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
||||
static void CalcChar(CHAR_INFO& c, float color, uint16_t text) {
|
||||
constexpr wchar_t chars[] = L" .,:x!|X#%@$M";
|
||||
constexpr uint8_t attrs[] = {
|
||||
FOREGROUND_INTENSITY,
|
||||
BACKGROUND_INTENSITY,
|
||||
BACKGROUND_INTENSITY | FOREGROUND_RED,
|
||||
BACKGROUND_RED | FOREGROUND_INTENSITY,
|
||||
};
|
||||
|
||||
constexpr size_t char_expr_count = sizeof(chars)/sizeof(chars[0])-1;
|
||||
constexpr size_t attr_expr_count = sizeof(attrs)/sizeof(attrs[0]);
|
||||
|
||||
constexpr size_t reso = char_expr_count*attr_expr_count;
|
||||
|
||||
/* post effect */
|
||||
color = std::pow(color, 1.9);
|
||||
|
||||
int8_t a = static_cast<int8_t>(color*reso);
|
||||
if (a >= reso) a = reso-1;
|
||||
if (a < 0) a = 0;
|
||||
|
||||
size_t ci = a%char_expr_count;
|
||||
size_t ai = a/char_expr_count;
|
||||
if (ai%2 == 1) ci = char_expr_count-ci-1;
|
||||
|
||||
c.Char.UnicodeChar = chars[ci];
|
||||
c.Attributes = attrs[ai];
|
||||
|
||||
if (text) c.Char.UnicodeChar = text;
|
||||
}
|
||||
|
||||
void gj::Win32Console::main() {
|
||||
bool shown = false;
|
||||
|
||||
while (alive_.load()) {
|
||||
if (shown_.load()) {
|
||||
if (!shown) {
|
||||
shown = true;
|
||||
ShowWindow(win_, TRUE);
|
||||
}
|
||||
|
||||
constexpr CONSOLE_CURSOR_INFO cursor{ 1, FALSE };
|
||||
SetConsoleCursorInfo(screen_, &cursor);
|
||||
|
||||
CHAR_INFO* c = chars_.get();
|
||||
{ /* critical section */
|
||||
std::lock_guard<std::mutex> _(mtx_);
|
||||
|
||||
const float* cb = cb_main_.ptr();
|
||||
const char16_t* tb = tb_main_.ptr();
|
||||
|
||||
for (uint32_t y = 0; y < h_; ++y) {
|
||||
bool mb = false;
|
||||
for (uint32_t x = 0; x < w_; ++x) {
|
||||
if (mb) {
|
||||
*c = *(c - 1);
|
||||
(c - 1)->Attributes |= COMMON_LVB_LEADING_BYTE;
|
||||
c->Attributes |= COMMON_LVB_TRAILING_BYTE;
|
||||
mb = false;
|
||||
} else {
|
||||
CalcChar(*c, *cb, *tb);
|
||||
mb = (*tb & 0x80);
|
||||
}
|
||||
++cb, ++tb, ++c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const COORD size = { static_cast<SHORT>(w_), static_cast<SHORT>(h_), };
|
||||
const COORD pos = { 0, 0, };
|
||||
SMALL_RECT rc = { 0, 0, static_cast<SHORT>(w_), static_cast<SHORT>(h_), };
|
||||
WriteConsoleOutput(screen_, chars_.get(), size, pos, &rc);
|
||||
|
||||
} else {
|
||||
if (shown) {
|
||||
ShowWindow(win_, FALSE);
|
||||
shown = false;
|
||||
}
|
||||
}
|
||||
Sleep(30);
|
||||
}
|
||||
}
|
114
Win32Console.h
Normal file
114
Win32Console.h
Normal file
@ -0,0 +1,114 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "iConsole.h"
|
||||
|
||||
|
||||
namespace gj {
|
||||
|
||||
|
||||
class Win32Console : iConsole {
|
||||
public:
|
||||
Win32Console() = delete;
|
||||
Win32Console(Win32Console&&) = delete;
|
||||
Win32Console(const Win32Console&) = delete;
|
||||
|
||||
Win32Console& operator=(Win32Console&&) = delete;
|
||||
Win32Console& operator=(const Win32Console&) = delete;
|
||||
|
||||
Win32Console(iAllocator* alloc, uint32_t w, uint32_t h) :
|
||||
w_(w), h_(h), shown_(false), alive_(true),
|
||||
th_([this]() { main(); }),
|
||||
cb_main_(alloc, w, h), cb_sub_(alloc, w, h),
|
||||
tb_main_(alloc, w, h), tb_sub_(alloc, w, h),
|
||||
chars_(std::make_unique<CHAR_INFO[]>(static_cast<uint64_t>(w)*h)),
|
||||
win_(GetConsoleWindow()) {
|
||||
_ASSERT(win_);
|
||||
|
||||
screen_ = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
_ASSERT(screen_ != INVALID_HANDLE_VALUE);
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFOEX size;
|
||||
size.cbSize = sizeof(size);
|
||||
|
||||
GetConsoleScreenBufferInfoEx(screen_, &size);
|
||||
COORD c;
|
||||
c.X = w_;
|
||||
c.Y = h_;
|
||||
size.dwSize = c;
|
||||
|
||||
size.srWindow.Left = 0;
|
||||
size.srWindow.Right = w_ + 1;
|
||||
size.srWindow.Top = 0;
|
||||
size.srWindow.Bottom = h_ + 1;
|
||||
SetConsoleScreenBufferInfoEx(screen_, &size);
|
||||
|
||||
ShowWindow(win_, FALSE);
|
||||
SetWindowLong(win_, GWL_STYLE, GetWindowLong(win_, GWL_STYLE) & ~WS_SIZEBOX);
|
||||
}
|
||||
~Win32Console() {
|
||||
alive_.store(false);
|
||||
th_.join();
|
||||
}
|
||||
|
||||
void Show() override {
|
||||
shown_.store(true);
|
||||
}
|
||||
void Hide() override {
|
||||
shown_.store(false);
|
||||
}
|
||||
|
||||
Colorbuffer& TakeColorbuffer() override {
|
||||
return cb_sub_;
|
||||
}
|
||||
void SwapColorbuffer() override {
|
||||
std::lock_guard<std::mutex> _(mtx_);
|
||||
std::swap(cb_main_, cb_sub_);
|
||||
}
|
||||
|
||||
Textbuffer& TakeTextbuffer() override {
|
||||
return tb_sub_;
|
||||
}
|
||||
void SwapTextbuffer() override {
|
||||
std::lock_guard<std::mutex> _(mtx_);
|
||||
std::swap(tb_main_, tb_sub_);
|
||||
}
|
||||
|
||||
uint32_t width() const override {
|
||||
return w_;
|
||||
}
|
||||
uint32_t height() const override {
|
||||
return h_;
|
||||
}
|
||||
|
||||
private:
|
||||
const uint32_t w_, h_;
|
||||
|
||||
std::atomic_bool alive_;
|
||||
std::atomic_bool shown_;
|
||||
std::mutex mtx_;
|
||||
std::thread th_;
|
||||
|
||||
Colorbuffer cb_main_;
|
||||
Colorbuffer cb_sub_;
|
||||
|
||||
Textbuffer tb_main_;
|
||||
Textbuffer tb_sub_;
|
||||
|
||||
std::unique_ptr<CHAR_INFO[]> chars_;
|
||||
|
||||
HANDLE screen_ = INVALID_HANDLE_VALUE;
|
||||
HWND win_ = nullptr;
|
||||
|
||||
void main();
|
||||
};
|
||||
|
||||
|
||||
}
|
23
common.h
Normal file
23
common.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <codecvt>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace gj {
|
||||
|
||||
|
||||
[[noreturn]]
|
||||
static inline void Abort(const std::string& msg) {
|
||||
std::wostringstream conv;
|
||||
conv << msg.c_str();
|
||||
|
||||
MessageBox(NULL, conv.str().c_str(), L"PROGRAM ABORTED", MB_OK);
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
|
||||
}
|
68
iAllocator.h
Normal file
68
iAllocator.h
Normal file
@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace gj {
|
||||
|
||||
|
||||
class iAllocator {
|
||||
public:
|
||||
template <typename T>
|
||||
struct Deleter {
|
||||
Deleter() = default;
|
||||
Deleter(Deleter&&) = default;
|
||||
Deleter(const Deleter&) = delete;
|
||||
|
||||
Deleter& operator=(Deleter&&) = default;
|
||||
Deleter& operator=(const Deleter&) = delete;
|
||||
|
||||
Deleter(iAllocator* alloc) : alloc_(alloc) {
|
||||
}
|
||||
|
||||
void operator()(T* ptr) {
|
||||
assert(alloc_);
|
||||
ptr->~T();
|
||||
alloc_->Free(ptr);
|
||||
}
|
||||
|
||||
iAllocator* alloc_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using UniquePtr = std::unique_ptr<T, Deleter<T>>;
|
||||
|
||||
iAllocator(iAllocator&&) = delete;
|
||||
iAllocator(const iAllocator&) = delete;
|
||||
|
||||
iAllocator& operator=(iAllocator&&) = delete;
|
||||
iAllocator& operator=(const iAllocator&) = delete;
|
||||
|
||||
iAllocator() = default;
|
||||
|
||||
virtual ~iAllocator() = default;
|
||||
|
||||
virtual void* Alloc(const size_t size) = 0;
|
||||
virtual void Free(void* ptr) = 0;
|
||||
|
||||
template <typename T>
|
||||
T* Alloc(size_t n = 1) {
|
||||
return reinterpret_cast<T*>(Alloc(sizeof(T) * n));
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
UniquePtr<T> MakeUnique(Args&&... args) {
|
||||
T* ptr = Alloc<T>();
|
||||
return std::unique_ptr<T, Deleter<T>>(new(ptr) T(args...), Deleter<T>(this));
|
||||
}
|
||||
template <typename T>
|
||||
UniquePtr<T> MakeUniqueArray(size_t n) {
|
||||
T* ptr = Alloc<T>(n);
|
||||
return std::unique_ptr<T, Deleter<T>>(ptr, Deleter<T>(this));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
34
iConsole.h
Normal file
34
iConsole.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "Rasterbuffer.h"
|
||||
|
||||
|
||||
namespace gj {
|
||||
|
||||
|
||||
class iConsole {
|
||||
public:
|
||||
iConsole(iConsole&&) = delete;
|
||||
iConsole(const iConsole&) = delete;
|
||||
|
||||
iConsole& operator=(iConsole&&) = delete;
|
||||
iConsole& operator=(const iConsole&) = delete;
|
||||
|
||||
iConsole() = default;
|
||||
virtual ~iConsole() = default;
|
||||
|
||||
virtual void Show() = 0;
|
||||
virtual void Hide() = 0;
|
||||
|
||||
virtual Colorbuffer& TakeColorbuffer() = 0;
|
||||
virtual void SwapColorbuffer() = 0;
|
||||
|
||||
virtual Textbuffer& TakeTextbuffer() = 0;
|
||||
virtual void SwapTextbuffer() = 0;
|
||||
|
||||
virtual uint32_t width() const = 0;
|
||||
virtual uint32_t height() const = 0;
|
||||
};
|
||||
|
||||
|
||||
}
|
74
main.cc
Normal file
74
main.cc
Normal file
@ -0,0 +1,74 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "Font.h"
|
||||
#include "LinearAllocator.h"
|
||||
#include "Win32Console.h"
|
||||
|
||||
|
||||
constexpr size_t kHeapSize = 1024*1024*64;
|
||||
|
||||
constexpr uint32_t kWidth = 96;
|
||||
constexpr uint32_t kHeight = 28;
|
||||
|
||||
int main() {
|
||||
auto memory = std::make_unique<uint8_t[]>(kHeapSize);
|
||||
gj::LinearAllocator alloc(memory.get(), kHeapSize);
|
||||
|
||||
gj::Win32Console console(&alloc, kWidth, kHeight);
|
||||
console.Show();
|
||||
|
||||
gj::Font font(&alloc, "./font/shippori.ttf");
|
||||
gj::Colorbuffer glyph = font.RenderGlyph(L'繍', 50);
|
||||
|
||||
size_t t = 0;
|
||||
while (true) {
|
||||
{
|
||||
const std::u16string s = u"世界は猫によって支配されている";
|
||||
|
||||
gj::Textbuffer& tb = console.TakeTextbuffer();
|
||||
tb.Clear();
|
||||
|
||||
char16_t* ptr = tb.ptr() + kWidth*(kHeight/2)+(t%(kWidth-s.length()*2));
|
||||
for (size_t i = 0; i < s.length(); ++i) {
|
||||
ptr[i*2] = s[i];
|
||||
}
|
||||
console.SwapTextbuffer();
|
||||
}
|
||||
|
||||
{
|
||||
gj::Colorbuffer& cb = console.TakeColorbuffer();
|
||||
float* ptr = cb.ptr();
|
||||
|
||||
constexpr uintmax_t max = kHeight + kWidth;
|
||||
for (uint32_t y = 0; y < kHeight; ++y) {
|
||||
for (uint32_t x = 0; x < kWidth; ++x) {
|
||||
*ptr = static_cast<float>((static_cast<uintmax_t>(y)+x+t)%(max*2)*1./max);
|
||||
if (*ptr > 1) *ptr = 2-*ptr;
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
|
||||
ptr = cb.ptr();
|
||||
const uint32_t w = glyph.width();
|
||||
const uint32_t h = glyph.height();
|
||||
const float* src = glyph.ptr();
|
||||
for (uint32_t y = 0; y < h; ++y) {
|
||||
if (y >= kHeight) break;
|
||||
for (uint32_t x = 0; x < w; ++x) {
|
||||
if (x*2+1 >= kWidth) break;
|
||||
ptr[y*kWidth+x*2] += src[y*w+x]*.3;
|
||||
ptr[y*kWidth+x*2+1] += src[y*w+x]*.3;
|
||||
}
|
||||
}
|
||||
|
||||
console.SwapColorbuffer();
|
||||
}
|
||||
|
||||
Sleep(60);
|
||||
++t;
|
||||
}
|
||||
}
|
5089
stb_truetype.h
Normal file
5089
stb_truetype.h
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user