lots of stuff

This commit is contained in:
Squishy Bloob 2024-03-26 02:24:40 +00:00
parent 855d331741
commit ab1241b8f6
19 changed files with 8312 additions and 4 deletions

View File

@ -19,11 +19,20 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\tileset.cpp" />
<ClCompile Include="src\image.cpp" />
<ClCompile Include="src\game.cpp" />
<ClCompile Include="src\main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\bloob.h" />
<ClInclude Include="include\game.h" />
<ClInclude Include="include\image.h" />
<ClInclude Include="include\rect.h" />
<ClInclude Include="include\settings.h" />
<ClInclude Include="include\tileset.h" />
<ClInclude Include="include\vec2.h" />
<ClInclude Include="src\stb_image.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
@ -113,6 +122,7 @@
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)include;$(SolutionDir)extern\SDL3-3.1.0\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -132,13 +142,19 @@
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)include;$(SolutionDir)extern\SDL3-3.1.0\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<LanguageStandard>stdcpp20</LanguageStandard>
<OpenMPSupport>true</OpenMPSupport>
<Optimization>MaxSpeed</Optimization>
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>$(SolutionDir)extern\SDL3-3.1.0\VisualC\x64\Release\SDL3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>gdiplus.lib;%(AdditionalDependencies)</AdditionalDependencies>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -18,5 +18,40 @@
<ClCompile Include="src\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\game.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\image.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\tileset.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\game.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\image.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\vec2.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\settings.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\bloob.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\tileset.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\rect.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\stb_image.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

9
blooblib/include/bloob.h Normal file
View File

@ -0,0 +1,9 @@
#pragma once
#include "game.h"
#include "image.h"
#include "settings.h"
#include "vec2.h"
const double PI = 3.141592653589793238462643383279502884197169399375105820974944592307816406286;
const double TAU = PI * 2;

11
blooblib/include/game.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
#include "image.h"
#include "settings.h"
struct game {
void run();
virtual void init(settings& settings);
virtual void render(image& target);
virtual void update();
};

View File

32
blooblib/include/image.h Normal file
View File

@ -0,0 +1,32 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include "rect.h"
#include "vec2.h"
using color = uint32_t;
struct image {
image(vec2i size);
image(vec2i size, color* data);
image(std::string path);
~image();
//static image_from_pointer()
vec2i const& size() const;
recti const& bounds() const;
color* raw_pointer() const;
void clear(color color);
void draw(image const& image, vec2i pos);
void draw(image const& image, vec2i pos, recti src_rect);
void draw_upscaled(image const& image);
private:
bool _borrowed_pointer; //to know if to free or not
color* _data; //not a vector so can wrap sdl surfaces
recti _bounds;
};

49
blooblib/include/rect.h Normal file
View File

@ -0,0 +1,49 @@
#pragma once
#include "vec2.h"
template <typename T>
struct rect {
vec2<T> pos, size;
rect() : pos(vec2<T>::zero), size(vec2<T>::zero) {};
rect(vec2<T> pos, vec2<T> size) : pos(pos), size(size) {};
rect<T> normal() const; //flip direction so size is positive
vec2<T> pos2() const;
static rect<T> from_points(vec2<T> pos1, vec2<T> pos2);
static rect<T> intersection(rect<T> const& a, rect<T> const& b);
};
template<typename T>
inline rect<T> rect<T>::normal() const {
auto r = *this;
if(r.size.x < 0) {
r.pos.x += r.size.x;
r.size.x *= -1;
}
if(r.size.y < 0) {
r.pos.y += r.size.y;
r.size.y *= -1;
}
return r;
}
template<typename T>
inline vec2<T> rect<T>::pos2() const {
return pos + size - vec2<T>::one;
}
template<typename T>
inline rect<T> rect<T>::from_points(vec2<T> pos1, vec2<T> pos2) {
return rect<T>(pos1, pos2-pos1+vec2<T>::one).normal();
}
template<typename T>
inline rect<T> rect<T>::intersection(rect<T> const& a, rect<T> const& b) {
return rect<T>::from_points(vec2<T>::max(a.pos, b.pos), vec2<T>::min(a.pos2(), b.pos2()));
}
using recti = rect<int32_t>;
using rectf = rect<float>;

