Files
mini/mini.cpp
2022-12-28 18:35:09 +01:00

994 lines
25 KiB
C++

#include "mini.h"
#include "jfile.h"
#include <string.h>
#include "lua.h"
#include "gif.c"
#include "chirp.h"
#pragma pack(1)
struct surface_t {
uint8_t *p;
uint16_t w, h;
uint32_t size;
};
char window_title[256];
uint16_t screen_width = 160;
uint16_t screen_height = 120;
uint8_t screen_zoom = 4;
uint8_t show_cursor = SDL_ENABLE;
surface_t surfaces[10];
surface_t *screen_surface = &surfaces[0];
surface_t *dest_surface = screen_surface;
surface_t *source_surface = NULL;
surface_t *map_surface = NULL;
FILE *file = NULL;
//uint8_t file_mode = 0;
bool file_ignore_comma=true;
char lua_files[1024];
#define DEST(x, y) dest_surface->p[x+y*dest_surface->w]
#define SOURCE(x, y) source_surface->p[x+y*source_surface->w]
#define TILES(x, y) map_surface->p[x+y*map_surface->w]
#define CURRENT(x, y) surfaces[i].p[(x)+(y)*surfaces[i].w]
namespace ds {
uint8_t pen_color = 6;
int cam[2] = {0, 0};
int clip[4] = {0, 0, screen_width, screen_height};
int clp[4] = {0, 0, screen_width-1, screen_height-1};
uint8_t trans = 0;
uint16_t fill_pattern = 0b1111111111111111;
bool fill_trans = false;
}
bool should_exit = false;
bool should_quit = false;
SDL_Window *mini_win;
SDL_Renderer *mini_ren;
SDL_Texture *mini_bak;
Uint32 *pixels;
int pitch;
uint32_t palette[256] = { 0x001a1c2c, 0x005d275d, 0x00b13e53, 0x00ef7d57, 0x00ffcd75, 0x00a7f070, 0x0038b764, 0x00257179,
0x0029366f, 0x003b5dc9, 0x0041a6f6, 0x0073eff7, 0x00f4f4f4, 0x0094b0c2, 0x00566c86, 0x00333c57 };
const char base64[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char base64font[241] = "00@B@]0X__OnZDYK[G10:9BTDEG5j20@1h000RB:_]OBjW?odl]Wlil9_oTT__omT@@02:DA477ADid@Z=nm]_[g9a[]oIi?;a9m]_mBjGB[M]99o_][]e]M"
"_?A]c_[eiLGBZ]e]mZ]o]Z]mlW:O9IABdTdZ000hR00__H[7?iH]3Oih;1?mXm5GjhB3M]897o]H]5^Mhm1ZchM5>LhB2]eXm2]oXZ5mlh<gJbBBJbJP?0Zm";
uint16_t font[96];
char base64glyphs[193] = "/h/AqV/hhhh/GMYYMGz/t/eS33H477wsjjswY4IOPHEFFVVVAVAVAVIc+dJHMMM/h/qBgBgVqq+//eIUi/dJzhAAhzAAA/eM"
"AMShAAAQsjAAAwsjAAAeSzAAAcU3AAAEqRAAABVaiAAMezhAAAAAMAADH4wAASb2SAAMAttAQYcefACGOe+AAAVVAAAAbbAA";
//Uint8 keymapping[6] = { SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_Z, SDL_SCANCODE_X };
const Uint8 *keys;
Uint8 key_just_pressed = 0;
int mouse_x, mouse_y, mouse_wheel;
Uint32 mouse_buttons;
char* get_value_from_line(char* line) {
char* equal_character = strchr(line, '=');
if (equal_character == NULL) return NULL;
*equal_character = '\0';
return ++equal_character;
}
void read_ini() {
int size;
FILE *f = file_getfilepointer("game.ini", size); // fopen("game.ini", "r");
char line[1024];
if (f == NULL) return;
while (fgets(line, sizeof(line), f)) {
char *value = get_value_from_line(line);
if (value != NULL) {
value[strlen(value)-1] = '\0';
if (strcmp(line, "title") == 0) strcpy(window_title, value);
else if (strcmp(line, "width") == 0) screen_width = atoi(value);
else if (strcmp(line, "height") == 0) screen_height = atoi(value);
else if (strcmp(line, "zoom") == 0) screen_zoom = atoi(value);
else if (strcmp(line, "hidemouse") == 0) show_cursor = SDL_DISABLE;
else if (strcmp(line, "files") == 0) {
//lua_files = (char*)malloc(strlen(value));
strcpy(lua_files, value);
}
}
}
fclose(f);
}
void reinit() {
ds::pen_color = 6;
ds::cam[0] = ds::cam[1] = 0;
ds::clip[0] = ds::clip[1] = 0; ds::clip[2] = screen_width; ds::clip[3] = screen_height;
ds::clp[0] = ds::clp[1] = 0; ds::clp[2] = screen_width-1; ds::clp[3] = screen_height-1;
ds::trans=0;
ds::fill_pattern = 0b1111111111111111;
ds::fill_trans = false;
for (int i=1; i<10; ++i) {
if (surfaces[i].p != NULL) free(surfaces[i].p);
surfaces[i].p = NULL;
}
if (file!=NULL) fclose(file);
file = NULL;
}
void initaudio() {
chirp_init();
}
void quitaudio() {
}
int scrw() {
return screen_width;
}
int scrh() {
return screen_height;
}
uint8_t newsurf(int w, int h) {
int i = 0;
while (i<10 && surfaces[i].p != NULL) ++i;
//[TODO] Gestionar el cas en que no queden surfaces lliures
surfaces[i].w = w;
surfaces[i].h = h;
surfaces[i].size = w*h;
surfaces[i].p = (uint8_t*)malloc(surfaces[i].size);
return i;
}
uint8_t loadsurf(const char* filename) {
int i = 0;
while (i<10 && surfaces[i].p != NULL) ++i;
//[TODO] Gestionar el cas en que no queden surfaces lliures
int size;
uint8_t *buffer = (uint8_t*)file_getfilebuffer(filename, size);
surfaces[i].p = LoadGif(buffer, &surfaces[i].w, &surfaces[i].h);
surfaces[i].size = surfaces[i].w*surfaces[i].h;
free(buffer);
return i;
}
void freesurf(uint8_t surface) {
if (surfaces[surface].p != NULL) free(surfaces[surface].p);
surfaces[surface].p = NULL;
}
void setdest(uint8_t surface) {
dest_surface = &surfaces[surface];
}
void setsource(uint8_t surface) {
source_surface = &surfaces[surface];
}
void setmap(uint8_t surface) {
map_surface = &surfaces[surface];
}
int main(int argc,char*argv[]){
while (!should_quit) {
should_exit=false;
// initfont()
int bi = 0;
for (int ci=0; ci<96; ci+=2) {
font[ci] = base64font[bi]-48+((base64font[bi+1]-48)<<6)+((base64font[bi+2]-48&7)<<12);
font[ci+1] = ((base64font[bi+2]-48)>>3)+((base64font[bi+3]-48)<<3)+((base64font[bi+4]-48)<<9);
bi += 5;
}
read_ini();
setdest(newsurf(screen_width, screen_height));
SDL_Init(SDL_INIT_EVERYTHING);
mini_win = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_width*screen_zoom, screen_height*screen_zoom, SDL_WINDOW_SHOWN);
mini_ren = SDL_CreateRenderer(mini_win, -1, SDL_RENDERER_PRESENTVSYNC);
//SDL_CreateWindowAndRenderer(512,512,0,&mini_win,&mini_ren);
SDL_RenderSetLogicalSize(mini_ren, screen_width, screen_height);
SDL_ShowCursor(show_cursor);
mini_bak = SDL_CreateTexture(mini_ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, screen_width, screen_height);
SDL_Event mini_eve;
reinit();
initaudio();
debug("MINI v%s\n",MINI_VERSION);
lua_init(lua_files);
lua_call_init();
while(!should_exit) {
key_just_pressed = 0;
mouse_wheel = 0;
while(SDL_PollEvent(&mini_eve)) {
if (mini_eve.type == SDL_QUIT) { should_exit=true; should_quit=true; break; }
if (mini_eve.type == SDL_KEYDOWN) {
#ifdef DEBUG
if (mini_eve.key.keysym.scancode == SDL_SCANCODE_ESCAPE) {
chirp_stop();
if (lua_is_playing()) {
lua_quit();
quitaudio();
reinit();
} else {
should_exit=true;
}
} else if (mini_eve.key.keysym.scancode == SDL_SCANCODE_F5) {
chirp_stop();
} else {
key_just_pressed = mini_eve.key.keysym.scancode;
}
#else
key_just_pressed = mini_eve.key.keysym.scancode;
#endif
}
if (mini_eve.type == SDL_MOUSEWHEEL) {
mouse_wheel = mini_eve.wheel.y;
}
}
keys = SDL_GetKeyboardState(NULL);
mouse_buttons = SDL_GetMouseState(&mouse_x, &mouse_y);
mouse_x /= screen_zoom; mouse_y /= screen_zoom;
if (lua_is_playing()) {
lua_call_update();
} else {
loop();
}
SDL_LockTexture(mini_bak, NULL, (void**)&pixels, &pitch);
for (int i=0;i<screen_surface->size;++i) pixels[i] = palette[screen_surface->p[i]];
SDL_UnlockTexture(mini_bak);
SDL_RenderCopy(mini_ren, mini_bak, NULL, NULL);
SDL_RenderPresent(mini_ren);
}
lua_quit();
quitaudio();
for (int i=0;i<10;++i) freesurf(i);
SDL_DestroyTexture(mini_bak);
SDL_DestroyRenderer(mini_ren);
SDL_DestroyWindow(mini_win);
SDL_Quit();
}
return 0;
}
void cls(uint8_t color) {
SDL_memset(dest_surface->p, color, dest_surface->size);
}
void color(uint8_t color) {
ds::pen_color=color;
}
uint32_t *loadpal(const char* filename) {
int size;
uint8_t *buffer = (uint8_t*)file_getfilebuffer(filename, size);
uint32_t *pal = LoadPalette(buffer);
free(buffer);
return pal;
/*
FILE *f = fopen(filename, "rb");
if (f) {
fseek(f, 0, SEEK_END);
long size = ftell(f);
fseek(f, 0, SEEK_SET);
uint8_t *buffer = (uint8_t*)malloc(size);
fread(buffer, size, 1, f);
fclose(f);
uint32_t *pal = LoadPalette(buffer);
free(buffer);
return pal;
//memcpy(palette, pal, 1024);
//free(pal);
}
return NULL;*/
}
void setpal(uint32_t *pal) {
memcpy(palette, pal, 1024);
}
void setcolor(uint8_t index, uint32_t color) {
palette[index] = color;
}
uint32_t getcolor(uint8_t index) {
return palette[index];
}
void settrans(uint8_t index) {
ds::trans = index;
}
uint8_t gettrans() {
return ds::trans;
}
/*void pal() {
for (int i=0; i<16; ++i) {
ds::draw_palette[i] = i;
ds::screen_palette[i] = i;
}
palt();
}
void pal(uint8_t c0, uint8_t c1, uint8_t p) {
if (p==0) ds::draw_palette[c0] = c1; else if (p==1) ds::screen_palette[c0]=c1;
}
void palt() {
ds::trans[0] = true;
for (int i=1; i<16; ++i) ds::trans[i] = false;
}
void palt(uint16_t bits) {
for (int i=0; i<16; ++i) ds::trans[i] = (bits & (1<<i));
}
void palt(uint8_t col, bool t) {
ds::trans[col] = t;
}
*/
void simple_pset(int x, int y, uint8_t color) {
x -= ds::cam[0]; y -= ds::cam[1];
if (x < ds::clp[0] || x > ds::clp[2] || y < ds::clp[1] || y > ds::clp[3]) return;
DEST(x, y) = color;
}
void pset(int x, int y) {
x -= ds::cam[0]; y -= ds::cam[1];
if (x < ds::clp[0] || x > ds::clp[2] || y < ds::clp[1] || y > ds::clp[3]) return;
if (ds::trans != ds::pen_color) DEST(x, y) = ds::pen_color;
}
/*void pset(int x, int y) {
x -= ds::cam[0]; y -= ds::cam[1];
if (x < ds::clp[0] || x > ds::clp[2] || y < ds::clp[1] || y > ds::clp[3]) return;
int pbx = x % 4, pby = y % 4;
int pb = pbx+pby*4;
if (ds::fill_pattern & (1 << pb)) {
if (!ds::trans[ds::pen_color & 0xf]) DEST(x, y) = ds::draw_palette[ds::pen_color & 0xf];
} else {
if (!ds::fill_trans) DEST(x, y) = ds::draw_palette[ds::pen_color >> 4];
}
}*/
void pset(int x, int y, uint8_t color) {
ds::pen_color = color;
pset(x, y);
}
uint8_t pget(int x, int y) {
x -= ds::cam[0]; y -= ds::cam[1];
if (x < 0 || x > (dest_surface->w-1) || y < 0 || y > (dest_surface->h-1)) return 0;
return DEST(x, y);
}
// Bresenham Line Algorithm
void line(int x0, int y0, int x1, int y1) {
int x, y;
int dx, dy;
int incx, incy;
int balance;
if (x1 >= x0) { dx = x1 - x0; incx = 1; } else { dx = x0 - x1; incx = -1; }
if (y1 >= y0) { dy = y1 - y0; incy = 1; } else { dy = y0 - y1; incy = -1; }
x = x0; y = y0;
if (dx >= dy) {
dy <<= 1;
balance = dy - dx;
dx <<= 1;
while (x != x1) {
pset(x, y);
if (balance >= 0) { y += incy; balance -= dx; }
balance += dy;
x += incx;
}
pset(x, y);
} else {
dx <<= 1;
balance = dx - dy;
dy <<= 1;
while (y != y1) {
pset(x, y);
if (balance >= 0) { x += incx; balance -= dy; }
balance += dx;
y += incy;
}
pset(x, y);
}
}
void line(int x0, int y0, int x1, int y1, uint8_t color) {
ds::pen_color = color;
line(x0, y0, x1, y1);
}
void hline(int x0, int y, int x1) {
if (x0>x1) { const int tmp=x0;x0=x1;x1=tmp; }
for (int x=x0; x<=x1; ++x) pset(x, y);
}
void hline(int x0, int y, int x1, uint8_t color) {
ds::pen_color = color;
hline(x0, y, x1);
}
void vline(int x, int y0, int y1) {
if (y0>y1) { const int tmp=y0;y0=y1;y1=tmp; }
for (int y=y0; y<=y1; ++y) pset(x, y);
}
void vline(int x, int y0, int y1, uint8_t color) {
ds::pen_color = color;
vline(x, y0, y1);
}
void rect(int x0, int y0, int x1, int y1) {
hline(x0, y0, x1);
hline(x0, y1, x1);
vline(x0, y0, y1);
vline(x1, y0, y1);
}
void rect(int x0, int y0, int x1, int y1, uint8_t color) {
ds::pen_color = color;
rect(x0, y0, x1, y1);
}
void rectfill(int x0, int y0, int x1, int y1) {
for (int y=y0; y<=y1; ++y) hline(x0, y, x1);
}
void rectfill(int x0, int y0, int x1, int y1, uint8_t color) {
ds::pen_color = color;
rectfill(x0, y0, x1, y1);
}
void fillp(uint16_t pat, bool transparent) {
ds::fill_trans = transparent;
ds::fill_pattern = pat;
}
void print_symbol(char sym, int x, int y) {
switch(sym) {
case 1: pset(x, y-3); pset(x+1, y-2); break;
case 2: pset(x+1, y-2); pset(x+2, y-3); break;
case 3: pset(x+1, y+5); break;
case 4: pset(x, y-2); pset(x+1, y-2); pset(x+2, y-2); break;
case 5: pset(x, y-2); pset(x+1, y-1); break;
case 6: pset(x+1, y-1); pset(x+2, y-2); break;
case 7: pset(x, y-1); pset(x+1, y-1); pset(x+2, y-1); break;
}
}
void print_char(char chr, int x, int y) {
int xi = 0, yi = 0;
uint16_t val = 1;
while(1) {
if (font[chr-32] & val) pset(x+xi, y+yi);
if (xi<2) xi++; else { if (yi==4) return; else { xi=0; yi++; } }
val <<= 1;
}
}
void print_char_hv(char chr, int x, int y) {
int xi = 0, yi = 0;
uint16_t val = 1;
while(1) {
if (font[chr-32] & val) pset(x+(2-xi), y+(4-yi));
if (xi<2) xi++; else { if (yi==4) return; else { xi=0; yi++; } }
val <<= 1;
}
}
const char t195_char[]={65,65,0,0,0,0,0,67,69,69,0,0,73,73,0,0,0,78,79,79,0,0,0,0,0,85,85,0,0,0,0,0,97,97,0,0,0,0,0,99,101,101,0,0,105,105,0,0,0,110,111,111,0,0,0,0,0,117,117,0,0,0,0,0};
const char t195_symbol[]={1,2,0,0,0,0,0,3,1,2,0,0,1,2,0,0,0,4,1,2,0,0,0,0,0,1,2,0,0,0,0,0,5,6,0,0,0,0,0,3,5,6,0,0,5,6,0,0,0,7,5,6,0,0,0,0,0,5,6,0,0,0,0,0};
void print(const char *str, int x, int y) {
int pos=0;
for (int i=0; i < SDL_strlen(str); ++i) {
if ((unsigned char)str[i]==194) {
i++;
if ((unsigned char)str[i]==161) print_char_hv('!', x+pos*4, y);
else if ((unsigned char)str[i]==191) print_char_hv('?', x+pos*4, y);
} else if ((unsigned char)str[i]==195) {
i++;
print_char(t195_char[(unsigned char)str[i]-128], x+pos*4, y);
print_symbol(t195_symbol[(unsigned char)str[i]-128], x+pos*4, y);
} else {
print_char(str[i], x+pos*4, y);
}
pos++;
}
}
void print(const char *str, int x, int y, uint8_t color) {
ds::pen_color=color;
print(str, x, y);
}
void clip(int x, int y, int w, int h) {
ds::clip[0] = x; ds::clip[1] = y; ds::clip[2] = w; ds::clip[3] = h;
ds::clp[0] = x; ds::clp[1] = y; ds::clp[2] = w-x-1; ds::clp[3] = h-y-1;
}
void camera(int x, int y) {
ds::cam[0] = x;
ds::cam[1] = y;
}
void _drawcirc(int xc, int yc, int x, int y) {
pset(xc+x, yc+y);
pset(xc-x, yc+y);
pset(xc+x, yc-y);
pset(xc-x, yc-y);
pset(xc+y, yc+x);
pset(xc-y, yc+x);
pset(xc+y, yc-x);
pset(xc-y, yc-x);
}
void _fillcirc(int xc, int yc, int x, int y) {
hline(xc-x, yc+y, xc+x);
hline(xc-x, yc-y, xc+x);
hline(xc-y, yc+x, xc+y);
hline(xc-y, yc-x, xc+y);
}
void _anycirc(int x, int y, uint8_t r, void (*fun_ptr)(int, int, int, int)) {
int xi=0, yi=r;
int d=3-2*r;
(*fun_ptr)(x, y, xi, yi);
while (yi>=xi++) {
d += d>0 ? 4*(xi-yi--)+10 : 4*xi+6;
(*fun_ptr)(x, y, xi, yi);
}
}
void circ(int x, int y, uint8_t r) {
_anycirc(x, y, r, &_drawcirc);
}
void circ(int x, int y, uint8_t r, uint8_t color) {
ds::pen_color=color;
circ(x, y, r);
}
void circfill(int x, int y, uint8_t r) {
_anycirc(x, y, r, &_fillcirc);
}
void circfill(int x, int y, uint8_t r, uint8_t color) {
ds::pen_color=color;
circfill(x, y, r);
}
void _drawoval(int xc, int yc, int x, int y, float xf, float yf) {
pset((xc+x)*xf, (yc+y)*yf);
pset((xc-x)*xf, (yc+y)*yf);
pset((xc+x)*xf, (yc-y)*yf);
pset((xc-x)*xf, (yc-y)*yf);
pset((xc+y)*xf, (yc+x)*yf);
pset((xc-y)*xf, (yc+x)*yf);
pset((xc+y)*xf, (yc-x)*yf);
pset((xc-y)*xf, (yc-x)*yf);
}
void _filloval(int xc, int yc, int x, int y, float xf, float yf) {
hline((xc-x)*xf, (yc+y)*yf, (xc+x)*xf);
hline((xc-x)*xf, (yc-y)*yf, (xc+x)*xf);
hline((xc-y)*xf, (yc+x)*yf, (xc+y)*xf);
hline((xc-y)*xf, (yc-x)*yf, (xc+y)*xf);
}
void _anyoval(int x0, int y0, int x1, int y1, void (*fun_ptr)(int, int, int, int, float, float)) {
int rx = (x1-x0)/2;
int ry = (y1-y0)/2;
int r = rx;
int x = x0 + rx;
int y = y0 + ry;
float xf = 1.0f, yf = 1.0f;
if (rx>=ry) {r=rx;yf=float(ry)/float(rx);} else {r=ry;xf=float(rx)/float(ry);}
int xi=0, yi=r;
int d=3-2*r;
(*fun_ptr)(x, y, xi, yi, xf, yf);
while (yi>=xi++) {
d += d>0 ? 4*(xi-yi--)+10 : 4*xi+6;
(*fun_ptr)(x, y, xi, yi, xf, yf);
}
}
void oval(int x0, int y0, int x1, int y1) {
_anyoval(x0, y0, x1, y1, &_drawoval);
}
void oval(int x0, int y0, int x1, int y1, uint8_t color) {
ds::pen_color=color;
oval(x0, y0, x1, y1);
}
void ovalfill(int x0, int y0, int x1, int y1) {
_anyoval(x0, y0, x1, y1, &_filloval);
}
void ovalfill(int x0, int y0, int x1, int y1, uint8_t color) {
ds::pen_color=color;
ovalfill(x0, y0, x1, y1);
}
uint8_t sget(int x, int y) {
if (x < 0 || x > (source_surface->w-1) || y < 0 || y > (source_surface->h-1)) return 0;
return SOURCE(x, y);
}
void sset(int x, int y) {
if (x < 0 || x > (source_surface->w-1) || y < 0 || y > (source_surface->h-1)) return;
SOURCE(x, y) = ds::pen_color;
}
void sset(int x, int y, uint8_t color) {
ds::pen_color=color;
sset(x, y);
}
void spr(uint8_t n, int x, int y, float w, float h, bool flip_x, bool flip_y) {
int tx = (n%(source_surface->w >> 3))<<3;
int ty = (n/(source_surface->w >> 3))<<3;
int tw = w*8 - 1;
int th = h*8 - 1;
//int tx2 = tx1 + tw;
//int ty2 = ty1 + th;
int txd = 1;
int tyd = 1;
if (flip_x) {tx+=tw;txd=-1;}
if (flip_y) {ty+=th;tyd=-1;}
for (int yi=0; yi<=th; ++yi) {
int ttx = tx;
for (int xi=0; xi<=tw; ++xi) {
pset(x+xi, y+yi, sget(ttx, ty));
ttx += txd;
}
ty += tyd;
}
}
void sspr(int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, bool flip_x, bool flip_y) {
if (dw==0)dw=sw; if (dh==0)dh=sh;
float sdx = float(sw)/float(dw);
float sdy = float(sh)/float(dh);
float ssx = sx; float ssy = sy;
if (flip_x) { sdx = -sdx; ssx += sw+sdx; }
if (flip_y) { sdy = -sdy; ssy += sh+sdy; }
float csx = ssx;
float csy = ssy;
for(int y=dy;y<dy+dh;++y) {
csx = ssx;
for(int x=dx;x<dx+dw;++x) {
pset(x, y, sget(SDL_max(sx, csx), SDL_max(sy,csy)));
csx += sdx;
}
csy += sdy;
}
}
void tline(int x0, int y0, int x1, int y1, float mx, float my, float mdx, float mdy) {
int x, y;
int dx, dy;
int incx, incy;
int balance;
if (x1 >= x0) { dx = x1 - x0; incx = 1; } else { dx = x0 - x1; incx = -1; }
if (y1 >= y0) { dy = y1 - y0; incy = 1; } else { dy = y0 - y1; incy = -1; }
x = x0; y = y0;
if (dx >= dy) {
dy <<= 1;
balance = dy - dx;
dx <<= 1;
while (x != x1) {
pset(x, y, sget(mx*8, my*8));
if (balance >= 0) { y += incy; balance -= dx; }
balance += dy;
x += incx;
mx += mdx;
my += mdy;
}
pset(x, y, sget(mx*8, my*8));
} else {
dx <<= 1;
balance = dx - dy;
dy <<= 1;
while (y != y1) {
pset(x, y, sget(mx*8, my*8));
if (balance >= 0) { x += incx; balance -= dy; }
balance += dx;
y += incy;
mx += mdx;
my += mdy;
}
pset(x, y, sget(mx*8, my*8));
}
}
void thline(int x0, int y, int x1, float mx, float my, float mdx, float mdy) {
if (x0>x1) { const int tmp=x0;x0=x1;x1=tmp; }
for (int x=x0; x<=x1; ++x) {
pset(x, y, sget(mx*8, my*8));
mx += mdx;
my += mdy;
}
}
void tvline(int x, int y0, int y1, float mx, float my, float mdx, float mdy) {
if (y0>y1) { const int tmp=y0;y0=y1;y1=tmp; }
for (int y=y0; y<=y1; ++y) {
pset(x, y, sget(mx*8, my*8));
mx += mdx;
my += mdy;
}
}
void cline(int x0, int y0, int x1, int y1, uint8_t c0, uint8_t c1) {
}
void chline(int x0, int y, int x1, uint8_t c0, uint8_t c1) {
}
void cvline(int x, int y0, int y1, uint8_t c0, uint8_t c1) {
}
uint8_t mget(int celx, int cely) {
if (celx < 0 || celx > (map_surface->w-1) || cely < 0 || cely > (map_surface->h-1)) return 0;
return TILES(celx, cely);
}
void mset(int celx, int cely, uint8_t snum) {
if (celx < 0 || celx > (map_surface->w-1) || cely < 0 || cely > (map_surface->h-1)) return;
TILES(celx, cely) = snum;
}
void map(int celx, int cely, int sx, int sy, uint8_t celw, uint8_t celh, uint8_t layer) {
//if (celw <= 0 || celh <= 0 || celw >= TILES_WIDTH || celh >= TILES_HEIGHT) return;
sx -= ds::cam[0]; sy -= ds::cam[1];
if (sx+celw*8 < ds::clp[0] || sx > ds::clp[2] || sy+celh*8 < ds::clp[1] || sy > ds::clp[3]) return;
if (sx<0) {
int diff = -sx/8;
celx += diff;
celw -= diff;
sx += diff*8;
}
if (sy<0) {
int diff = -sy/8;
cely += diff;
celh -= diff;
sy += diff*8;
}
sx += ds::cam[0]; sy += ds::cam[1];
for (int y=0; y<celh; ++y) {
for (int x=0; x<celw; ++x) {
spr(mget(celx+x, cely+y), sx+x*8, sy+y*8);
}
}
}
bool btn(uint8_t i) {
return keys[i];
}
bool btnp(uint8_t i) {
return key_just_pressed == i;
}
bool anykey() {
return key_just_pressed != 0;
}
int mousex() {
return mouse_x;
}
int mousey() {
return mouse_y;
}
int mwheel() {
return mouse_wheel;
}
bool mbtn(uint8_t i) {
return mouse_buttons & SDL_BUTTON(i);
}
float time() {
return float(SDL_GetTicks())/1000.0f;
}
/*float abs(float x) {
return SDL_fabsf(x);
}*/
float flr(float x) {
return SDL_floorf(x);
}
float sgn(float x) {
return x >= 0 ? 1 : -1;
}
#ifdef __WINDOWS__
float ceil(float x) {
return SDL_ceilf(x);
}
float sin(float x) {
return SDL_sinf(x);
}
float cos(float x) {
return SDL_cosf(x);
}
float atan2(float dx, float dy) {
return SDL_atan2f(dx, dy);
}
float sqrt(float x) {
return SDL_sqrtf(x);
}
#endif
float max(float x, float y) {
return SDL_max(x, y);
}
float mid(float x, float y, float z) {
return max(x, min(y, z));
}
float min(float x, float y) {
return SDL_min(x, y);
}
int utfstrlen(const char *str) {
const int size_in_bytes = SDL_strlen(str);
int size_in_utfchars = 0;
for (int i=0;i<size_in_bytes;++i) if ((unsigned char)str[i] != 194 && (unsigned char)str[i] != 195) size_in_utfchars++;
return size_in_utfchars;
}
int rnd(int x) {
return rand()%x;
}
/*void srand(int x) {
srand(x);
}*/
char tostr_tmp[1024];
const char* tostr(int val) {
return SDL_itoa(val, tostr_tmp, 10);
}
/*void debug(const char *str) {
printf("%s\n",str);
}*/
uint8_t ascii(const char *str, uint8_t index) {
return str[index];
}
char fstr[1024];
void fopen(const char *filename, uint8_t mode) {
if (file != NULL) fclose(file);
file = fopen(filename, mode==0?"r":"w");
}
void fopenres(const char *filename) {
if (file != NULL) fclose(file);
int size;
file = file_getfilepointer(filename, size);
}
void fclose() {
fclose(file);
}
bool feof() {
return feof(file);
}
void fwritei(int value) {
sprintf(fstr, "%i ", value);
fwrite(fstr, strlen(fstr), 1, file);
}
void fwrited(float value) {
sprintf(fstr, "%f ", value);
fwrite(fstr, strlen(fstr), 1, file);
}
void fwrites(const char *value) {
sprintf(fstr, "\"%s\" ", value);
fwrite(fstr, strlen(fstr), 1, file);
}
void fwritew(const char *value) {
sprintf(fstr, "%s ", value);
fwrite(fstr, strlen(fstr), 1, file);
}
void fwriteb(bool value) {
sprintf(fstr, value?"true ":"false ");
fwrite(fstr, strlen(fstr), 1, file);
}
void fwriteln() {
fwrite("\n", 1, 1, file);
}
int freadi() {
int value;
fscanf(file, "%i", &value);
return value;
}
float freadd() {
float value;
fscanf(file, "%f", &value);
return value;
}
const char *freads() {
fscanf(file, " \"%[^\"]\"", &fstr[0]);
//fscanf(file, "\"%[^\"]\"", &fstr);
return fstr;
}
const char *freadw() {
fscanf(file, "%s", &fstr[0]);
return fstr;
}
bool freadb() {
fscanf(file, "%s", &fstr[0]);
return strcmp(fstr, "true")==0?true:false;
}
void playchirp(const char *song, const bool lock) {
chirp_play(song, lock);
}
void stopchirp() {
chirp_stop();
}
void exit() {
should_exit = true;
}