diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 0ee8c37..82f3a50 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -42,7 +42,9 @@ jobs: - name: Build MacOS env: ENV_QT_PATH: ${{ env.qt-install-path }} - run: ci/mac/build_for_mac.sh release + run: | + python ci/generate-version.py + ci/mac/build_for_mac.sh release # 获取ref最后一个/后的内容 - name: Get the version shell: bash diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index cdf06d1..75d6915 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -45,4 +45,6 @@ jobs: - name: Build Ubuntu env: ENV_QT_PATH: ${{ env.qt-install-path }} - run: ci/linux/build_for_ubuntu.sh release + run: | + python ci/generate-version.py + ci/linux/build_for_ubuntu.sh release diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 7b9c140..448dc1a 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -71,6 +71,7 @@ jobs: ENV_VCVARSALL: ${{ env.vcvarsall-path }} ENV_QT_PATH: ${{ env.qt-install-path }} run: | + call python ci\generate-version.py call "ci\win\build_for_win.bat" release ${{ matrix.msvc-arch }} # 获取ref最后一个/后的内容 - name: Get the version diff --git a/QtScrcpy/QtScrcpy.pro b/QtScrcpy/QtScrcpy.pro index 1fec900..c2ef405 100644 --- a/QtScrcpy/QtScrcpy.pro +++ b/QtScrcpy/QtScrcpy.pro @@ -26,6 +26,12 @@ msvc{ QMAKE_CFLAGS += -source-charset:utf-8 QMAKE_CXXFLAGS += -source-charset:utf-8 } + +# warning as error +#4566 https://github.com/Chuyu-Team/VC-LTL/issues/27 +*g++*: QMAKE_CXXFLAGS += -Werror +*msvc*: QMAKE_CXXFLAGS += /WX /wd4566 + # 源码 SOURCES += \ main.cpp \ @@ -56,10 +62,18 @@ INCLUDEPATH += \ $$PWD/devicemanage \ $$PWD/fontawesome -# 统一版本号入口,只修改这一个地方即可 -VERSION_MAJOR = 1 -VERSION_MINOR = 3 -VERSION_PATCH = 1 +# 如果变量没有定义 +# !defined(TEST_VAR, var) { +# message("test") +# } + +# 从文件读取版本号 +CAT_VERSION = $$cat($$PWD/version) +# 拆分出版本号 +VERSION_MAJOR = $$section(CAT_VERSION, ., 0, 0) +VERSION_MINOR = $$section(CAT_VERSION, ., 1, 1) +VERSION_PATCH = $$section(CAT_VERSION, ., 2, 2) +message("version:" $${VERSION_MAJOR}.$${VERSION_MINOR}.$${VERSION_PATCH}) # qmake变量的方式定义版本号 VERSION = $${VERSION_MAJOR}.$${VERSION_MINOR}.$${VERSION_PATCH} diff --git a/QtScrcpy/adb/adbprocess.cpp b/QtScrcpy/adb/adbprocess.cpp index 5dcd92c..6d4980d 100644 --- a/QtScrcpy/adb/adbprocess.cpp +++ b/QtScrcpy/adb/adbprocess.cpp @@ -5,6 +5,7 @@ #include #include "adbprocess.h" +#include "config.h" QString AdbProcess::s_adbPath = ""; @@ -25,9 +26,14 @@ const QString &AdbProcess::getAdbPath() if (s_adbPath.isEmpty()) { s_adbPath = QString::fromLocal8Bit(qgetenv("QTSCRCPY_ADB_PATH")); QFileInfo fileInfo(s_adbPath); + if (s_adbPath.isEmpty() || !fileInfo.isFile()) { + s_adbPath = Config::getInstance().getAdbPath(); + } + fileInfo = s_adbPath; if (s_adbPath.isEmpty() || !fileInfo.isFile()) { s_adbPath = QCoreApplication::applicationDirPath() + "/adb"; } + qInfo("adb path: %s", QDir(s_adbPath).absolutePath().toUtf8().data()); } return s_adbPath; } diff --git a/QtScrcpy/device/controller/inputconvert/controlmsg.cpp b/QtScrcpy/device/controller/inputconvert/controlmsg.cpp index fa6444d..021b097 100644 --- a/QtScrcpy/device/controller/inputconvert/controlmsg.cpp +++ b/QtScrcpy/device/controller/inputconvert/controlmsg.cpp @@ -107,7 +107,7 @@ QByteArray ControlMsg::serializeData() BufferUtil::write32(buffer, m_data.injectKeycode.metastate); break; case CMT_INJECT_TEXT: - BufferUtil::write16(buffer, strlen(m_data.injectText.text)); + BufferUtil::write16(buffer, static_cast(strlen(m_data.injectText.text))); buffer.write(m_data.injectText.text, strlen(m_data.injectText.text)); break; case CMT_INJECT_TOUCH: { @@ -124,7 +124,7 @@ QByteArray ControlMsg::serializeData() BufferUtil::write32(buffer, m_data.injectScroll.vScroll); break; case CMT_SET_CLIPBOARD: - BufferUtil::write16(buffer, strlen(m_data.setClipboard.text)); + BufferUtil::write16(buffer, static_cast(strlen(m_data.setClipboard.text))); buffer.write(m_data.setClipboard.text, strlen(m_data.setClipboard.text)); break; case CMT_SET_SCREEN_POWER_MODE: diff --git a/QtScrcpy/device/render/qyuvopenglwidget.cpp b/QtScrcpy/device/render/qyuvopenglwidget.cpp index 44572b7..783bdc9 100644 --- a/QtScrcpy/device/render/qyuvopenglwidget.cpp +++ b/QtScrcpy/device/render/qyuvopenglwidget.cpp @@ -29,7 +29,6 @@ static const GLfloat coordinate[] = { // 纹理坐标,存储4个xy坐标 // 坐标范围为[0,1],左下角为 0,0 - // TODO 为什么这个顺序指定四个顶点?顶点坐标和纹理坐标如何映射的? 0.0f, 1.0f, 1.0f, @@ -62,15 +61,21 @@ static QString s_fragShader = R"( { vec3 yuv; vec3 rgb; - // SDL2-2.0.10\src\render\opengl\SDL_shaders_gl.c BT709_SHADER_CONSTANTS + + // SDL2 BT709_SHADER_CONSTANTS + // https://github.com/spurious/SDL-mirror/blob/4ddd4c445aa059bb127e101b74a8c5b59257fbe2/src/render/opengl/SDL_shaders_gl.c#L102 const vec3 Rcoeff = vec3(1.1644, 0.000, 1.7927); const vec3 Gcoeff = vec3(1.1644, -0.2132, -0.5329); const vec3 Bcoeff = vec3(1.1644, 2.1124, 0.000); + // 根据指定的纹理textureY和坐标textureOut来采样 yuv.x = texture2D(textureY, textureOut).r; yuv.y = texture2D(textureU, textureOut).r - 0.5; yuv.z = texture2D(textureV, textureOut).r - 0.5; + // 采样完转为rgb + // 减少一些亮度 + yuv.x = yuv.x - 0.0625; rgb.r = dot(yuv, Rcoeff); rgb.g = dot(yuv, Gcoeff); rgb.b = dot(yuv, Bcoeff); @@ -220,7 +225,7 @@ void QYUVOpenGLWidget::initTextures() // 设置st方向上纹理超出坐标时的显示策略 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, m_frameSize.width(), m_frameSize.height(), 0, GL_RED, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_frameSize.width(), m_frameSize.height(), 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr); glGenTextures(1, &m_texture[1]); glBindTexture(GL_TEXTURE_2D, m_texture[1]); @@ -228,7 +233,7 @@ void QYUVOpenGLWidget::initTextures() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, m_frameSize.width() / 2, m_frameSize.height() / 2, 0, GL_RED, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_frameSize.width() / 2, m_frameSize.height() / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr); glGenTextures(1, &m_texture[2]); glBindTexture(GL_TEXTURE_2D, m_texture[2]); @@ -238,7 +243,7 @@ void QYUVOpenGLWidget::initTextures() // 设置st方向上纹理超出坐标时的显示策略 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, m_frameSize.width() / 2, m_frameSize.height() / 2, 0, GL_RED, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_frameSize.width() / 2, m_frameSize.height() / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr); m_textureInited = true; } @@ -249,7 +254,7 @@ void QYUVOpenGLWidget::deInitTextures() glDeleteTextures(3, m_texture); } - memset(m_texture, 0, 3); + memset(m_texture, 0, sizeof(m_texture)); m_textureInited = false; } @@ -262,7 +267,7 @@ void QYUVOpenGLWidget::updateTexture(GLuint texture, quint32 textureType, quint8 makeCurrent(); glBindTexture(GL_TEXTURE_2D, texture); - glPixelStorei(GL_UNPACK_ROW_LENGTH, stride); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size.width(), size.height(), GL_RED, GL_UNSIGNED_BYTE, pixels); + glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast(stride)); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size.width(), size.height(), GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels); doneCurrent(); } diff --git a/QtScrcpy/device/stream/stream.cpp b/QtScrcpy/device/stream/stream.cpp index 2611156..3eac3e4 100644 --- a/QtScrcpy/device/stream/stream.cpp +++ b/QtScrcpy/device/stream/stream.cpp @@ -9,7 +9,7 @@ #define BUFSIZE 0x10000 #define HEADER_SIZE 12 -#define NO_PTS UINT64_C(-1) +#define NO_PTS UINT64_MAX typedef qint32 (*ReadPacketFunc)(void *, quint8 *, qint32); @@ -28,6 +28,7 @@ static void avLogCallback(void *avcl, int level, const char *fmt, va_list vl) case AV_LOG_PANIC: case AV_LOG_FATAL: qFatal("%s", localFmt.toUtf8().data()); + break; case AV_LOG_ERROR: qCritical() << localFmt.toUtf8(); break; @@ -70,14 +71,14 @@ void Stream::setDecoder(Decoder *decoder) static quint32 bufferRead32be(quint8 *buf) { - return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; + return static_cast((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]); } static quint64 bufferRead64be(quint8 *buf) { quint32 msb = bufferRead32be(buf); quint32 lsb = bufferRead32be(&buf[4]); - return ((quint64)msb << 32) | lsb; + return (static_cast(msb) << 32) | lsb; } void Stream::setVideoSocket(VideoSocket *videoSocket) @@ -230,16 +231,16 @@ bool Stream::recvPacket(AVPacket *packet) quint64 pts = bufferRead64be(header); quint32 len = bufferRead32be(&header[8]); - Q_ASSERT(pts == static_cast(NO_PTS) || (pts & 0x8000000000000000) == 0); + Q_ASSERT(pts == NO_PTS || (pts & 0x8000000000000000) == 0); Q_ASSERT(len); - if (av_new_packet(packet, len)) { + if (av_new_packet(packet, static_cast(len))) { qCritical("Could not allocate packet"); return false; } - r = recvData(packet->data, len); - if (r < 0 || ((uint32_t)r) < len) { + r = recvData(packet->data, static_cast(len)); + if (r < 0 || static_cast(r) < len) { av_packet_unref(packet); return false; } @@ -272,7 +273,7 @@ bool Stream::pushPacket(AVPacket *packet) m_hasPending = true; } - memcpy(m_pending.data + offset, packet->data, packet->size); + memcpy(m_pending.data + offset, packet->data, static_cast(packet->size)); if (!isConfig) { // prepare the concat packet to send to the decoder diff --git a/QtScrcpy/res/QtScrcpy.rc b/QtScrcpy/res/QtScrcpy.rc index 5898338..f65b4ab 100644 --- a/QtScrcpy/res/QtScrcpy.rc +++ b/QtScrcpy/res/QtScrcpy.rc @@ -1,9 +1,7 @@ #include "winres.h" -// ͼ IDI_ICON1 ICON "QtScrcpy.ico" - -// 汾Ϣ +// 为了FileDescription的中文不乱码,中文系统上本文件需要gbk编码,英文系统上本文件需要utf8编码 VS_VERSION_INFO VERSIONINFO FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH @@ -22,7 +20,7 @@ BEGIN BLOCK "080404b0" BEGIN VALUE "CompanyName", "RanKun" - VALUE "FileDescription", "׿ʵʱͬ" + VALUE "FileDescription", "安卓实时同屏软件" VALUE "FileVersion", VERSION_RC_STR VALUE "LegalCopyright", "Copyright (C) RanKun 2018-2038. All rights reserved." VALUE "ProductName", "QtScrcpy" diff --git a/QtScrcpy/util/config.cpp b/QtScrcpy/util/config.cpp index 222a3c3..bf9c43a 100644 --- a/QtScrcpy/util/config.cpp +++ b/QtScrcpy/util/config.cpp @@ -31,6 +31,9 @@ #define COMMON_RENDER_EXPIRED_FRAMES_KEY "RenderExpiredFrames" #define COMMON_RENDER_EXPIRED_FRAMES_DEF 0 +#define COMMON_ADB_PATH_KEY "AdbPath" +#define COMMON_ADB_PATH_DEF "" + // user data #define COMMON_RECORD_KEY "RecordPath" #define COMMON_RECORD_DEF "" @@ -253,6 +256,15 @@ QString Config::getServerPath() return serverPath; } +QString Config::getAdbPath() +{ + QString adbPath; + m_settings->beginGroup(GROUP_COMMON); + adbPath = m_settings->value(COMMON_ADB_PATH_KEY, COMMON_ADB_PATH_DEF).toString(); + m_settings->endGroup(); + return adbPath; +} + QString Config::getTitle() { QString title; diff --git a/QtScrcpy/util/config.h b/QtScrcpy/util/config.h index ed472fe..274c9e5 100644 --- a/QtScrcpy/util/config.h +++ b/QtScrcpy/util/config.h @@ -20,6 +20,7 @@ public: int getRenderExpiredFrames(); QString getPushFilePath(); QString getServerPath(); + QString getAdbPath(); // user data QString getRecordPath(); diff --git a/QtScrcpy/version b/QtScrcpy/version new file mode 100644 index 0000000..77d6f4c --- /dev/null +++ b/QtScrcpy/version @@ -0,0 +1 @@ +0.0.0 diff --git a/README.md b/README.md index 1f4a9af..c381a4b 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ It focuses on: ![linux](screenshot/ubuntu.png) -## Customized key mapping (Windows only) +## Customized key mapping (Windows&MacOS only) You can write your own script to map keyboard and mouse actions to touches and clicks of the mobile phone according to your needs. [Here](docs/按键映射说明.md) are the rules. A script for "PUBG mobile" and TikTok mapping is provided by default. Once enabled, you can play the game with your keyboard and mouse as the PC version. or you can use up/down/left/right direction keys to simulate up/down/left/right sliding. You can also write your own mapping files for other games according to [writing rules](docs/按键映射说明.md). The default key mapping is as follows: diff --git a/README_zh.md b/README_zh.md index 31c2670..acbb6ce 100644 --- a/README_zh.md +++ b/README_zh.md @@ -33,7 +33,7 @@ QtScrcpy可以通过USB(或通过TCP/IP)连接Android设备,并进行显示和 ![linux](screenshot/ubuntu.png) -## 自定义按键映射(仅windows平台开启) +## 自定义按键映射(仅windows&MacOS平台开启) 可以根据需要,自己编写脚本将PC键盘按键映射为手机的触摸点击,编写规则在[这里](docs/按键映射说明.md)。 默认自带了针对和平精英手游和抖音进行键鼠映射的映射脚本,开启平精英手游后可以用键鼠像玩端游一样玩和平精英手游,开启抖音映射以后可以使用上下左右方向键模拟上下左右滑动,你也可以按照[编写规则](docs/按键映射说明.md)编写其他游戏的映射文件,默认按键映射如下: diff --git a/ci/generate-version.py b/ci/generate-version.py new file mode 100644 index 0000000..8cd42cb --- /dev/null +++ b/ci/generate-version.py @@ -0,0 +1,20 @@ +import sys +import os + +if __name__ == '__main__': + p = os.popen('git rev-list --tags --max-count=1') + commit = p.read() + p.close() + + p = os.popen('git describe --tags ' + commit) + tag = p.read() + p.close() + + # print('get tag:', tag) + + version = str(tag[1:]) + version_file = os.path.abspath(os.path.join(os.path.dirname(__file__), "../QtScrcpy/version")) + file=open(version_file, 'w') + file.write(version) + file.close() + sys.exit(0) \ No newline at end of file diff --git a/config/config.ini b/config/config.ini index b77dcf2..9a36955 100644 --- a/config/config.ini +++ b/config/config.ini @@ -1,8 +1,6 @@ [common] # 窗口标题 WindowTitle=QtScrcpy -# 录制文件保存路径(必须以/作为分隔符) -RecordPath= # 推送到安卓设备的文件保存路径(必须以/结尾) PushFilePath=/sdcard/ # 最大fps(仅支持Android 10以上) @@ -15,3 +13,5 @@ UseDesktopOpenGL=-1 ServerVersion=1.12.1 # scrcpy-server推送到安卓设备的路径 ServerPath=/data/local/tmp/scrcpy-server.jar +# 自定义adb路径,例如D:/android/tools/adb.exe +AdbPath= diff --git a/docs/FAQ.md b/docs/FAQ.md index 1ebe090..91c9864 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -6,6 +6,18 @@ ## 支持声音(软件不做支持) [关于转发安卓声音到PC的讨论](https://github.com/Genymobile/scrcpy/issues/14#issuecomment-543204526) +## 画面不清晰 +在Windows上,您可能需要配置缩放行为。 + +QtScrcpy.exe>属性>兼容性>更改高DPI设置>覆盖高DPI缩放行为>由以下人员执行缩放:应用程序。 + +如果视频窗口大小远远小于设备屏幕的大小,则画面会不清晰。这在文字上尤其明显 + +## 玩和平精英上下车操作会失效 +这是由于游戏中上车会创建新的界面,导致鼠标触摸点失效,目前技术上没有好的解决办法 + +可以通过`连续按两次~键(数字键1左边)`来恢复,这是目前最好的办法。 + ## 无法输入中文 手机端安装搜狗输入法/QQ输入法就可以支持输入中文了