mtsedit/src/sdl.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;
}