#include "mini.h" #include #include "lua.h" #define swap(a, b) {auto tmp=a;a=b;b=tmp;} #define SCREEN_WIDTH 160 #define SCREEN_HEIGHT 120 #define SCREEN_SIZE_BYTES SCREEN_WIDTH*SCREEN_HEIGHT #define SPRITES_WIDTH 128 #define SPRITES_HEIGHT 128 #define SPRITES_SIZE_BYTES SPRITES_WIDTH*SPRITES_HEIGHT #define SPRITES_PER_LINE SPRITES_WIDTH/8 #define SPRITES_PER_ROW SPRITES_HEIGHT/8 #define TILES_WIDTH 128 #define TILES_HEIGHT 128 #define TILES_SIZE_BYTES TILES_WIDTH*TILES_HEIGHT #define SCREEN(x, y) screen[x+(y)*SCREEN_WIDTH] #define SPRITES(x, y) sprites[x+(y)*SPRITES_WIDTH] #define TILES(x, y) tiles[x+(y)*TILES_WIDTH] 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 draw_palette[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; uint8_t screen_palette[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; bool trans[16] = {true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}; uint16_t fill_pattern = 0b1111111111111111; bool fill_trans = false; } SDL_Window *mini_win; SDL_Renderer *mini_ren; SDL_Texture *mini_bak; Uint32 *pixels; int pitch; uint8_t screen[SCREEN_SIZE_BYTES]; uint8_t sprites[SPRITES_SIZE_BYTES]; uint8_t tiles[TILES_SIZE_BYTES]; uint32_t palette[16] = { 0x1a1c2c00, 0x5d275d00, 0xb13e5300, 0xef7d5700, 0xffcd7500, 0xa7f07000, 0x38b76400, 0x25717900, 0x29366f00, 0x3b5dc900, 0x41a6f600, 0x73eff700, 0xf4f4f400, 0x94b0c200, 0x566c8600, 0x333c5700 }; 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>3)+(base64font[bi+3]-48<<3)+(base64font[bi+4]-48<<9); bi += 5; } FILE *f = fopen("sprites.bmp", "rb"); if (f) { uint8_t buffer[SPRITES_SIZE_BYTES/2]; fseek(f, 118, SEEK_SET); fread(buffer, SPRITES_SIZE_BYTES/2, 1, f); fclose(f); for (int y=0; y> 4; SPRITES(x*2+1, SPRITES_WIDTH-1-y) = buffer[x+y*(SPRITES_WIDTH/2)] & 0xf; } } } SDL_Init(49); mini_win = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH*4, SCREEN_HEIGHT*4, 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); mini_bak = SDL_CreateTexture(mini_ren, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT); bool exit = false; SDL_Event mini_eve; debug("MINI SYSTEM BOOTING..."); lua_init(); lua_call_init(); while(!exit) { key_just_pressed = 0; while(SDL_PollEvent(&mini_eve)) { if (mini_eve.type == SDL_QUIT) { exit=true; break; } if (mini_eve.type == SDL_KEYDOWN) { if (mini_eve.key.keysym.scancode == SDL_SCANCODE_ESCAPE) { if (lua_is_playing()) { lua_quit(); reinit(); } else { lua_init(); lua_call_init(); } } else if (mini_eve.key.keysym.scancode == SDL_SCANCODE_F5) { lua_quit(); reinit(); lua_init(); lua_call_init(); } else { key_just_pressed = mini_eve.key.keysym.scancode; } } } keys = SDL_GetKeyboardState(NULL); if (lua_is_playing()) { lua_call_update(); } else { loop(); } SDL_LockTexture(mini_bak, NULL, (void**)&pixels, &pitch); for (int i=0;i ds::clp[2] || y < ds::clp[1] || y > ds::clp[3]) return; SCREEN(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; 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]) SCREEN(x, y) = ds::draw_palette[ds::pen_color & 0xf]; } else { if (!ds::fill_trans) SCREEN(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 > (SCREEN_WIDTH-1) || y < 0 || y > (SCREEN_HEIGHT-1)) return 0; return SCREEN(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) swap(x0, x1); 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) swap(y0, y1); 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_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(const char *str, int x, int y) { for (int i=0; i < SDL_strlen(str); ++i) print_char(str[i], x+i*4, y); } 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 > (SPRITES_WIDTH-1) || y < 0 || y > (SPRITES_HEIGHT-1)) return 0; return SPRITES(x, y); } void sset(int x, int y) { if (x < 0 || x > (SPRITES_WIDTH-1) || y < 0 || y > (SPRITES_HEIGHT-1)) return; SPRITES(x, y) = ds::draw_palette[ds::pen_color & 0xf]; } 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%(SPRITES_PER_LINE))<<3; int ty = (n/(SPRITES_PER_LINE))<<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= 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) swap(x0, x1); 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) swap(y0, y1); 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(uint8_t celx, uint8_t cely) { if (celx < 0 || celx > (TILES_WIDTH-1) || cely < 0 || cely > (TILES_HEIGHT-1)) return 0; return TILES(celx, cely); } void mset(uint8_t celx, uint8_t cely, uint8_t snum) { if (celx < 0 || celx > (TILES_WIDTH-1) || cely < 0 || cely > (TILES_HEIGHT-1)) return; TILES(celx, cely) = snum; } void map(uint8_t celx, uint8_t 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= 0 ? 1 : -1; } 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); } 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 rnd(int x) { return rand()%x; } /*void srand(int x) { srand(x); }*/ void debug_one_line_up() { for (int i=0; i= debug_total_size) debug_one_line_up(); } debug_cursor = (int(debug_cursor/debug_line_size)+1)*debug_line_size; if (debug_cursor >= debug_total_size) debug_one_line_up(); } void pdebug() { int i=0; for (int y=0; y