diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e2f5ee5b..a9ed390bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -587,6 +587,10 @@ extern/igfd/ImGuiFileDialog.cpp src/gui/plot_nolerp.cpp +src/gui/render.cpp +src/gui/render/abstract.cpp +src/gui/render/renderSDL.cpp + src/gui/font_exo.cpp src/gui/font_liberationSans.cpp src/gui/font_mononoki.cpp diff --git a/src/gui/chanOsc.cpp b/src/gui/chanOsc.cpp index 7bcece959..f697a1421 100644 --- a/src/gui/chanOsc.cpp +++ b/src/gui/chanOsc.cpp @@ -152,10 +152,10 @@ void FurnaceGUI::drawChanOsc() { if (chanOscUseGrad) { if (chanOscGradTex==NULL) { - chanOscGradTex=SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,SDL_TEXTUREACCESS_STREAMING,chanOscGrad.width,chanOscGrad.height); + chanOscGradTex=rend->createTexture(true,chanOscGrad.width,chanOscGrad.height); if (chanOscGradTex==NULL) { - logE("error while creating gradient texture! %s",SDL_GetError()); + logE("error while creating gradient texture!"); } else { updateChanOscGradTex=true; } @@ -170,10 +170,10 @@ void FurnaceGUI::drawChanOsc() { if (chanOscGradTex!=NULL) { if (updateChanOscGradTex) { chanOscGrad.render(); - if (SDL_UpdateTexture(chanOscGradTex,NULL,chanOscGrad.grad.get(),chanOscGrad.width*4)==0) { + if (rend->updateTexture(chanOscGradTex,chanOscGrad.grad.get(),chanOscGrad.width*4)) { updateChanOscGradTex=false; } else { - logE("error while updating gradient texture! %s",SDL_GetError()); + logE("error while updating gradient texture!"); } } diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 614066a11..3781f289e 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -3537,8 +3537,8 @@ bool FurnaceGUI::loop() { } } // update canvas size as well - if (SDL_GetRendererOutputSize(sdlRend,&canvasW,&canvasH)!=0) { - logW("loop: error while getting output size! %s",SDL_GetError()); + if (!rend->getOutputSize(canvasW,canvasH)) { + logW("loop: error while getting output size!"); } else { //logV("updateWindow: canvas size %dx%d",canvasW,canvasH); // and therefore window size @@ -4418,7 +4418,7 @@ bool FurnaceGUI::loop() { portrait=(scrWgetOutputSize(canvasW,canvasH); #endif if (patternOpen) nextWindow=GUI_WINDOW_PATTERN; #ifdef __APPLE__ @@ -5796,30 +5796,24 @@ bool FurnaceGUI::loop() { } } - SDL_SetRenderDrawColor(sdlRend,uiColors[GUI_COLOR_BACKGROUND].x*255, - uiColors[GUI_COLOR_BACKGROUND].y*255, - uiColors[GUI_COLOR_BACKGROUND].z*255, - uiColors[GUI_COLOR_BACKGROUND].w*255); - SDL_RenderClear(sdlRend); + rend->clear(uiColors[GUI_COLOR_BACKGROUND]); renderTimeBegin=SDL_GetPerformanceCounter(); ImGui::Render(); renderTimeEnd=SDL_GetPerformanceCounter(); - ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData()); + rend->renderGUI(); if (mustClear) { - SDL_RenderClear(sdlRend); + rend->clear(ImVec4(0,0,0,0)); mustClear--; } else { if (initialScreenWipe>0.0f && !settings.disableFadeIn) { WAKE_UP; initialScreenWipe-=ImGui::GetIO().DeltaTime*5.0f; if (initialScreenWipe>0.0f) { - SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_BLEND); - SDL_SetRenderDrawColor(sdlRend,0,0,0,255*pow(initialScreenWipe,2.0f)); - SDL_RenderFillRect(sdlRend,NULL); + rend->wipe(pow(initialScreenWipe,2.0f)); } } } - SDL_RenderPresent(sdlRend); + rend->present(); layoutTimeDelta=layoutTimeEnd-layoutTimeBegin; renderTimeDelta=renderTimeEnd-renderTimeBegin; @@ -6186,22 +6180,27 @@ bool FurnaceGUI::init() { SDL_SetHint(SDL_HINT_RENDER_DRIVER,settings.renderDriver.c_str()); } - sdlRend=SDL_CreateRenderer(sdlWin,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC|SDL_RENDERER_TARGETTEXTURE); - - if (sdlRend==NULL) { - lastError=fmt::sprintf("could not init renderer! %s",SDL_GetError()); - if (!settings.renderDriver.empty()) { - settings.renderDriver=""; - e->setConf("renderDriver",""); + if (!initRender()) { + if (settings.renderBackend=="OpenGL") { + settings.renderBackend=""; + e->setConf("renderBackend",""); e->saveConf(); - lastError=fmt::sprintf("\r\nthe render driver has been set to a safe value. please restart Furnace."); + lastError=fmt::sprintf("\r\nthe render backend has been set to a safe value. please restart Furnace."); + } else { + lastError=fmt::sprintf("could not init renderer! %s",SDL_GetError()); + if (!settings.renderDriver.empty()) { + settings.renderDriver=""; + e->setConf("renderDriver",""); + e->saveConf(); + lastError=fmt::sprintf("\r\nthe render driver has been set to a safe value. please restart Furnace."); + } } return false; } // try acquiring the canvas size - if (SDL_GetRendererOutputSize(sdlRend,&canvasW,&canvasH)!=0) { - logW("could not get renderer output size! %s",SDL_GetError()); + if (!rend->getOutputSize(canvasW,canvasH)) { + logW("could not get renderer output size!"); } else { logV("canvas size: %dx%d",canvasW,canvasH); } @@ -6213,11 +6212,7 @@ bool FurnaceGUI::init() { } } - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - - ImGui_ImplSDL2_InitForSDLRenderer(sdlWin,sdlRend); - ImGui_ImplSDLRenderer_Init(sdlRend); + rend->initGUI(sdlWin); applyUISettings(); @@ -6439,10 +6434,10 @@ void FurnaceGUI::commitState() { bool FurnaceGUI::finish() { commitState(); - ImGui_ImplSDLRenderer_Shutdown(); + rend->quitGUI(); ImGui_ImplSDL2_Shutdown(); ImGui::DestroyContext(); - SDL_DestroyRenderer(sdlRend); + quitRender(); SDL_DestroyWindow(sdlWin); if (vibrator) { @@ -6463,7 +6458,6 @@ bool FurnaceGUI::finish() { FurnaceGUI::FurnaceGUI(): e(NULL), sdlWin(NULL), - sdlRend(NULL), vibrator(NULL), vibratorAvailable(false), sampleTex(NULL), diff --git a/src/gui/gui.h b/src/gui/gui.h index 296014e16..ac8908cd3 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -70,6 +70,11 @@ #define FM_PREVIEW_SIZE 512 +enum FurnaceGUIRenderBackend { + GUI_BACKEND_SDL=0, + GUI_BACKEND_GL +}; + // TODO: // - add colors for FM envelope and waveform // - maybe add "alternate" color for FM modulators/carriers (a bit difficult) @@ -1191,7 +1196,7 @@ struct FurnaceGUIQueryResult { struct FurnaceGUIImage { unsigned char* data; - SDL_Texture* tex; + void* tex; int width, height, ch; FurnaceGUIImage(): @@ -1213,15 +1218,45 @@ struct FurnaceGUIPerfMetric { elapsed(0) {} }; +enum FurnaceGUIBlendMode { + GUI_BLEND_MODE_NONE=0, + GUI_BLEND_MODE_BLEND, + GUI_BLEND_MODE_ADD, + GUI_BLEND_MODE_MULTIPLY +}; + +class FurnaceGUIRender { + public: + virtual bool lockTexture(void* which, void** data, int* pitch); + virtual bool unlockTexture(void* which); + virtual bool updateTexture(void* which, void* data, int pitch); + virtual void* createTexture(bool dynamic, int width, int height); + virtual bool destroyTexture(void* which); + virtual void setTextureBlendMode(void* which, FurnaceGUIBlendMode mode); + virtual void setBlendMode(FurnaceGUIBlendMode mode); + virtual void clear(ImVec4 color); + virtual void renderGUI(); + virtual void wipe(float alpha); + virtual void present(); + virtual bool getOutputSize(int& w, int& h); + virtual bool init(SDL_Window* win); + virtual void initGUI(SDL_Window* win); + virtual void quitGUI(); + virtual bool quit(); + virtual ~FurnaceGUIRender(); +}; + class FurnaceGUI { DivEngine* e; + FurnaceGUIRenderBackend renderBackend; + FurnaceGUIRender* rend; + SDL_Window* sdlWin; - SDL_Renderer* sdlRend; SDL_Haptic* vibrator; bool vibratorAvailable; - - SDL_Texture* sampleTex; + + void* sampleTex; int sampleTexW, sampleTexH; bool updateSampleTex; @@ -1454,6 +1489,7 @@ class FurnaceGUI { String midiInDevice; String midiOutDevice; String c163Name; + String renderBackend; String renderDriver; String initialSysName; String noteOffLabel; @@ -1601,6 +1637,7 @@ class FurnaceGUI { midiInDevice(""), midiOutDevice(""), c163Name(""), + renderBackend(""), renderDriver(""), initialSysName("Sega Genesis/Mega Drive"), noteOffLabel("OFF"), @@ -1887,7 +1924,7 @@ class FurnaceGUI { bool chanOscWaveCorr, chanOscOptions, updateChanOscGradTex, chanOscUseGrad; ImVec4 chanOscColor; Gradient2D chanOscGrad; - SDL_Texture* chanOscGradTex; + void* chanOscGradTex; float chanOscLP0[DIV_MAX_CHANS]; float chanOscLP1[DIV_MAX_CHANS]; float chanOscVol[DIV_MAX_CHANS]; @@ -2040,7 +2077,7 @@ class FurnaceGUI { void highlightWindow(const char* winName); FurnaceGUIImage* getImage(FurnaceGUIImages image); - SDL_Texture* getTexture(FurnaceGUIImages image, SDL_BlendMode blendMode=SDL_BLENDMODE_BLEND); + void* getTexture(FurnaceGUIImages image, FurnaceGUIBlendMode blendMode=GUI_BLEND_MODE_BLEND); void drawImage(ImDrawList* dl, FurnaceGUIImages image, const ImVec2& pos, const ImVec2& scale, double rotate, const ImVec2& uvMin, const ImVec2& uvMax, const ImVec4& imgColor); void drawMobileControls(); @@ -2189,6 +2226,9 @@ class FurnaceGUI { String encodeKeyMap(std::map& map); void decodeKeyMap(std::map& map, String source); + bool initRender(); + bool quitRender(); + const char* getSystemName(DivSystem which); public: diff --git a/src/gui/image.cpp b/src/gui/image.cpp index 976504b84..a075d8ac6 100644 --- a/src/gui/image.cpp +++ b/src/gui/image.cpp @@ -49,7 +49,7 @@ const unsigned int imageLen[GUI_IMAGE_MAX]={ image_pat_size }; -SDL_Texture* FurnaceGUI::getTexture(FurnaceGUIImages image, SDL_BlendMode blendMode) { +void* FurnaceGUI::getTexture(FurnaceGUIImages image, FurnaceGUIBlendMode blendMode) { FurnaceGUIImage* img=getImage(image); if (img==NULL) return NULL; @@ -57,14 +57,14 @@ SDL_Texture* FurnaceGUI::getTexture(FurnaceGUIImages image, SDL_BlendMode blendM if (img->width<=0 || img->height<=0) return NULL; if (img->tex==NULL) { - img->tex=SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,SDL_TEXTUREACCESS_STATIC,img->width,img->height); + img->tex=rend->createTexture(false,img->width,img->height); if (img->tex==NULL) { logE("error while creating image %d texture! %s",(int)image,SDL_GetError()); return NULL; } - SDL_SetTextureBlendMode(img->tex,blendMode); + rend->setTextureBlendMode(img->tex,blendMode); - if (SDL_UpdateTexture(img->tex,NULL,img->data,img->width*4)!=0) { + if (!rend->updateTexture(img->tex,img->data,img->width*4)) { logE("error while updating texture of image %d! %s",(int)image,SDL_GetError()); } } diff --git a/src/gui/intro.cpp b/src/gui/intro.cpp index 73f1cac12..75cc0fc1b 100644 --- a/src/gui/intro.cpp +++ b/src/gui/intro.cpp @@ -24,7 +24,7 @@ void FurnaceGUI::drawImage(ImDrawList* dl, FurnaceGUIImages image, const ImVec2& pos, const ImVec2& scale, double rotate, const ImVec2& uvMin, const ImVec2& uvMax, const ImVec4& imgColor) { FurnaceGUIImage* imgI=getImage(image); - SDL_Texture* img=getTexture(image); + void* img=getTexture(image); float squareSize=MAX(introMax.x-introMin.x,introMax.y-introMin.y); float uDiff=uvMax.x-uvMin.x; @@ -162,7 +162,7 @@ void FurnaceGUI::drawIntro(double introTime, bool monitor) { getTexture(GUI_IMAGE_TALOGO); getTexture(GUI_IMAGE_TACHIP); getTexture(GUI_IMAGE_LOGO); - getTexture(GUI_IMAGE_INTROBG,SDL_BLENDMODE_ADD); + getTexture(GUI_IMAGE_INTROBG,GUI_BLEND_MODE_ADD); if (monitor) { ImVec2 textPos=ImLerp(top,bottom,ImVec2(0.5,0.5)); diff --git a/src/gui/pattern.cpp b/src/gui/pattern.cpp index 554984043..934faacfb 100644 --- a/src/gui/pattern.cpp +++ b/src/gui/pattern.cpp @@ -49,11 +49,11 @@ void _popPartBlend(const ImDrawList* drawList, const ImDrawCmd* cmd) { } void FurnaceGUI::pushPartBlend() { - SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_ADD); + rend->setBlendMode(GUI_BLEND_MODE_ADD); } void FurnaceGUI::popPartBlend() { - SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_BLEND); + rend->setBlendMode(GUI_BLEND_MODE_BLEND); } // draw a pattern row diff --git a/src/gui/render.cpp b/src/gui/render.cpp new file mode 100644 index 000000000..069205d50 --- /dev/null +++ b/src/gui/render.cpp @@ -0,0 +1,36 @@ +/** + * Furnace Tracker - multi-system chiptune tracker + * Copyright (C) 2021-2023 tildearrow and contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "gui.h" +#include "render/renderSDL.h" + +bool FurnaceGUI::initRender() { + if (rend!=NULL) return false; + + rend=new FurnaceGUIRenderSDL; + return rend->init(sdlWin); +} + +bool FurnaceGUI::quitRender() { + if (rend==NULL) return false; + bool ret=rend->quit(); + delete rend; + rend=NULL; + return ret; +} \ No newline at end of file diff --git a/src/gui/render/abstract.cpp b/src/gui/render/abstract.cpp new file mode 100644 index 000000000..69adad0d4 --- /dev/null +++ b/src/gui/render/abstract.cpp @@ -0,0 +1,79 @@ +/** + * Furnace Tracker - multi-system chiptune tracker + * Copyright (C) 2021-2023 tildearrow and contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "../gui.h" + +bool FurnaceGUIRender::lockTexture(void* which, void** data, int* pitch) { + return false; +} + +bool FurnaceGUIRender::unlockTexture(void* which) { + return false; +} + +bool FurnaceGUIRender::updateTexture(void* which, void* data, int pitch) { + return false; +} + +void* FurnaceGUIRender::createTexture(bool dynamic, int width, int height) { + return NULL; +} + +bool FurnaceGUIRender::destroyTexture(void* which) { + return false; +} + +void FurnaceGUIRender::setTextureBlendMode(void* which, FurnaceGUIBlendMode mode) { +} + +void FurnaceGUIRender::setBlendMode(FurnaceGUIBlendMode mode) { +} + +void FurnaceGUIRender::clear(ImVec4 color) { +} + +void FurnaceGUIRender::renderGUI() { +} + +void FurnaceGUIRender::wipe(float alpha) { +} + +void FurnaceGUIRender::present() { +} + +bool FurnaceGUIRender::getOutputSize(int& w, int& h) { + return false; +} + +bool FurnaceGUIRender::init(SDL_Window* win) { + return false; +} + +void FurnaceGUIRender::initGUI(SDL_Window* win) { +} + +bool FurnaceGUIRender::quit() { + return false; +} + +void FurnaceGUIRender::quitGUI(){ +} + +FurnaceGUIRender::~FurnaceGUIRender() { +} \ No newline at end of file diff --git a/src/gui/render/renderGL.cpp b/src/gui/render/renderGL.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/gui/render/renderGL.h b/src/gui/render/renderGL.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/gui/render/renderSDL.cpp b/src/gui/render/renderSDL.cpp new file mode 100644 index 000000000..aea055a46 --- /dev/null +++ b/src/gui/render/renderSDL.cpp @@ -0,0 +1,123 @@ +/** + * Furnace Tracker - multi-system chiptune tracker + * Copyright (C) 2021-2023 tildearrow and contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "renderSDL.h" + +bool FurnaceGUIRenderSDL::lockTexture(void* which, void** data, int* pitch) { + return SDL_LockTexture((SDL_Texture*)which,NULL,data,pitch)==0; +} + +bool FurnaceGUIRenderSDL::unlockTexture(void* which) { + SDL_UnlockTexture((SDL_Texture*)which); + return true; +} + +bool FurnaceGUIRenderSDL::updateTexture(void* which, void* data, int pitch) { + return SDL_UpdateTexture((SDL_Texture*)which,NULL,data,pitch)==0; +} + +void* FurnaceGUIRenderSDL::createTexture(bool dynamic, int width, int height) { + return SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,dynamic?SDL_TEXTUREACCESS_STREAMING:SDL_TEXTUREACCESS_STATIC,width,height); +} + +bool FurnaceGUIRenderSDL::destroyTexture(void* which) { + SDL_DestroyTexture((SDL_Texture*)which); + return true; +} + +void FurnaceGUIRenderSDL::setTextureBlendMode(void* which, FurnaceGUIBlendMode mode) { + switch (mode) { + case GUI_BLEND_MODE_NONE: + SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_NONE); + break; + case GUI_BLEND_MODE_BLEND: + SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_BLEND); + break; + case GUI_BLEND_MODE_ADD: + SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_ADD); + break; + case GUI_BLEND_MODE_MULTIPLY: + SDL_SetTextureBlendMode((SDL_Texture*)which,SDL_BLENDMODE_MOD); + break; + } +} + +void FurnaceGUIRenderSDL::setBlendMode(FurnaceGUIBlendMode mode) { + switch (mode) { + case GUI_BLEND_MODE_NONE: + SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_NONE); + break; + case GUI_BLEND_MODE_BLEND: + SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_BLEND); + break; + case GUI_BLEND_MODE_ADD: + SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_ADD); + break; + case GUI_BLEND_MODE_MULTIPLY: + SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_MOD); + break; + } +} + +void FurnaceGUIRenderSDL::clear(ImVec4 color) { + SDL_SetRenderDrawColor(sdlRend,color.x*255,color.y*255,color.z*255,color.w*255); + SDL_RenderClear(sdlRend); +} + +void FurnaceGUIRenderSDL::renderGUI() { + ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData()); +} + +void FurnaceGUIRenderSDL::wipe(float alpha) { + SDL_SetRenderDrawBlendMode(sdlRend,SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(sdlRend,0,0,0,255*alpha); + SDL_RenderFillRect(sdlRend,NULL); +} + +void FurnaceGUIRenderSDL::present() { + SDL_RenderPresent(sdlRend); +} + +bool FurnaceGUIRenderSDL::getOutputSize(int& w, int& h) { + return SDL_GetRendererOutputSize(sdlRend,&w,&h)==0; +} + +bool FurnaceGUIRenderSDL::init(SDL_Window* win) { + sdlRend=SDL_CreateRenderer(win,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC|SDL_RENDERER_TARGETTEXTURE); + return (sdlRend!=NULL); +} + +void FurnaceGUIRenderSDL::initGUI(SDL_Window* win) { + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + + ImGui_ImplSDL2_InitForSDLRenderer(win,sdlRend); + ImGui_ImplSDLRenderer_Init(sdlRend); +} + +void FurnaceGUIRenderSDL::quitGUI() { + ImGui_ImplSDLRenderer_Shutdown(); +} + +bool FurnaceGUIRenderSDL::quit() { + if (sdlRend==NULL) return false; + SDL_DestroyRenderer(sdlRend); + sdlRend=NULL; + return true; +} \ No newline at end of file diff --git a/src/gui/render/renderSDL.h b/src/gui/render/renderSDL.h new file mode 100644 index 000000000..d6071b2a8 --- /dev/null +++ b/src/gui/render/renderSDL.h @@ -0,0 +1,43 @@ +/** + * Furnace Tracker - multi-system chiptune tracker + * Copyright (C) 2021-2023 tildearrow and contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "../gui.h" + +class FurnaceGUIRenderSDL: public FurnaceGUIRender { + SDL_Renderer* sdlRend; + public: + bool lockTexture(void* which, void** data, int* pitch); + bool unlockTexture(void* which); + bool updateTexture(void* which, void* data, int pitch); + void* createTexture(bool dynamic, int width, int height); + bool destroyTexture(void* which); + void setTextureBlendMode(void* which, FurnaceGUIBlendMode mode); + void setBlendMode(FurnaceGUIBlendMode mode); + void clear(ImVec4 color); + void renderGUI(); + void wipe(float alpha); + void present(); + bool getOutputSize(int& w, int& h); + bool init(SDL_Window* win); + void initGUI(SDL_Window* win); + void quitGUI(); + bool quit(); + FurnaceGUIRenderSDL(): + sdlRend(NULL) {} +}; \ No newline at end of file diff --git a/src/gui/sampleEdit.cpp b/src/gui/sampleEdit.cpp index 9d0fcc19b..301c3b8b2 100644 --- a/src/gui/sampleEdit.cpp +++ b/src/gui/sampleEdit.cpp @@ -1110,12 +1110,12 @@ void FurnaceGUI::drawSampleEdit() { if (sampleTex==NULL || sampleTexW!=avail.x || sampleTexH!=avail.y) { if (sampleTex!=NULL) { - SDL_DestroyTexture(sampleTex); + rend->destroyTexture(sampleTex); sampleTex=NULL; } if (avail.x>=1 && avail.y>=1) { logD("recreating sample texture."); - sampleTex=SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,SDL_TEXTUREACCESS_STREAMING,avail.x,avail.y); + sampleTex=rend->createTexture(true,avail.x,avail.y); sampleTexW=avail.x; sampleTexH=avail.y; if (sampleTex==NULL) { @@ -1131,7 +1131,7 @@ void FurnaceGUI::drawSampleEdit() { unsigned int* dataT=NULL; int pitch=0; logD("updating sample texture."); - if (SDL_LockTexture(sampleTex,NULL,(void**)&dataT,&pitch)!=0) { + if (!rend->lockTexture(sampleTex,(void**)&dataT,&pitch)) { logE("error while locking sample texture! %s",SDL_GetError()); } else { unsigned int* data=new unsigned int[sampleTexW*sampleTexH]; @@ -1217,7 +1217,7 @@ void FurnaceGUI::drawSampleEdit() { } memcpy(dataT,data,sampleTexW*sampleTexH*sizeof(unsigned int)); - SDL_UnlockTexture(sampleTex); + rend->unlockTexture(sampleTex); delete[] data; } updateSampleTex=false;