// for finding memory leaks in debug mode with Visual Studio#if defined _DEBUG && defined _MSC_VER#include <crtdbg.h>#endif #include <stdio.h>#include <stdbool.h>#include "ft2_header.h"#include "ft2_gui.h"#include "ft2_video.h"#include "scopes/ft2_scopes.h"#include "ft2_help.h"#include "ft2_sample_ed.h"#include "ft2_inst_ed.h"#include "ft2_pattern_ed.h"#include "ft2_mouse.h"#include "ft2_config.h"#include "ft2_diskop.h"#include "ft2_audioselector.h"#include "ft2_midi.h"#include "ft2_bmp.h"#include "ft2_structs.h" #define NUM_CURSORS 6 mouse_t mouse; // globalized static bool mouseBusyGfxBackwards;static int16_t mouseShape;static int32_t mouseModeGfxOffs, mouseBusyGfxFrame;static SDL_Cursor *cursors[NUM_CURSORS]; static bool setSystemCursor(SDL_Cursor *cur){ if (config.specialFlags2 & USE_OS_MOUSE_POINTER) { SDL_SetCursor(SDL_GetDefaultCursor()); return true; } if (cur == NULL) { SDL_SetCursor(SDL_GetDefaultCursor()); return false; } SDL_SetCursor(cur); return true;} void freeMouseCursors(void){ SDL_SetCursor(SDL_GetDefaultCursor()); for (int32_t i = 0; i < NUM_CURSORS; i++) { if (cursors[i] != NULL) { SDL_FreeCursor(cursors[i]); cursors[i] = NULL; } }} bool createMouseCursors(void) // creates scaled SDL surfaces for current mouse pointer shape{ freeMouseCursors(); const uint8_t *cursorsSrc = bmp.mouseCursors; switch (config.mouseType) { case MOUSE_IDLE_SHAPE_NICE: cursorsSrc += 0 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; case MOUSE_IDLE_SHAPE_UGLY: cursorsSrc += 1 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; case MOUSE_IDLE_SHAPE_AWFUL: cursorsSrc += 2 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; case MOUSE_IDLE_SHAPE_USABLE: cursorsSrc += 3 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; default: break; } for (int32_t i = 0; i < NUM_CURSORS; i++) { int32_t scaleFactor = video.yScale; if (scaleFactor > 8) // just in case scaleFactor = 8; SDL_Surface *surface = SDL_CreateRGBSurface(0, MOUSE_CURSOR_W*scaleFactor, MOUSE_CURSOR_H*scaleFactor, 32, 0, 0, 0, 0); if (surface == NULL) { freeMouseCursors(); if (config.specialFlags2 & USE_OS_MOUSE_POINTER) { SDL_ShowCursor(SDL_TRUE); } else { // enable software mouse config.specialFlags2 &= ~HARDWARE_MOUSE; SDL_ShowCursor(SDL_FALSE); } return false; } const uint32_t colorkey = SDL_MapRGB(surface->format, 0x00, 0xFF, 0x00); // colorkey const uint32_t fg = SDL_MapRGB(surface->format, 0xFF, 0xFF, 0xFF); // foreground const uint32_t border = SDL_MapRGB(surface->format, 0x00, 0x00, 0x00); // border SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE); SDL_SetColorKey(surface, SDL_TRUE, colorkey); SDL_SetSurfaceRLE(surface, SDL_TRUE); const uint8_t *srcPixels8; if (i == 3) // text edit cursor srcPixels8 = &bmp.mouseCursors[12 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H)]; else if (i == 4) // mouse busy (wall clock) srcPixels8 = &bmp.mouseCursorBusyClock[2 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H)]; // pick a good still-frame else if (i == 5) // mouse busy (hourglass) srcPixels8 = &bmp.mouseCursorBusyGlass[2 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H)]; // pick a good still-frame else // normal idle cursor + disk op. "delete/rename" cursors srcPixels8 = &cursorsSrc[i * (4 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H))]; SDL_LockSurface(surface); uint32_t *dstPixels32 = (uint32_t *)surface->pixels; for (int32_t k = 0; k < surface->w*surface->h; k++) // fill surface with colorkey pixels dstPixels32[k] = colorkey; // blit upscaled cursor to surface for (int32_t y = 0; y < MOUSE_CURSOR_H; y++) { uint32_t *outX = &dstPixels32[(y * scaleFactor) * surface->w]; for (int32_t yScale = 0; yScale < scaleFactor; yScale++) { const uint8_t *srcPtr = &srcPixels8[y * MOUSE_CURSOR_W]; for (int32_t x = 0; x < MOUSE_CURSOR_W; x++) { const uint8_t srcPix = srcPtr[x]; if (srcPix != PAL_TRANSPR) { uint32_t pixel = colorkey; if (srcPix == PAL_MOUSEPT) pixel = fg; else if (srcPix == PAL_BCKGRND) pixel = border; for (int32_t xScale = 0; xScale < scaleFactor; xScale++) outX[xScale] = pixel; } outX += scaleFactor; } } } SDL_UnlockSurface(surface); uint32_t hotX = 0; uint32_t hotY = 0; if (i == 3) // text edit cursor bias { hotX = 2 * video.xScale; hotY = 6 * video.yScale; } cursors[i] = SDL_CreateColorCursor(surface, hotX, hotY); if (cursors[i] == NULL) { SDL_FreeSurface(surface); freeMouseCursors(); if (config.specialFlags2 & USE_OS_MOUSE_POINTER) { SDL_ShowCursor(SDL_TRUE); } else { // enable software mouse config.specialFlags2 &= ~HARDWARE_MOUSE; SDL_ShowCursor(SDL_FALSE); } return false; } SDL_FreeSurface(surface); } if (config.specialFlags2 & HARDWARE_MOUSE) { if (mouse.mode == MOUSE_MODE_NORMAL) setSystemCursor(cursors[0]); else if (mouse.mode == MOUSE_MODE_DELETE) setSystemCursor(cursors[1]); else if (mouse.mode == MOUSE_MODE_RENAME) setSystemCursor(cursors[2]); SDL_ShowCursor(SDL_TRUE); } else { SDL_ShowCursor(SDL_FALSE); } return true;} void setMousePosToCenter(void){ if (video.fullscreen) { mouse.setPosX = video.displayW >> 1; mouse.setPosY = video.displayH >> 1; } else { mouse.setPosX = video.renderW >> 1; mouse.setPosY = video.renderH >> 1; } mouse.setPosFlag = true;} void animateBusyMouse(void){ if (config.mouseAnimType == MOUSE_BUSY_SHAPE_CLOCK) { if (config.specialFlags2 & HARDWARE_MOUSE) { setSystemCursor(cursors[4]); return; } if ((editor.framesPassed % 7) == 6) { if (mouseBusyGfxBackwards) { if (--mouseBusyGfxFrame <= 0) { mouseBusyGfxFrame = 0; mouseBusyGfxBackwards = false; } } else { if (++mouseBusyGfxFrame >= MOUSE_CLOCK_ANI_FRAMES-1) { mouseBusyGfxFrame = MOUSE_CLOCK_ANI_FRAMES - 1; mouseBusyGfxBackwards = true; } } changeSpriteData(SPRITE_MOUSE_POINTER, &bmp.mouseCursorBusyClock[(mouseBusyGfxFrame % MOUSE_CLOCK_ANI_FRAMES) * (MOUSE_CURSOR_W * MOUSE_CURSOR_H)]); } } else { if (config.specialFlags2 & HARDWARE_MOUSE) { setSystemCursor(cursors[5]); return; } if ((editor.framesPassed % 5) == 4) { mouseBusyGfxFrame = (mouseBusyGfxFrame + 1) % MOUSE_GLASS_ANI_FRAMES; changeSpriteData(SPRITE_MOUSE_POINTER, &bmp.mouseCursorBusyGlass[mouseBusyGfxFrame * (MOUSE_CURSOR_W * MOUSE_CURSOR_H)]); } }} void setMouseShape(int16_t shape){ const uint8_t *gfxPtr; if (editor.busy) { if (config.mouseAnimType == MOUSE_BUSY_SHAPE_CLOCK) gfxPtr = &bmp.mouseCursorBusyClock[(mouseBusyGfxFrame % MOUSE_GLASS_ANI_FRAMES) * (MOUSE_CURSOR_W * MOUSE_CURSOR_H)]; else gfxPtr = &bmp.mouseCursorBusyGlass[(mouseBusyGfxFrame % MOUSE_CLOCK_ANI_FRAMES) * (MOUSE_CURSOR_W * MOUSE_CURSOR_H)]; } else { gfxPtr = &bmp.mouseCursors[mouseModeGfxOffs]; switch (shape) { case MOUSE_IDLE_SHAPE_NICE: gfxPtr += 0 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; case MOUSE_IDLE_SHAPE_UGLY: gfxPtr += 1 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; case MOUSE_IDLE_SHAPE_AWFUL: gfxPtr += 2 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; case MOUSE_IDLE_SHAPE_USABLE: gfxPtr += 3 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; case MOUSE_IDLE_TEXT_EDIT: gfxPtr += 12 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; default: return; } } mouseShape = shape; changeSpriteData(SPRITE_MOUSE_POINTER, gfxPtr); if (config.specialFlags2 & HARDWARE_MOUSE) { if (mouse.mode == MOUSE_MODE_NORMAL) setSystemCursor(cursors[0]); else if (mouse.mode == MOUSE_MODE_DELETE) setSystemCursor(cursors[1]); else if (mouse.mode == MOUSE_MODE_RENAME) setSystemCursor(cursors[2]); }} static void setTextEditMouse(void){ setMouseShape(MOUSE_IDLE_TEXT_EDIT); mouse.xBias = -2; mouse.yBias = -6; if (config.specialFlags2 & HARDWARE_MOUSE) setSystemCursor(cursors[3]);} static void clearTextEditMouse(void){ setMouseShape(config.mouseType); mouse.xBias = 0; mouse.yBias = 0; if (config.specialFlags2 & HARDWARE_MOUSE) setSystemCursor(cursors[0]);} static void changeCursorIfOverTextBoxes(void){ int32_t i; mouse.mouseOverTextBox = false; if (editor.busy || mouse.mode != MOUSE_MODE_NORMAL) return; const int32_t mx = mouse.x; const int32_t my = mouse.y; textBox_t *t = textBoxes; for (i = 0; i < NUM_TEXTBOXES; i++, t++) { if (ui.sysReqShown && i != 0) // Sys. Req can only have one (special) text box continue; if (!t->visible) continue; if (!t->changeMouseCursor && (!editor.editTextFlag || i != mouse.lastEditBox)) continue; // some kludge of sorts if (my >= t->y && my < t->y+t->h && mx >= t->x && mx < t->x+t->w) { mouse.mouseOverTextBox = true; if (mouseShape != MOUSE_IDLE_TEXT_EDIT) setTextEditMouse(); return; } } // we're not inside a text edit box, set back mouse cursor if (i == NUM_TEXTBOXES && mouseShape == MOUSE_IDLE_TEXT_EDIT) clearTextEditMouse();} void setMouseMode(uint8_t mode){ switch (mode) { case MOUSE_MODE_NORMAL: { mouse.mode = mode; mouseModeGfxOffs = 0 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); } break; case MOUSE_MODE_DELETE: { mouse.mode = mode; mouseModeGfxOffs = 4 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); } break; case MOUSE_MODE_RENAME: { mouse.mode = mode; mouseModeGfxOffs = 8 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); } break; default: return; } setMouseShape(config.mouseType);} void resetMouseBusyAnimation(void){ mouseBusyGfxBackwards = false; mouseBusyGfxFrame = 0;} void setMouseBusy(bool busy) // can be called from other threads{ if (busy) { ui.setMouseIdle = false; ui.setMouseBusy = true; } else { ui.setMouseBusy = false; ui.setMouseIdle = true; }} void mouseAnimOn(void){ ui.setMouseBusy = false; ui.setMouseIdle = false; editor.busy = true; setMouseShape(config.mouseAnimType);} void mouseAnimOff(void){ ui.setMouseBusy = false; ui.setMouseIdle = false; editor.busy = false; setMouseShape(config.mouseType);} static void mouseWheelDecRow(void){ if (songPlaying) return; int16_t row = editor.row - 1; if (row < 0) row = patternNumRows[editor.editPattern] - 1; setPos(-1, row, true);} static void mouseWheelIncRow(void){ if (songPlaying) return; int16_t row = editor.row + 1; if (row >= patternNumRows[editor.editPattern]) row = 0; setPos(-1, row, true);} void mouseWheelHandler(bool directionUp){ if (ui.sysReqShown || editor.editTextFlag) return; if (ui.extended) { if (mouse.y <= 52) { if (mouse.x <= 111) directionUp ? decSongPos() : incSongPos(); else if (mouse.x >= 386) directionUp ? decCurIns() : incCurIns(); } else { directionUp ? mouseWheelDecRow() : mouseWheelIncRow(); } return; } if (mouse.y < 173) { // top screens if (ui.helpScreenShown) { // help screen if (directionUp) { helpScrollUp(); helpScrollUp(); } else { helpScrollDown(); helpScrollDown(); } } else if (ui.diskOpShown) { // disk op - 3x speed if (mouse.x <= 355) { if (directionUp) { pbDiskOpListUp(); pbDiskOpListUp(); pbDiskOpListUp(); } else { pbDiskOpListDown(); pbDiskOpListDown(); pbDiskOpListDown(); } } } else if (ui.configScreenShown) {Lines 1–500 of 918. Load more
// for finding memory leaks in debug mode with Visual Studio #if defined _DEBUG && defined _MSC_VER #include <crtdbg.h> #endif #include <stdio.h> #include <stdbool.h> #include "ft2_header.h" #include "ft2_gui.h" #include "ft2_video.h" #include "scopes/ft2_scopes.h" #include "ft2_help.h" #include "ft2_sample_ed.h" #include "ft2_inst_ed.h" #include "ft2_pattern_ed.h" #include "ft2_mouse.h" #include "ft2_config.h" #include "ft2_diskop.h" #include "ft2_audioselector.h" #include "ft2_midi.h" #include "ft2_bmp.h" #include "ft2_structs.h" #define NUM_CURSORS 6 mouse_t mouse; // globalized static bool mouseBusyGfxBackwards; static int16_t mouseShape; static int32_t mouseModeGfxOffs, mouseBusyGfxFrame; static SDL_Cursor *cursors[NUM_CURSORS]; static bool setSystemCursor(SDL_Cursor *cur) { if (config.specialFlags2 & USE_OS_MOUSE_POINTER) { SDL_SetCursor(SDL_GetDefaultCursor()); return true; } if (cur == NULL) { SDL_SetCursor(SDL_GetDefaultCursor()); return false; } SDL_SetCursor(cur); return true; } void freeMouseCursors(void) { SDL_SetCursor(SDL_GetDefaultCursor()); for (int32_t i = 0; i < NUM_CURSORS; i++) { if (cursors[i] != NULL) { SDL_FreeCursor(cursors[i]); cursors[i] = NULL; } } } bool createMouseCursors(void) // creates scaled SDL surfaces for current mouse pointer shape { freeMouseCursors(); const uint8_t *cursorsSrc = bmp.mouseCursors; switch (config.mouseType) { case MOUSE_IDLE_SHAPE_NICE: cursorsSrc += 0 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; case MOUSE_IDLE_SHAPE_UGLY: cursorsSrc += 1 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; case MOUSE_IDLE_SHAPE_AWFUL: cursorsSrc += 2 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; case MOUSE_IDLE_SHAPE_USABLE: cursorsSrc += 3 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; default: break; } for (int32_t i = 0; i < NUM_CURSORS; i++) { int32_t scaleFactor = video.yScale; if (scaleFactor > 8) // just in case scaleFactor = 8; SDL_Surface *surface = SDL_CreateRGBSurface(0, MOUSE_CURSOR_W*scaleFactor, MOUSE_CURSOR_H*scaleFactor, 32, 0, 0, 0, 0); if (surface == NULL) { freeMouseCursors(); if (config.specialFlags2 & USE_OS_MOUSE_POINTER) { SDL_ShowCursor(SDL_TRUE); } else { // enable software mouse config.specialFlags2 &= ~HARDWARE_MOUSE; SDL_ShowCursor(SDL_FALSE); } return false; } const uint32_t colorkey = SDL_MapRGB(surface->format, 0x00, 0xFF, 0x00); // colorkey const uint32_t fg = SDL_MapRGB(surface->format, 0xFF, 0xFF, 0xFF); // foreground const uint32_t border = SDL_MapRGB(surface->format, 0x00, 0x00, 0x00); // border SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE); SDL_SetColorKey(surface, SDL_TRUE, colorkey); SDL_SetSurfaceRLE(surface, SDL_TRUE); const uint8_t *srcPixels8; if (i == 3) // text edit cursor srcPixels8 = &bmp.mouseCursors[12 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H)]; else if (i == 4) // mouse busy (wall clock) srcPixels8 = &bmp.mouseCursorBusyClock[2 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H)]; // pick a good still-frame else if (i == 5) // mouse busy (hourglass) srcPixels8 = &bmp.mouseCursorBusyGlass[2 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H)]; // pick a good still-frame else // normal idle cursor + disk op. "delete/rename" cursors srcPixels8 = &cursorsSrc[i * (4 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H))]; SDL_LockSurface(surface); uint32_t *dstPixels32 = (uint32_t *)surface->pixels; for (int32_t k = 0; k < surface->w*surface->h; k++) // fill surface with colorkey pixels dstPixels32[k] = colorkey; // blit upscaled cursor to surface for (int32_t y = 0; y < MOUSE_CURSOR_H; y++) { uint32_t *outX = &dstPixels32[(y * scaleFactor) * surface->w]; for (int32_t yScale = 0; yScale < scaleFactor; yScale++) { const uint8_t *srcPtr = &srcPixels8[y * MOUSE_CURSOR_W]; for (int32_t x = 0; x < MOUSE_CURSOR_W; x++) { const uint8_t srcPix = srcPtr[x]; if (srcPix != PAL_TRANSPR) { uint32_t pixel = colorkey; if (srcPix == PAL_MOUSEPT) pixel = fg; else if (srcPix == PAL_BCKGRND) pixel = border; for (int32_t xScale = 0; xScale < scaleFactor; xScale++) outX[xScale] = pixel; } outX += scaleFactor; } } } SDL_UnlockSurface(surface); uint32_t hotX = 0; uint32_t hotY = 0; if (i == 3) // text edit cursor bias { hotX = 2 * video.xScale; hotY = 6 * video.yScale; } cursors[i] = SDL_CreateColorCursor(surface, hotX, hotY); if (cursors[i] == NULL) { SDL_FreeSurface(surface); freeMouseCursors(); if (config.specialFlags2 & USE_OS_MOUSE_POINTER) { SDL_ShowCursor(SDL_TRUE); } else { // enable software mouse config.specialFlags2 &= ~HARDWARE_MOUSE; SDL_ShowCursor(SDL_FALSE); } return false; } SDL_FreeSurface(surface); } if (config.specialFlags2 & HARDWARE_MOUSE) { if (mouse.mode == MOUSE_MODE_NORMAL) setSystemCursor(cursors[0]); else if (mouse.mode == MOUSE_MODE_DELETE) setSystemCursor(cursors[1]); else if (mouse.mode == MOUSE_MODE_RENAME) setSystemCursor(cursors[2]); SDL_ShowCursor(SDL_TRUE); } else { SDL_ShowCursor(SDL_FALSE); } return true; } void setMousePosToCenter(void) { if (video.fullscreen) { mouse.setPosX = video.displayW >> 1; mouse.setPosY = video.displayH >> 1; } else { mouse.setPosX = video.renderW >> 1; mouse.setPosY = video.renderH >> 1; } mouse.setPosFlag = true; } void animateBusyMouse(void) { if (config.mouseAnimType == MOUSE_BUSY_SHAPE_CLOCK) { if (config.specialFlags2 & HARDWARE_MOUSE) { setSystemCursor(cursors[4]); return; } if ((editor.framesPassed % 7) == 6) { if (mouseBusyGfxBackwards) { if (--mouseBusyGfxFrame <= 0) { mouseBusyGfxFrame = 0; mouseBusyGfxBackwards = false; } } else { if (++mouseBusyGfxFrame >= MOUSE_CLOCK_ANI_FRAMES-1) { mouseBusyGfxFrame = MOUSE_CLOCK_ANI_FRAMES - 1; mouseBusyGfxBackwards = true; } } changeSpriteData(SPRITE_MOUSE_POINTER, &bmp.mouseCursorBusyClock[(mouseBusyGfxFrame % MOUSE_CLOCK_ANI_FRAMES) * (MOUSE_CURSOR_W * MOUSE_CURSOR_H)]); } } else { if (config.specialFlags2 & HARDWARE_MOUSE) { setSystemCursor(cursors[5]); return; } if ((editor.framesPassed % 5) == 4) { mouseBusyGfxFrame = (mouseBusyGfxFrame + 1) % MOUSE_GLASS_ANI_FRAMES; changeSpriteData(SPRITE_MOUSE_POINTER, &bmp.mouseCursorBusyGlass[mouseBusyGfxFrame * (MOUSE_CURSOR_W * MOUSE_CURSOR_H)]); } } } void setMouseShape(int16_t shape) { const uint8_t *gfxPtr; if (editor.busy) { if (config.mouseAnimType == MOUSE_BUSY_SHAPE_CLOCK) gfxPtr = &bmp.mouseCursorBusyClock[(mouseBusyGfxFrame % MOUSE_GLASS_ANI_FRAMES) * (MOUSE_CURSOR_W * MOUSE_CURSOR_H)]; else gfxPtr = &bmp.mouseCursorBusyGlass[(mouseBusyGfxFrame % MOUSE_CLOCK_ANI_FRAMES) * (MOUSE_CURSOR_W * MOUSE_CURSOR_H)]; } else { gfxPtr = &bmp.mouseCursors[mouseModeGfxOffs]; switch (shape) { case MOUSE_IDLE_SHAPE_NICE: gfxPtr += 0 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; case MOUSE_IDLE_SHAPE_UGLY: gfxPtr += 1 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; case MOUSE_IDLE_SHAPE_AWFUL: gfxPtr += 2 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; case MOUSE_IDLE_SHAPE_USABLE: gfxPtr += 3 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; case MOUSE_IDLE_TEXT_EDIT: gfxPtr += 12 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); break; default: return; } } mouseShape = shape; changeSpriteData(SPRITE_MOUSE_POINTER, gfxPtr); if (config.specialFlags2 & HARDWARE_MOUSE) { if (mouse.mode == MOUSE_MODE_NORMAL) setSystemCursor(cursors[0]); else if (mouse.mode == MOUSE_MODE_DELETE) setSystemCursor(cursors[1]); else if (mouse.mode == MOUSE_MODE_RENAME) setSystemCursor(cursors[2]); } } static void setTextEditMouse(void) { setMouseShape(MOUSE_IDLE_TEXT_EDIT); mouse.xBias = -2; mouse.yBias = -6; if (config.specialFlags2 & HARDWARE_MOUSE) setSystemCursor(cursors[3]); } static void clearTextEditMouse(void) { setMouseShape(config.mouseType); mouse.xBias = 0; mouse.yBias = 0; if (config.specialFlags2 & HARDWARE_MOUSE) setSystemCursor(cursors[0]); } static void changeCursorIfOverTextBoxes(void) { int32_t i; mouse.mouseOverTextBox = false; if (editor.busy || mouse.mode != MOUSE_MODE_NORMAL) return; const int32_t mx = mouse.x; const int32_t my = mouse.y; textBox_t *t = textBoxes; for (i = 0; i < NUM_TEXTBOXES; i++, t++) { if (ui.sysReqShown && i != 0) // Sys. Req can only have one (special) text box continue; if (!t->visible) continue; if (!t->changeMouseCursor && (!editor.editTextFlag || i != mouse.lastEditBox)) continue; // some kludge of sorts if (my >= t->y && my < t->y+t->h && mx >= t->x && mx < t->x+t->w) { mouse.mouseOverTextBox = true; if (mouseShape != MOUSE_IDLE_TEXT_EDIT) setTextEditMouse(); return; } } // we're not inside a text edit box, set back mouse cursor if (i == NUM_TEXTBOXES && mouseShape == MOUSE_IDLE_TEXT_EDIT) clearTextEditMouse(); } void setMouseMode(uint8_t mode) { switch (mode) { case MOUSE_MODE_NORMAL: { mouse.mode = mode; mouseModeGfxOffs = 0 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); } break; case MOUSE_MODE_DELETE: { mouse.mode = mode; mouseModeGfxOffs = 4 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); } break; case MOUSE_MODE_RENAME: { mouse.mode = mode; mouseModeGfxOffs = 8 * (MOUSE_CURSOR_W * MOUSE_CURSOR_H); } break; default: return; } setMouseShape(config.mouseType); } void resetMouseBusyAnimation(void) { mouseBusyGfxBackwards = false; mouseBusyGfxFrame = 0; } void setMouseBusy(bool busy) // can be called from other threads { if (busy) { ui.setMouseIdle = false; ui.setMouseBusy = true; } else { ui.setMouseBusy = false; ui.setMouseIdle = true; } } void mouseAnimOn(void) { ui.setMouseBusy = false; ui.setMouseIdle = false; editor.busy = true; setMouseShape(config.mouseAnimType); } void mouseAnimOff(void) { ui.setMouseBusy = false; ui.setMouseIdle = false; editor.busy = false; setMouseShape(config.mouseType); } static void mouseWheelDecRow(void) { if (songPlaying) return; int16_t row = editor.row - 1; if (row < 0) row = patternNumRows[editor.editPattern] - 1; setPos(-1, row, true); } static void mouseWheelIncRow(void) { if (songPlaying) return; int16_t row = editor.row + 1; if (row >= patternNumRows[editor.editPattern]) row = 0; setPos(-1, row, true); } void mouseWheelHandler(bool directionUp) { if (ui.sysReqShown || editor.editTextFlag) return; if (ui.extended) { if (mouse.y <= 52) { if (mouse.x <= 111) directionUp ? decSongPos() : incSongPos(); else if (mouse.x >= 386) directionUp ? decCurIns() : incCurIns(); } else { directionUp ? mouseWheelDecRow() : mouseWheelIncRow(); } return; } if (mouse.y < 173) { // top screens if (ui.helpScreenShown) { // help screen if (directionUp) { helpScrollUp(); helpScrollUp(); } else { helpScrollDown(); helpScrollDown(); } } else if (ui.diskOpShown) { // disk op - 3x speed if (mouse.x <= 355) { if (directionUp) { pbDiskOpListUp(); pbDiskOpListUp(); pbDiskOpListUp(); } else { pbDiskOpListDown(); pbDiskOpListDown(); pbDiskOpListDown(); } } } else if (ui.configScreenShown) {