upscalers
This commit is contained in:
parent
e83ed1172c
commit
702aa679b9
|
@ -19,6 +19,7 @@
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="src\draw\upscale.cpp" />
|
||||||
<ClCompile Include="src\util.cpp" />
|
<ClCompile Include="src\util.cpp" />
|
||||||
<ClCompile Include="src\ini.cpp" />
|
<ClCompile Include="src\ini.cpp" />
|
||||||
<ClCompile Include="src\draw\draw_text.cpp" />
|
<ClCompile Include="src\draw\draw_text.cpp" />
|
||||||
|
@ -42,6 +43,7 @@
|
||||||
<ClInclude Include="include\util.h" />
|
<ClInclude Include="include\util.h" />
|
||||||
<ClInclude Include="include\vec2.h" />
|
<ClInclude Include="include\vec2.h" />
|
||||||
<ClInclude Include="include\resource_manager.h" />
|
<ClInclude Include="include\resource_manager.h" />
|
||||||
|
<ClInclude Include="include\math_util.h" />
|
||||||
<ClInclude Include="src\stb_image.h" />
|
<ClInclude Include="src\stb_image.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -42,6 +42,9 @@
|
||||||
<ClCompile Include="src\util.cpp">
|
<ClCompile Include="src\util.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\draw\upscale.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="include\game.h">
|
<ClInclude Include="include\game.h">
|
||||||
|
@ -83,6 +86,9 @@
|
||||||
<ClInclude Include="include\util.h">
|
<ClInclude Include="include\util.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\math_util.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="fontconvert.bat">
|
<None Include="fontconvert.bat">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ShowAllFiles>false</ShowAllFiles>
|
<ShowAllFiles>true</ShowAllFiles>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -4,6 +4,7 @@
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "ini.h"
|
#include "ini.h"
|
||||||
|
#include "math_util.h"
|
||||||
#include "rect.h"
|
#include "rect.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "resource_manager.h"
|
#include "resource_manager.h"
|
||||||
|
@ -12,8 +13,6 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "vec2.h"
|
#include "vec2.h"
|
||||||
|
|
||||||
const double PI = 3.141592653589793238462643383279502884197169399375105820974944592307816406286;
|
|
||||||
const double TAU = PI * 2;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,12 @@
|
||||||
using color = uint32_t;
|
using color = uint32_t;
|
||||||
struct ini;
|
struct ini;
|
||||||
|
|
||||||
|
enum class upscaler {
|
||||||
|
none, scale2x, scale3x, lcd3x, rgb3x, bilinear3x, hatch3x
|
||||||
|
};
|
||||||
|
|
||||||
|
int upscaler_scale(upscaler upscaler);
|
||||||
|
|
||||||
struct image : resource {
|
struct image : resource {
|
||||||
image(resource_manager& rm, ini_category const* ini, std::string const& path, std::vector<uint8_t> const& data);
|
image(resource_manager& rm, ini_category const* ini, std::string const& path, std::vector<uint8_t> const& data);
|
||||||
image(image const& other);
|
image(image const& other);
|
||||||
|
@ -23,6 +29,7 @@ struct image : resource {
|
||||||
|
|
||||||
color* raw_pointer() const;
|
color* raw_pointer() const;
|
||||||
color get(vec2i pos) const;
|
color get(vec2i pos) const;
|
||||||
|
color get_safe(vec2i pos) const;
|
||||||
|
|
||||||
void clear(color color);
|
void clear(color color);
|
||||||
|
|
||||||
|
@ -30,11 +37,19 @@ struct image : resource {
|
||||||
void draw(image const* image, vec2i pos, recti src_rect);
|
void draw(image const* image, vec2i pos, recti src_rect);
|
||||||
void draw(image const* image, vec2i pos, color color);
|
void draw(image const* image, vec2i pos, color color);
|
||||||
void draw(image const* image, vec2i pos, color color, recti src_rect);
|
void draw(image const* image, vec2i pos, color color, recti src_rect);
|
||||||
void draw_upscaled(image const* image);
|
//void draw_upscaled(image const* image);
|
||||||
|
|
||||||
|
void draw_rot(image const* image, vec2i pos, double rot);
|
||||||
|
void draw_rot(image const* image, vec2i pos, recti src_rect, double rot);
|
||||||
|
|
||||||
|
void draw_upscaled(image const* image, upscaler upscaler);
|
||||||
|
void draw_upscaled(image const* image, std::vector<upscaler> upscalers);
|
||||||
|
image const* upscale_eagle_2x() const;
|
||||||
|
|
||||||
void draw(std::string const& str, vec2i pos, font const* font, color color);
|
void draw(std::string const& str, vec2i pos, font const* font, color color);
|
||||||
void draw(std::string const& str, vec2i pos, font const* font, color color1, color color2);
|
void draw(std::string const& str, vec2i pos, font const* font, color color1, color color2);
|
||||||
private:
|
private:
|
||||||
|
void draw_upscaled(image const* image, vec2i size, upscaler upscaler);
|
||||||
bool _alpha;
|
bool _alpha;
|
||||||
bool _borrowed_pointer; //to know if to free or not
|
bool _borrowed_pointer; //to know if to free or not
|
||||||
color* _data; //not a vector so can wrap sdl surfaces
|
color* _data; //not a vector so can wrap sdl surfaces
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
const double PI = 3.141592653589793238462643383279502884197169399375105820974944592307816406286;
|
||||||
|
const double TAU = (PI * 2);
|
|
@ -1,4 +1,5 @@
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
#include "math_util.h"
|
||||||
|
|
||||||
void image::draw(image const* image, vec2i pos) {
|
void image::draw(image const* image, vec2i pos) {
|
||||||
draw(image, pos, image->bounds());
|
draw(image, pos, image->bounds());
|
||||||
|
@ -22,16 +23,12 @@ void image::draw(image const* image, vec2i pos, recti src_rect) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//#pragma omp parallel for
|
|
||||||
for(int y = start.y; y <= end.y; ++y) {
|
for(int y = start.y; y <= end.y; ++y) {
|
||||||
std::memcpy(_data + (y * _bounds.size.x), image->_data - start.x + src_off.x + (y-start.y + src_off.y) * image->_bounds.size.x, (end.x - start.x + 1)*4);
|
std::memcpy(
|
||||||
/* for(int x = start.x; x <= end.x; ++x) {
|
_data + (y * _bounds.size.x),
|
||||||
auto color = image->_data[
|
image->_data - start.x + src_off.x + (y-start.y + src_off.y) * image->_bounds.size.x,
|
||||||
x - start.x + src_off.x + (y - start.y + src_off.y) * image->_bounds.size.x
|
(end.x - start.x + 1)*4
|
||||||
];
|
);
|
||||||
_data[x + y * _bounds.size.x] = color;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +56,7 @@ void image::draw(image const* image, vec2i pos, color color, recti src_rect) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void image::draw_upscaled(image const* image) {
|
void image::draw_upscaled(image const* image) {
|
||||||
if(image->bounds() == bounds()) {
|
if(image->bounds() == bounds()) {
|
||||||
std::memcpy(_data, image->_data, bounds().size.size() * 4);
|
std::memcpy(_data, image->_data, bounds().size.size() * 4);
|
||||||
|
@ -101,3 +98,64 @@ void image::draw_upscaled(image const* image) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void image::draw_rot(image const* image, vec2i pos, double rot) {
|
||||||
|
draw_rot(image, pos, image->bounds(), rot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void image::draw_rot(image const* image, vec2i pos, recti src_rect, double rot) {
|
||||||
|
src_rect = recti::intersection(src_rect, image->bounds());
|
||||||
|
//auto crop = recti::intersection(bounds(), recti(pos, image->bounds().size));
|
||||||
|
//crop = recti::intersection(crop, recti(crop.pos, src_rect.size));
|
||||||
|
//todo: crop to screen...
|
||||||
|
//todo: fmod the rot?
|
||||||
|
//rot = rot/2;
|
||||||
|
//if(rot >= 0.5)
|
||||||
|
// rot = 0.5 - rot;
|
||||||
|
rot /= 2;
|
||||||
|
if(rot >= 0.25)
|
||||||
|
rot = 0.25 - (rot - 0.25);
|
||||||
|
rot -= 0.125;
|
||||||
|
auto crop = recti::intersection(recti(pos, src_rect.size), recti(pos, image->bounds().size));
|
||||||
|
auto src_off = crop.pos - pos + src_rect.pos;
|
||||||
|
auto start = crop.pos;
|
||||||
|
auto end = crop.pos2();
|
||||||
|
|
||||||
|
auto xshear = -std::tan(rot * TAU / 2.0) *crop.size.x;
|
||||||
|
auto yshear = std::sin(rot * TAU) * crop.size.y;
|
||||||
|
//auto xshear = (std::cos(rot * TAU) - 1) / sin(rot * TAU);
|
||||||
|
|
||||||
|
std::vector<int> xshears;
|
||||||
|
for(int y = start.y; y <= end.y; ++y) {
|
||||||
|
auto yf = static_cast<double>(y - crop.pos.y) / crop.size.y * 2 - 0.5;
|
||||||
|
xshears.push_back(static_cast<int>(xshear * yf));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int y = 0; y <= end.y - start.y; ++y) {
|
||||||
|
auto yf = static_cast<double>(y) / crop.size.y * 2 - 1;
|
||||||
|
for(int x = 0; x <= end.x - start.x; ++x) {
|
||||||
|
double xf, yf;
|
||||||
|
int nx, ny;
|
||||||
|
nx = x;
|
||||||
|
ny = y;
|
||||||
|
|
||||||
|
yf = (static_cast<double>(ny) / crop.size.y * 1 - 0.5);
|
||||||
|
nx = nx + yf * xshear;
|
||||||
|
//int nxt = x;
|
||||||
|
|
||||||
|
xf = (static_cast<double>(nx) / crop.size.x * 1 - 0.5);
|
||||||
|
ny = ny + xf * yshear;
|
||||||
|
|
||||||
|
yf = (static_cast<double>(ny) / crop.size.y * 1 - 0.5);
|
||||||
|
nx = nx + yf * xshear;
|
||||||
|
|
||||||
|
|
||||||
|
auto color = image->_data[
|
||||||
|
x + src_off.x + (y + src_off.y) * image->_bounds.size.x
|
||||||
|
];
|
||||||
|
if(color & 0xff000000)
|
||||||
|
_data[nx + start.x + (ny+start.y) * _bounds.size.x] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,199 @@
|
||||||
|
#include "image.h"
|
||||||
|
|
||||||
|
#define UPSCALE_1X \
|
||||||
|
for(int y = 0; y < s.y; ++y) {\
|
||||||
|
for(int x = 0; x < s.x; ++x) {\
|
||||||
|
color in, out;\
|
||||||
|
in = img->get(vec2i(x, y));
|
||||||
|
|
||||||
|
#define UPSCALE_1X_END \
|
||||||
|
_data[x + y * size().x] = out;\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
break;
|
||||||
|
|
||||||
|
#define UPSCALE_2X \
|
||||||
|
for(int y = 0; y < s.y; ++y) {\
|
||||||
|
for(int x = 0; x < s.x; ++x) {\
|
||||||
|
color in_t, in_b, in_l, in_r, in_m;\
|
||||||
|
color in_tl, in_tr, in_bl, in_br;\
|
||||||
|
color out_tl, out_tr, out_bl, out_br;\
|
||||||
|
in_t = img->get_safe(vec2i(x, y - 1));\
|
||||||
|
in_b = img->get_safe(vec2i(x, y + 1));\
|
||||||
|
in_l = img->get_safe(vec2i(x - 1, y));\
|
||||||
|
in_r = img->get_safe(vec2i(x + 1, y));\
|
||||||
|
in_tl = img->get_safe(vec2i(x - 1, y - 1));\
|
||||||
|
in_tr = img->get_safe(vec2i(x + 1, y - 1));\
|
||||||
|
in_bl = img->get_safe(vec2i(x - 1, y + 1));\
|
||||||
|
in_br = img->get_safe(vec2i(x + 1, y + 1));\
|
||||||
|
in_m = img->get(vec2i(x, y));
|
||||||
|
|
||||||
|
#define UPSCALE_2X_END \
|
||||||
|
_data[(x * 2 + 0) + (y * 2 + 0) * size().x] = out_tl;\
|
||||||
|
_data[(x * 2 + 1) + (y * 2 + 0) * size().x] = out_tr;\
|
||||||
|
_data[(x * 2 + 0) + (y * 2 + 1) * size().x] = out_bl;\
|
||||||
|
_data[(x * 2 + 1) + (y * 2 + 1) * size().x] = out_br;\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
break;
|
||||||
|
|
||||||
|
#define UPSCALE_3X \
|
||||||
|
for(int y = 0; y < s.y; ++y) {\
|
||||||
|
for(int x = 0; x < s.x; ++x) {\
|
||||||
|
color in_t, in_b, in_l, in_r, in_m;\
|
||||||
|
color in_tl, in_tr, in_bl, in_br;\
|
||||||
|
color out_t, out_b, out_l, out_r, out_m;\
|
||||||
|
color out_tl, out_tr, out_bl, out_br;\
|
||||||
|
in_t = img->get_safe(vec2i(x, y - 1));\
|
||||||
|
in_b = img->get_safe(vec2i(x, y + 1));\
|
||||||
|
in_l = img->get_safe(vec2i(x - 1, y));\
|
||||||
|
in_r = img->get_safe(vec2i(x + 1, y));\
|
||||||
|
in_tl = img->get_safe(vec2i(x - 1, y - 1));\
|
||||||
|
in_tr = img->get_safe(vec2i(x + 1, y - 1));\
|
||||||
|
in_bl = img->get_safe(vec2i(x - 1, y + 1));\
|
||||||
|
in_br = img->get_safe(vec2i(x + 1, y + 1));\
|
||||||
|
in_m = img->get(vec2i(x, y));
|
||||||
|
|
||||||
|
#define UPSCALE_3X_END \
|
||||||
|
_data[(x * 3 + 0) + (y * 3 + 0) * size().x] = out_tl;\
|
||||||
|
_data[(x * 3 + 1) + (y * 3 + 0) * size().x] = out_t;\
|
||||||
|
_data[(x * 3 + 2) + (y * 3 + 0) * size().x] = out_tr;\
|
||||||
|
_data[(x * 3 + 0) + (y * 3 + 1) * size().x] = out_l;\
|
||||||
|
_data[(x * 3 + 1) + (y * 3 + 1) * size().x] = out_m;\
|
||||||
|
_data[(x * 3 + 2) + (y * 3 + 1) * size().x] = out_r;\
|
||||||
|
_data[(x * 3 + 0) + (y * 3 + 2) * size().x] = out_bl;\
|
||||||
|
_data[(x * 3 + 1) + (y * 3 + 2) * size().x] = out_b;\
|
||||||
|
_data[(x * 3 + 2) + (y * 3 + 2) * size().x] = out_br;\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
break;
|
||||||
|
|
||||||
|
int upscaler_scale(upscaler upscaler) {
|
||||||
|
switch(upscaler) {
|
||||||
|
case upscaler::none: return 1;
|
||||||
|
case upscaler::scale2x: return 2;
|
||||||
|
case upscaler::scale3x: return 3;
|
||||||
|
case upscaler::lcd3x: return 3;
|
||||||
|
case upscaler::rgb3x: return 3;
|
||||||
|
case upscaler::bilinear3x: return 3;
|
||||||
|
case upscaler::hatch3x: return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void image::draw_upscaled(image const* img, upscaler upscaler) {
|
||||||
|
draw_upscaled(img, img->size(), upscaler);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<image*> scale_buffers;
|
||||||
|
|
||||||
|
void image::draw_upscaled(image const* img, std::vector<upscaler> upscalers) {
|
||||||
|
if(upscalers.size() > scale_buffers.size() + 1)
|
||||||
|
scale_buffers.resize(upscalers.size() - 1, nullptr);
|
||||||
|
auto src = img;
|
||||||
|
auto size = img->size();
|
||||||
|
for(int i = 0; i + 1 < upscalers.size(); ++i) {
|
||||||
|
auto osize = size * upscaler_scale(upscalers[i]);
|
||||||
|
if(!scale_buffers[i] || scale_buffers[i]->size().x < osize.x || scale_buffers[i]->size().y < osize.y) {
|
||||||
|
delete scale_buffers[i];
|
||||||
|
scale_buffers[i] = new image(osize);
|
||||||
|
}
|
||||||
|
scale_buffers[i]->draw_upscaled(src, size, upscalers[i]);
|
||||||
|
src = scale_buffers[i];
|
||||||
|
size = osize;
|
||||||
|
}
|
||||||
|
this->draw_upscaled(src, size, upscalers.back());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void image::draw_upscaled(image const* img, vec2i s, upscaler upscaler) {
|
||||||
|
switch(upscaler) {
|
||||||
|
case upscaler::none:
|
||||||
|
UPSCALE_1X
|
||||||
|
out = in;
|
||||||
|
UPSCALE_1X_END
|
||||||
|
case upscaler::scale2x:
|
||||||
|
UPSCALE_2X
|
||||||
|
out_tl = in_l == in_t && in_t != in_r && in_l != in_b ? in_l : in_m;
|
||||||
|
out_tr = in_t == in_r && in_t != in_l && in_r != in_b ? in_r : in_m;
|
||||||
|
out_bl = in_l == in_b && in_l != in_t && in_b != in_r ? in_l : in_m;
|
||||||
|
out_br = in_b == in_r && in_l != in_b && in_t != in_r ? in_r : in_m;
|
||||||
|
UPSCALE_2X_END
|
||||||
|
case upscaler::scale3x:
|
||||||
|
UPSCALE_3X
|
||||||
|
out_tl = in_l == in_t && in_l != in_b && in_t != in_r ? in_l : in_m;
|
||||||
|
out_t = (in_l == in_t && in_l != in_b && in_t != in_r && in_m != in_tr) ||
|
||||||
|
(in_t == in_r && in_t != in_l && in_r != in_b && in_m != in_tl) ? in_t : in_m;
|
||||||
|
out_tr = in_t == in_r && in_t != in_l && in_r != in_b ? in_r : in_m;
|
||||||
|
out_l = (in_b == in_l && in_b != in_r && in_l != in_t && in_m != in_tl) ||
|
||||||
|
(in_l == in_t && in_l != in_b && in_t != in_r && in_m != in_bl) ? in_l : in_m;
|
||||||
|
out_m = in_m;
|
||||||
|
out_r = (in_t == in_r && in_t != in_l && in_r != in_b && in_m != in_br) ||
|
||||||
|
(in_r == in_b && in_r != in_t && in_b != in_l && in_m != in_tr) ? in_r : in_m;
|
||||||
|
out_bl = in_b == in_l && in_b != in_r && in_l != in_t ? in_l : in_m;
|
||||||
|
out_b = (in_r == in_b && in_r != in_t && in_b != in_l && in_m != in_bl) ||
|
||||||
|
(in_b == in_l && in_b != in_r && in_l != in_t && in_m != in_br) ? in_b : in_m;
|
||||||
|
out_br = in_r == in_b && in_r != in_t && in_b != in_l ? in_r : in_m;
|
||||||
|
UPSCALE_3X_END
|
||||||
|
case upscaler::lcd3x:
|
||||||
|
UPSCALE_3X
|
||||||
|
out_tl = out_t = out_l = out_m = in_m;
|
||||||
|
out_tr = out_r = out_br = out_b = out_bl = (in_m & 0xfefefe) >> 1;
|
||||||
|
UPSCALE_3X_END
|
||||||
|
case upscaler::rgb3x:
|
||||||
|
UPSCALE_3X
|
||||||
|
out_tl = out_l = out_bl = in_m & 0xff0000;
|
||||||
|
out_t = out_m = out_b = in_m & 0x00ff00;
|
||||||
|
out_tr = out_r = out_br = in_m & 0x0000ff;
|
||||||
|
UPSCALE_3X_END
|
||||||
|
case upscaler::bilinear3x:
|
||||||
|
UPSCALE_3X
|
||||||
|
out_m = in_m;
|
||||||
|
out_l = ((in_m & 0xfefefe) >> 1) + ((in_l & 0xfefefe) >> 1);
|
||||||
|
out_r = ((in_m & 0xfefefe) >> 1) + ((in_r & 0xfefefe) >> 1);
|
||||||
|
out_t = ((in_m & 0xfefefe) >> 1) + ((in_t & 0xfefefe) >> 1);
|
||||||
|
out_b = ((in_m & 0xfefefe) >> 1) + ((in_b & 0xfefefe) >> 1);
|
||||||
|
out_tl = ((in_m & 0xfcfcfc) >> 2) + ((in_t & 0xfcfcfc) >> 2) + ((in_l & 0xfcfcfc) >> 2) + ((in_tl & 0xfcfcfc) >> 2);
|
||||||
|
out_tr = ((in_m & 0xfcfcfc) >> 2) + ((in_t & 0xfcfcfc) >> 2) + ((in_r & 0xfcfcfc) >> 2) + ((in_tr & 0xfcfcfc) >> 2);
|
||||||
|
out_bl = ((in_m & 0xfcfcfc) >> 2) + ((in_b & 0xfcfcfc) >> 2) + ((in_l & 0xfcfcfc) >> 2) + ((in_bl & 0xfcfcfc) >> 2);
|
||||||
|
out_br = ((in_m & 0xfcfcfc) >> 2) + ((in_b & 0xfcfcfc) >> 2) + ((in_r & 0xfcfcfc) >> 2) + ((in_br & 0xfcfcfc) >> 2);
|
||||||
|
UPSCALE_3X_END
|
||||||
|
case upscaler::hatch3x:
|
||||||
|
UPSCALE_3X
|
||||||
|
out_m = in_m;
|
||||||
|
out_l = in_l;
|
||||||
|
out_r = in_r;
|
||||||
|
out_t = in_t;
|
||||||
|
out_b = in_b;
|
||||||
|
out_tl = in_tl;
|
||||||
|
out_tr = in_tr;
|
||||||
|
out_bl = in_bl;
|
||||||
|
out_br = in_br;
|
||||||
|
UPSCALE_3X_END
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
image const* image::upscale_eagle_2x() const {
|
||||||
|
auto img = new image(size() * 2);
|
||||||
|
for(int y = 0; y < size().y; ++y) {
|
||||||
|
for(int x = 0; x < size().x; ++x) {
|
||||||
|
color in_t, in_b, in_l, in_r, in_m, out_tl, out_tr, out_bl, out_br;
|
||||||
|
in_t = get_safe(vec2i(x, y - 1));
|
||||||
|
in_b = get_safe(vec2i(x, y + 1));
|
||||||
|
in_l = get_safe(vec2i(x - 1, y));
|
||||||
|
in_r = get_safe(vec2i(x + 1, y));
|
||||||
|
in_m = get(vec2i(x, y));
|
||||||
|
|
||||||
|
out_tl = in_l == in_t && in_t != in_r && in_l != in_b ? in_l : in_m;
|
||||||
|
out_tr = in_t == in_r && in_t != in_l && in_r != in_b ? in_r : in_m;
|
||||||
|
out_bl = in_l == in_b && in_l != in_t && in_b != in_r ? in_l : in_m;
|
||||||
|
out_br = in_b == in_r && in_l != in_b && in_t != in_r ? in_r : in_m;
|
||||||
|
|
||||||
|
img->_data[(x * 2 + 0) + (y * 2 + 0) * img->size().x] = out_tl;
|
||||||
|
img->_data[(x * 2 + 1) + (y * 2 + 0) * img->size().x] = out_tr;
|
||||||
|
img->_data[(x * 2 + 0) + (y * 2 + 1) * img->size().x] = out_bl;
|
||||||
|
img->_data[(x * 2 + 1) + (y * 2 + 1) * img->size().x] = out_br;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return img;
|
||||||
|
}
|
|
@ -96,7 +96,13 @@ void game::run() {
|
||||||
screen.draw(_cursor, _mouse_pos);
|
screen.draw(_cursor, _mouse_pos);
|
||||||
auto p = screen.raw_pointer();
|
auto p = screen.raw_pointer();
|
||||||
if(screen.bounds() != window_image.bounds()) {
|
if(screen.bounds() != window_image.bounds()) {
|
||||||
window_image.draw_upscaled(&screen);
|
//window_image.draw_upscaled(&screen);
|
||||||
|
std::vector<upscaler> scalers;
|
||||||
|
//scalers.push_back(upscaler::scale3x);
|
||||||
|
//scalers.push_back(upscaler::scale3x);
|
||||||
|
scalers.push_back(upscaler::lcd3x);
|
||||||
|
//scalers.push_back(upscaler::hatch3x);
|
||||||
|
window_image.draw_upscaled(&screen, scalers);
|
||||||
p = window_image.raw_pointer();
|
p = window_image.raw_pointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,12 @@ color image::get(vec2i pos) const {
|
||||||
return _data[pos.x + pos.y * _bounds.size.x];
|
return _data[pos.x + pos.y * _bounds.size.x];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
color image::get_safe(vec2i pos) const {
|
||||||
|
if(pos.x < 0 || pos.y < 0 || pos.x >= _bounds.size.x || pos.y >= _bounds.size.y)
|
||||||
|
return 0x00000000;
|
||||||
|
return _data[pos.x + pos.y * _bounds.size.x];
|
||||||
|
}
|
||||||
|
|
||||||
void image::clear(color color) {
|
void image::clear(color color) {
|
||||||
std::fill(_data, _data + size().size(), color);
|
std::fill(_data, _data + size().size(), color);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ std::string const& ini_category::get_string(std::string const& entry) const {
|
||||||
|
|
||||||
if(_data.contains(entry))
|
if(_data.contains(entry))
|
||||||
return _data.at(entry);
|
return _data.at(entry);
|
||||||
return "";
|
return std::string("");
|
||||||
}
|
}
|
||||||
|
|
||||||
ini::ini(resource_manager& rm, ini_category const* ini, std::string const& path, std::vector<uint8_t> data) {
|
ini::ini(resource_manager& rm, ini_category const* ini, std::string const& path, std::vector<uint8_t> data) {
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 444 B |
|
@ -7,6 +7,7 @@ struct my_game : game {
|
||||||
void render(image& target);
|
void render(image& target);
|
||||||
|
|
||||||
image const* img;
|
image const* img;
|
||||||
|
image const* slime;
|
||||||
ini const* ini;
|
ini const* ini;
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,28 +17,36 @@ struct my_game : game {
|
||||||
};
|
};
|
||||||
|
|
||||||
void my_game::init(settings& settings) {
|
void my_game::init(settings& settings) {
|
||||||
settings.target_fps = 60000;
|
settings.target_fps = 6000;
|
||||||
settings.scale = 1;
|
time = 0.0;
|
||||||
settings.size = vec2i(1920, 1080);
|
settings.scale = 3;
|
||||||
|
settings.size = vec2i(1920/3, 1080/3);
|
||||||
img = get<image>("test.png");
|
img = get<image>("test.png");
|
||||||
|
slime = get<image>("slime.png");
|
||||||
|
//slime = slime->upscale_2x();
|
||||||
|
//slime = slime->upscale_2x();
|
||||||
|
//slime = slime->upscale_2x();
|
||||||
//ini = get<::ini>("test.ini");
|
//ini = get<::ini>("test.ini");
|
||||||
font = get<::font>("_/default-font-prop.png");
|
font = get<::font>("_/default-font-prop.png");
|
||||||
//cursor(&font['\\']);
|
//cursor(&font['\\']);
|
||||||
}
|
}
|
||||||
|
|
||||||
void my_game::update() {
|
void my_game::update() {
|
||||||
time += 1.0 / 60.0;
|
time = std::fmod(time + 1.0 / 60.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void my_game::render(image& target) {
|
void my_game::render(image& target) {
|
||||||
target.clear(0xffdddd);
|
target.clear(0xffdddd);
|
||||||
auto pos = vec2i(std::sin(time * TAU / 4) * 100, std::cos(time * TAU / 4) * 100);
|
auto pos = vec2i(std::sin(time * TAU / 4) * 100, std::cos(time * TAU / 4) * 100);
|
||||||
//target.draw(img, vec2i(320, 180) + pos, recti(vec2i(8, 14), vec2i(8 * 4, 14 * 4)));
|
//target.draw(img, vec2i(320, 180) + pos, recti(vec2i(8, 14), vec2i(8 * 4, 14 * 4)));
|
||||||
for(int i = 0; i < 1; ++i)
|
//for(int i = 0; i < 1; ++i)
|
||||||
target.draw(img, vec2i::zero);
|
// target.draw(img, vec2i::zero);
|
||||||
|
|
||||||
|
//target.draw_rot(slime, vec2i(200, 200), time);
|
||||||
|
target.draw(slime, vec2i(40, 40));
|
||||||
//target.draw(tileset[0xda], vec2i(320, 180) + pos, 0xff00ff);
|
//target.draw(tileset[0xda], vec2i(320, 180) + pos, 0xff00ff);
|
||||||
auto str = "Can only be played if\nthere are no card in\nyour draw pile.\nDeal 50 damage to ALL\nenemies.";
|
auto str = "Can only be played if\nthere are no card in\nyour draw pile.\nDeal 50 damage to ALL\nenemies.";
|
||||||
target.draw(str, vec2i(100, 100) + pos, font, 0xffffff, 0);
|
//target.draw(str, vec2i(100, 100) + pos, font, 0xffffff, 0);
|
||||||
target.draw(std::format("FPS: {}", fps()), vec2i(10, 10), font, 0xffffff, 0);
|
target.draw(std::format("FPS: {}", fps()), vec2i(10, 10), font, 0xffffff, 0);
|
||||||
//target.draw("\\", mouse_pos(), font, 0xffffff, 0);
|
//target.draw("\\", mouse_pos(), font, 0xffffff, 0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue