661 lines
28 KiB
C
661 lines
28 KiB
C
/*
|
|
* mtsedit/sdl.c
|
|
*
|
|
* Copyright (C) 2019 bzt (bztsrc@gitlab)
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person
|
|
* obtaining a copy of this software and associated documentation
|
|
* files (the "Software"), to deal in the Software without
|
|
* restriction, including without limitation the rights to use, copy,
|
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
* of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be
|
|
* included in all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* @brief SDL specific UI code
|
|
*
|
|
*/
|
|
|
|
#include "main.h"
|
|
#include "data.h"
|
|
|
|
uint32_t theme[] = { 0xFFF0F0F0, 0xFFF4F4F4, 0xFFBEBEBE, 0xFF808080, 0xFF5C5C5C, 0xFF4C4C4C, 0xFF454545, 0xFF383838, 0xFF303030,
|
|
0xFFC00000, 0xFF800000, 0xFF7F7F7F, 0xFF3F0000 };
|
|
|
|
int quitting = 0, activetool = -1, overtool = -1, activeblock = 0, overblock = -1, palette[16], strmaxw, strsepar = 1;
|
|
int shift = 0, ctrl = 0, help = 0, systemcursor = 0;
|
|
char *status = NULL;
|
|
unsigned char *tmpblk = NULL;
|
|
SDL_Window *window = NULL;
|
|
SDL_Surface *icons = NULL;
|
|
SDL_Surface *screen = NULL;
|
|
SDL_Surface *fg = NULL;
|
|
SDL_Surface *cl = NULL;
|
|
SDL_Surface *bg = NULL;
|
|
SDL_Surface *blk = NULL;
|
|
SDL_Cursor *working, *pointer;
|
|
|
|
psf_t *font = NULL;
|
|
|
|
/* help strings */
|
|
help_t helpkeys[] = {
|
|
{ ADDBLOCKS, " TAB \001 / \001 M " },
|
|
{ SELBLOCK, " 0 \001 .. \001 9 " },
|
|
{ FILL, " Enter " },
|
|
{ PAINT, " " },
|
|
{ LOADFROM, " L " },
|
|
{ SAVE, " S " },
|
|
{ SAVEAS, " Shift \001 + \001 S " },
|
|
{ SAVEPREVIEW, " P " },
|
|
{ CHANGEORIENT, " R " },
|
|
{ MIRROR, " F " },
|
|
{ ADDY, " X " },
|
|
{ DELY, " Ctrl \001 + \001 X " },
|
|
{ ADDZ, " C " },
|
|
{ DELZ, " Ctrl \001 + \001 C " },
|
|
{ ADDX, " V " },
|
|
{ DELX, " Ctrl \001 + \001 V " },
|
|
{ UNDO, " Z " },
|
|
{ REDO, " Y " },
|
|
{ BRUSH, " B " },
|
|
{ GRID, " ; " },
|
|
{ GROUNDLEVEL, " G " },
|
|
{ LAYERUP, " PgUp " },
|
|
{ LAYERDOWN, " PgDn " },
|
|
{ ZOOMOUT, " , \001 / \001 < " },
|
|
{ ZOOMIN, " . \001 / \001 > " },
|
|
{ SCROLL, " Ctrl \001 + \001\033\001 \001\030\001 \001\031\001 \001\032" }
|
|
};
|
|
|
|
/**
|
|
* Print string to screen
|
|
*/
|
|
void sdlprint(int x, int y, int fg, int bg, char *s)
|
|
{
|
|
unsigned char *glyph;
|
|
unsigned int c, offs, i, j, line, mask, bytesperline = (font->width + 7) / 8;
|
|
|
|
for(; *s && x < strmaxw;) {
|
|
if((*s & 128) != 0) {
|
|
if(!(*s & 32)) { c = ((*s & 0x1F)<<6)|(*(s+1) & 0x3F); s++; } else
|
|
if(!(*s & 16)) { c = ((*s & 0xF)<<12)|((*(s+1) & 0x3F)<<6)|(*(s+2) & 0x3F); s += 2; } else
|
|
if(!(*s & 8)) { c = ((*s & 0x7)<<18)|((*(s+1) & 0x3F)<<12)|((*(s+2) & 0x3F)<<6)|(*(s+3) & 0x3F); *s += 3; }
|
|
else c = 0;
|
|
} else c = *s;
|
|
s++;
|
|
if(c == 1) { fg += bg; bg = fg - bg; fg -= bg; continue; }
|
|
glyph = (unsigned char*)font + font->headersize + (c < font->numglyph ? c : 0) * font->bytesperglyph;
|
|
offs = (y * screen->pitch) + (x * 4);
|
|
for(j = 0; j < font->height; j++){
|
|
line = offs;
|
|
mask = 1<<(font->width-1);
|
|
for(i = 0; i < font->width && (int)(x + i) < strmaxw; i++){
|
|
*((uint32_t*)((uint8_t*)screen->pixels + line)) = theme[(*glyph & mask)?fg:bg];
|
|
mask >>= 1;
|
|
line += 4;
|
|
}
|
|
glyph += bytesperline;
|
|
offs += screen->pitch;
|
|
}
|
|
x += font->width + strsepar;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Draw help window
|
|
*/
|
|
void sdlhelp()
|
|
{
|
|
int i;
|
|
SDL_Rect rect;
|
|
|
|
i = screen->w * 3 / 4;
|
|
rect.w = mbstrlen(lang[HELP]) * (font->width+1) + 8;
|
|
if(i > rect.w) rect.w = i;
|
|
rect.h = ((int)(sizeof(helpkeys)/sizeof(helpkeys[0])) + 1) * (font->height + 4) + 8;
|
|
rect.x = (screen->w - rect.w)/2;
|
|
rect.y = (screen->h - rect.h)/2;
|
|
if(rect.x < 0 || rect.y < 0) { help = 0; return; }
|
|
SDL_FillRect(screen, &rect, theme[THEME_BG]);
|
|
rect.x += 4; rect.y += 4; strmaxw = rect.x + rect.w - 8;
|
|
|
|
for(i = 0; i < (int)(sizeof(helpkeys)/sizeof(helpkeys[0])); i++) {
|
|
strsepar = 0; sdlprint(rect.x, rect.y, THEME_BG, THEME_FG, helpkeys[i].key); strsepar = 1;
|
|
sdlprint(rect.x + 136, rect.y, THEME_FG, THEME_BG, lang[(int)helpkeys[i].text]);
|
|
rect.y += font->height + 4;
|
|
}
|
|
sdlprint(rect.x + (rect.w - mbstrlen(lang[HELP]) * (font->width+1)) / 2, rect.y, THEME_INACT, THEME_BG, lang[HELP]);
|
|
}
|
|
|
|
/**
|
|
* Redraw the toolbar
|
|
*/
|
|
void sdltoolbar()
|
|
{
|
|
int i, m;
|
|
char *s = status, str[16];
|
|
SDL_Rect src, dst;
|
|
|
|
strmaxw = screen->w - 5;
|
|
dst.x = dst.y = 0; dst.w = 36; dst.h = screen->h;
|
|
SDL_FillRect(screen, &dst, theme[THEME_BG]);
|
|
dst.x = 2; dst.y = 4 + 5*36 + 84; dst.w = 32; dst.h = screen->h - 3*font->height - 4 - 2*37 - dst.y;
|
|
SDL_FillRect(screen, &dst, theme[THEME_TABBG]);
|
|
|
|
/* layer up and down */
|
|
src.w = src.h = dst.w = dst.h = 32; src.x = 0; dst.x = 2;
|
|
dst.y = screen->h - 3*font->height - 2*37;
|
|
for(i = 0; i < 2; i++, dst.y += 36) {
|
|
src.y = (i+14) * 32;
|
|
dst.x--; dst.y--; dst.w += 2; dst.h += 2;
|
|
SDL_FillRect(screen, &dst, theme[(i+17) == activetool ? THEME_FG : ((i+17) == overtool ? THEME_INACT : THEME_BG)]);
|
|
dst.x++; dst.y++; dst.w -= 2; dst.h -= 2;
|
|
SDL_BlitSurface(icons, &src, screen, &dst);
|
|
}
|
|
/* load, save, preview */
|
|
dst.y = 2;
|
|
for(i = 0; i < 3; i++) {
|
|
src.y = (i+5) * 32;
|
|
dst.y = 4 + (i * 36);
|
|
dst.x--; dst.y--; dst.w += 2; dst.h += 2;
|
|
SDL_FillRect(screen, &dst, theme[i == activetool ? THEME_FG : (i == overtool ? THEME_INACT : THEME_BG)]);
|
|
dst.x++; dst.y++; dst.w -= 2; dst.h -= 2;
|
|
SDL_BlitSurface(icons, &src, screen, &dst);
|
|
}
|
|
/* rotate, flip, insert, remove, undo, redo, zoom */
|
|
dst.w = dst.h = 16;
|
|
for(i = 0; i < 10; i++) {
|
|
dst.x = 2 + (i & 1)*16;
|
|
dst.y = 4 + (3 * 36) + (i >> 1) * 16;
|
|
SDL_FillRect(screen, &dst, theme[(i+3) == activetool ? THEME_FG : ((i+3) == overtool ? THEME_INACT : THEME_BG)]);
|
|
}
|
|
src.y = 8 * 32; dst.x = 2; dst.y = 4 + (3 * 36); dst.w = 32; src.h = dst.h = 80;
|
|
SDL_BlitSurface(icons, &src, screen, &dst);
|
|
/* brush shape, all blocks (search blocks to add to palette) */
|
|
dst.w = dst.h = src.h = 32;
|
|
for(i = 0; i < 2; i++) {
|
|
src.y = (i+11) * 32;
|
|
dst.y = 88 + ((i+3) * 36);
|
|
dst.x--; dst.y--; dst.w += 2; dst.h += 2;
|
|
SDL_FillRect(screen, &dst, theme[(i + 15) == activetool ? THEME_FG : ((i + 15) == overtool ? THEME_INACT : THEME_BG)]);
|
|
dst.x++; dst.y++; dst.w -= 2; dst.h -= 2;
|
|
SDL_BlitSurface(icons, &src, screen, &dst);
|
|
}
|
|
/* blocks palette */
|
|
src.y = 13 * 32; dst.x = 2; dst.y = 4 + 5*36 + 84;
|
|
m = screen->h - 3*font->height - 2*37 - 4;
|
|
SDL_FillRect(screen, &dst, theme[!activeblock ? THEME_INACT : (!overblock ? THEME_INPBG : THEME_TABBG)]);
|
|
SDL_BlitSurface(icons, &src, screen, &dst);
|
|
src.y = 0; dst.y += 32;
|
|
for(i = 1; i < 16 && palette[i] && dst.y < m; dst.y += 32, i++) {
|
|
if(dst.y + dst.h > m) dst.h = src.h = m - dst.y;
|
|
SDL_FillRect(screen, &dst, theme[i == activeblock ? THEME_INACT : (i == overblock ? THEME_INPBG : THEME_TABBG)]);
|
|
blk->pixels = blocks[palette[i]].img ? blocks[palette[i]].img : (uint8_t*)icons->pixels + 32 * icons->pitch;
|
|
SDL_BlitSurface(blk, &src, screen, &dst);
|
|
}
|
|
dst.x = 36; dst.y = screen->h - font->height; dst.w = screen->w - 36; dst.h = font->height;
|
|
SDL_FillRect(screen, &dst, theme[THEME_BG]);
|
|
if(!status) {
|
|
if((activetool == -1 && overtool < -1) || overtool >= 0) s = lang[LOAD + overtool];
|
|
if(overblock != -1 && (!overblock || palette[overblock])) s = blocks[palette[overblock]].name;
|
|
}
|
|
/* ground layer */
|
|
dst.x = 2; dst.y = screen->h - 3*font->height; dst.w = 32; dst.h = font->height;
|
|
i = currlayer == gndlayer ? THEME_FG : THEME_TABBG;
|
|
SDL_FillRect(screen, &dst, theme[i]);
|
|
sdlprint(5, screen->h - 3*font->height, THEME_INACT, i, lang[GND]);
|
|
/* current layer */
|
|
dst.x = 2; dst.y = screen->h - 2*font->height; dst.w = 32; dst.h = font->height;
|
|
SDL_FillRect(screen, &dst, theme[THEME_BG]);
|
|
sprintf(str, "%4d", currlayer - gndlayer);
|
|
/* probability */
|
|
sdlprint(0, screen->h - 2*font->height, THEME_INACT, THEME_BG, str);
|
|
sprintf(str, "%3d%%", layerprob[currlayer] * 100 / 127);
|
|
sdlprint(2, screen->h - font->height, THEME_INACT, THEME_BG, str);
|
|
/* status bar */
|
|
src.x = 16; src.y = 8 * 32 + 80; dst.x = screen->w - 16 * font->width - 20 - 60; dst.y = screen->h - font->height / 2 - 8;
|
|
if(nodes[currlayer][cz][cx].param0 && dst.x >= 0) {
|
|
sprintf(str, "%02X %02X", nodes[currlayer][cz][cx].param1, nodes[currlayer][cz][cx].param2);
|
|
sdlprint(dst.x, screen->h - font->height, THEME_FG, THEME_BG, str);
|
|
} else if(overtool == -3) {
|
|
sprintf(str, "%3d", layerprob[currlayer]);
|
|
sdlprint(dst.x, screen->h - font->height, THEME_FG, THEME_BG, str);
|
|
} else if(overtool == -4) {
|
|
sprintf(str, "%3d", currlayer);
|
|
sdlprint(dst.x, screen->h - font->height, THEME_FG, THEME_BG, str);
|
|
}
|
|
dst.x += 5*font->width + 15;
|
|
if((nodes[currlayer][cz][cx].param1 & 0x80) && dst.x >= 0) {
|
|
strsepar = 0;
|
|
sdlprint(dst.x, screen->h - font->height, THEME_FG, THEME_BG, "\004\005");
|
|
strsepar = 1;
|
|
}
|
|
dst.x += 2*font->width + 4;
|
|
if(dst.x >= 0) {
|
|
src.w = src.h = dst.w = dst.h = 16;
|
|
SDL_BlitSurface(icons, &src, screen, &dst);
|
|
}
|
|
dst.x += 20;
|
|
if(dst.x >= 0) {
|
|
sprintf(str, "%3d%%", zoom * 100 / 128);
|
|
sdlprint(dst.x, screen->h - font->height, THEME_FG, THEME_BG, str);
|
|
}
|
|
dst.x += 4 * (font->width+2);
|
|
src.x = 0;
|
|
if(dst.x >= 0)
|
|
SDL_BlitSurface(icons, &src, screen, &dst);
|
|
dst.x += 24;
|
|
if(dst.x >= 0) {
|
|
sprintf(str, "%3d", brush_height());
|
|
sdlprint(dst.x, screen->h - font->height, THEME_FG, THEME_BG, str);
|
|
}
|
|
dst.x += 3 * (font->width+1);
|
|
if(dst.x >= 0) {
|
|
memcpy(str, "\xC2\x80\xC2\x80", 5);
|
|
strsepar = 0;
|
|
str[1] = 0x80 + (4*brush_type) + (2*brush_hollow);
|
|
str[3] = 0x81 + (4*brush_type) + (2*brush_hollow);
|
|
sdlprint(dst.x, screen->h - font->height, THEME_FG, THEME_BG, str);
|
|
strsepar = 1;
|
|
}
|
|
if(s)
|
|
sdlprint(42, screen->h - font->height, THEME_FG, THEME_BG, s);
|
|
}
|
|
|
|
/**
|
|
* Redraw the SDL window
|
|
*/
|
|
void sdlredraw()
|
|
{
|
|
SDL_Rect dst;
|
|
|
|
/* main window area */
|
|
if(!activetool) load_redraw(); else
|
|
if(!dx || !dz) {
|
|
dst.x = 36; dst.y = 0; dst.w = screen->w - 36; dst.h = screen->h - font->height;
|
|
SDL_FillRect(screen, &dst, theme[THEME_TABBG]);
|
|
} else {
|
|
switch(activetool) {
|
|
case 1: save_redraw(); break;
|
|
case 15: brush_redraw(); break;
|
|
case 16: search_redraw(); break;
|
|
default: edit_redraw(1); break;
|
|
}
|
|
}
|
|
|
|
/* toolbar and status bar */
|
|
sdltoolbar();
|
|
|
|
if(help) sdlhelp();
|
|
|
|
/* flush the window */
|
|
SDL_UpdateWindowSurface(window);
|
|
}
|
|
|
|
/**
|
|
* Set window title
|
|
*/
|
|
void sdltitle()
|
|
{
|
|
char *fn, *title;
|
|
fn = strrchr(mtsfile, DIRSEP);
|
|
if(fn) fn++; else fn = mtsfile;
|
|
title = (char*)malloc(strlen(fn) + 10);
|
|
sprintf(title, "MTSEdit: %s", fn);
|
|
SDL_SetWindowTitle(window, title);
|
|
free(title);
|
|
}
|
|
|
|
/**
|
|
* UI for various MTS operations
|
|
*/
|
|
void sdldo(int opt)
|
|
{
|
|
int i;
|
|
|
|
SDL_ShowCursor(1); systemcursor = 1;
|
|
SDL_SetCursor(working);
|
|
switch(opt) {
|
|
case -1: activetool = -1; break;
|
|
case -2: readschem(); if(mts_x && mts_y && mts_z) { sdltitle(); activetool = -1; activeblock = 0; } break;
|
|
case 0: activetool = 0; break;
|
|
case 1: mts_save(); activetool = -1; activeblock = 0; break;
|
|
case 2: mts_view(shift); break;
|
|
case 3:
|
|
case 4:
|
|
hist_prepare(opt == 4 ? HIST_ROTCCW : HIST_ROTCW, 0);
|
|
mts_rotate(4-opt); i = cx; if(opt == 3) { cx = cz; cz = 255 - i; } else { cx = 255 - cz; cz = i; }
|
|
hist_commit();
|
|
break;
|
|
case 5: hist_prepare(HIST_FLIP, 0); mts_flip(); hist_commit(); break;
|
|
case 6: hist_prepare(HIST_ADDY, currlayer); mts_addy(currlayer, shift); hist_commit(); break;
|
|
case 7: hist_prepare(HIST_DELY, currlayer); mts_dely(currlayer); hist_commit(); break;
|
|
case 8: hist_prepare(HIST_ADDZ, cz); mts_addz(cz, shift); hist_commit(); break;
|
|
case 9: hist_prepare(HIST_DELZ, cz); mts_delz(cz); hist_commit(); break;
|
|
case 10: hist_prepare(HIST_ADDX, cx); mts_addx(cx, shift); hist_commit(); break;
|
|
case 11: hist_prepare(HIST_DELX, cx); mts_delx(cx); hist_commit(); break;
|
|
case 12: mts_blueprint(shift); break;
|
|
}
|
|
SDL_SetCursor(pointer);
|
|
SDL_ShowCursor(0); systemcursor = 0;
|
|
sdlredraw();
|
|
}
|
|
|
|
/**
|
|
* The main SDL loop
|
|
*/
|
|
int sdlmain(int opt)
|
|
{
|
|
stbi__context s;
|
|
stbi__result_info ri;
|
|
unsigned char *icondata;
|
|
char *fn, *title;
|
|
int iw = 0, ih = 0, len, i, j, k, l;
|
|
SDL_Event event, lookahead;
|
|
|
|
/* this is tricky, because extern wouldn't know sizeof() */
|
|
if(opt == 7) return instmod(binary_mtsedit, sizeof(binary_mtsedit));
|
|
|
|
/* get our font */
|
|
font = (psf_t*)stbi_zlib_decode_malloc_guesssize_headerflag((const char*)binary_font_psf_gz + 10,
|
|
sizeof(binary_font_psf_gz) - 10, 32768, &len, 0);
|
|
if(!font) error(lang[ERR_MEM]);
|
|
|
|
/* as an additional dependency, blueprint needs the font */
|
|
if(opt) return mts_blueprint(shift);
|
|
|
|
/* initialize SDL */
|
|
SDL_Init(SDL_INIT_VIDEO);
|
|
fn = strrchr(mtsfile, DIRSEP);
|
|
if(fn) fn++; else fn = mtsfile;
|
|
title = (char*)malloc(strlen(fn) + 10);
|
|
sprintf(title, "MTSEdit: %s", fn);
|
|
window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_RESIZABLE);
|
|
free(title);
|
|
screen = SDL_GetWindowSurface(window);
|
|
|
|
working = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAITARROW);
|
|
pointer = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
|
|
|
|
/* get icons and surfaces */
|
|
s.read_from_callbacks = 0;
|
|
s.img_buffer = s.img_buffer_original = binary_icons_png;
|
|
s.img_buffer_end = s.img_buffer_original_end = binary_icons_png + sizeof(binary_icons_png);
|
|
ri.bits_per_channel = 8;
|
|
icondata = (uint8_t*)stbi__png_load(&s, &iw, &ih, &len, 0, &ri);
|
|
icons = SDL_CreateRGBSurfaceFrom((uint32_t*)icondata, iw, iw, 32, iw*4, 0xFF, 0xFF00, 0xFF0000, 0xFF000000);
|
|
SDL_SetWindowIcon(window, icons);
|
|
SDL_FreeSurface(icons);
|
|
icons = SDL_CreateRGBSurfaceFrom((uint32_t*)icondata, iw, ih, 32, iw*4, 0xFF, 0xFF00, 0xFF0000, 0xFF000000);
|
|
blk = SDL_CreateRGBSurfaceFrom(NULL, 32, 32, 32, 32*4, 0xFF, 0xFF00, 0xFF0000, 0xFF000000);
|
|
fg = SDL_CreateRGBSurface(0, screen->w - 36 + 64, screen->h - font->height + 64, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000);
|
|
cl = SDL_CreateRGBSurface(0, screen->w - 36 + 64, screen->h - font->height + 64, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000);
|
|
bg = SDL_CreateRGBSurface(0, screen->w - 36 + 64, screen->h - font->height + 64, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000);
|
|
memset(&histcurr, 0, sizeof(histlist_t));
|
|
dx = dz = 0;
|
|
|
|
/* draw window and loading message */
|
|
memset(palette, 0, sizeof(palette));
|
|
status = lang[LOADING];
|
|
SDL_SetCursor(working);
|
|
sdlredraw();
|
|
|
|
/* parse blocks.csv */
|
|
blocks_parse();
|
|
/* load schematics from file */
|
|
readschem();
|
|
if(!mts_y || !mts_y || !mts_x)
|
|
activetool = 0;
|
|
|
|
/* populate search window with default results (may include unknown blocks from the MTS) */
|
|
numresults = numblocks - 1;
|
|
results = (int*)malloc(numresults * sizeof(int));
|
|
for(i = 0; (int)i < numresults; i++) results[i] = i + 1;
|
|
/* clear block probability for air */
|
|
for(i = 0; i < 256; i++)
|
|
for(j = 0; j < 256; j++)
|
|
for(k = 0; k < 256; k++)
|
|
if(!nodes[i][j][k].param0) nodes[i][j][k].param1 = 0;
|
|
|
|
/* repaint window with the loaded MTS */
|
|
sdlredraw();
|
|
SDL_SetCursor(pointer);
|
|
SDL_ShowCursor(0);
|
|
SDL_StartTextInput();
|
|
|
|
/* main loop */
|
|
while (!quitting) {
|
|
if (SDL_WaitEvent(&event)) {
|
|
/* check if we have multiple mouse motion events in the queue, only serve the last */
|
|
if(event.type == SDL_MOUSEMOTION) {
|
|
lookahead.type = 0;
|
|
while(SDL_PollEvent(&lookahead) && lookahead.type == SDL_MOUSEMOTION)
|
|
memcpy(&event, &lookahead, sizeof(SDL_Event));
|
|
if(lookahead.type && lookahead.type != SDL_MOUSEMOTION)
|
|
SDL_PushEvent(&lookahead);
|
|
}
|
|
switch (event.type) {
|
|
/* window events */
|
|
case SDL_QUIT: quitting = 1; break;
|
|
case SDL_WINDOWEVENT:
|
|
switch(event.window.event) {
|
|
case SDL_WINDOWEVENT_CLOSE: quitting = 1; break;
|
|
case SDL_WINDOWEVENT_RESIZED:
|
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
|
SDL_FreeSurface(screen);
|
|
SDL_FreeSurface(fg);
|
|
SDL_FreeSurface(bg);
|
|
screen = SDL_GetWindowSurface(window);
|
|
fg = SDL_CreateRGBSurface(0, screen->w - 36 + 64, screen->h - font->height + 64, 32,
|
|
0xFF, 0xFF00, 0xFF0000, 0xFF000000);
|
|
cl = SDL_CreateRGBSurface(0, screen->w - 36 + 64, screen->h - font->height + 64, 32,
|
|
0xFF, 0xFF00, 0xFF0000, 0xFF000000);
|
|
bg = SDL_CreateRGBSurface(0, screen->w - 36 + 64, screen->h - font->height + 64, 32,
|
|
0xFF, 0xFF00, 0xFF0000, 0xFF000000);
|
|
sdlredraw();
|
|
break;
|
|
default: sdlredraw(); break;
|
|
}
|
|
break;
|
|
|
|
/* mouse events */
|
|
case SDL_MOUSEMOTION:
|
|
i = j = -1; status = NULL; help = 0;
|
|
if(event.motion.x >= 36 && event.motion.y < screen->h - (int)font->height &&
|
|
activetool == -1 && SDL_GetCursor() != working) {
|
|
if(systemcursor) SDL_ShowCursor(0);
|
|
systemcursor = 0;
|
|
} else {
|
|
if(!systemcursor) SDL_ShowCursor(1);
|
|
systemcursor = 1;
|
|
}
|
|
if(event.motion.x < 36) {
|
|
/* toolbar */
|
|
if(event.motion.y < 4 + 3 * 36) {
|
|
i = (event.motion.y > 3 ? event.motion.y - 4 : event.motion.y) / 36;
|
|
} else
|
|
if(event.motion.y < 4 + 3 * 36 + 80) {
|
|
i = 3 + ((((event.motion.y - 4 - 3 * 36) / 16) << 1) | (event.motion.x >= 18 ? 1 : 0));
|
|
} else
|
|
if(event.motion.y < 4 + 5 * 36 + 84) {
|
|
i = 15 + ((event.motion.y - 4 - 3 * 36 - 84) / 36);
|
|
} else
|
|
if(event.motion.y >= (int)(screen->h - font->height)) i = -3; else
|
|
if(event.motion.y >= (int)(screen->h - 2*font->height)) i = -4; else
|
|
if(event.motion.y >= (int)(screen->h - 3*font->height)) i = -2; else
|
|
if(event.motion.y >= (int)(screen->h - 3*font->height - 36)) i = 18; else
|
|
if(event.motion.y >= (int)(screen->h - 3*font->height - 2*36)) i = 17; else
|
|
if(event.motion.y < (int)(screen->h - 3*font->height - 2*36))
|
|
j = (event.motion.y - 4 - 5 * 36 - 88) / 32;
|
|
} else
|
|
if(event.motion.y > screen->h - (int)font->height) {
|
|
if(event.motion.x > screen->w - 9 * (int)font->width - 9 - 52 &&
|
|
event.motion.x < screen->w - 7 * (int)font->width - 2 - 32) i = 14;
|
|
if(event.motion.x > screen->w - 7 * (int)font->width - 7 - 32 &&
|
|
event.motion.x < screen->w - 5 * (int)font->width - 5 - 12) i = 13;
|
|
} else
|
|
if(activetool == 16) search_mouseover(&event); else
|
|
if(activetool == -1) {
|
|
if(event.motion.x > screen->w - 32 && event.motion.y >= (int)(screen->h - font->height - 32)) i = -5;
|
|
k = cx; l = cz;
|
|
edit_mouseover(&event);
|
|
if(k != cx || l != cz) {
|
|
edit_redraw(0);
|
|
sdltoolbar();
|
|
SDL_UpdateWindowSurface(window);
|
|
}
|
|
}
|
|
if(i != overtool || j != overblock) {
|
|
overtool = i;
|
|
overblock = j;
|
|
sdltoolbar();
|
|
SDL_UpdateWindowSurface(window);
|
|
}
|
|
break;
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
if(activetool == -1 && overtool == -1 && event.motion.x > 36) {
|
|
edit_mousedown(&event);
|
|
sdltoolbar();
|
|
SDL_UpdateWindowSurface(window);
|
|
} else
|
|
if(overtool == -3) mts_layerprob(event.button.button == 1 ? +1 : -1); else
|
|
if(overtool == -2) gndlayer = currlayer; else
|
|
if(overtool >= 0 || overblock != -1) {
|
|
if(overtool >= 0 && activetool != overtool) activetool = overtool;
|
|
else { activetool = -1; if(overblock != -1) activeblock = overblock; }
|
|
sdltoolbar();
|
|
SDL_UpdateWindowSurface(window);
|
|
}
|
|
switch(activetool) {
|
|
case 0: load_mousedown(&event); break;
|
|
case 1: save_mousedown(&event); break;
|
|
case 15:
|
|
if(event.motion.x > 36) {
|
|
if(!brush_mousedown(&event)) {
|
|
edit_mouseover(&event);
|
|
edit_redraw(0);
|
|
SDL_ShowCursor(0); systemcursor = 0; activetool = -1;
|
|
}
|
|
SDL_UpdateWindowSurface(window);
|
|
}
|
|
break;
|
|
case 16: search_mousedown(&event); break;
|
|
}
|
|
break;
|
|
case SDL_MOUSEBUTTONUP:
|
|
i = 1;
|
|
if(activetool != -1 && activetool == overtool) {
|
|
switch(activetool) {
|
|
case 2: sdldo(2); break;
|
|
case 3: sdldo(shift || event.button.button != 1 ? 4 : 3); break;
|
|
case 4: sdldo(5); break;
|
|
case 5: sdldo(6); break;
|
|
case 6: sdldo(7); break;
|
|
case 7: sdldo(8); break;
|
|
case 8: sdldo(9); break;
|
|
case 9: sdldo(10); break;
|
|
case 10: sdldo(11); break;
|
|
case 11: i = hist_undo(); break;
|
|
case 12: i = hist_redo(); break;
|
|
case 13: i = edit_zoomin(); break;
|
|
case 14: i = edit_zoomout(); break;
|
|
case 17: if(currlayer < 255) currlayer++; break;
|
|
case 18: if(currlayer > 0) currlayer--; break;
|
|
}
|
|
if(activetool != 0 && activetool != 1 && activetool != 15 && activetool != 16) activetool = -1;
|
|
}
|
|
if(i) sdlredraw();
|
|
break;
|
|
case SDL_MOUSEWHEEL:
|
|
i = 1;
|
|
if(overtool == -3) mts_layerprob(event.wheel.y); else
|
|
switch(activetool) {
|
|
case 0: load_scroll(&event); break;
|
|
case 1: save_scroll(&event); break;
|
|
case 16: search_scroll(&event); break;
|
|
case -1: i = edit_scroll(&event); break;
|
|
}
|
|
if(i) sdlredraw();
|
|
break;
|
|
|
|
/* handle the keyboard */
|
|
case SDL_KEYDOWN:
|
|
status = NULL;
|
|
if(event.key.keysym.sym == SDLK_LSHIFT || event.key.keysym.sym == SDLK_RSHIFT) shift = 1;
|
|
if(event.key.keysym.sym == SDLK_LCTRL || event.key.keysym.sym == SDLK_RCTRL) ctrl = 1;
|
|
if(!help) {
|
|
if(activetool != -1 && event.key.keysym.sym == SDLK_ESCAPE) {
|
|
if(activetool == 15) brush_setmask(1);
|
|
SDL_ShowCursor(0);
|
|
systemcursor = 0;
|
|
activetool = -1;
|
|
} else
|
|
if(activetool != 0 && activetool != 1 && activetool != 15 && activetool != 16) edit_key(&event);
|
|
}
|
|
break;
|
|
case SDL_TEXTINPUT:
|
|
case SDL_KEYUP:
|
|
if(event.key.keysym.sym == SDLK_LSHIFT || event.key.keysym.sym == SDLK_RSHIFT) shift = 0;
|
|
if(event.key.keysym.sym == SDLK_LCTRL || event.key.keysym.sym == SDLK_RCTRL) ctrl = 0;
|
|
if(event.key.keysym.sym == SDLK_F1) { help ^= 1; sdlredraw(); break; }
|
|
if(!help) {
|
|
i = 0;
|
|
switch(activetool) {
|
|
case 0: load_key(&event); break;
|
|
case 1: save_key(&event); break;
|
|
case 15: brush_key(&event); break;
|
|
case 16: search_key(&event); break;
|
|
default:
|
|
if(event.key.keysym.sym == SDLK_f) sdldo(5); else
|
|
if(event.key.keysym.sym == SDLK_m || event.key.keysym.sym == SDLK_TAB) activetool = 16;
|
|
if(event.key.keysym.sym == SDLK_b) activetool = 15;
|
|
if(shift && event.key.keysym.sym == SDLK_s) activetool = 1;
|
|
break;
|
|
}
|
|
if(!i) sdlredraw();
|
|
else {
|
|
edit_redraw(0);
|
|
sdltoolbar();
|
|
SDL_UpdateWindowSurface(window);
|
|
}
|
|
} else {
|
|
help = 0;
|
|
sdlredraw();
|
|
}
|
|
break;
|
|
}
|
|
if(activetool != -1 || overtool != -1 || SDL_GetCursor() == working) {
|
|
if(!systemcursor) SDL_ShowCursor(1);
|
|
systemcursor = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* cleanup SDL */
|
|
SDL_StopTextInput();
|
|
SDL_FreeCursor(working);
|
|
SDL_FreeCursor(pointer);
|
|
SDL_FreeSurface(icons);
|
|
SDL_FreeSurface(blk);
|
|
SDL_FreeSurface(fg);
|
|
SDL_FreeSurface(cl);
|
|
SDL_FreeSurface(bg);
|
|
SDL_Quit();
|
|
hist_free(-1, -1);
|
|
free(icondata);
|
|
free(font);
|
|
blocks_free();
|
|
return 0;
|
|
}
|