View File

@ -0,0 +1,18 @@
#pragma once
#include <string>
#include "vec2.h"
struct settings {
settings() :
scale(3),
size(vec2i(640, 360)),
target_fps(60),
title("Blooblib v0.0")
{}
int scale;
vec2i size;
int target_fps;
std::string title;
};

View File

@ -0,0 +1,18 @@
#pragma once
#include <string>
#include <vector>
#include "image.h"
#include "vec2.h"
struct tileset {
tileset(image const&, vec2i tile_size);
tileset(std::string path, vec2i tile_size);
image& operator[](int index);
vec2i const& tile_size();
private:
std::vector<image> _tiles;
vec2i _tile_size;
};

56
blooblib/include/vec2.h Normal file
View File

@ -0,0 +1,56 @@
#pragma once
#include <algorithm>
#include <cstdint>
#include <iostream>
template <typename T>
struct vec2 {
T x, y;
vec2() : x(0), y(0) {}
vec2(T x, T y) : x(x), y(y) {}
static const vec2<T> zero;
static const vec2<T> one;
vec2<T> operator+(vec2<T> a) const { return vec2(x + a.x, y + a.y); }
vec2<T> operator-(vec2<T> a) const { return vec2(x - a.x, y - a.y); }
vec2<T> operator*(vec2<T> a) const { return vec2(x * a.x, y * a.y); }
vec2<T> operator/(vec2<T> a) const { return vec2(x / a.x, y / a.y); }
vec2<T> operator+(T a) const { return vec2(x + a, y + a); }
vec2<T> operator-(T a) const { return vec2(x - a, y - a); }
vec2<T> operator*(T a) const { return vec2(x * a, y * a); }
vec2<T> operator/(T a) const { return vec2(x / a, y / a); }
static vec2<T> min(vec2<T> a, vec2<T> b);
static vec2<T> max(vec2<T> a, vec2<T> b);
int32_t size() const;
};
using vec2i = vec2<int32_t>;
using vec2f = vec2<float>;
template <typename T>
vec2<T> vec2<T>::min(vec2<T> a, vec2<T> b) {
return vec2<T>(std::min(a.x, b.x), std::min(a.y, b.y));
}
template <typename T>
vec2<T> vec2<T>::max(vec2<T> a, vec2<T> b) {
return vec2<T>(std::max(a.x, b.x), std::max(a.y, b.y));
}
template <typename T>
int32_t vec2<T>::size() const {
return x * y;
}
template <typename T>
std::ostream& operator<<(std::ostream& os, vec2<T> const& v) {
return os << "vec2(" << v.x << "," << v.y << ")";
}
template <typename T> const vec2<T> vec2<T>::zero(0, 0);
template <typename T> const vec2<T> vec2<T>::one(1, 1);

View File

168
blooblib/src/game.cpp Normal file
View File

