Files
dilemmaker/source/japi/draw.cpp

192 lines
5.5 KiB
C++

#include "draw.h"
#include <SDL3/SDL.h>
#include "gif.h"
#include "file.h"
namespace draw
{
SDL_Window *sdl_window {nullptr}; // La finestra de SDL
SDL_Renderer *sdl_renderer {nullptr}; // El renderer de SDL
SDL_Texture *sdl_source {nullptr};
void init(const char *titol, const uint16_t width, const uint16_t height)
{
sdl_window = SDL_CreateWindow(titol, width, height, SDL_WINDOW_RESIZABLE);
if (!sdl_window) {
SDL_LogCritical(SDL_LOG_CATEGORY_VIDEO, "ERROR (draw::init): Failed to initialize window!\n");
exit(1);
}
sdl_renderer = SDL_CreateRenderer(sdl_window, NULL);
if (!sdl_renderer) {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "ERROR (draw::init): Failed to initialize renderer!\n");
exit(1);
}
//SDL_SetRenderDrawBlendMode(sdl_renderer, SDL_BLENDMODE_BLEND);
}
void quit()
{
SDL_DestroyRenderer(sdl_renderer);
SDL_DestroyWindow(sdl_window);
sdl_window = nullptr;
sdl_renderer = nullptr;
}
SDL_Texture *createSurface(const uint16_t w, const uint16_t h)
{
return SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, w, h);
}
SDL_Texture *loadSurface(const char *filename, const int transparent)
{
int size;
uint8_t *buffer = (uint8_t *)file::getFileBuffer(filename, size);
if (buffer == nullptr) return nullptr;
uint16_t w, h;
uint8_t *pixels = LoadGif(buffer, &w, &h);
int paletteSize;
uint32_t *pal = LoadPalette(buffer, &paletteSize);
SDL_Texture *surf = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, w, h);
SDL_SetTextureBlendMode(surf, SDL_BLENDMODE_BLEND);
Uint32 *sdl_pixels;
int sdl_pitch;
SDL_LockTexture(surf, NULL, (void **)&sdl_pixels, &sdl_pitch);
int i=0;
for (int y=0; y<h; ++y) {
for (int x=0; x<w; ++x) {
sdl_pixels[x+y*(sdl_pitch/4)] = transparent==pixels[i] ? 0x00000000 : pal[pixels[i]] | 0xff000000;
i++;
}
}
//for (uint32_t i = 0; i < w*h; ++i) sdl_pixels[i] = transparent==pixels[i] ? 0x00000000 : pal[pixels[i]] | 0xff000000;
SDL_UnlockTexture(surf);
free(pal);
free(pixels);
free(buffer);
return surf;
}
void freeSurface(SDL_Texture *surf)
{
SDL_DestroyTexture(surf);
}
void setDestination(SDL_Texture *surf)
{
SDL_SetRenderTarget(sdl_renderer, surf);
}
void setSource(SDL_Texture *surf)
{
sdl_source = surf;
}
void setClip(const int x, const int y, const int w, const int h)
{
SDL_Rect rect {x, y, w, h};
SDL_SetRenderClipRect(sdl_renderer, &rect);
}
void resetClip()
{
SDL_SetRenderClipRect(sdl_renderer, nullptr);
}
SDL_Point getWindowSize()
{
SDL_Point p;
SDL_GetWindowSize(sdl_window, &p.x, &p.y);
return p;
}
void setColor(const uint32_t col)
{
SDL_SetRenderDrawColor(sdl_renderer, (col>>16)&0xff, (col>>8)&0xff, (col)&0xff, (col>>24)&0xff);
}
void cls(const uint32_t color)
{
setColor(color);
SDL_RenderClear(sdl_renderer);
}
void line(const int x1, const int y1, const int x2, const int y2)
{
SDL_RenderLine(sdl_renderer, x1, y1, x2, y2);
}
void fillrect(const int x, const int y, const int w, const int h)
{
SDL_FRect rect {float(x), float(y), float(w),float(h)};
SDL_RenderFillRect(sdl_renderer, &rect);
}
void rect(const int x, const int y, const int w, const int h)
{
SDL_FRect rect {float(x), float(y), float(w),float(h)};
SDL_RenderRect(sdl_renderer, &rect);
}
void draw(const SDL_Rect source, const SDL_Rect dest, const SDL_FlipMode flip)
{
if (!sdl_source) return;
SDL_FRect src {float(source.x), float(source.y), float(source.w),float(source.h)};
SDL_FRect dst {float(dest.x), float(dest.y), float(dest.w),float(dest.h)};
SDL_RenderTextureRotated(sdl_renderer, sdl_source, &src, &dst, 0.0, nullptr, flip);
}
/*
void draw(const int dx, const int dy, const int w, const int h, const int sx, const int sy, const int zoom)
{
// Si no hi ha superficie d'oritge especificada, no fem res, o petarà el mame
if (source == nullptr) return;
for (int y=0; y<h; ++y) {
for (int x=0; x<w; ++x) {
const uint8_t pixel = pget(source, sx+x, sy+y);
for (int zx=0; zx<zoom; ++zx)
for (int zy=0; zy<zoom; ++zy) {
pset(destination, dx+zx+x*zoom, dy+zy+y*zoom, pixel);
}
}
}
}
// Pinta tota la superficie "source" en la superficie "destination", posició (x,y).
void draw(const int x, const int y)
{
draw(x, y, source->w, source->h, 0, 0);
}
// Pinta tota la superficie "source" en la superficie "destination", posició (0,0)
void draw()
{
draw(0,0,source->w, source->h, 0, 0);
}
// Carrega la superficie especificada en "source" i la pinta tota en la superficie "destination", posició (0,0).
void draw(SDL_Texture* surf)
{
setSource(surf);
draw();
}
*/
// Refresca la pantalla
void render()
{
SDL_RenderPresent(sdl_renderer);
}
}