- Initial commit
This commit is contained in:
177
source/draw.cpp
Normal file
177
source/draw.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
#include "draw.h"
|
||||
#include <vector>
|
||||
#include "gif.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace draw
|
||||
{
|
||||
SDL_Window *win = nullptr;
|
||||
SDL_Renderer *ren = nullptr;
|
||||
SDL_Texture *tex = nullptr;
|
||||
|
||||
SDL_Texture *source = nullptr;
|
||||
SDL_Texture *dest = nullptr;
|
||||
|
||||
std::vector<texture_t> textures;
|
||||
|
||||
uint32_t palette[16];
|
||||
|
||||
void init()
|
||||
{
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
win = SDL_CreateWindow("DILEMMAKER v0.1", 1280, 960, 0);
|
||||
ren = SDL_CreateRenderer(win, NULL);
|
||||
tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 256, 192);
|
||||
SDL_SetTextureScaleMode(tex, SDL_SCALEMODE_NEAREST);
|
||||
}
|
||||
|
||||
void fillRect(int x, int y, int w, int h, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||
{
|
||||
SDL_SetRenderDrawColor(ren, r, g, b, a);
|
||||
SDL_FRect rect {float(x), float(y), float(w), float(h)};
|
||||
SDL_RenderFillRect(ren, &rect);
|
||||
}
|
||||
|
||||
void setSource(SDL_Texture *texture)
|
||||
{
|
||||
source = texture;
|
||||
}
|
||||
|
||||
void setDest(SDL_Texture *texture)
|
||||
{
|
||||
dest = texture;
|
||||
SDL_SetRenderTarget(ren, dest);
|
||||
}
|
||||
|
||||
void regenerateTexture(texture_t &texture)
|
||||
{
|
||||
if (texture.target) return;
|
||||
uint32_t *argb;
|
||||
int pitch;
|
||||
SDL_LockTexture(texture.texture, NULL, (void**)&argb, &pitch);
|
||||
for (int i=0; i<texture.w*texture.h; ++i) argb[i] = palette[texture.pixels[i]];
|
||||
SDL_UnlockTexture(texture.texture);
|
||||
}
|
||||
|
||||
int loadPalette(const char *filename)
|
||||
{
|
||||
FILE *fp = fopen(filename, "r");
|
||||
if (!fp) return -1;
|
||||
|
||||
char header[32];
|
||||
int version, count;
|
||||
|
||||
// Read and validate header
|
||||
if (!fgets(header, sizeof(header), fp) || strncmp(header, "JASC-PAL", 8) != 0) {
|
||||
fclose(fp);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (fscanf(fp, "%d\n%d\n", &version, &count) != 2 || count != 16) {
|
||||
fclose(fp);
|
||||
return -3;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
int r, g, b;
|
||||
if (fscanf(fp, "%d %d %d\n", &b, &g, &r) != 3) {
|
||||
fclose(fp);
|
||||
return -4;
|
||||
}
|
||||
palette[i] = (0xFF << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
regenerateTextures();
|
||||
return 0; // Success
|
||||
}
|
||||
|
||||
void regenerateTextures()
|
||||
{
|
||||
for (auto &tex : textures)
|
||||
{
|
||||
regenerateTexture(tex);
|
||||
}
|
||||
}
|
||||
|
||||
texture_t getTexture(const char *filename)
|
||||
{
|
||||
std::string name = filename;
|
||||
for (auto tex : textures) if (tex.name == name) return tex;
|
||||
|
||||
FILE *f = fopen(filename, "rb");
|
||||
fseek(f, 0, SEEK_END);
|
||||
int file_size = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
uint8_t *buffer = (uint8_t*)malloc(file_size);
|
||||
fread(buffer, file_size, 1, f);
|
||||
fclose(f);
|
||||
|
||||
uint16_t w, h;
|
||||
uint8_t *pixels = gif::Load(buffer, &w, &h);
|
||||
free(buffer);
|
||||
|
||||
SDL_Texture * tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, w, h);
|
||||
SDL_SetTextureScaleMode(tex, SDL_SCALEMODE_NEAREST);
|
||||
|
||||
texture_t t;
|
||||
t.name = filename;
|
||||
t.texture = tex;
|
||||
t.pixels = pixels;
|
||||
t.w = w;
|
||||
t.h = h;
|
||||
regenerateTexture(t);
|
||||
textures.push_back(t);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
texture_t createTexture(const char* name, int w, int h, SDL_TextureAccess access)
|
||||
{
|
||||
SDL_Texture * tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, access, w, h);
|
||||
SDL_SetTextureScaleMode(tex, SDL_SCALEMODE_NEAREST);
|
||||
|
||||
texture_t t;
|
||||
t.name = name;
|
||||
t.texture = tex;
|
||||
if (access == SDL_TEXTUREACCESS_TARGET) {
|
||||
t.target = true;
|
||||
} else {
|
||||
t.pixels = (uint8_t*)malloc(w*h);
|
||||
for (int i=0; i<w*h; ++i) t.pixels[i] = 0x00000000;
|
||||
}
|
||||
t.w = w;
|
||||
t.h = h;
|
||||
regenerateTexture(t);
|
||||
textures.push_back(t);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void deleteTexture(const char *name)
|
||||
{
|
||||
for (auto it = textures.begin(); it != textures.end(); ++it) {
|
||||
if ((*it).name == name)
|
||||
{
|
||||
SDL_DestroyTexture((*it).texture);
|
||||
free((*it).pixels);
|
||||
textures.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void draw(int dx, int dy, int dw, int dh, int sx, int sy, int sw, int sh)
|
||||
{
|
||||
SDL_FRect src {float(sx), float(sy), float(sw), float(sh)};
|
||||
SDL_FRect dst {float(dx), float(dy), float(dw), float(dh)};
|
||||
SDL_RenderTexture(ren, source, &src, &dst);
|
||||
}
|
||||
|
||||
void present()
|
||||
{
|
||||
SDL_RenderPresent(ren);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user