diff --git a/README.md b/README.md index d6ef4b3..848b702 100644 --- a/README.md +++ b/README.md @@ -21,17 +21,14 @@ SmallPot是一个轻量级播放器。 ## 编译 -首先需要取得mlcc工程。 +部分源码在mlcc和kys-cpp(Engine.h和Engine.cpp)中,需同时将这些工程放到同级别的目录。 ```shell git clone https://github.com/scarsty/mlcc mlcc +git clone https://github.com/scarsty/kys-cpp kys-cpp ``` -Engine.h和Engine.cpp在kys-cpp中。 - -其余依赖库包括iconv,ffmpeg,libass,SDL2,SDL2-image,SDL2-ttf等,推荐使用系统的包管理工具获取这些库,Windows下推荐使用vcpkg。其中SDL2_image仅有一处使用,且并不是必须的,可以简单修改后去除。 - -Windows下也可以从取得头文件和导入库。 +其余依赖库包括iconv,ffmpeg,libass,SDL2,SDL2-ttf等,推荐使用系统的包管理工具获取这些库,Windows下推荐使用vcpkg。 直接包含代码到工程中。 @@ -57,9 +54,9 @@ Windows下也可以从取得头文件 ### 单文件版 -如果需要编译单文件(全静态链接)版,导入库比动态链接版要多出很多,建议使用vcpkg之类解决(vcpkg生成的fribidi静态库不正确,需手动修正)。 +如果需要编译单文件(全静态链接)版,导入库比动态链接版要多出很多,建议使用vcpkg之类解决。 -以下为参考(fribidi及以下是动态链接不需要的): +以下为参考。其中fribidi及以下是动态链接不需要的,winmm.lib及以下是Windows自带的库: ``` sdl2.lib @@ -86,6 +83,9 @@ imm32.lib bcrypt.lib secur32.lib ws2_32.Lib +mfplat.lib +mfuuid.lib +strmiids.lib ``` 若是需要编译dll文件,用于在其他基于SDL2的游戏中播放视频时,则SmallPot和游戏均不应静态链接SDL。因为SDL的动态库中含有全局变量,多次静态链接后该变量会有多个副本,其中一个很可能是不正确的。 @@ -106,6 +106,10 @@ FFmpeg能解什么格式它就能放什么格式,FFmpeg不能解的,它也 查找字幕的方式是先依次将媒体文件的扩展名替换为ass、ssa、srt,并在媒体所在目录下以及subs子目录中寻找,即可以将字幕集中放到subs子目录。 +### 字幕的字体文件 + +libass的字体文件只能设置一个目录,所以如果字体显示不正常请将其安装进系统。 + ### 功能键 | 按键 | 功能 | diff --git a/smallpot.dll/PotDll.cpp b/smallpot.dll/PotDll.cpp index 5be4fe4..be60cc2 100644 --- a/smallpot.dll/PotDll.cpp +++ b/smallpot.dll/PotDll.cpp @@ -11,7 +11,7 @@ HBAPI void* MYTHAPI PotCreateFromHandle(void* handle) HBAPI void* MYTHAPI PotCreateFromWindow(void* handle) { - auto bp = new PotPlayer((BP_Window*)handle, 1); + auto bp = new PotPlayer((Window*)handle, 1); return bp; } diff --git a/smallpot.dll/smallpot.dll.vcxproj b/smallpot.dll/smallpot.dll.vcxproj index e33acc4..a8febda 100644 --- a/smallpot.dll/smallpot.dll.vcxproj +++ b/smallpot.dll/smallpot.dll.vcxproj @@ -48,7 +48,6 @@ - diff --git a/smallpot.dll/smallpot.dll.vcxproj.filters b/smallpot.dll/smallpot.dll.vcxproj.filters index e2115dc..046b8b1 100644 --- a/smallpot.dll/smallpot.dll.vcxproj.filters +++ b/smallpot.dll/smallpot.dll.vcxproj.filters @@ -92,9 +92,6 @@ 源文件 - - 源文件 - 源文件 diff --git a/src/Config.cpp b/src/Config.cpp index 80cf75b..afe3343 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -14,6 +14,7 @@ Config::Config() ".bt.td", ".td", }; + fmt1::print("Config init\n"); } Config::~Config() @@ -28,71 +29,21 @@ void Config::init(std::string filepath) { filepath = filepath + "/"; } - filename_ = filepath + "smallpot.config.ini"; + filename_ = filepath + "smallpot.config.json"; fmt1::print("try find config file: {}\n", filename_); - ini_.loadFile(filename_); - //setString("filepath", filepath); - - for (auto& s : ini_["record"].getAllKeys()) - { - if (!s.empty()) - { - Record r; - uint64_t t; - r.filename = s; - auto v = strfunc::findNumbers(ini_.getString("record", s)); - if (v.size() >= 1) - { - r.second = v[0]; - } - if (v.size() >= 2) - { - t = v[1]; - } - ini_["record"][s]["progress"] = r.second; - ini_["record"][s]["time_int"] = t; - //ini_["record"][s]["time"] = Timer::timeToString(time_t(t)); - } - } + parse(filefunc::readFileToString(filename_)); + fmt1::print("read config file\n"); } void Config::write() { - ini_.saveFile(filename_); -} - -std::string Config::getString(const std::string& name, std::string def /*= ""*/) -{ - if (!ini_.hasKey("", name)) - { - setString(name, def); - } - return ini_.getString("", name); -} - -int Config::getInteger(const std::string& name, int def /*= 0*/) -{ - if (!ini_.hasKey("", name)) - { - setInteger(name, def); - } - return ini_.getInt("", name); -} - -void Config::setString(const std::string& name, const std::string v) -{ - ini_.setKey("", name, v); -} - -void Config::setInteger(const std::string& name, int v) -{ - setString(name, fmt1::format("{}", v)); + filefunc::writeStringToFile(allToString(), filename_); + fmt1::print("write config file\n"); } int Config::getRecord(const std::string& name) { - //return ini_.getInt("record", enStr(name)); - return ini_["record"][enStr(name)]["progress"].toInt(); + return (*this)["record"][enStr(name)]["progress"].toInt(); } std::string Config::getNewestRecord() @@ -107,24 +58,21 @@ std::string Config::getNewestRecord() void Config::removeRecord(const std::string& name) { - ini_.eraseKey("record", enStr(name)); + (*this)["record"].erase(enStr(name)); } void Config::setRecord(const std::string& name, int v) { - //ini_.setKey("record", enStr(name), std::to_string(v) + "," + std::to_string(time(0))); - ini_["record"][enStr(name)]["progress"] = v; - ini_["record"][enStr(name)]["time"] = Timer::getNowAsString(); + (*this)["record"][enStr(name)]["progress"] = v; + (*this)["record"][enStr(name)]["time"] = Timer::getNowAsString(); } void Config::clearAllRecord() { - for (auto& s : ini_.getAllKeys("record")) - { - ini_.eraseKey("record", s); - } + (*this)["record"].clear(); } +// void Config::autoClearRecord() { auto rv = getSortedRecord(); @@ -140,29 +88,29 @@ void Config::autoClearRecord() { if (i > 100) { - ini_.eraseKey("record", rv[i].filename); + (*this)["record"].erase(rv[i].filename); } else { - auto s1 = PotConv::conv(deStr(r.filename), "utf-8", getString("sys_encode")); + auto s1 = PotConv::conv(deStr(r.filename), "utf-8", (*this)["sys_encode"].toString()); if (!filefunc::fileExist(s1)) { - ini_.eraseKey("record", r.filename); + (*this)["record"].erase(r.filename); } } } } -std::string Config::dealFilename(const std::string& s0) -{ - auto s = s0; - for (auto str : ignore_strs_) - { - s = strfunc::replaceAllSubString(s, str, ""); - } - return s; -} - +//std::string Config::dealFilename(const std::string& s0) +//{ +// auto s = s0; +// for (auto str : ignore_strs_) +// { +// s = strfunc::replaceAllSubString(s, str, ""); +// } +// return s; +//} +// std::string Config::enStr(const std::string& in) { return in; @@ -223,12 +171,13 @@ std::string Config::deStr(std::string out) std::vector Config::getSortedRecord() { std::vector rv; - for (auto& s : ini_["record"].getAllSections()) + for (auto [k, v] : (*this)["record"].asMap()) { Record r; - r.filename = s; - r.second = ini_["record"][s]["progress"].toInt(); - r.time = ini_["record"][s]["time"].toString(); + uint64_t t; + r.filename = k; + r.second = v["progress"].toInt(); + r.time = v["time"].toString(); rv.push_back(r); } std::sort(rv.begin(), rv.end(), [](const Record& l, const Record& r) @@ -248,7 +197,7 @@ std::string Config::findSuitableFilename(const std::string& filename) { return filename; } - if (rv.filename.find(filename) == 0) + if (!filename.empty() && rv.filename.find(filename) == 0) { filename1 = rv.filename; return filename1; diff --git a/src/Config.h b/src/Config.h index 0764230..25c6293 100644 --- a/src/Config.h +++ b/src/Config.h @@ -1,44 +1,51 @@ #pragma once -#include "INIReader.h" -#include +#include "FakeJson.h" #include -class Config +class Config : public FakeJson { struct Record { - std::string filename; + std::string filename, path; int second; std::string time; }; + // private: std::string content_; std::string filename_; Config(); virtual ~Config(); - - INIReaderNormal ini_; - + // + // INIReaderNormal ini_; + // std::vector ignore_strs_; - + // public: void init(std::string filepath); - + // void write(); - static Config* getInstance() + + static Config& getInstance() { static Config c; - return &c; + return c; } - //xml只有字串,故首先完成字串功能 - std::string getString(const std::string& name, std::string def = ""); - int getInteger(const std::string& name, int def = 0); - - void setString(const std::string& name, const std::string v); - void setInteger(const std::string& name, int v); + template + T get(const K& k, T default_v) + { + if (exist(k)) + { + return (*this)[k].to(); + } + else + { + return default_v; + } + } //记录 int getRecord(const std::string& name); @@ -48,7 +55,7 @@ class Config void clearAllRecord(); void autoClearRecord(); - std::string dealFilename(const std::string& s0); + // std::string dealFilename(const std::string& s0); std::string enStr(const std::string& in); std::string deStr(std::string out); diff --git a/src/Font.cpp b/src/Font.cpp index 2bf317f..4147f90 100644 --- a/src/Font.cpp +++ b/src/Font.cpp @@ -9,7 +9,7 @@ Font::~Font() { } -BP_Texture* Font::indexTex(const std::string& fontname, uint16_t c, int size) +Texture* Font::indexTex(const std::string& fontname, uint16_t c, int size) { auto index = fontname + "-" + std::to_string(c) + "-" + std::to_string(size); if (buffer_.count(index) == 0) @@ -37,13 +37,14 @@ int Font::getTextWidth(const std::string& fontname, const std::string& text, int p++; } auto tex = indexTex(fontname, c, size); - Engine::getInstance()->queryTexture(tex, &w, nullptr); + int h = 0; + Engine::getInstance()->getTextureSize(tex, w, h); x += w; } return x; } -void Font::draw(const std::string& fontname, const std::string& text, int size, int x, int y, BP_Color color, uint8_t alpha) +void Font::draw(const std::string& fontname, const std::string& text, int size, int x, int y, Color color, uint8_t alpha) { int p = 0; while (p < text.size()) @@ -57,12 +58,12 @@ void Font::draw(const std::string& fontname, const std::string& text, int size, p++; } auto tex = indexTex(fontname, c, size); - Engine::getInstance()->queryTexture(tex, &w, &h); + Engine::getInstance()->getTextureSize(tex, w, h); //Engine::getInstance()->setColor(tex, { uint8_t(color.r / 2), uint8_t(color.g / 2), uint8_t(color.b / 2), color.a }, alpha); - //Engine::getInstance()->renderCopy(tex, x + 1, y, w, h); + //Engine::getInstance()->renderTexture(tex, x + 1, y, w, h); color.a = alpha; Engine::getInstance()->setColor(tex, color); - Engine::getInstance()->renderCopy(tex, x, y, w, h); + Engine::getInstance()->renderTexture(tex, x, y, w, h); x += w; } } @@ -86,12 +87,12 @@ void Font::drawText(const std::string& fontname, const std::string& text, int si int w = Font::getInstance()->getTextWidth(fontname, text, size); switch (align) { - case BP_ALIGN_LEFT: + case ALIGN_LEFT: break; - case BP_ALIGN_RIGHT: + case ALIGN_RIGHT: x = x - w; break; - case BP_ALIGN_MIDDLE: + case ALIGN_MIDDLE: x = x - w / 2; break; } diff --git a/src/Font.h b/src/Font.h index 6af8170..84699d7 100644 --- a/src/Font.h +++ b/src/Font.h @@ -8,8 +8,8 @@ class Font private: Font(); ~Font(); - std::map buffer_; //缓存所有已经画过的字体 - BP_Texture* indexTex(const std::string& fontname, uint16_t c, int size); + std::map buffer_; //缓存所有已经画过的字体 + Texture* indexTex(const std::string& fontname, uint16_t c, int size); public: static Font* getInstance() @@ -18,11 +18,11 @@ class Font return &f; } int getTextWidth(const std::string& fontname, const std::string& text, int size); - void draw(const std::string& fontname, const std::string& text, int size, int x, int y, BP_Color color = { 255, 255, 255, 255 }, uint8_t alpha = 255); + void draw(const std::string& fontname, const std::string& text, int size, int x, int y, Color color = { 255, 255, 255, 255 }, uint8_t alpha = 255); void clearBuffer(); int getBufferSize() { return buffer_.size(); } - BP_Texture* createTextTexture2(const std::string& fontname, const std::string& s, int size); + Texture* createTextTexture2(const std::string& fontname, const std::string& s, int size); void drawText(const std::string& fontname, const std::string& text, int size, int x, int y, uint8_t alpha, int align); void drawSubtitle(const std::string& fontname, const std::string& text, int size, int x, int y, uint8_t alpha, int align); }; diff --git a/src/PotMedia.cpp b/src/PotMedia.cpp index 7b3f7e8..75c85fb 100644 --- a/src/PotMedia.cpp +++ b/src/PotMedia.cpp @@ -90,7 +90,7 @@ int PotMedia::openFile(const std::string& filename) { switch (format_ctx->streams[i]->codecpar->codec_type) { - case BPMEDIA_TYPE_VIDEO: + case MEDIA_TYPE_VIDEO: { auto st = new PotStreamVideo(); st->setFormatCtx(format_ctx_video_); @@ -101,7 +101,7 @@ int PotMedia::openFile(const std::string& filename) } break; } - case BPMEDIA_TYPE_AUDIO: + case MEDIA_TYPE_AUDIO: { auto st = new PotStreamAudio(); st->setFormatCtx(format_ctx_audio_); @@ -112,7 +112,7 @@ int PotMedia::openFile(const std::string& filename) } break; } - case BPMEDIA_TYPE_SUBTITLE: + case MEDIA_TYPE_SUBTITLE: { auto st = new PotStreamSubtitle(); st->setFormatCtx(format_ctx_subtitle_); @@ -214,6 +214,10 @@ void PotMedia::destroy() bool PotMedia::isMedia() { + if (streams_.empty()) + { + return false; + } return stream_audio_->exist() || stream_video_->exist(); } @@ -267,12 +271,12 @@ void PotMedia::switchStream(PotMediaType mt) switch (mt) { - case BPMEDIA_TYPE_VIDEO: + case MEDIA_TYPE_VIDEO: { stream_video_ = (PotStreamVideo*)st; break; } - case BPMEDIA_TYPE_AUDIO: + case MEDIA_TYPE_AUDIO: { //注意此处效果不佳 //若假设所有音频使用同一解码器,则切换的效果会较好 @@ -285,7 +289,7 @@ void PotMedia::switchStream(PotMediaType mt) //stream_audio_->setStreamIndex(st->getStreamIndex()); break; } - case BPMEDIA_TYPE_SUBTITLE: + case MEDIA_TYPE_SUBTITLE: { stream_subtitle_ = (PotStreamSubtitle*)st; stream_subtitle_->seek(getTime() - 5000); diff --git a/src/PotPlayer.cpp b/src/PotPlayer.cpp index 5e11786..7f19370 100644 --- a/src/PotPlayer.cpp +++ b/src/PotPlayer.cpp @@ -9,6 +9,11 @@ //#pragma comment(lib,"shfolder.lib") #endif +int xDir = 0; +int yDir = 0; +float axes[16] = {0.0f}; +const int CONTROLLER_DEAD_ZONE = 20000; + PotPlayer::PotPlayer() { //_subtitle = new BigPotSubtitle; @@ -19,7 +24,8 @@ PotPlayer::PotPlayer() run_path_ = "./"; } -PotPlayer::PotPlayer(char* s) : PotPlayer() +PotPlayer::PotPlayer(char* s) : + PotPlayer() { run_path_ = filefunc::getParentPath(s); #if defined(_WIN32) && defined(_SINGLE_FILE) @@ -47,14 +53,14 @@ PotPlayer::~PotPlayer() int PotPlayer::eventLoop() { - BP_Event e; + EngineEvent e; bool hold_mouse = false; int64_t hold_time = 0; bool loop = true, pause = false, seeking = false; int finished, i = 0; const int seek_step = 1000; - int volume_step = 1; + float volume_step = 1.0 / 128; bool havevideo = media_->getVideo()->exist(); bool havemedia = media_->getAudio()->exist() || havevideo; int totalTime = media_->getTotalTime(); @@ -66,7 +72,7 @@ int PotPlayer::eventLoop() exit_type_ = 0; int sub_state = 0; //0不显示,1外部字幕,2及以上内部字幕 - int internal_sub_count = media_->getStreamCount(BPMEDIA_TYPE_SUBTITLE); + int internal_sub_count = media_->getStreamCount(MEDIA_TYPE_SUBTITLE); if (internal_sub_count > 0) { sub_state = 2; @@ -77,6 +83,9 @@ int PotPlayer::eventLoop() } int find_direct = 0; + float touch_start_x = 0, touch_start_y = 0; + double touch_start_time = 0; + while (loop && engine_->pollEvent(e) >= 0) { seeking = false; @@ -95,7 +104,7 @@ int PotPlayer::eventLoop() } else if (sub_state > 2) { - media_->switchStream(BPMEDIA_TYPE_SUBTITLE); + media_->switchStream(MEDIA_TYPE_SUBTITLE); media_->getSubtitle()->setFrameSize(engine_->getPresentWidth(), engine_->getPresentHeight()); } if (sub_state >= 2 + internal_sub_count) @@ -118,7 +127,7 @@ int PotPlayer::eventLoop() auto seekButton = [&]() { - if (e.button.button == BP_BUTTON_LEFT) + if (e.button.button == BUTTON_LEFT) { int button = UI_.inButton(); if (button == PotUI::ButtonLeft) @@ -143,12 +152,121 @@ int PotPlayer::eventLoop() switch (e.type) { - case BP_MOUSEMOTION: + case SDL_CONTROLLERBUTTONDOWN: + //if( e.jaxis.which == 1 ) + //{ + if (e.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_UP) + { + media_->getAudio()->changeVolume(volume_step); + UI_.setText("v"); + } + else if (e.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN) + { + media_->getAudio()->changeVolume(-volume_step); + UI_.setText("v"); + } + else if (e.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT) + { + media_->seekTime(media_->getTime() - seek_step, -1); + UI_.setText(""); + seeking = true; + } + else if (e.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT) + { + media_->seekTime(media_->getTime() + seek_step, 1); + UI_.setText(""); + seeking = true; + } + else if (e.cbutton.button == SDL_CONTROLLER_BUTTON_A) + { + pause = !pause; + media_->setPause(pause); + } + else if (e.cbutton.button == SDL_CONTROLLER_BUTTON_B) + { + loop = false; + running_ = false; + } + else + { + } + //} + break; + case SDL_CONTROLLERAXISMOTION: + axes[e.caxis.axis] = e.caxis.value; + if ((axes[1] > CONTROLLER_DEAD_ZONE) && (axes[0] > CONTROLLER_DEAD_ZONE))//rightdown + { + xDir = 1073741905; + yDir = 1073741903; + } + else if ((axes[1] < -CONTROLLER_DEAD_ZONE) && (axes[0] > CONTROLLER_DEAD_ZONE))//rightup + { + xDir = 1073741906; + yDir = 1073741903; + } + else if ((axes[1] > CONTROLLER_DEAD_ZONE) && (axes[0] < -CONTROLLER_DEAD_ZONE))//leftdown + { + xDir = 1073741905; + yDir = 1073741904; + } + else if ((axes[1] < -CONTROLLER_DEAD_ZONE) && (axes[0] < -CONTROLLER_DEAD_ZONE))//leftup + { + xDir = 1073741906; + yDir = 1073741904; + break; + } + else if ((axes[1] > CONTROLLER_DEAD_ZONE) &&((xDir != 1073741905) || (yDir != 0)))//down of dead zone + { + xDir = 1073741905; + yDir = 0; + media_->getAudio()->changeVolume(-volume_step); + UI_.setText("v"); + break; + } + else if ((axes[1] < -CONTROLLER_DEAD_ZONE) &&((xDir != 1073741906) || (yDir != 0)))// upof dead zone + { + xDir = 1073741906; + yDir = 0; + media_->getAudio()->changeVolume(volume_step); + UI_.setText("v"); + break; + } + else if ((axes[0] < -CONTROLLER_DEAD_ZONE) && ((xDir != 0) || (yDir != 1073741904)))//left of dead zone + { + xDir = 0; + yDir = 1073741904; + media_->seekTime(media_->getTime() - seek_step, -1); + UI_.setText(""); + seeking = true; + break; + } + else if ((axes[0] > CONTROLLER_DEAD_ZONE) && ((xDir != 0) || (yDir != 1073741903)))//Right of dead zone + { + xDir = 0; + yDir = 1073741903; + media_->seekTime(media_->getTime() + seek_step, 1); + UI_.setText(""); + seeking = true; + break; + } + else if ((abs(axes[0]) < 4000 )&&(abs(axes[1]) < 4000 )&&(abs(axes[2]) < 4000 )&&(abs(axes[3]) < 4000 )) + { + xDir = 0; + yDir = 0; + } + case EVENT_MOUSE_MOTION: break; - case BP_MOUSEBUTTONUP: + case EVENT_MOUSE_BUTTON_UP: hold_mouse = false; - if (e.button.button == BP_BUTTON_LEFT) + if (e.button.button == BUTTON_LEFT) { + int w, h; + engine_->getWindowSize(w, h); + if (e.motion.x > w - 150 && e.motion.y < 150) { + loop = false; + running_ = false; + break; + } double pos = UI_.inProcess(); int button = UI_.inButton(); if (pos >= 0) @@ -178,7 +296,7 @@ int PotPlayer::eventLoop() } else if (button == PotUI::ButtonAudio) { - media_->switchStream(BPMEDIA_TYPE_AUDIO); + media_->switchStream(MEDIA_TYPE_AUDIO); UI_.setText(fmt1::format("Switch audio stream to {}", media_->getAudio()->getStreamIndex())); } else if (button == PotUI::ButtonSubtitle) @@ -189,24 +307,24 @@ int PotPlayer::eventLoop() { int x, y; engine_->getMouseState(x, y); - int v = 128 * (x - UI_.getButtonPos(button)) / UI_.getButtonWidth(button); + float v = 1.0 * (x - UI_.getButtonPos(button)) / UI_.getButtonWidth(button); media_->getAudio()->setVolume(v); } } #ifdef _WINDLL - if (e.button.button == BP_BUTTON_RIGHT) + if (e.button.button == BUTTON_RIGHT) { loop = false; running_ = false; } #endif break; - case BP_MOUSEBUTTONDOWN: + case EVENT_MOUSE_BUTTON_DOWN: hold_mouse = true; hold_time = engine_->getTicks(); seekButton(); break; - case BP_MOUSEWHEEL: + case EVENT_MOUSE_WHEEL: { if (int(UI_.inButton()) == PotUI::ButtonVolume) { @@ -240,43 +358,43 @@ int PotPlayer::eventLoop() //UI_.setText("v"); break; } - case BP_KEYDOWN: + case EVENT_KEY_DOWN: { - switch (e.key.keysym.sym) + switch (e.key.key) { - case BPK_LEFT: + case K_LEFT: media_->seekTime(media_->getTime() - seek_step, -1); UI_.setText(""); seeking = true; break; - case BPK_RIGHT: + case K_RIGHT: media_->seekTime(media_->getTime() + seek_step, 1); UI_.setText(""); seeking = true; break; - case BPK_UP: + case K_UP: media_->getAudio()->changeVolume(volume_step); UI_.setText("v"); break; - case BPK_DOWN: + case K_DOWN: media_->getAudio()->changeVolume(-volume_step); UI_.setText("v"); break; - case BPK_1: - media_->switchStream(BPMEDIA_TYPE_AUDIO); + case K_1: + media_->switchStream(MEDIA_TYPE_AUDIO); UI_.setText(fmt1::format("Switch audio stream to {}", media_->getAudio()->getStreamIndex())); break; - case BPK_2: + case K_2: switchSubtitle(); break; } break; } - case BP_KEYUP: + case EVENT_KEY_UP: { - switch (e.key.keysym.sym) + switch (e.key.key) { - case BPK_ESCAPE: + case K_ESCAPE: if (engine_->isFullScreen()) { engine_->toggleFullscreen(); @@ -288,23 +406,23 @@ int PotPlayer::eventLoop() running_ = false; } break; - case BPK_BACKSPACE: + case K_BACKSPACE: media_->seekTime(0); seeking = true; break; #ifndef _WINDLL - case BPK_SPACE: + case K_SPACE: pause = !pause; media_->setPause(pause); break; - case BPK_RETURN: + case K_RETURN: engine_->toggleFullscreen(); setSubtitleFrameSize(); break; - case BPK_DELETE: - Config::getInstance()->clearAllRecord(); + case K_DELETE: + Config::getInstance().clearAllRecord(); break; - case BPK_PERIOD: + case K_PERIOD: { find_direct = 1; auto next_file = findNextFile(drop_filename_, find_direct); @@ -315,7 +433,7 @@ int PotPlayer::eventLoop() } break; } - case BPK_COMMA: + case K_COMMA: { find_direct = -60 * 1000; auto next_file = findNextFile(drop_filename_, find_direct); @@ -326,36 +444,37 @@ int PotPlayer::eventLoop() } break; } - case BPK_EQUALS: + case K_EQUALS: { int w, h; engine_->getWindowSize(w, h); w += width_ / 4; h += height_ / 4; setWindowSize(w, h); - engine_->setWindowPosition(BP_WINDOWPOS_CENTERED, BP_WINDOWPOS_CENTERED); + engine_->setWindowPosition(WINDOWPOS_CENTERED, WINDOWPOS_CENTERED); break; } - case BPK_MINUS: + case K_MINUS: { int w, h; engine_->getWindowSize(w, h); w -= width_ / 4; h -= height_ / 4; setWindowSize(w, h); - engine_->setWindowPosition(BP_WINDOWPOS_CENTERED, BP_WINDOWPOS_CENTERED); + engine_->setWindowPosition(WINDOWPOS_CENTERED, WINDOWPOS_CENTERED); break; } - case BPK_0: + case K_0: setWindowSize(media_->getVideo()->getWidth(), media_->getVideo()->getHeight()); - engine_->setWindowPosition(BP_WINDOWPOS_CENTERED, BP_WINDOWPOS_CENTERED); + engine_->setWindowPosition(WINDOWPOS_CENTERED, WINDOWPOS_CENTERED); break; #endif } + break; } //#ifndef _WINDLL - case BP_QUIT: + case EVENT_QUIT: //pause = true; #ifdef _WINDLL engine_->delay(10); @@ -366,19 +485,15 @@ int PotPlayer::eventLoop() exit_type_ = 1; break; //#endif - case BP_WINDOWEVENT: - if (e.window.event == BP_WINDOWEVENT_RESIZED) - { - setWindowSize(e.window.data1, e.window.data2); - } - else if (e.window.event == BP_WINDOWEVENT_LEAVE) - { - } + case EVENT_WINDOW_RESIZED: + setWindowSize(e.window.data1, e.window.data2); break; - case BP_DROPFILE: + case EVENT_WINDOW_MOUSE_LEAVE: + break; + case EVENT_DROP_FILE: //有文件拖入先检查是不是字幕,不是字幕则当作媒体文件,打开失败活该 //若将媒体文件当成字幕打开会非常慢,故限制字幕文件的扩展名 - open_filename = PotConv::conv(e.drop.file, BP_encode_, sys_encode_); + open_filename = PotConv::conv(e.drop.data, BP_encode_, sys_encode_); fmt1::print("Change file: {}\n", open_filename); //检查是不是字幕,如果是则打开 if (PotSubtitleManager::isSubtitle(open_filename)) @@ -393,15 +508,84 @@ int PotPlayer::eventLoop() } else { - drop_filename_ = e.drop.file; + drop_filename_ = e.drop.data; loop = false; } - engine_->free(e.drop.file); break; + case EVENT_FINGER_DOWN: // 触摸开始 + touch_start_x = e.tfinger.x; + touch_start_y = e.tfinger.y; + touch_start_time = engine_->getTicks(); + break; + case EVENT_FINGER_MOTION: // 触摸移动 + { + float dx = e.tfinger.x - touch_start_x; + float dy = e.tfinger.y - touch_start_y; + + // 判断主要滑动方向(横向/纵向) + if (fabsf(dx) > fabsf(dy)) + { + // 横向滑动处理(进度调节) + if (fabsf(dx) > 0.05f) + { // 滑动阈值 + if (dx > 0) + { + media_->seekTime(media_->getTime() + seek_step, 1); + } + else + { + media_->seekTime(media_->getTime() - seek_step, -1); + } + UI_.setText(""); + seeking = true; + // 重置起始位置以便连续滑动 + touch_start_x = e.tfinger.x; + touch_start_y = e.tfinger.y; + } + } + else + { + // 纵向滑动处理(音量调节) + if (fabsf(dy) > 0.05f) + { + if (dy > 0) + { + media_->getAudio()->changeVolume(-volume_step); + } + else + { + media_->getAudio()->changeVolume(volume_step); + } + UI_.setText("v"); + // 重置起始位置 + touch_start_x = e.tfinger.x; + touch_start_y = e.tfinger.y; + } + } + break; + } + case EVENT_FINGER_UP: // 触摸结束 + { + uint32_t duration = engine_->getTicks() - touch_start_time; + float dx = e.tfinger.x - touch_start_x; + float dy = e.tfinger.y - touch_start_y; + + // 点击判断(短时间+小距离) + if (duration < 300 && (dx * dx + dy * dy) < 0.0001f) + { + // 检查右上角区域(归一化坐标) + if (e.tfinger.x > 0.8f && e.tfinger.y < 0.2f) + { + loop = false; + running_ = false; + } + } + break; + } default: break; } - e.type = BP_FIRSTEVENT; + e.type = EVENT_FIRST; if (!loop) { @@ -409,6 +593,7 @@ int PotPlayer::eventLoop() } //在每个循环均尝试预解压 media_->decodeFrame(); + //media_->getAudio()->show(); //尝试以音频为基准显示视频 int audioTime = media_->getTime(); //注意优先为音频时间,若音频不存在使用视频时间 //if (seeking) @@ -418,11 +603,11 @@ int PotPlayer::eventLoop() if (last_volume == media_->getAudio()->getVolume()) { - volume_step = 1; + volume_step = 1.0 / 128; } else { - volume_step = (std::min)(volume_step + 1, 5); + volume_step = (std::min)(volume_step + 1.0 / 128, 5.0 / 128); } int time_s = audioTime; @@ -460,7 +645,7 @@ int PotPlayer::eventLoop() int videoTime = (media_->getVideo()->getTimedts()); int delay = -videoTime + audioTime; fmt1::print("\rvolume {}, audio {:4.3}, video {:4.3}, diff {:1.3} in loop {}\t", - media_->getAudio()->changeVolume(0), audioTime / 1e3, videoTime / 1e3, delay / 1e3, i); + media_->getAudio()->getVolume(), audioTime / 1e3, videoTime / 1e3, delay / 1e3, i); #endif } //静止时,无视频时,视频已放完时40毫秒显示一次 @@ -470,11 +655,11 @@ int PotPlayer::eventLoop() show = true; if (havevideo) { - engine_->renderCopy(engine_->getMainTexture()); + engine_->renderTexture(engine_->getMainTexture()); } else { - engine_->showLogo(); + //engine_->showLogo(); } } if (show) @@ -495,17 +680,6 @@ int PotPlayer::eventLoop() engine_->delay(1); if (audioTime >= totalTime) { - if (Config::getInstance()->getInteger("loop", 0)) - { - find_direct = 0; - } - auto next_file = findNextFile(drop_filename_, find_direct); - if (next_file != "") - { - drop_filename_ = next_file; - Config::getInstance()->setRecord(drop_filename_, 0); //若是自动跳转,则设置从头开始 - loop = false; - } } #ifdef _WINDLL if (videostate == PotStreamVideo::NoVideo || time_s >= totalTime) @@ -525,18 +699,18 @@ int PotPlayer::eventLoop() int PotPlayer::init() { - Config::getInstance()->init(run_path_); - int maximum = Config::getInstance()->getInteger("windows_maximized", 0); + Config::getInstance().init(run_path_); + int maximum = Config::getInstance()["windows_maximized"]; if (engine_->init(handle_, handle_type_, maximum)) { return -1; } #ifdef _WIN32 - sys_encode_ = Config::getInstance()->getString("sys_encode", "cp936"); + sys_encode_ = Config::getInstance().get("sys_encode", "cp936"); #else - sys_encode_ = Config::getInstance()->getString("sys_encode", "utf-8"); + sys_encode_ = Config::getInstance().get("sys_encode", "utf-8"); #endif - cur_volume_ = Config::getInstance()->getInteger("volume", BP_AUDIO_MIX_MAXVOLUME / 2); + cur_volume_ = Config::getInstance().get("volume", 0.5); PotStreamAudio::setVolume(cur_volume_); UI_.init(); return 0; @@ -547,7 +721,11 @@ void PotPlayer::destroy() UI_.destory(); //engine_->destroy(); #ifndef _WINDLL - Config::getInstance()->write(); + if (!media_) + { + //从未打开过文件 + Config::getInstance().write(); //关闭媒体时已经保存了 + } #endif } @@ -561,16 +739,16 @@ int PotPlayer::beginWithFile(std::string filename) engine_->resetRenderTarget(); int start_time = engine_->getTicks(); - if (filename.empty() && Config::getInstance()->getInteger("auto_play_recent")) + if (filename.empty() && Config::getInstance()["auto_play_recent"].toInt()) { - filename = Config::getInstance()->getNewestRecord(); + filename = Config::getInstance().getNewestRecord(); if (!filefunc::fileExist(PotConv::conv(filename, BP_encode_, sys_encode_))) { filename = ""; } - } + } //首次运行拖拽的文件也认为是同一个 - drop_filename_ = Config::getInstance()->findSuitableFilename(filename); + drop_filename_ = Config::getInstance().findSuitableFilename(filename); fmt1::print("Begin with file: {}\n", filename); auto play_filename = drop_filename_; @@ -599,8 +777,8 @@ int PotPlayer::beginWithFile(std::string filename) engine_->setWindowPosition(x, y);*/ int w, h; engine_->getWindowSize(w, h); - w = Config::getInstance()->getInteger("windows_width", w); - h = Config::getInstance()->getInteger("windows_height", h); + w = Config::getInstance().get("windows_width", w); + h = Config::getInstance().get("windows_height", h); setWindowSize(w, h); //首次打开文件窗口居中 if (engine_->isFullScreen() || engine_->getWindowIsMaximized()) @@ -608,7 +786,7 @@ int PotPlayer::beginWithFile(std::string filename) } else { - engine_->setWindowPosition(BP_WINDOWPOS_CENTERED, BP_WINDOWPOS_CENTERED); + engine_->setWindowPosition(WINDOWPOS_CENTERED, WINDOWPOS_CENTERED); } } #endif @@ -654,7 +832,7 @@ void PotPlayer::openMedia(const std::string& filename) engine_->setWindowTitle(filename); #endif auto pixfmt = media_->getVideo()->getSDLPixFmt(); - engine_->createMainTexture(pixfmt, BP_TEXTUREACCESS_STREAMING, width_, height_); + engine_->createMainTexture(pixfmt, TEXTUREACCESS_STREAMING, width_, height_); //engine_->createAssistTexture(width_, height_); //重新获取尺寸,有可能与之前不同 @@ -674,10 +852,10 @@ void PotPlayer::openMedia(const std::string& filename) if (media_->isMedia()) { cur_time_ = 0; - cur_time_ = Config::getInstance()->getRecord(filename.c_str()); + cur_time_ = Config::getInstance().getRecord(filename.c_str()); std::thread th{ [this]() { - Config::getInstance()->autoClearRecord(); + Config::getInstance().autoClearRecord(); return; } }; th.detach(); @@ -711,25 +889,28 @@ void PotPlayer::closeMedia(const std::string& filename) //如果是媒体文件就记录时间 #ifndef _WINDLL - auto config = Config::getInstance(); + auto& config = Config::getInstance(); if (media_->isMedia() && cur_time_ < media_->getTotalTime() && cur_time_ > 0) { - config->setRecord(filename, cur_time_); + config.setRecord(filename, cur_time_); } else { - config->removeRecord(filename); + config["record"].erase(filename); + } + if (media_->isMedia()) + { + config["sys_encode"] = sys_encode_; + config["volume"] = cur_volume_; + int w, h; + engine_->getWindowSize(w, h); + //config->setInteger("windows_width", w); + //config->setInteger("windows_height", h); + config["windows_maximized"] = int(engine_->getWindowIsMaximized()); + //config->autoClearRecord(); + + config.write(); } - config->setString("sys_encode", sys_encode_); - config->setInteger("volume", cur_volume_); - int w, h; - engine_->getWindowSize(w, h); - //config->setInteger("windows_width", w); - //config->setInteger("windows_height", h); - config->setInteger("windows_maximized", engine_->getWindowIsMaximized()); - //config->autoClearRecord(); - - config->write(); #endif delete media_; filefunc::changePath(run_path_); diff --git a/src/PotPlayer.h b/src/PotPlayer.h index d50b655..4827426 100644 --- a/src/PotPlayer.h +++ b/src/PotPlayer.h @@ -32,7 +32,7 @@ class PotPlayer : public PotBase bool running_ = true; std::string sys_encode_ = "cp936", BP_encode_ = "utf-8"; - int cur_volume_; + float cur_volume_; int eventLoop(); void* handle_; int handle_type_; diff --git a/src/PotStream.cpp b/src/PotStream.cpp index f26ea91..c79591c 100644 --- a/src/PotStream.cpp +++ b/src/PotStream.cpp @@ -267,7 +267,7 @@ int PotStream::tryDecodeFrame(bool reset) int got_frame = 0; for (int i = 0; i < decode_frame_count_; i++) { - got_frame = decodeNextPacketToFrame(true, type_ != BPMEDIA_TYPE_SUBTITLE); + got_frame = decodeNextPacketToFrame(true, type_ != MEDIA_TYPE_SUBTITLE); if (got_frame <= 0) { continue; @@ -318,7 +318,7 @@ int PotStream::seek(int time, int direct /*= 1*/, int reset /*= 0*/) flag = flag | AVSEEK_FLAG_BACKWARD; } //间隔比较大的情况重置播放器 - if (type_ == BPMEDIA_TYPE_VIDEO && (pause_ || reset || engine_->getTicks() - seek_record_ > 100)) + if (type_ == MEDIA_TYPE_VIDEO && (pause_ || reset || engine_->getTicks() - seek_record_ > 100)) { avcodec_flush_buffers(codec_ctx_); } @@ -327,6 +327,7 @@ int PotStream::seek(int time, int direct /*= 1*/, int reset /*= 0*/) //avformat_seek_file(format_ctx_, -1, INT64_MIN, i, INT64_MAX, 0); } seek_record_ = engine_->getTicks(); + Engine::getInstance()->clearAudioStream(); return 0; } @@ -359,7 +360,7 @@ int PotStream::skipFrame(int time) { n++; //视频需解码,因为关键帧不解后续一系列都有问题,音频可以只读不解 - if (decodeNextPacketToFrame(type_ == BPMEDIA_TYPE_VIDEO, type_ != BPMEDIA_TYPE_SUBTITLE) < 0) + if (decodeNextPacketToFrame(type_ == MEDIA_TYPE_VIDEO, type_ != MEDIA_TYPE_SUBTITLE) < 0) { break; } @@ -420,7 +421,7 @@ void PotStream::getRatio(int& x, int& y) //{ // //避免卡死 -// if (type_ == BPMEDIA_TYPE_VIDEO && gotsize < 0) +// if (type_ == MEDIA_TYPE_VIDEO && gotsize < 0) // { // BP_Event e; // //这里只接受QUIT和拖入事件,将其压回主序列,跳出 diff --git a/src/PotStream.h b/src/PotStream.h index 1ef12bf..088d46b 100644 --- a/src/PotStream.h +++ b/src/PotStream.h @@ -15,9 +15,9 @@ extern "C" enum PotMediaType { - BPMEDIA_TYPE_VIDEO = AVMEDIA_TYPE_VIDEO, - BPMEDIA_TYPE_AUDIO = AVMEDIA_TYPE_AUDIO, - BPMEDIA_TYPE_SUBTITLE = AVMEDIA_TYPE_SUBTITLE, + MEDIA_TYPE_VIDEO = AVMEDIA_TYPE_VIDEO, + MEDIA_TYPE_AUDIO = AVMEDIA_TYPE_AUDIO, + MEDIA_TYPE_SUBTITLE = AVMEDIA_TYPE_SUBTITLE, }; /* diff --git a/src/PotStreamAudio.cpp b/src/PotStreamAudio.cpp index a2ddb4c..b9a10cc 100644 --- a/src/PotStreamAudio.cpp +++ b/src/PotStreamAudio.cpp @@ -1,7 +1,7 @@ #include "PotStreamAudio.h" #include "Config.h" -int PotStreamAudio::volume_; +float PotStreamAudio::volume_; PotStreamAudio::PotStreamAudio() { @@ -12,7 +12,7 @@ PotStreamAudio::PotStreamAudio() //缓冲区大小4M保存 buffer_ = av_mallocz(buffer_size_); resample_buffer_ = (decltype(resample_buffer_))av_mallocz(convert_size_); - type_ = BPMEDIA_TYPE_AUDIO; + type_ = MEDIA_TYPE_AUDIO; decode_frame_count_ = 2; } @@ -134,6 +134,69 @@ FrameContent PotStreamAudio::convertFrameToContent() return f; } +int PotStreamAudio::show() +{ + if (data_map_.size() >= max_size_) { return 1; } + const int len = 3840; + if (buffer_ == nullptr) { return -1; } + if (data_write_ <= data_read_) + { + return -2; + } + //SDL_LockMutex(t->mutex_cpp); + auto data1 = (uint8_t*)buffer_; + int pos = data_read_ % buffer_size_; + int rest = buffer_size_ - pos; + //一次或者两次,保证缓冲区大小足够 + if (len <= rest) + { + engine_->putAudioStreamData(data1 + pos, len); + } + else + { + engine_->putAudioStreamData(data1 + pos, rest); + engine_->putAudioStreamData(data1, len - rest); + } + while (haveDecoded()) + { + auto f = getCurrentContent(); + Engine::getInstance()->putAudioStreamData(resample_buffer_, data_length_); + if (!f.data || f.time < 0) + { + dropDecoded(); + break; + } + if (data_read_ >= f.info) + { + //fmt1::print("drop %I64d\n", t->dataRead - f.info); + dropDecoded(); + if (data_read_ == f.info && time_shown_ != f.time) + { + time_shown_ = f.time; + ticks_shown_ = engine_->getTicks(); + break; + } + else + { + //获取下一个 + auto f1 = getCurrentContent(); + //后一个包如果时间是一样的不更新计时 + if (f1.info > data_read_ && f.time != f1.time) + { + time_shown_ = f.time + (f1.time - f.time) * (data_read_ - f.info) / (f1.info - f.info); + ticks_shown_ = engine_->getTicks(); + } + } + } + else + { + break; + } + } + data_read_ += len; + return 0; +} + bool PotStreamAudio::needDecode2() { if (buffer_ == nullptr) { return false; } @@ -147,23 +210,26 @@ void PotStreamAudio::openAudioDevice() return; } freq_ = codec_ctx_->sample_rate; - channels_ = Config::getInstance()->getInteger("channels", -1); + channels_ = Config::getInstance().get("channels", -1); if (channels_ < 0) { channels_ = codec_ctx_->ch_layout.nb_channels; } - engine_->openAudio(freq_, channels_, codec_ctx_->frame_size, 2048, std::bind(&PotStreamAudio::mixAudioData, this, std::placeholders::_1, std::placeholders::_2)); + //注意这里仍然使用的是回调,计算时间比较简单 + engine_->openAudio(freq_, channels_, codec_ctx_->frame_size, 2048, [this](uint8_t* stream, int len) + { + mixAudioData(stream, len); + }); auto audio_format = AV_SAMPLE_FMT_S16; - std::map SDL_FFMPEG_AUDIO_FORMAT = - { - { AUDIO_U8, AV_SAMPLE_FMT_U8 }, - { AUDIO_S16, AV_SAMPLE_FMT_S16 }, - { AUDIO_S32, AV_SAMPLE_FMT_S32 }, - { AUDIO_F32, AV_SAMPLE_FMT_FLT }, - //{ AUDIO_U8, AV_SAMPLE_FMT_DBL }, - }; + std::map SDL_FFMPEG_AUDIO_FORMAT = { + { SDL_AUDIO_U8, AV_SAMPLE_FMT_U8 }, + { SDL_AUDIO_S16LE, AV_SAMPLE_FMT_S16 }, + { SDL_AUDIO_S32LE, AV_SAMPLE_FMT_S32 }, + { SDL_AUDIO_F32LE, AV_SAMPLE_FMT_FLT }, + //{ AUDIO_U8, AV_SAMPLE_FMT_DBL }, + }; resample_.setOutFormat(SDL_FFMPEG_AUDIO_FORMAT[engine_->getAudioFormat()]); } @@ -180,21 +246,21 @@ void PotStreamAudio::resetDecodeState() //memset(data, 0, screamSize); } -int PotStreamAudio::setVolume(int v) +void PotStreamAudio::setVolume(float v) { - v = std::max(v, 0); + v = std::max(v, 0.0f); v = std::min(v, Engine::getMaxVolume()); //fmt1::print("\rvolume is %d\t\t\t\t\t", v); - return volume_ = v; + volume_ = v; + Engine::getInstance()->setAudioStreamGain(v); } -int PotStreamAudio::changeVolume(int v) +void PotStreamAudio::changeVolume(float v) { - if (v == 0) + if (v != 0) { - return volume_; + setVolume(volume_ + v); } - return setVolume(volume_ + v); } void PotStreamAudio::setPause(bool pause) diff --git a/src/PotStreamAudio.h b/src/PotStreamAudio.h index c685058..1a1e752 100644 --- a/src/PotStreamAudio.h +++ b/src/PotStreamAudio.h @@ -14,9 +14,9 @@ class PotStreamAudio : public PotStream virtual ~PotStreamAudio(); private: - const int buffer_size_ = 0x400000, convert_size_ = 192000; + const int buffer_size_ = 0x400000, convert_size_ = 0x400000; void* buffer_ = nullptr; - static int volume_; + static float volume_; int scream_length_ = 0; uint8_t* resample_buffer_ = nullptr; int64_t data_read_ = 0, data_write_ = 0; //读取和写入字节数,实际位置由该值与尺寸的余数计算 @@ -24,15 +24,21 @@ class PotStreamAudio : public PotStream PotResample resample_; void mixAudioData(uint8_t* stream, int len); + virtual FrameContent convertFrameToContent() override; virtual bool needDecode2() override; public: + int show(); void openAudioDevice(); int closeAudioDevice(); void resetDecodeState(); - static int setVolume(int v); - static int changeVolume(int v); - static int getVolume() { return volume_; }; + + //音量看起来是全局的,并非是每个音频流的 + static void setVolume(float v); + static void changeVolume(float v); + + static float getVolume() { return volume_; } + virtual void setPause(bool pause) override; }; diff --git a/src/PotStreamSubtitle.cpp b/src/PotStreamSubtitle.cpp index 302fcdb..4ff5cf3 100644 --- a/src/PotStreamSubtitle.cpp +++ b/src/PotStreamSubtitle.cpp @@ -5,7 +5,7 @@ PotStreamSubtitle::PotStreamSubtitle() { - type_ = BPMEDIA_TYPE_SUBTITLE; + type_ = MEDIA_TYPE_SUBTITLE; sub_ = PotSubtitleManager::createSubtitle(" .ass"); } @@ -76,8 +76,8 @@ FrameContent PotStreamSubtitle::convertFrameToContent() if (rect->ass) { sub_->readOne(rect->ass, - avsubtitle_.pts / AV_TIME_BASE * 1000 + avsubtitle_.start_display_time, - avsubtitle_.pts / AV_TIME_BASE * 1000 + avsubtitle_.end_display_time); + 1.0 * avsubtitle_.pts / AV_TIME_BASE * 1000 + avsubtitle_.start_display_time, + 1.0 * avsubtitle_.pts / AV_TIME_BASE * 1000 + avsubtitle_.end_display_time); } } return { time_dts_, 0, nullptr }; diff --git a/src/PotStreamVideo.cpp b/src/PotStreamVideo.cpp index 3dfb9d0..ea3deef 100644 --- a/src/PotStreamVideo.cpp +++ b/src/PotStreamVideo.cpp @@ -5,7 +5,7 @@ PotStreamVideo::PotStreamVideo() { //视频缓冲区, 足够大时会较流畅,但是跳帧会闪烁 - type_ = BPMEDIA_TYPE_VIDEO; + type_ = MEDIA_TYPE_VIDEO; //create_module_ = (create_module_t)DynamicLibrary::getFunction(Config::getInstance()->getString("plugin"), "create_module"); //if (create_module_) @@ -43,7 +43,7 @@ void PotStreamVideo::freeContent(void* p) { if (p != engine_->getMainTexture()) { - engine_->destroyTexture((BP_Texture*)p); + engine_->destroyTexture((Texture*)p); } } @@ -56,14 +56,14 @@ FrameContent PotStreamVideo::convertFrameToContent() auto tex = engine_->getMainTexture(); switch (texture_pix_fmt_) { - case SDL_PIXELFORMAT_UNKNOWN: + case SDL_PIXELFORMAT_UNKNOWN: //实际使用SDL_PIXELFORMAT_RGBA8888 { uint8_t* pixels[4]; int pitch[4]; if (plugin_ == nullptr) { - img_convert_ctx_ = sws_getCachedContext(img_convert_ctx_, f->width, f->height, AVPixelFormat(f->format), f->width, f->height, AV_PIX_FMT_RGB24, SWS_FAST_BILINEAR, NULL, NULL, NULL); - if (!engine_->lockTexture(tex, nullptr, (void**)pixels, pitch)) + img_convert_ctx_ = sws_getCachedContext(img_convert_ctx_, f->width, f->height, AVPixelFormat(f->format), f->width, f->height, AV_PIX_FMT_RGB32_1, SWS_FAST_BILINEAR, NULL, NULL, NULL); + if (engine_->lockTexture(tex, nullptr, (void**)pixels, pitch)) { sws_scale(img_convert_ctx_, (const uint8_t* const*)f->data, f->linesize, 0, f->height, pixels, pitch); engine_->unlockTexture(tex); @@ -72,8 +72,8 @@ FrameContent PotStreamVideo::convertFrameToContent() else { double scale = 1; - img_convert_ctx_ = sws_getCachedContext(img_convert_ctx_, f->width, f->height, AVPixelFormat(f->format), f->width / scale, f->height / scale, AV_PIX_FMT_RGB24, SWS_FAST_BILINEAR, NULL, NULL, NULL); - if (!engine_->lockTexture(tex, nullptr, (void**)pixels, pitch)) + img_convert_ctx_ = sws_getCachedContext(img_convert_ctx_, f->width, f->height, AVPixelFormat(f->format), f->width / scale, f->height / scale, AV_PIX_FMT_RGB32_1, SWS_FAST_BILINEAR, NULL, NULL, NULL); + if (engine_->lockTexture(tex, nullptr, (void**)pixels, pitch)) { std::vector buffer(f->width * f->height * 3); uint8_t* pixels1[4]; @@ -107,11 +107,11 @@ FrameContent PotStreamVideo::convertFrameToContent() default: if (f->linesize[0] < 0) { - engine_->updateARGBTexture(tex, f->data[0] + f->linesize[0] * (f->height - 1), -f->linesize[0]); + engine_->updateTexture(tex, f->data[0] + f->linesize[0] * (f->height - 1), -f->linesize[0]); } else { - engine_->updateARGBTexture(tex, f->data[0], f->linesize[0]); + engine_->updateTexture(tex, f->data[0], f->linesize[0]); } } return { time_dts_, f->linesize[0], tex }; @@ -132,8 +132,8 @@ int PotStreamVideo::show(int time) int time_c = f.time; if (time >= time_c) { - auto tex = (BP_Texture*)f.data; - engine_->renderCopy(tex); + auto tex = (Texture*)f.data; + engine_->renderTexture(tex); time_shown_ = time_c; ticks_shown_ = engine_->getTicks(); dropDecoded(); @@ -147,23 +147,23 @@ int PotStreamVideo::show(int time) return NoVideoFrame; } -int PotStreamVideo::getSDLPixFmt() +SDL_PixelFormat PotStreamVideo::getSDLPixFmt() { if (!exist()) { return SDL_PIXELFORMAT_UNKNOWN; } - std::map pix_ffmpeg_sdl = { + std::map pix_ffmpeg_sdl = { { AV_PIX_FMT_RGB8, SDL_PIXELFORMAT_RGB332 }, - { AV_PIX_FMT_RGB444, SDL_PIXELFORMAT_RGB444 }, - { AV_PIX_FMT_RGB555, SDL_PIXELFORMAT_RGB555 }, - { AV_PIX_FMT_BGR555, SDL_PIXELFORMAT_BGR555 }, + { AV_PIX_FMT_RGB444, SDL_PIXELFORMAT_XRGB4444 }, + { AV_PIX_FMT_RGB555, SDL_PIXELFORMAT_XRGB1555 }, + { AV_PIX_FMT_BGR555, SDL_PIXELFORMAT_XBGR1555 }, { AV_PIX_FMT_RGB565, SDL_PIXELFORMAT_RGB565 }, { AV_PIX_FMT_BGR565, SDL_PIXELFORMAT_BGR565 }, { AV_PIX_FMT_RGB24, SDL_PIXELFORMAT_RGB24 }, { AV_PIX_FMT_BGR24, SDL_PIXELFORMAT_BGR24 }, - { AV_PIX_FMT_0RGB32, SDL_PIXELFORMAT_RGB888 }, - { AV_PIX_FMT_0BGR32, SDL_PIXELFORMAT_BGR888 }, + { AV_PIX_FMT_0RGB32, SDL_PIXELFORMAT_XRGB8888 }, + { AV_PIX_FMT_0BGR32, SDL_PIXELFORMAT_XBGR8888 }, { AV_PIX_FMT_NE(RGB0, 0BGR), SDL_PIXELFORMAT_RGBX8888 }, { AV_PIX_FMT_NE(BGR0, 0RGB), SDL_PIXELFORMAT_BGRX8888 }, { AV_PIX_FMT_RGB32, SDL_PIXELFORMAT_ARGB8888 }, @@ -175,13 +175,13 @@ int PotStreamVideo::getSDLPixFmt() { AV_PIX_FMT_UYVY422, SDL_PIXELFORMAT_UYVY }, { AV_PIX_FMT_NONE, SDL_PIXELFORMAT_UNKNOWN }, }; - int r = SDL_PIXELFORMAT_UNKNOWN; + auto r = SDL_PIXELFORMAT_UNKNOWN; if (plugin_ == nullptr) { if (codec_ctx_ && pix_ffmpeg_sdl.count(codec_ctx_->pix_fmt) > 0) { r = pix_ffmpeg_sdl[codec_ctx_->pix_fmt]; - fmt1::print("pixel format is {}\n", r); + fmt1::print("pixel format is {}\n", int(r)); } } texture_pix_fmt_ = r; diff --git a/src/PotStreamVideo.h b/src/PotStreamVideo.h index 8fadad3..a5917b6 100644 --- a/src/PotStreamVideo.h +++ b/src/PotStreamVideo.h @@ -39,7 +39,7 @@ class PotStreamVideo : public PotStream virtual int getHeight() { return exist() ? int(codec_ctx_->height / 1) * scale_ : 0; } public: - int getSDLPixFmt(); + SDL_PixelFormat getSDLPixFmt(); private: int texture_pix_fmt_; diff --git a/src/PotSubtitle.cpp b/src/PotSubtitle.cpp index 5108225..f719b61 100644 --- a/src/PotSubtitle.cpp +++ b/src/PotSubtitle.cpp @@ -1,4 +1,4 @@ -#include "PotSubtitle.h" +#include "PotSubtitle.h" #include "Config.h" #include "PotSubtitleAss.h" #include "PotSubtitleSrt.h" @@ -6,23 +6,9 @@ PotSubtitle::PotSubtitle() { -#ifdef _WIN32 - fontpath_ = R"(C:/Program Files/Microsoft Office/root/vfs/Fonts/private,C:/Windows/Fonts)"; -#endif -#ifdef __APPLE__ - fontpath_ = "/System/Library/Fonts"; -#endif - auto fontpath = Config::getInstance()->getString("sub_font"); - if (filefunc::fileExist(fontpath)) - { - fontpath_ += fontpath + "," + fontpath_; - } + subfilename_ = Config::getInstance()["sub_font"].toString(); } PotSubtitle::~PotSubtitle() { - if (Config::getInstance()->getString("sub_font") == "") - { - Config::getInstance()->setString("sub_font", fontpath_); - } } diff --git a/src/PotSubtitle.h b/src/PotSubtitle.h index ee67acc..4578f3d 100644 --- a/src/PotSubtitle.h +++ b/src/PotSubtitle.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "PotBase.h" extern "C" @@ -30,7 +30,6 @@ class PotSubtitle : public PotBase public: bool exist() { return exist_; } - bool reOpenSubtitle() { return openSubtitle(subfilename_); } virtual void init() {} virtual bool openSubtitle(const std::string& filename) { return false; } diff --git a/src/PotSubtitleAss.cpp b/src/PotSubtitleAss.cpp index 1c03bf9..c7bb693 100644 --- a/src/PotSubtitleAss.cpp +++ b/src/PotSubtitleAss.cpp @@ -39,6 +39,13 @@ void PotSubtitleAss::init() // fmt1::print("{} ", int(p[i])); //} +#ifdef _WIN32 + fontpath_ = R"(C:/Windows/Fonts)"; +#endif +#ifdef __APPLE__ + fontpath_ = "/System/Library/Fonts"; +#endif + ass_set_fonts_dir(library_, fontpath_.c_str()); //字体目录看起来只能设置一个 ass_set_fonts(renderer_, NULL, NULL, 1, NULL, 1); ass_set_extract_fonts(library_, 1); } @@ -113,8 +120,8 @@ int PotSubtitleAss::show(int time) destroyAllTex(); while (img) { - auto t = engine_->transBitmapToTexture(img->bitmap, img->color, img->w, img->h, img->stride); - engine_->renderCopy(t, img->dst_x, img->dst_y, img->w, img->h, 0, 1); + auto t = engine_->transRGBABitmapToTexture(img->bitmap, img->color, img->w, img->h, img->stride); + engine_->renderTexture(t, img->dst_x, img->dst_y, img->w, img->h, 0, 1); tex_vector_.push_back(t); img = img->next; } @@ -124,7 +131,7 @@ int PotSubtitleAss::show(int time) int i = 0; while (img && i < tex_vector_.size()) { - engine_->renderCopy(tex_vector_[i++], img->dst_x, img->dst_y, img->w, img->h, 0, 1); + engine_->renderTexture(tex_vector_[i++], img->dst_x, img->dst_y, img->w, img->h, 0, 1); img = img->next; } } @@ -167,7 +174,7 @@ void PotSubtitleAss::readOne(const std::string& str, int start_time, int end_tim str2.pop_back(); ass_process_data(track_, (char*)str2.c_str(), str2.size()); #ifdef _DEBUG - fmt1::print("{}\n", str); + fmt1::print("{}\n", str2); #endif } } diff --git a/src/PotSubtitleAss.h b/src/PotSubtitleAss.h index f771ce5..1f03c11 100644 --- a/src/PotSubtitleAss.h +++ b/src/PotSubtitleAss.h @@ -13,7 +13,7 @@ class PotSubtitleAss : public PotSubtitle ASS_Track* track_ = nullptr; ASS_Image* image_ = nullptr; - std::vector tex_vector_; + std::vector tex_vector_; void destroyAllTex(); public: diff --git a/src/PotSubtitleSrt.cpp b/src/PotSubtitleSrt.cpp index d9640ce..d7df1e1 100644 --- a/src/PotSubtitleSrt.cpp +++ b/src/PotSubtitleSrt.cpp @@ -144,7 +144,7 @@ int PotSubtitleSrt::show(int time) //engine_->renderCopy() int w, h; engine_->getWindowSize(w, h); - Font::getInstance()->drawSubtitle(fontpath_, tmplist.str, w * 16 / 720, w / 2, h * 9 / 10 - 5, 255, 1); + Font::getInstance()->drawSubtitle(subfilename_, tmplist.str, w * 16 / 720, w / 2, h * 9 / 10 - 5, 255, 1); break; } } diff --git a/src/PotUI.cpp b/src/PotUI.cpp index ac5b2aa..e4a6fec 100644 --- a/src/PotUI.cpp +++ b/src/PotUI.cpp @@ -36,11 +36,11 @@ void PotUI::init() void PotUI::drawText(const std::string& text) { - Font::getInstance()->drawText(fontname_.c_str(), text, 22, win_w_ - 30 - button_w_ * 2, win_h_ - 48, alpha_, BP_ALIGN_RIGHT); - //engine_->drawText(_fontname.c_str(), std::to_string(_volume / 128.0)+"%", 20, _win_w - 10, 35, _alpha, BP_ALIGN_RIGHT); + Font::getInstance()->drawText(fontname_.c_str(), text, 22, win_w_ - 30 - button_w_ * 2, win_h_ - 48, alpha_, ALIGN_RIGHT); + //engine_->drawText(_fontname.c_str(), std::to_string(_volume / 128.0)+"%", 20, _win_w - 10, 35, _alpha, ALIGN_RIGHT); } -void PotUI::drawUI(int time, int totoal_time, int volume, bool pause) +void PotUI::drawUI(int time, int totoal_time, float volume, bool pause) { engine_->getWindowSize(win_w_, win_h_); int in_button = inButton(); @@ -75,9 +75,9 @@ void PotUI::drawUI(int time, int totoal_time, int volume, bool pause) int x, y; y = win_h_ - 12; engine_->setColor(square_, { 255, 255, 255, uint8_t(alpha_ / 2) }); - engine_->renderCopy(square_, 0, y - 1, win_w_, 4); + engine_->renderTexture(square_, 0, y - 1, win_w_, 4); engine_->setColor(square_, { 255, 0, 0, alpha_ }); - engine_->renderCopy(square_, 0, y - 1, 1.0 * time / totoal_time * win_w_, 4); + engine_->renderTexture(square_, 0, y - 1, 1.0 * time / totoal_time * win_w_, 4); //ť engine_->setColor(square_, { 255, 255, 255, alpha_ }); @@ -97,43 +97,43 @@ void PotUI::drawUI(int time, int totoal_time, int volume, bool pause) case ButtonPause: if (pause) { - engine_->renderCopy(triangle_, button_x, button_y, button_w_, button_h_); + engine_->renderTexture(triangle_, button_x, button_y, button_w_, button_h_); } else { - engine_->renderCopy(square_, button_x, button_y, 8, button_h_); - engine_->renderCopy(square_, button_x + 12, button_y, 8, button_h_); + engine_->renderTexture(square_, button_x, button_y, 8, button_h_); + engine_->renderTexture(square_, button_x + 12, button_y, 8, button_h_); } break; case ButtonNext: - engine_->renderCopy(triangle_, button_x, button_y, button_w_ / 2, button_h_); - engine_->renderCopy(square_, button_x + 12, button_y, 8, button_h_); + engine_->renderTexture(triangle_, button_x, button_y, button_w_ / 2, button_h_); + engine_->renderTexture(square_, button_x + 12, button_y, 8, button_h_); break; case ButtonFullScreen: if (engine_->isFullScreen()) { - engine_->renderCopy(to_window_, button_x, button_y, button_w_, button_h_); + engine_->renderTexture(to_window_, button_x, button_y, button_w_, button_h_); } else { - engine_->renderCopy(to_full_screen_, button_x, button_y, button_w_, button_h_); + engine_->renderTexture(to_full_screen_, button_x, button_y, button_w_, button_h_); } break; case ButtonLeft: - engine_->renderCopy(triangle2_, button_x, button_y, button_w_ / 2, button_h_); - engine_->renderCopy(triangle2_, button_x + 10, button_y, button_w_ / 2, button_h_); + engine_->renderTexture(triangle2_, button_x, button_y, button_w_ / 2, button_h_); + engine_->renderTexture(triangle2_, button_x + 10, button_y, button_w_ / 2, button_h_); break; case ButtonRight: - engine_->renderCopy(triangle_, button_x, button_y, button_w_ / 2, button_h_); - engine_->renderCopy(triangle_, button_x + 10, button_y, button_w_ / 2, button_h_); + engine_->renderTexture(triangle_, button_x, button_y, button_w_ / 2, button_h_); + engine_->renderTexture(triangle_, button_x + 10, button_y, button_w_ / 2, button_h_); break; case ButtonAudio: - engine_->renderCopy(square_, button_x, button_y + 5, button_w_ / 2, button_h_ / 2 + 1); - engine_->renderCopy(triangle2_, button_x + 10, button_y, button_w_ / 2, button_h_); + engine_->renderTexture(square_, button_x, button_y + 5, button_w_ / 2, button_h_ / 2 + 1); + engine_->renderTexture(triangle2_, button_x + 10, button_y, button_w_ / 2, button_h_); break; case ButtonSubtitle: - engine_->renderCopy(hollow_, button_x, button_y, button_w_, button_h_); - engine_->renderCopy(square_, button_x + button_w_ * 0.2, button_y + button_h_ * 0.6, button_w_ * 0.6, button_h_ * 0.2); + engine_->renderTexture(hollow_, button_x, button_y, button_w_, button_h_); + engine_->renderTexture(square_, button_x + button_w_ * 0.2, button_y + button_h_ * 0.6, button_w_ * 0.6, button_h_ * 0.2); break; } } @@ -141,12 +141,12 @@ void PotUI::drawUI(int time, int totoal_time, int volume, bool pause) { int x = getButtonPos(in_button) - 2; int w = getButtonWidth(in_button) + 4; - engine_->renderCopy(frame_, x, button_y_ - 2, w, button_h_ + 4); + engine_->renderTexture(frame_, x, button_y_ - 2, w, button_h_ + 4); } int button_x = win_w_ - 20 - button_w_ * 2; - int one_square = BP_AUDIO_MIX_MAXVOLUME / 16; - int v = volume; + int one_square = 8; + int v = volume * 128; for (int i_v = 0; i_v < 16; i_v++) { int h = (i_v + 1) * 1; @@ -157,7 +157,7 @@ void PotUI::drawUI(int time, int totoal_time, int volume, bool pause) r = 1.0 * (one_square + v) / one_square; } int hc = r * h; - engine_->renderCopy(square_, button_x + i_v * 3, button_y_ + button_h_ - hc, 2, hc); + engine_->renderTexture(square_, button_x + i_v * 3, button_y_ + button_h_ - hc, 2, hc); if (v < 0) { break; @@ -217,14 +217,14 @@ void PotUI::drawUI(int time, int totoal_time, int volume, bool pause) // text = strfunc::formatString("Volume %5.1f", 100.0 * volume / BP_AUDIO_MIX_MAXVOLUME); // break; } - Font::getInstance()->drawText(fontname_.c_str(), text, 18, button_x_ - 2, button_y_ - 26, alpha_, BP_ALIGN_LEFT); + Font::getInstance()->drawText(fontname_.c_str(), text, 18, button_x_ - 2, button_y_ - 26, alpha_, ALIGN_LEFT); } void PotUI::destory() { - if (Config::getInstance()->getString("ui_font") == "") + if (Config::getInstance()["ui_font"].toString() == "") { - Config::getInstance()->setString("ui_font", fontname_); + Config::getInstance()["ui_font"] = fontname_; } } @@ -292,23 +292,23 @@ int PotUI::getButtonPos(int b) return button_x_ + (b - 1) * (button_w_ + 10); } -BP_Texture* PotUI::createSquareTexture(int size) +Texture* PotUI::createSquareTexture(int size) { int d = size; - auto square_s = SDL_CreateRGBSurface(0, d, d, 32, RMASK, GMASK, BMASK, AMASK); - SDL_FillRect(square_s, nullptr, 0xffffffff); + auto square_s = SDL_CreateSurface(d, d, SDL_PIXELFORMAT_RGBA8888); + SDL_FillSurfaceRect(square_s, nullptr, 0xffffffff); auto square = SDL_CreateTextureFromSurface(engine_->getRenderer(), square_s); SDL_SetTextureBlendMode(square, SDL_BLENDMODE_BLEND); SDL_SetTextureAlphaMod(square, 128); - SDL_FreeSurface(square_s); + SDL_DestroySurface(square_s); return square; } -BP_Texture* PotUI::createSpecialTexture(int size, int mode) +Texture* PotUI::createSpecialTexture(int size, int mode) { int d = size; - auto ball_s = SDL_CreateRGBSurface(0, d, d, 32, RMASK, GMASK, BMASK, AMASK); - SDL_FillRect(ball_s, nullptr, 0); + auto ball_s = SDL_CreateSurface(d, d, SDL_PIXELFORMAT_RGBA8888); + SDL_FillSurfaceRect(ball_s, nullptr, 0); SDL_Rect r = { 0, 0, 1, 1 }; auto& x = r.x; auto& y = r.y; @@ -331,7 +331,7 @@ BP_Texture* PotUI::createSpecialTexture(int size, int mode) a0 = 0; // (1 - ra) * 255 * 2; } uint8_t a = a0 > 255 ? 255 : a0; - SDL_FillRect(ball_s, &r, SDL_MapRGBA(ball_s->format, 255, 255, 255, a)); + SDL_FillSurfaceRect(ball_s, &r, SDL_MapSurfaceRGBA(ball_s, 255, 255, 255, a)); } if (mode == 1) { @@ -340,7 +340,7 @@ BP_Texture* PotUI::createSpecialTexture(int size, int mode) { a = 0; } - SDL_FillRect(ball_s, &r, SDL_MapRGBA(ball_s->format, 255, 255, 255, a)); + SDL_FillSurfaceRect(ball_s, &r, SDL_MapSurfaceRGBA(ball_s, 255, 255, 255, a)); } if (mode == 2) { @@ -349,13 +349,13 @@ BP_Texture* PotUI::createSpecialTexture(int size, int mode) { a = 0; } - SDL_FillRect(ball_s, &r, SDL_MapRGBA(ball_s->format, 255, 255, 255, a)); + SDL_FillSurfaceRect(ball_s, &r, SDL_MapSurfaceRGBA(ball_s, 255, 255, 255, a)); } if (mode == 3) { uint8_t a = 255; a = 225.0 / d * y; - SDL_FillRect(ball_s, &r, SDL_MapRGBA(ball_s->format, 0, 0, 0, a)); + SDL_FillSurfaceRect(ball_s, &r, SDL_MapSurfaceRGBA(ball_s, 0, 0, 0, a)); } if (mode == 4) { @@ -366,7 +366,7 @@ BP_Texture* PotUI::createSpecialTexture(int size, int mode) { a = 0; } - SDL_FillRect(ball_s, &r, SDL_MapRGBA(ball_s->format, 255, 255, 255, a)); + SDL_FillSurfaceRect(ball_s, &r, SDL_MapSurfaceRGBA(ball_s, 255, 255, 255, a)); } if (mode == 5) { @@ -377,7 +377,7 @@ BP_Texture* PotUI::createSpecialTexture(int size, int mode) { a = 0; } - SDL_FillRect(ball_s, &r, SDL_MapRGBA(ball_s->format, 255, 255, 255, a)); + SDL_FillSurfaceRect(ball_s, &r, SDL_MapSurfaceRGBA(ball_s, 255, 255, 255, a)); } if (mode == 6) { @@ -387,7 +387,7 @@ BP_Texture* PotUI::createSpecialTexture(int size, int mode) { a = 0; } - SDL_FillRect(ball_s, &r, SDL_MapRGBA(ball_s->format, 255, 255, 255, a)); + SDL_FillSurfaceRect(ball_s, &r, SDL_MapSurfaceRGBA(ball_s, 255, 255, 255, a)); } if (mode == 7) { @@ -396,13 +396,13 @@ BP_Texture* PotUI::createSpecialTexture(int size, int mode) { a = 255; } - SDL_FillRect(ball_s, &r, SDL_MapRGBA(ball_s->format, 255, 255, 255, a)); + SDL_FillSurfaceRect(ball_s, &r, SDL_MapSurfaceRGBA(ball_s, 255, 255, 255, a)); } } } auto ball = SDL_CreateTextureFromSurface(engine_->getRenderer(), ball_s); SDL_SetTextureBlendMode(ball, SDL_BLENDMODE_BLEND); SDL_SetTextureAlphaMod(ball, 128); - SDL_FreeSurface(ball_s); + SDL_DestroySurface(ball_s); return ball; } diff --git a/src/PotUI.h b/src/PotUI.h index 8ea81ca..2ffcb51 100644 --- a/src/PotUI.h +++ b/src/PotUI.h @@ -22,9 +22,9 @@ class PotUI : public PotBase }; private: - BP_Texture *square_ = nullptr, *ball_ = nullptr, *triangle_ = nullptr, *triangle2_ = nullptr, *hollow_ = nullptr; - BP_Texture *to_full_screen_ = nullptr, *to_window_ = nullptr; - BP_Texture *frame_ = nullptr; + Texture *square_ = nullptr, *ball_ = nullptr, *triangle_ = nullptr, *triangle2_ = nullptr, *hollow_ = nullptr; + Texture *to_full_screen_ = nullptr, *to_window_ = nullptr; + Texture *frame_ = nullptr; int win_w_, win_h_; //int x = 0, y = 0, w = 0, h = 0; @@ -38,7 +38,7 @@ class PotUI : public PotBase public: void init(); void drawText(const std::string& text); - void drawUI(int time, int totoal_time, int volume, bool pause); + void drawUI(int time, int totoal_time, float volume, bool pause); void destory(); std::string convertTimeToString(int time); void setText(std::string t); @@ -48,6 +48,6 @@ class PotUI : public PotBase int getButtonPos(int b); private: - BP_Texture* createSquareTexture(int size); - BP_Texture* createSpecialTexture(int size, int mode = 0); + Texture* createSquareTexture(int size); + Texture* createSpecialTexture(int size, int mode = 0); }; diff --git a/src/pot.cpp b/src/pot.cpp index ea2d666..542fa32 100644 --- a/src/pot.cpp +++ b/src/pot.cpp @@ -1,5 +1,6 @@ #include "PotPlayer.h" +#include "SDL3/SDL_main.h" #ifndef _WINDLL //in SDL, this is not the real main function, the argc is of utf-8, not ansi on Windows diff --git a/src/smallpot.vcxproj b/src/smallpot.vcxproj index c0a418c..d82b49b 100644 --- a/src/smallpot.vcxproj +++ b/src/smallpot.vcxproj @@ -141,12 +141,12 @@ Console true - sdl2main.lib;%(AdditionalDependencies) + sdl3_ttf.lib;%(AdditionalDependencies) false false - $(VCPKG_LIB_PATH)\x64-windows\lib;$(VCPKG_LIB_PATH)\x64-windows\lib\manual-link;lib/x64 + ../lib/x64 true @@ -207,8 +207,8 @@ false - sdl2main.lib;%(AdditionalDependencies) - $(VCPKG_LIB_PATH)\x64-windows\lib\manual-link;lib/x64 + sdl3_ttf.lib;%(AdditionalDependencies) + ../lib/x64 copy /y ..\x64\Release\*.exe ..\smallpot-x64\