@ -0,0 +1,168 @@
#include "game.h"
#include <chrono>
#include <format>
#include <iostream>
#define WIN32_LEAN_AND_MEAN
#include <SDL3/SDL.h>
#include <Windows.h>
#include "image.h"
#include "settings.h"
LRESULT WINAPI wnd_proc(HWND window, UINT msg, WPARAM w, LPARAM l) {
switch(msg) {
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProc(window, msg, w, l);
}
void game::run() {
settings settings;
init(settings);
auto title = std::wstring(settings.title.begin(), settings.title.end());
auto instance = GetModuleHandle(0);
auto wc = WNDCLASS{
.lpfnWndProc = wnd_proc,
.hInstance = instance,
.lpszClassName = title.c_str(),
};
auto atom = RegisterClass(&wc);
auto window = CreateWindow(
wc.lpszClassName,
title.c_str(),
WS_POPUP,
0,
0,
settings.size.x * settings.scale,
settings.size.y * settings.scale,
0,
0,
instance,
0
);
ShowWindow(window, SW_SHOWNORMAL);
auto window_image = image(settings.size * settings.scale);
auto screen = image(settings.size);
screen.clear(0xffdddd);
auto last_second = std::chrono::steady_clock::now();
auto frames_since_last_second = 0;
auto running = true;
while(running) {
MSG msg;
while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
switch(msg.message) {
case WM_QUIT:
running = false;
break;
}
}
auto now = std::chrono::steady_clock::now();
if(now - last_second >= std::chrono::seconds(1)) {
std::cout << std::format("FPS: {:5} | mspf: {}", frames_since_last_second, 1000.0 / frames_since_last_second) << std::endl;
frames_since_last_second = 0;
last_second += std::chrono::seconds(1);
}
update();
render(screen);
window_image.draw_upscaled(screen);
BITMAPINFOHEADER bi{ sizeof(bi) };
bi.biWidth = window_image.size().x;
bi.biHeight = -window_image.size().y;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
auto dc = GetDC(window);
SetDIBitsToDevice(dc, 0, 0, window_image.size().x, window_image.size().y, 0, 0, 0, window_image.size().y, window_image.raw_pointer(),
(BITMAPINFO*)&bi, DIB_RGB_COLORS);
ReleaseDC(window, dc);
++frames_since_last_second;
}
}
/*
void game::run() {
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
settings settings;
init(settings);
SDL_PropertiesID props = SDL_CreateProperties();
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, "title");
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, SDL_WINDOWPOS_CENTERED);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, SDL_WINDOWPOS_CENTERED);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, settings.size.x * settings.scale);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, settings.size.y * settings.scale);
auto window = SDL_CreateWindowWithProperties(props);
auto screen = image(settings.size);
auto renderer = SDL_CreateRenderer(window, 0, SDL_RENDERER_ACCELERATED);
auto window_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, settings.size.x * settings.scale, settings.size.y * settings.scale);
auto last_second = std::chrono::steady_clock::now();
auto frames_since_last_second = 0;
auto running = true;
while(running) {
auto event = SDL_Event{};
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_EVENT_QUIT:
running = false;
break;
}
}
auto now = std::chrono::steady_clock::now();
if(now - last_second >= std::chrono::seconds(1)) {
std::cout << std::format("FPS: {:5} | mspf: {}", frames_since_last_second, 1000.0/frames_since_last_second) << std::endl;
frames_since_last_second = 0;
last_second += std::chrono::seconds(1);
}
update();
render(screen);
++frames_since_last_second;
int pitch;
void* pixels = 0;
SDL_LockTexture(window_texture, 0, &pixels, &pitch);
auto window_image = image(settings.size * settings.scale, static_cast<color*>(pixels));
window_image.draw_upscaled(screen);
SDL_UnlockTexture(window_texture);
SDL_RenderTexture(renderer, window_texture, 0, 0);
SDL_RenderPresent(renderer);
}
SDL_Quit();
}
*/
void game::init(settings& settings) {
}
void game::render(image& target) {
}
void game::update() {
}

108
blooblib/src/image.cpp Normal file
View File

