// for finding memory leaks in debug mode with Visual Studio #if defined _DEBUG && defined _MSC_VER#include <crtdbg.h>#endif #include <stdint.h>#include <stdbool.h>#ifndef _WIN32#include <unistd.h>#endif#include <stdio.h>#include "pt2_helpers.h"#include "pt2_diskop.h"#include "pt2_sampler.h"#include "pt2_module_saver.h"#include "pt2_edit.h"#include "pt2_sample_saver.h"#include "pt2_visuals.h"#include "pt2_tables.h"#include "pt2_audio.h"#include "pt2_textout.h"#include "pt2_keyboard.h"#include "pt2_config.h"#include "pt2_bmp.h"#include "pt2_sampling.h"#include "pt2_chordmaker.h"#include "pt2_pat2smp.h"#include "pt2_mod2wav.h"#include "pt2_askbox.h"#include "pt2_replayer.h"#include "pt2_posed.h"#include "pt2_textedit.h" SDL_Cursor *cursors[NUM_CURSORS]; // globalized static int32_t checkGUIButtons(void);static bool handleRightMouseButton(void);static bool handleLeftMouseButton(void);static bool handleGUIButtons(int32_t button);static void handleRepeatedGUIButtons(void);static void handleRepeatedSamplerFilterButtons(void); void sampleUpButton(void){ if (editor.sampleZero) { editor.sampleZero = false; editor.currSample = 0; } else if (editor.currSample < 30) { editor.currSample++; } updateCurrSample();} void sampleDownButton(void){ if (!editor.sampleZero && editor.currSample > 0) { editor.currSample--; updateCurrSample(); }} static void pointerSetColor(uint8_t cursorColorIndex){ assert(cursorColorIndex <= 5); video.palette[PAL_MOUSE_1] = cursorColors[cursorColorIndex][0]; video.palette[PAL_MOUSE_2] = cursorColors[cursorColorIndex][1]; video.palette[PAL_MOUSE_3] = cursorColors[cursorColorIndex][2]; if (config.hwMouse) setSystemCursor(cursors[cursorColorIndex]);} void updatePointerColor(void){ switch (ui.pointerMode) { case POINTER_MODE_IDLE: pointerSetColor(POINTER_GRAY); break; case POINTER_MODE_PLAY: pointerSetColor(POINTER_YELLOW); break; case POINTER_MODE_EDIT: pointerSetColor(POINTER_BLUE); break; case POINTER_MODE_RECORD: pointerSetColor(POINTER_BLUE); break; case POINTER_MODE_MSG1: pointerSetColor(POINTER_PURPLE); break; case POINTER_MODE_MSG2: pointerSetColor(POINTER_GREEN); break; default: break; }} void pointerSetMode(uint8_t pointerMode, bool carry){ assert(pointerMode <= 5); ui.pointerMode = pointerMode; if (carry) ui.previousPointerMode = ui.pointerMode; updatePointerColor();} void pointerSetModeThreadSafe(uint8_t pointerMode, bool carry){ assert(pointerMode <= 5); ui.pointerMode = pointerMode; if (carry) ui.previousPointerMode = ui.pointerMode; // in hardware mouse mode, the pointer color can only be changed from the main thread if (config.hwMouse) mouse.updatePointerColorFlag = true; else updatePointerColor();} void pointerSetPreviousMode(void){ if (ui.editTextFlag || ui.askBoxShown) pointerSetMode(POINTER_MODE_MSG1, NO_CARRY); else pointerSetMode(ui.previousPointerMode, NO_CARRY);} void setMsgPointer(void){ pointerSetMode(POINTER_MODE_MSG2, false);} void setErrPointer(void){ pointerSetColor(POINTER_RED);} bool setSystemCursor(SDL_Cursor *cur){ if (cur == NULL) { SDL_SetCursor(SDL_GetDefaultCursor()); return false; } SDL_SetCursor(cur); return true;} void freeMouseCursors(void){ SDL_SetCursor(SDL_GetDefaultCursor()); for (uint32_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(); uint32_t scaleFactor = video.yScale; if (scaleFactor > 8) // just in case scaleFactor = 8; for (uint32_t i = 0; i < NUM_CURSORS; i++) { SDL_Surface *surface = SDL_CreateRGBSurface(0, POINTER_W*scaleFactor, POINTER_H*scaleFactor, 32, 0, 0, 0, 0); if (surface == NULL) { freeMouseCursors(); config.hwMouse = false; // enable software mouse return false; } uint32_t color1 = cursorColors[i][0]; uint32_t color2 = cursorColors[i][1]; uint32_t color3 = cursorColors[i][2]; uint32_t colorkey = 0x12345678; color1 = SDL_MapRGB(surface->format, R24(color1), G24(color1), B24(color1)); color2 = SDL_MapRGB(surface->format, R24(color2), G24(color2), B24(color2)); color3 = SDL_MapRGB(surface->format, R24(color3), G24(color3), B24(color3)); colorkey = SDL_MapRGB(surface->format, R24(colorkey), G24(colorkey), B24(colorkey)); SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE); SDL_SetColorKey(surface, SDL_TRUE, colorkey); SDL_SetSurfaceRLE(surface, SDL_TRUE); const uint8_t *srcPixels8 = mousePointerBMP; 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 (uint32_t y = 0; y < POINTER_H; y++) { uint32_t *outX = &dstPixels32[(y * scaleFactor) * surface->w]; for (uint32_t yScale = 0; yScale < scaleFactor; yScale++) { for (uint32_t x = 0; x < POINTER_W; x++) { uint8_t srcPix = srcPixels8[(y * POINTER_W) + x]; if (srcPix != PAL_COLORKEY) { uint32_t pixel = colorkey; // make compiler happy if (srcPix == PAL_MOUSE_1) pixel = color1; else if (srcPix == PAL_MOUSE_2) pixel = color2; else if (srcPix == PAL_MOUSE_3) pixel = color3; for (uint32_t xScale = 0; xScale < scaleFactor; xScale++) outX[xScale] = pixel; } outX += scaleFactor; } } } SDL_UnlockSurface(surface); cursors[i] = SDL_CreateColorCursor(surface, 0, 0); if (cursors[i] == NULL) { SDL_FreeSurface(surface); freeMouseCursors(); config.hwMouse = false; // enable software mouse return false; } SDL_FreeSurface(surface); } pointerSetPreviousMode(); // this sets the appropriate the hardware cursor return true;} void updateMouseScaling(void){ if (video.renderW > 0) video.fMouseXMul = (float)SCREEN_W / video.renderW; if (video.renderH > 0) video.fMouseYMul = (float)SCREEN_H / video.renderH;} void readMouseXY(void){ int32_t mx, my, windowX, windowY; if (mouse.updatePointerColorFlag) // used when changing pointer color from other threads { mouse.updatePointerColorFlag = false; updatePointerColor(); } if (mouse.setPosFlag) { if (!video.windowHidden) SDL_WarpMouseInWindow(video.window, mouse.setPosX, mouse.setPosY); mouse.setPosFlag = false; return; } if (video.useDesktopMouseCoords) { mouse.buttonState = SDL_GetGlobalMouseState(&mx, &my); // convert desktop coords to window coords SDL_GetWindowPosition(video.window, &windowX, &windowY); mx -= windowX; my -= windowY; } else { // special mode for KMSDRM (XXX: Confirm that this still works...) mouse.buttonState = SDL_GetMouseState(&mx, &my); } mouse.rawX = mx; mouse.rawY = my; if (video.fullscreen) { // centered fullscreen mode (not stretched) needs further coord translation if (!config.fullScreenStretch) { // if software mouse is enabled, warp mouse inside render space if (!config.hwMouse) { bool warpMouse = false; if (mx < video.renderX) { mx = video.renderX; warpMouse = true; } else if (mx >= video.renderX+video.renderW) { mx = (video.renderX + video.renderW) - 1; warpMouse = true; } if (my < video.renderY) { my = video.renderY; warpMouse = true; } else if (my >= video.renderY+video.renderH) { my = (video.renderY + video.renderH) - 1; warpMouse = true; } if (warpMouse) SDL_WarpMouseInWindow(video.window, mx, my); } // convert fullscreen coords to window (centered image) coords mx -= video.renderX; my -= video.renderY; } } // multiply coords by video upscaling factors (don't round) mouse.x = (int32_t)(mx * video.fMouseXMul); mouse.y = (int32_t)(my * video.fMouseYMul); if (config.hwMouse) { // hardware mouse mode (OS) hideSprite(SPRITE_MOUSE_POINTER); } else { // software mouse mode (PT mouse) setSpritePos(SPRITE_MOUSE_POINTER, mouse.x, mouse.y); }} void mouseButtonUpHandler(uint8_t mouseButton){ mouse.buttonWaitCounter = 0; mouse.buttonWaiting = false; if (mouseButton == SDL_BUTTON_LEFT) { mouse.leftButtonPressed = false; ui.forceSampleDrag = false; ui.forceVolDrag = false; ui.leftLoopPinMoving = false; ui.rightLoopPinMoving = false; ui.sampleMarkingPos = -1; switch (mouse.lastGUIButton) { case PTB_SLENGTHU: case PTB_SLENGTHD: { if (ui.samplerScreenShown) redrawSample(); recalcChordLength(); updateSamplePos(); ui.updateSongSize = true; } break; case PTB_LENGTHU: case PTB_LENGTHD: case PTB_PATTERNU: case PTB_PATTERND: { ui.updateSongSize = true; if (ui.posEdScreenShown) ui.updatePosEd = true; } break; default: break; } mouse.lastGUIButton = -1; mouse.lastSmpFilterButton = -1; mouse.lastSamplingButton = -1; } if (mouseButton == SDL_BUTTON_RIGHT) { mouse.rightButtonPressed = false; ui.forceSampleEdit = false; }} void mouseButtonDownHandler(uint8_t mouseButton){ if (mouseButton == SDL_BUTTON_LEFT) { mouse.leftButtonPressed = true; mouse.buttonWaiting = true; } if (mouseButton == SDL_BUTTON_RIGHT) mouse.rightButtonPressed = true; // when red mouse pointer (error), block further input for a while if (editor.errorMsgActive && editor.errorMsgBlock) return; if (handleRightMouseButton() || handleLeftMouseButton()) return; handleTextEditing(mouseButton);} void handleGUIButtonRepeat(void){ if (!mouse.leftButtonPressed) { // left mouse button released, stop repeating buttons mouse.repeatCounter = 0; return; } if (ui.samplerFiltersBoxShown) { handleRepeatedSamplerFilterButtons(); return; } if (ui.samplingBoxShown) { handleRepeatedSamplingButtons(); return; } if (mouse.lastGUIButton != checkGUIButtons()) // FIXME: This can potentially do a ton of iterations, bad design! { // only repeat the button that was first clicked (e.g. if you hold and move mouse to another button) mouse.repeatCounter = 0; return; } handleRepeatedGUIButtons(); mouse.repeatCounter++;} static void edNote1UpButton(void){ if (mouse.rightButtonPressed) editor.note1 += 12; else editor.note1++; if (editor.note1 > 36) editor.note1 = 36; ui.updateChordNote1Text = true; recalcChordLength();} static void edNote1DownButton(void){ if (mouse.rightButtonPressed) editor.note1 -= 12; else editor.note1--; if (editor.note1 < 0) editor.note1 = 0; ui.updateChordNote1Text = true; recalcChordLength();} static void edNote2UpButton(void){ if (mouse.rightButtonPressed) editor.note2 += 12; else editor.note2++; if (editor.note2 > 36) editor.note2 = 36; ui.updateChordNote2Text = true; recalcChordLength();} static void edNote2DownButton(void){Lines 1–500 of 4698. Load more
// for finding memory leaks in debug mode with Visual Studio #if defined _DEBUG && defined _MSC_VER #include <crtdbg.h> #endif #include <stdint.h> #include <stdbool.h> #ifndef _WIN32 #include <unistd.h> #endif #include <stdio.h> #include "pt2_helpers.h" #include "pt2_diskop.h" #include "pt2_sampler.h" #include "pt2_module_saver.h" #include "pt2_edit.h" #include "pt2_sample_saver.h" #include "pt2_visuals.h" #include "pt2_tables.h" #include "pt2_audio.h" #include "pt2_textout.h" #include "pt2_keyboard.h" #include "pt2_config.h" #include "pt2_bmp.h" #include "pt2_sampling.h" #include "pt2_chordmaker.h" #include "pt2_pat2smp.h" #include "pt2_mod2wav.h" #include "pt2_askbox.h" #include "pt2_replayer.h" #include "pt2_posed.h" #include "pt2_textedit.h" SDL_Cursor *cursors[NUM_CURSORS]; // globalized static int32_t checkGUIButtons(void); static bool handleRightMouseButton(void); static bool handleLeftMouseButton(void); static bool handleGUIButtons(int32_t button); static void handleRepeatedGUIButtons(void); static void handleRepeatedSamplerFilterButtons(void); void sampleUpButton(void) { if (editor.sampleZero) { editor.sampleZero = false; editor.currSample = 0; } else if (editor.currSample < 30) { editor.currSample++; } updateCurrSample(); } void sampleDownButton(void) { if (!editor.sampleZero && editor.currSample > 0) { editor.currSample--; updateCurrSample(); } } static void pointerSetColor(uint8_t cursorColorIndex) { assert(cursorColorIndex <= 5); video.palette[PAL_MOUSE_1] = cursorColors[cursorColorIndex][0]; video.palette[PAL_MOUSE_2] = cursorColors[cursorColorIndex][1]; video.palette[PAL_MOUSE_3] = cursorColors[cursorColorIndex][2]; if (config.hwMouse) setSystemCursor(cursors[cursorColorIndex]); } void updatePointerColor(void) { switch (ui.pointerMode) { case POINTER_MODE_IDLE: pointerSetColor(POINTER_GRAY); break; case POINTER_MODE_PLAY: pointerSetColor(POINTER_YELLOW); break; case POINTER_MODE_EDIT: pointerSetColor(POINTER_BLUE); break; case POINTER_MODE_RECORD: pointerSetColor(POINTER_BLUE); break; case POINTER_MODE_MSG1: pointerSetColor(POINTER_PURPLE); break; case POINTER_MODE_MSG2: pointerSetColor(POINTER_GREEN); break; default: break; } } void pointerSetMode(uint8_t pointerMode, bool carry) { assert(pointerMode <= 5); ui.pointerMode = pointerMode; if (carry) ui.previousPointerMode = ui.pointerMode; updatePointerColor(); } void pointerSetModeThreadSafe(uint8_t pointerMode, bool carry) { assert(pointerMode <= 5); ui.pointerMode = pointerMode; if (carry) ui.previousPointerMode = ui.pointerMode; // in hardware mouse mode, the pointer color can only be changed from the main thread if (config.hwMouse) mouse.updatePointerColorFlag = true; else updatePointerColor(); } void pointerSetPreviousMode(void) { if (ui.editTextFlag || ui.askBoxShown) pointerSetMode(POINTER_MODE_MSG1, NO_CARRY); else pointerSetMode(ui.previousPointerMode, NO_CARRY); } void setMsgPointer(void) { pointerSetMode(POINTER_MODE_MSG2, false); } void setErrPointer(void) { pointerSetColor(POINTER_RED); } bool setSystemCursor(SDL_Cursor *cur) { if (cur == NULL) { SDL_SetCursor(SDL_GetDefaultCursor()); return false; } SDL_SetCursor(cur); return true; } void freeMouseCursors(void) { SDL_SetCursor(SDL_GetDefaultCursor()); for (uint32_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(); uint32_t scaleFactor = video.yScale; if (scaleFactor > 8) // just in case scaleFactor = 8; for (uint32_t i = 0; i < NUM_CURSORS; i++) { SDL_Surface *surface = SDL_CreateRGBSurface(0, POINTER_W*scaleFactor, POINTER_H*scaleFactor, 32, 0, 0, 0, 0); if (surface == NULL) { freeMouseCursors(); config.hwMouse = false; // enable software mouse return false; } uint32_t color1 = cursorColors[i][0]; uint32_t color2 = cursorColors[i][1]; uint32_t color3 = cursorColors[i][2]; uint32_t colorkey = 0x12345678; color1 = SDL_MapRGB(surface->format, R24(color1), G24(color1), B24(color1)); color2 = SDL_MapRGB(surface->format, R24(color2), G24(color2), B24(color2)); color3 = SDL_MapRGB(surface->format, R24(color3), G24(color3), B24(color3)); colorkey = SDL_MapRGB(surface->format, R24(colorkey), G24(colorkey), B24(colorkey)); SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE); SDL_SetColorKey(surface, SDL_TRUE, colorkey); SDL_SetSurfaceRLE(surface, SDL_TRUE); const uint8_t *srcPixels8 = mousePointerBMP; 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 (uint32_t y = 0; y < POINTER_H; y++) { uint32_t *outX = &dstPixels32[(y * scaleFactor) * surface->w]; for (uint32_t yScale = 0; yScale < scaleFactor; yScale++) { for (uint32_t x = 0; x < POINTER_W; x++) { uint8_t srcPix = srcPixels8[(y * POINTER_W) + x]; if (srcPix != PAL_COLORKEY) { uint32_t pixel = colorkey; // make compiler happy if (srcPix == PAL_MOUSE_1) pixel = color1; else if (srcPix == PAL_MOUSE_2) pixel = color2; else if (srcPix == PAL_MOUSE_3) pixel = color3; for (uint32_t xScale = 0; xScale < scaleFactor; xScale++) outX[xScale] = pixel; } outX += scaleFactor; } } } SDL_UnlockSurface(surface); cursors[i] = SDL_CreateColorCursor(surface, 0, 0); if (cursors[i] == NULL) { SDL_FreeSurface(surface); freeMouseCursors(); config.hwMouse = false; // enable software mouse return false; } SDL_FreeSurface(surface); } pointerSetPreviousMode(); // this sets the appropriate the hardware cursor return true; } void updateMouseScaling(void) { if (video.renderW > 0) video.fMouseXMul = (float)SCREEN_W / video.renderW; if (video.renderH > 0) video.fMouseYMul = (float)SCREEN_H / video.renderH; } void readMouseXY(void) { int32_t mx, my, windowX, windowY; if (mouse.updatePointerColorFlag) // used when changing pointer color from other threads { mouse.updatePointerColorFlag = false; updatePointerColor(); } if (mouse.setPosFlag) { if (!video.windowHidden) SDL_WarpMouseInWindow(video.window, mouse.setPosX, mouse.setPosY); mouse.setPosFlag = false; return; } if (video.useDesktopMouseCoords) { mouse.buttonState = SDL_GetGlobalMouseState(&mx, &my); // convert desktop coords to window coords SDL_GetWindowPosition(video.window, &windowX, &windowY); mx -= windowX; my -= windowY; } else { // special mode for KMSDRM (XXX: Confirm that this still works...) mouse.buttonState = SDL_GetMouseState(&mx, &my); } mouse.rawX = mx; mouse.rawY = my; if (video.fullscreen) { // centered fullscreen mode (not stretched) needs further coord translation if (!config.fullScreenStretch) { // if software mouse is enabled, warp mouse inside render space if (!config.hwMouse) { bool warpMouse = false; if (mx < video.renderX) { mx = video.renderX; warpMouse = true; } else if (mx >= video.renderX+video.renderW) { mx = (video.renderX + video.renderW) - 1; warpMouse = true; } if (my < video.renderY) { my = video.renderY; warpMouse = true; } else if (my >= video.renderY+video.renderH) { my = (video.renderY + video.renderH) - 1; warpMouse = true; } if (warpMouse) SDL_WarpMouseInWindow(video.window, mx, my); } // convert fullscreen coords to window (centered image) coords mx -= video.renderX; my -= video.renderY; } } // multiply coords by video upscaling factors (don't round) mouse.x = (int32_t)(mx * video.fMouseXMul); mouse.y = (int32_t)(my * video.fMouseYMul); if (config.hwMouse) { // hardware mouse mode (OS) hideSprite(SPRITE_MOUSE_POINTER); } else { // software mouse mode (PT mouse) setSpritePos(SPRITE_MOUSE_POINTER, mouse.x, mouse.y); } } void mouseButtonUpHandler(uint8_t mouseButton) { mouse.buttonWaitCounter = 0; mouse.buttonWaiting = false; if (mouseButton == SDL_BUTTON_LEFT) { mouse.leftButtonPressed = false; ui.forceSampleDrag = false; ui.forceVolDrag = false; ui.leftLoopPinMoving = false; ui.rightLoopPinMoving = false; ui.sampleMarkingPos = -1; switch (mouse.lastGUIButton) { case PTB_SLENGTHU: case PTB_SLENGTHD: { if (ui.samplerScreenShown) redrawSample(); recalcChordLength(); updateSamplePos(); ui.updateSongSize = true; } break; case PTB_LENGTHU: case PTB_LENGTHD: case PTB_PATTERNU: case PTB_PATTERND: { ui.updateSongSize = true; if (ui.posEdScreenShown) ui.updatePosEd = true; } break; default: break; } mouse.lastGUIButton = -1; mouse.lastSmpFilterButton = -1; mouse.lastSamplingButton = -1; } if (mouseButton == SDL_BUTTON_RIGHT) { mouse.rightButtonPressed = false; ui.forceSampleEdit = false; } } void mouseButtonDownHandler(uint8_t mouseButton) { if (mouseButton == SDL_BUTTON_LEFT) { mouse.leftButtonPressed = true; mouse.buttonWaiting = true; } if (mouseButton == SDL_BUTTON_RIGHT) mouse.rightButtonPressed = true; // when red mouse pointer (error), block further input for a while if (editor.errorMsgActive && editor.errorMsgBlock) return; if (handleRightMouseButton() || handleLeftMouseButton()) return; handleTextEditing(mouseButton); } void handleGUIButtonRepeat(void) { if (!mouse.leftButtonPressed) { // left mouse button released, stop repeating buttons mouse.repeatCounter = 0; return; } if (ui.samplerFiltersBoxShown) { handleRepeatedSamplerFilterButtons(); return; } if (ui.samplingBoxShown) { handleRepeatedSamplingButtons(); return; } if (mouse.lastGUIButton != checkGUIButtons()) // FIXME: This can potentially do a ton of iterations, bad design! { // only repeat the button that was first clicked (e.g. if you hold and move mouse to another button) mouse.repeatCounter = 0; return; } handleRepeatedGUIButtons(); mouse.repeatCounter++; } static void edNote1UpButton(void) { if (mouse.rightButtonPressed) editor.note1 += 12; else editor.note1++; if (editor.note1 > 36) editor.note1 = 36; ui.updateChordNote1Text = true; recalcChordLength(); } static void edNote1DownButton(void) { if (mouse.rightButtonPressed) editor.note1 -= 12; else editor.note1--; if (editor.note1 < 0) editor.note1 = 0; ui.updateChordNote1Text = true; recalcChordLength(); } static void edNote2UpButton(void) { if (mouse.rightButtonPressed) editor.note2 += 12; else editor.note2++; if (editor.note2 > 36) editor.note2 = 36; ui.updateChordNote2Text = true; recalcChordLength(); } static void edNote2DownButton(void) {