@ -0,0 +1,108 @@
#include "image.h"
#include <bit>
#include <iostream>
//#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#define STB_IMAGE_IMPLEMENTATION
#define STBI_ONLY_PNG
#include "stb_image.h"
image::image(vec2i size) :
_borrowed_pointer(false),
_data(new color[size.size()]),
_bounds(vec2i::zero, size)
{
}
image::image(vec2i size, color* data) :
_borrowed_pointer(true),
_data(data),
_bounds(vec2i::zero, size) {
}
image::image(std::string path) : _borrowed_pointer(false) {
int w, h, n;
_data = reinterpret_cast<color*>(stbi_load(path.c_str(), &w, &h, &n, 0));
for(int i = 0; i < w*h; ++i) {
_data[i] = _data[i] & 0xff000000 | (_data[i] & 0x00ff0000) >> 16 | (_data[i] & 0x0000ff00) | (_data[i] & 0x000000ff) << 16;
}
_bounds = recti(vec2i::zero, vec2i(w, h));
}
image::~image() {
if(!_borrowed_pointer)
delete _data;
}
vec2i const& image::size() const {
return _bounds.size;
}
recti const& image::bounds() const {
return _bounds;
}
color* image::raw_pointer() const {
return _data;
}
void image::clear(color color) {
std::fill(_data, _data + size().size() - 1, color);
}
void image::draw(image const& image, vec2i pos) {
auto crop = recti::intersection(bounds(), recti(pos, image.bounds().size));
auto src_off = crop.pos - pos;
auto start = crop.pos;
auto end = crop.pos2();
for(int y = start.y; y <= end.y; ++y) {
for(int x = start.x; x <= end.x; ++x) {
auto color = image._data[x - start.x + src_off.x + (y - start.y + src_off.y) * image._bounds.size.x];
if(color & 0xff000000)
_data[x + y * _bounds.size.x] = color;
}
}
}
void image::draw(image const& image, vec2i pos, recti src_rect) {
}
void image::draw_upscaled(image const& image) {
auto ratio = _bounds.size / image._bounds.size;
auto scale = std::min(ratio.x, ratio.y);
switch(scale) {
case 3:
#pragma omp parallel for
for(int y = 0; y < image._bounds.size.y; ++y) {
for(int x = 0; x < image._bounds.size.x; ++x) {
auto color = image._data[x + y * image._bounds.size.x];
auto color2 = (color & 0xfefefe) >> 1;
_data[x * 3 + 0 + (y * 3 + 0) * _bounds.size.x] = color;
_data[x * 3 + 1 + (y * 3 + 0) * _bounds.size.x] = color;
_data[x * 3 + 2 + (y * 3 + 0) * _bounds.size.x] = color2;
_data[x * 3 + 0 + (y * 3 + 1) * _bounds.size.x] = color;
_data[x * 3 + 1 + (y * 3 + 1) * _bounds.size.x] = color;
_data[x * 3 + 2 + (y * 3 + 1) * _bounds.size.x] = color2;
_data[x * 3 + 0 + (y * 3 + 2) * _bounds.size.x] = color2;
_data[x * 3 + 1 + (y * 3 + 2) * _bounds.size.x] = color2;
_data[x * 3 + 2 + (y * 3 + 2) * _bounds.size.x] = color2;
}
}
break;
default:
#pragma omp parallel for
for(int y = 0; y < image._bounds.size.y; ++y) {
for(int x = 0; x < image._bounds.size.x; ++x) {
auto color = image._data[x + y * image._bounds.size.x];
for(int sy = 0; sy < scale; ++sy) {
for(int sx = 0; sx < scale; ++sx) {
_data[(x * scale + sx) + (y * scale + sy) * _bounds.size.x] = color;
}
}
}
}
}
}

View File

@ -1,8 +1,37 @@
#include <iostream>
#include <SDL3/SDL.h>
#include "bloob.h"
struct my_game : game {
my_game();
void init(settings& settings);
void update();
void render(image& target);
image img;
double time;
};
my_game::my_game() :
img("test.png"),
time(0.0)
{}
void my_game::init(settings& settings) {
}
void my_game::update() {
time += 1.0 / 60.0;
}
void my_game::render(image& target) {
target.clear(0xffdddd);
auto pos = vec2i(std::sin(time*TAU/100), std::cos(time*TAU/100));
std::cout << pos << std::endl;
target.draw(img, vec2i(320, 180) + pos);
}
int main(int argc, char* argv[]) {
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
std::cout << "Hello World" << std::endl;
my_game game;
game.run();
return 0;
}

7742
blooblib/src/stb_image.h Normal file

File diff suppressed because it is too large Load Diff

17
blooblib/src/tileset.cpp Normal file
View File

@ -0,0 +1,17 @@
#include "tileset.h"
tileset::tileset(image const&, vec2i tile_size) {
}
tileset::tileset(std::string path, vec2i tile_size) :
tileset(image(path), tile_size)
{}
image& tileset::operator[](int index) {
return _tiles[index];
}
vec2i const& tileset::tile_size() {
return _tile_size;
}

BIN
blooblib/test.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 900 KiB

BIN
blooblib/test.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
blooblib/test2.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 KiB