Ported to CMake, ...
* Ported the project to CMake * Android and Mac support dropped for the time being. * Tests, BASS and Discord-RPC are now options * Restructured and reformated the project. * Merged `include` and `src` * Renamed `resource` to `data` * Renamed various files * External libraries headers are no longer included in `src` * Replaced header guards with #pragma once * Multiple refactors (keywords, headers) * Added Qt6 compatibility * Removed various unused functions and headers * Reworked AOPacket * When content is passed to AOPacket, it should be ensured that the content is already decoded. * Encoding/decoding are now static methods. * Fixed various memory leaks * Removed animation code for AOImage * AOImage is always using static images * Simplified ChatLogPiece
@ -1,5 +1,73 @@
|
|||||||
|
Language: Cpp
|
||||||
BasedOnStyle: LLVM
|
BasedOnStyle: LLVM
|
||||||
BreakBeforeBraces: Stroustrup
|
|
||||||
AllowShortIfStatementsOnASingleLine: true
|
AccessModifierOffset: -2
|
||||||
NamespaceIndentation: All
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Left
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowShortBlocksOnASingleLine: Empty
|
||||||
|
AllowShortEnumsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: InlineOnly
|
||||||
|
AllowShortIfStatementsOnASingleLine : Never
|
||||||
|
AllowShortLambdasOnASingleLine: Inline
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
|
BreakBeforeConceptDeclarations: Always
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: BeforeComma
|
||||||
|
ColumnLimit: 486
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
FixNamespaceComments: true
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentRequiresClause: false
|
||||||
|
IndentWidth: 2
|
||||||
|
InsertTrailingCommas: Wrapped
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
LambdaBodyIndentation: OuterScope
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
PackConstructorInitializers: Never
|
||||||
|
PointerAlignment: Right
|
||||||
|
QualifierAlignment: Left
|
||||||
|
RequiresExpressionIndentation: OuterScope
|
||||||
|
ShortNamespaceLines: 0
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: true
|
||||||
|
AfterClass: true
|
||||||
|
AfterControlStatement: true
|
||||||
|
AfterEnum: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: true
|
||||||
|
AfterStruct: true
|
||||||
|
AfterUnion: true
|
||||||
|
AfterExternBlock: true
|
||||||
|
BeforeCatch: true
|
||||||
|
BeforeElse: true
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: false
|
||||||
|
SplitEmptyNamespace: false
|
1
.gitignore
vendored
@ -39,3 +39,4 @@ object_script*
|
|||||||
/attorney_online_*_plugin_import.cpp
|
/attorney_online_*_plugin_import.cpp
|
||||||
server/__pycache__
|
server/__pycache__
|
||||||
discord/
|
discord/
|
||||||
|
*.TMP
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
QT += core gui widgets network websockets uitools
|
|
||||||
|
|
||||||
TARGET = Attorney_Online
|
|
||||||
TEMPLATE = app
|
|
||||||
|
|
||||||
VERSION = 2.10.1.0
|
|
||||||
|
|
||||||
INCLUDEPATH += $$PWD/include
|
|
||||||
DESTDIR = $$PWD/bin
|
|
||||||
OBJECTS_DIR = $$PWD/build
|
|
||||||
MOC_DIR = $$PWD/build
|
|
||||||
|
|
||||||
SOURCES += $$files($$PWD/src/*.cpp, true)
|
|
||||||
HEADERS += $$files($$PWD/include/*.h, true)
|
|
||||||
|
|
||||||
FORMS += $$files($$PWD/resource/ui/*.ui)
|
|
||||||
|
|
||||||
LIBS += -L$$PWD/lib
|
|
||||||
QMAKE_LFLAGS += -Wl,-rpath,"'\$$ORIGIN/lib'"
|
|
||||||
QMAKE_CXXFLAGS += "-fno-sized-deallocation"
|
|
||||||
|
|
||||||
# Uncomment for verbose network logging
|
|
||||||
# DEFINES += DEBUG_NETWORK
|
|
||||||
|
|
||||||
# Uncomment for verbose animation logging
|
|
||||||
# DEFINES += DEBUG_MOVIE
|
|
||||||
|
|
||||||
# Uncomment for building with debug symbols
|
|
||||||
# CONFIG += debug
|
|
||||||
|
|
||||||
# Uncomment to enable Discord Rich Presence
|
|
||||||
# DEFINES += DISCORD
|
|
||||||
|
|
||||||
contains(DEFINES, DISCORD) {
|
|
||||||
win32:LIBS += -ldiscord-rpc
|
|
||||||
linux:!android:LIBS += -ldiscord-rpc
|
|
||||||
mac:LIBS += -ldiscord-rpc
|
|
||||||
}
|
|
||||||
|
|
||||||
# As of 2.8.5, BASS and BASSOPUS are required for all platforms. Qt Multimedia
|
|
||||||
# is no longer an option due to outdated code and lack of versatility.
|
|
||||||
# Download at un4seen.com and place the DLLs in the "lib" and "bin" folders.
|
|
||||||
DEFINES += BASSAUDIO
|
|
||||||
LIBS += -lbass
|
|
||||||
LIBS += -lbassopus
|
|
||||||
LIBS += -lbassmidi
|
|
||||||
|
|
||||||
macx:LIBS += -framework CoreFoundation -framework Foundation -framework CoreServices
|
|
||||||
|
|
||||||
win32:LIBS += -ladvapi32
|
|
||||||
|
|
||||||
CONFIG += c++17
|
|
||||||
|
|
||||||
RESOURCES += resources.qrc
|
|
||||||
|
|
||||||
TRANSLATIONS = resource/translations/ao_en.ts \
|
|
||||||
resource/translations/ao_jp.ts \
|
|
||||||
resource/translations/ao_de.ts \
|
|
||||||
resource/translations/ao_ru.ts \
|
|
||||||
resource/translations/ao_es.ts \
|
|
||||||
resource/translations/ao_pt.ts \
|
|
||||||
resource/translations/ao_pl.ts \
|
|
||||||
resource/translations/ao_it.ts \
|
|
||||||
ressource/ui/
|
|
||||||
|
|
||||||
win32:RC_ICONS = resource/logo_ao2.ico
|
|
||||||
macx:ICON = resource/logo_ao2.icns
|
|
||||||
|
|
||||||
android:QT += androidextras
|
|
||||||
|
|
||||||
android:DISTFILES += \
|
|
||||||
android/AndroidManifest.xml \
|
|
||||||
android/gradle.properties \
|
|
||||||
android/gradle/wrapper/gradle-wrapper.jar \
|
|
||||||
android/gradle/wrapper/gradle-wrapper.properties \
|
|
||||||
android/gradlew \
|
|
||||||
android/gradlew.bat
|
|
||||||
|
|
||||||
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
|
|
138
CMakeLists.txt
@ -1,8 +1,6 @@
|
|||||||
# Configure cmake
|
cmake_minimum_required(VERSION 3.7.0)
|
||||||
cmake_minimum_required(VERSION 3.1.0)
|
|
||||||
cmake_policy(SET CMP0076 NEW) # silence warning
|
|
||||||
|
|
||||||
project(AttorneyOnline)
|
project(AttorneyOnline VERSION 2.11.0.0 LANGUAGES CXX C)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
@ -11,39 +9,119 @@ set(CMAKE_AUTOMOC ON)
|
|||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
|
||||||
if(CMAKE_VERSION VERSION_LESS "3.7.0")
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# AO
|
option(AO_BUILD_TESTS "Build test programs" OFF)
|
||||||
add_executable(Attorney_Online resources.qrc)
|
option(AO_ENABLE_BASS "Enable BASS audio library" ON)
|
||||||
|
option(AO_ENABLE_DISCORD_RPC "Enable Discord Rich Presence" ON)
|
||||||
|
|
||||||
|
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core)
|
||||||
|
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui Network Widgets Concurrent WebSockets UiTools)
|
||||||
|
|
||||||
|
add_executable(Attorney_Online
|
||||||
|
src/aoapplication.cpp
|
||||||
|
src/aoapplication.h
|
||||||
|
src/aoblipplayer.cpp
|
||||||
|
src/aoblipplayer.h
|
||||||
|
src/aobutton.cpp
|
||||||
|
src/aobutton.h
|
||||||
|
src/aocharbutton.cpp
|
||||||
|
src/aocharbutton.h
|
||||||
|
src/aoclocklabel.cpp
|
||||||
|
src/aoclocklabel.h
|
||||||
|
src/aoemotebutton.cpp
|
||||||
|
src/aoemotebutton.h
|
||||||
|
src/aoemotepreview.cpp
|
||||||
|
src/aoemotepreview.h
|
||||||
|
src/aoevidencebutton.cpp
|
||||||
|
src/aoevidencebutton.h
|
||||||
|
src/aoevidencedisplay.cpp
|
||||||
|
src/aoevidencedisplay.h
|
||||||
|
src/aoimage.cpp
|
||||||
|
src/aoimage.h
|
||||||
|
src/aolayer.cpp
|
||||||
|
src/aolayer.h
|
||||||
|
src/aomusicplayer.cpp
|
||||||
|
src/aomusicplayer.h
|
||||||
|
src/aopacket.cpp
|
||||||
|
src/aopacket.h
|
||||||
|
src/aosfxplayer.cpp
|
||||||
|
src/aosfxplayer.h
|
||||||
|
src/aotextarea.cpp
|
||||||
|
src/aotextarea.h
|
||||||
|
src/aotextboxwidgets.cpp
|
||||||
|
src/aotextboxwidgets.h
|
||||||
|
src/aoutils.cpp
|
||||||
|
src/aoutils.h
|
||||||
|
src/charselect.cpp
|
||||||
|
src/chatlogpiece.cpp
|
||||||
|
src/chatlogpiece.h
|
||||||
|
src/courtroom.cpp
|
||||||
|
src/courtroom.h
|
||||||
|
src/datatypes.h
|
||||||
|
src/debug_functions.cpp
|
||||||
|
src/debug_functions.h
|
||||||
|
src/demoserver.cpp
|
||||||
|
src/demoserver.h
|
||||||
|
src/discord_rich_presence.cpp
|
||||||
|
src/discord_rich_presence.h
|
||||||
|
src/emotes.cpp
|
||||||
|
src/eventfilters.h
|
||||||
|
src/evidence.cpp
|
||||||
|
src/file_functions.cpp
|
||||||
|
src/file_functions.h
|
||||||
|
src/hardware_functions.cpp
|
||||||
|
src/hardware_functions.h
|
||||||
|
src/interfaces/server_dialog.h
|
||||||
|
src/lobby.cpp
|
||||||
|
src/lobby.h
|
||||||
|
src/main.cpp
|
||||||
|
src/networkmanager.cpp
|
||||||
|
src/networkmanager.h
|
||||||
|
src/options.cpp
|
||||||
|
src/options.h
|
||||||
|
src/packet_distribution.cpp
|
||||||
|
src/path_functions.cpp
|
||||||
|
src/scrolltext.cpp
|
||||||
|
src/scrolltext.h
|
||||||
|
src/text_file_functions.cpp
|
||||||
|
src/gui_utils.h
|
||||||
|
src/widgets/add_server_dialog.cpp
|
||||||
|
src/widgets/add_server_dialog.h
|
||||||
|
src/widgets/aooptionsdialog.cpp
|
||||||
|
src/widgets/aooptionsdialog.h
|
||||||
|
src/widgets/direct_connect_dialog.cpp
|
||||||
|
src/widgets/direct_connect_dialog.h
|
||||||
|
src/widgets/edit_server_dialog.cpp
|
||||||
|
src/widgets/edit_server_dialog.h
|
||||||
|
data.qrc
|
||||||
|
src/eventfilters.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(Attorney_Online PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin")
|
||||||
|
|
||||||
# WIN32
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
set_property(TARGET Attorney_Online PROPERTY WIN32_EXECUTABLE true)
|
set_property(TARGET Attorney_Online PROPERTY WIN32_EXECUTABLE true)
|
||||||
set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_CURRENT_SOURCE_DIR}/resource/logo_ao2.rc")
|
set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_CURRENT_SOURCE_DIR}/data/logo-client.rc")
|
||||||
target_sources(Attorney_Online PRIVATE ${APP_ICON_RESOURCE_WINDOWS})
|
target_sources(Attorney_Online PRIVATE ${APP_ICON_RESOURCE_WINDOWS})
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Target Include
|
target_include_directories(Attorney_Online PRIVATE src lib)
|
||||||
target_include_directories(Attorney_Online PRIVATE include)
|
|
||||||
|
|
||||||
# Target Lib
|
|
||||||
find_package(Qt5 COMPONENTS Core Gui Network Widgets Concurrent WebSockets REQUIRED)
|
|
||||||
target_link_directories(Attorney_Online PRIVATE lib)
|
target_link_directories(Attorney_Online PRIVATE lib)
|
||||||
target_link_libraries(Attorney_Online PRIVATE Qt5::Core Qt5::Gui Qt5::Network Qt5::Widgets Qt5::Concurrent
|
target_link_libraries(Attorney_Online PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Concurrent Qt${QT_VERSION_MAJOR}::WebSockets Qt${QT_VERSION_MAJOR}::UiTools)
|
||||||
Qt5::WebSockets bass bassmidi bassopus discord-rpc)
|
|
||||||
target_compile_definitions(Attorney_Online PRIVATE DISCORD)
|
|
||||||
|
|
||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
if(AO_ENABLE_BASS)
|
||||||
target_link_libraries(Attorney_Online PRIVATE "-framework CoreFoundation" "-framework Foundation" "-framework CoreServices")
|
target_compile_definitions(Attorney_Online PRIVATE AO_ENABLE_BASS)
|
||||||
|
target_link_libraries(Attorney_Online PRIVATE bass bassmidi bassopus)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Subdirectories
|
if(AO_ENABLE_DISCORD_RPC)
|
||||||
if (AO_BUILD_TESTS)
|
target_compile_definitions(Attorney_Online PRIVATE AO_ENABLE_DISCORD_RPC)
|
||||||
add_subdirectory(test)
|
target_link_libraries(Attorney_Online PRIVATE discord-rpc)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(AO_BUILD_TESTS)
|
||||||
|
add_subdirectory(test)
|
||||||
endif()
|
endif()
|
||||||
add_subdirectory(src)
|
|
||||||
add_subdirectory(include)
|
|
||||||
|
19
data.qrc
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>data/fonts/Ace-Attorney.ttf</file>
|
||||||
|
<file>data/logo-client.png</file>
|
||||||
|
<file>data/translations/ao_de.qm</file>
|
||||||
|
<file>data/translations/ao_en.qm</file>
|
||||||
|
<file>data/translations/ao_es.qm</file>
|
||||||
|
<file>data/translations/ao_jp.qm</file>
|
||||||
|
<file>data/translations/ao_pl.qm</file>
|
||||||
|
<file>data/translations/ao_pt.qm</file>
|
||||||
|
<file>data/translations/ao_ru.qm</file>
|
||||||
|
<file>data/ui/options_dialog.ui</file>
|
||||||
|
<file>data/ui/favorite_server_dialog.ui</file>
|
||||||
|
<file>data/ui/direct_connect_dialog.ui</file>
|
||||||
|
<file>data/ui/lobby.ui</file>
|
||||||
|
<file>data/ui/lobby_assets/down-arrow.png</file>
|
||||||
|
<file>data/ui/lobby_assets/up-arrow.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
1
data/logo-client.rc
Normal file
@ -0,0 +1 @@
|
|||||||
|
IDI_ICON1 ICON "logo-client.ico"
|
Before Width: | Height: | Size: 382 KiB After Width: | Height: | Size: 382 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 169 KiB After Width: | Height: | Size: 169 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 169 KiB After Width: | Height: | Size: 169 KiB |
Before Width: | Height: | Size: 382 KiB After Width: | Height: | Size: 382 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
@ -107,12 +107,12 @@ QHeaderView::section:pressed {
|
|||||||
|
|
||||||
QHeaderView::up-arrow
|
QHeaderView::up-arrow
|
||||||
{
|
{
|
||||||
image: url(":/resource/ui/lobby_assets/up-arrow.png");
|
image: url(":/data/ui/lobby_assets/up-arrow.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
QHeaderView::down-arrow
|
QHeaderView::down-arrow
|
||||||
{
|
{
|
||||||
image: url(":/resource/ui/lobby_assets/down-arrow.png");
|
image: url(":/data/ui/lobby_assets/down-arrow.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
QScrollBar:vertical {
|
QScrollBar:vertical {
|
Before Width: | Height: | Size: 181 B After Width: | Height: | Size: 181 B |
Before Width: | Height: | Size: 181 B After Width: | Height: | Size: 181 B |
@ -1,40 +0,0 @@
|
|||||||
target_sources(Attorney_Online PRIVATE
|
|
||||||
aoapplication.h
|
|
||||||
aoblipplayer.h
|
|
||||||
aobutton.h
|
|
||||||
aocaseannouncerdialog.h
|
|
||||||
aocharbutton.h
|
|
||||||
aoclocklabel.h
|
|
||||||
aoemotebutton.h
|
|
||||||
aoemotepreview.h
|
|
||||||
aoevidencebutton.h
|
|
||||||
aoevidencedisplay.h
|
|
||||||
aoimage.h
|
|
||||||
aolayer.h
|
|
||||||
aomusicplayer.h
|
|
||||||
aooptionsdialog.h
|
|
||||||
aopacket.h
|
|
||||||
aosfxplayer.h
|
|
||||||
aotextarea.h
|
|
||||||
aoutils.h
|
|
||||||
bass.h
|
|
||||||
bassmidi.h
|
|
||||||
bassopus.h
|
|
||||||
chatlogpiece.h
|
|
||||||
courtroom.h
|
|
||||||
datatypes.h
|
|
||||||
debug_functions.h
|
|
||||||
demoserver.h
|
|
||||||
discord-rpc.h
|
|
||||||
discord_register.h
|
|
||||||
discord_rich_presence.h
|
|
||||||
discord_rpc.h
|
|
||||||
eventfilters.h
|
|
||||||
file_functions.h
|
|
||||||
hardware_functions.h
|
|
||||||
lobby.h
|
|
||||||
misc_functions.h
|
|
||||||
networkmanager.h
|
|
||||||
scrolltext.h
|
|
||||||
text_file_functions.h
|
|
||||||
)
|
|
@ -1,23 +0,0 @@
|
|||||||
#ifndef AOBUTTON_H
|
|
||||||
#define AOBUTTON_H
|
|
||||||
|
|
||||||
#include "aoapplication.h"
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QMovie>
|
|
||||||
|
|
||||||
class AOButton : public QPushButton {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
AOButton(QWidget *parent, AOApplication *p_ao_app);
|
|
||||||
~AOButton();
|
|
||||||
|
|
||||||
AOApplication *ao_app;
|
|
||||||
QMovie *movie;
|
|
||||||
|
|
||||||
void set_image(QString p_image, QString p_misc="");
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // AOBUTTON_H
|
|
@ -1,31 +0,0 @@
|
|||||||
// This class represents a static theme-dependent image
|
|
||||||
|
|
||||||
#ifndef AOIMAGE_H
|
|
||||||
#define AOIMAGE_H
|
|
||||||
|
|
||||||
#include "aoapplication.h"
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QMovie>
|
|
||||||
|
|
||||||
class AOImage : public QLabel {
|
|
||||||
public:
|
|
||||||
AOImage(QWidget *parent, AOApplication *p_ao_app, bool make_static = false);
|
|
||||||
~AOImage();
|
|
||||||
|
|
||||||
QWidget *m_parent;
|
|
||||||
AOApplication *ao_app;
|
|
||||||
QMovie *movie;
|
|
||||||
|
|
||||||
QString path;
|
|
||||||
|
|
||||||
bool is_static = false;
|
|
||||||
|
|
||||||
bool masked = false;
|
|
||||||
|
|
||||||
bool set_image(QString p_image, QString p_misc = "");
|
|
||||||
void set_size_and_pos(QString identifier);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // AOIMAGE_H
|
|
@ -1,28 +0,0 @@
|
|||||||
#ifndef AOPACKET_H
|
|
||||||
#define AOPACKET_H
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QString>
|
|
||||||
#include <QStringList>
|
|
||||||
|
|
||||||
class AOPacket {
|
|
||||||
public:
|
|
||||||
AOPacket(QString header) : m_header(header){}
|
|
||||||
AOPacket(QString header, QStringList p_contents) : m_header(header), m_contents(p_contents){}
|
|
||||||
|
|
||||||
QString get_header() { return m_header; }
|
|
||||||
QStringList &get_contents() { return m_contents; }
|
|
||||||
QString to_string(bool encoded = false);
|
|
||||||
|
|
||||||
void net_encode();
|
|
||||||
void net_decode();
|
|
||||||
|
|
||||||
static void escape(QStringList &contents);
|
|
||||||
static void unescape(QStringList &contents);
|
|
||||||
private:
|
|
||||||
|
|
||||||
QString m_header;
|
|
||||||
QStringList m_contents;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // AOPACKET_H
|
|
@ -1,26 +0,0 @@
|
|||||||
#ifndef AOTEXTAREA_H
|
|
||||||
#define AOTEXTAREA_H
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QRegularExpression>
|
|
||||||
#include <QScrollBar>
|
|
||||||
#include <QTextBrowser>
|
|
||||||
#include <QTextCursor>
|
|
||||||
|
|
||||||
class AOTextArea : public QTextBrowser {
|
|
||||||
public:
|
|
||||||
AOTextArea(QWidget *p_parent = nullptr, int p_log_length = 5000);
|
|
||||||
|
|
||||||
void append_linked(QString p_message);
|
|
||||||
void append_chatmessage(QString p_name, QString p_message,
|
|
||||||
QString p_name_colour, QString p_color = QString());
|
|
||||||
void append_error(QString p_message);
|
|
||||||
|
|
||||||
private:
|
|
||||||
const QRegularExpression url_parser_regex = QRegularExpression("\\b(https?://\\S+\\.\\S+)\\b");
|
|
||||||
|
|
||||||
void auto_scroll(QTextCursor old_cursor, int scrollbar_value,
|
|
||||||
bool is_scrolled_down);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // AOTEXTAREA_H
|
|
@ -1,32 +0,0 @@
|
|||||||
#ifndef AOTEXTBOXWIDGETS_H
|
|
||||||
#define AOTEXTBOXWIDGETS_H
|
|
||||||
|
|
||||||
#include <QAbstractTextDocumentLayout>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QPaintEvent>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QPainterPath>
|
|
||||||
#include <QTextEdit>
|
|
||||||
|
|
||||||
class AOChatboxLabel : public QLabel {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
AOChatboxLabel(QWidget *parent);
|
|
||||||
void paintEvent(QPaintEvent *event);
|
|
||||||
|
|
||||||
void setOutlineColor(QColor color) { outline_color = color; };
|
|
||||||
void setOutlineWidth(int width) { outline_width = width; };
|
|
||||||
void setTextColor(QColor color) { text_color = color; };
|
|
||||||
void setIsOutlined(bool outlined) { is_outlined = outlined; };
|
|
||||||
|
|
||||||
protected:
|
|
||||||
private:
|
|
||||||
QColor outline_color;
|
|
||||||
QColor text_color;
|
|
||||||
int outline_width = 1;
|
|
||||||
bool is_outlined = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // AOTEXTBOXWIDGETS_H
|
|
1227
include/bass.h
@ -1,380 +0,0 @@
|
|||||||
/*
|
|
||||||
BASSMIDI 2.4 C/C++ header file
|
|
||||||
Copyright (c) 2006-2020 Un4seen Developments Ltd.
|
|
||||||
|
|
||||||
See the BASSMIDI.CHM file for more detailed documentation
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BASSMIDI_H
|
|
||||||
#define BASSMIDI_H
|
|
||||||
|
|
||||||
#include "bass.h"
|
|
||||||
|
|
||||||
#if BASSVERSION!=0x204
|
|
||||||
#error conflicting BASS and BASSMIDI versions
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BASSMIDIDEF
|
|
||||||
#define BASSMIDIDEF(f) WINAPI f
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef DWORD HSOUNDFONT; // soundfont handle
|
|
||||||
|
|
||||||
// Additional error codes returned by BASS_ErrorGetCode
|
|
||||||
#define BASS_ERROR_MIDI_INCLUDE 7000 // SFZ include file could not be opened
|
|
||||||
|
|
||||||
// Additional BASS_SetConfig options
|
|
||||||
#define BASS_CONFIG_MIDI_COMPACT 0x10400
|
|
||||||
#define BASS_CONFIG_MIDI_VOICES 0x10401
|
|
||||||
#define BASS_CONFIG_MIDI_AUTOFONT 0x10402
|
|
||||||
#define BASS_CONFIG_MIDI_IN_PORTS 0x10404
|
|
||||||
#define BASS_CONFIG_MIDI_SAMPLETHREADS 0x10406
|
|
||||||
#define BASS_CONFIG_MIDI_SAMPLEMEM 0x10407
|
|
||||||
#define BASS_CONFIG_MIDI_SAMPLEREAD 0x10408
|
|
||||||
|
|
||||||
// Additional BASS_SetConfigPtr options
|
|
||||||
#define BASS_CONFIG_MIDI_DEFFONT 0x10403
|
|
||||||
#define BASS_CONFIG_MIDI_SFZHEAD 0x10408
|
|
||||||
|
|
||||||
// Additional sync types
|
|
||||||
#define BASS_SYNC_MIDI_MARK 0x10000
|
|
||||||
#define BASS_SYNC_MIDI_MARKER 0x10000
|
|
||||||
#define BASS_SYNC_MIDI_CUE 0x10001
|
|
||||||
#define BASS_SYNC_MIDI_LYRIC 0x10002
|
|
||||||
#define BASS_SYNC_MIDI_TEXT 0x10003
|
|
||||||
#define BASS_SYNC_MIDI_EVENT 0x10004
|
|
||||||
#define BASS_SYNC_MIDI_TICK 0x10005
|
|
||||||
#define BASS_SYNC_MIDI_TIMESIG 0x10006
|
|
||||||
#define BASS_SYNC_MIDI_KEYSIG 0x10007
|
|
||||||
|
|
||||||
// Additional BASS_MIDI_StreamCreateFile/etc flags
|
|
||||||
#define BASS_MIDI_NOSYSRESET 0x800
|
|
||||||
#define BASS_MIDI_DECAYEND 0x1000
|
|
||||||
#define BASS_MIDI_NOFX 0x2000
|
|
||||||
#define BASS_MIDI_DECAYSEEK 0x4000
|
|
||||||
#define BASS_MIDI_NOCROP 0x8000
|
|
||||||
#define BASS_MIDI_NOTEOFF1 0x10000
|
|
||||||
#define BASS_MIDI_SINCINTER 0x800000
|
|
||||||
|
|
||||||
// BASS_MIDI_FontInit flags
|
|
||||||
#define BASS_MIDI_FONT_MEM 0x10000
|
|
||||||
#define BASS_MIDI_FONT_MMAP 0x20000
|
|
||||||
#define BASS_MIDI_FONT_XGDRUMS 0x40000
|
|
||||||
#define BASS_MIDI_FONT_NOFX 0x80000
|
|
||||||
#define BASS_MIDI_FONT_LINATTMOD 0x100000
|
|
||||||
#define BASS_MIDI_FONT_LINDECVOL 0x200000
|
|
||||||
#define BASS_MIDI_FONT_NORAMPIN 0x400000
|
|
||||||
#define BASS_MIDI_FONT_NOLIMITS 0x800000
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
HSOUNDFONT font; // soundfont
|
|
||||||
int preset; // preset number (-1=all)
|
|
||||||
int bank;
|
|
||||||
} BASS_MIDI_FONT;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
HSOUNDFONT font; // soundfont
|
|
||||||
int spreset; // source preset number
|
|
||||||
int sbank; // source bank number
|
|
||||||
int dpreset; // destination preset/program number
|
|
||||||
int dbank; // destination bank number
|
|
||||||
int dbanklsb; // destination bank number LSB
|
|
||||||
} BASS_MIDI_FONTEX;
|
|
||||||
|
|
||||||
// BASS_MIDI_StreamSet/GetFonts flag
|
|
||||||
#define BASS_MIDI_FONT_EX 0x1000000 // BASS_MIDI_FONTEX
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char *name;
|
|
||||||
const char *copyright;
|
|
||||||
const char *comment;
|
|
||||||
DWORD presets; // number of presets/instruments
|
|
||||||
DWORD samsize; // total size (in bytes) of the sample data
|
|
||||||
DWORD samload; // amount of sample data currently loaded
|
|
||||||
DWORD samtype; // sample format (CTYPE) if packed
|
|
||||||
} BASS_MIDI_FONTINFO;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
DWORD track; // track containing marker
|
|
||||||
DWORD pos; // marker position
|
|
||||||
const char *text; // marker text
|
|
||||||
} BASS_MIDI_MARK;
|
|
||||||
|
|
||||||
// Marker types
|
|
||||||
#define BASS_MIDI_MARK_MARKER 0 // marker
|
|
||||||
#define BASS_MIDI_MARK_CUE 1 // cue point
|
|
||||||
#define BASS_MIDI_MARK_LYRIC 2 // lyric
|
|
||||||
#define BASS_MIDI_MARK_TEXT 3 // text
|
|
||||||
#define BASS_MIDI_MARK_TIMESIG 4 // time signature
|
|
||||||
#define BASS_MIDI_MARK_KEYSIG 5 // key signature
|
|
||||||
#define BASS_MIDI_MARK_COPY 6 // copyright notice
|
|
||||||
#define BASS_MIDI_MARK_TRACK 7 // track name
|
|
||||||
#define BASS_MIDI_MARK_INST 8 // instrument name
|
|
||||||
#define BASS_MIDI_MARK_TRACKSTART 9 // track start (SMF2)
|
|
||||||
#define BASS_MIDI_MARK_TICK 0x10000 // flag: get position in ticks (otherwise bytes)
|
|
||||||
|
|
||||||
// MIDI events
|
|
||||||
#define MIDI_EVENT_NOTE 1
|
|
||||||
#define MIDI_EVENT_PROGRAM 2
|
|
||||||
#define MIDI_EVENT_CHANPRES 3
|
|
||||||
#define MIDI_EVENT_PITCH 4
|
|
||||||
#define MIDI_EVENT_PITCHRANGE 5
|
|
||||||
#define MIDI_EVENT_DRUMS 6
|
|
||||||
#define MIDI_EVENT_FINETUNE 7
|
|
||||||
#define MIDI_EVENT_COARSETUNE 8
|
|
||||||
#define MIDI_EVENT_MASTERVOL 9
|
|
||||||
#define MIDI_EVENT_BANK 10
|
|
||||||
#define MIDI_EVENT_MODULATION 11
|
|
||||||
#define MIDI_EVENT_VOLUME 12
|
|
||||||
#define MIDI_EVENT_PAN 13
|
|
||||||
#define MIDI_EVENT_EXPRESSION 14
|
|
||||||
#define MIDI_EVENT_SUSTAIN 15
|
|
||||||
#define MIDI_EVENT_SOUNDOFF 16
|
|
||||||
#define MIDI_EVENT_RESET 17
|
|
||||||
#define MIDI_EVENT_NOTESOFF 18
|
|
||||||
#define MIDI_EVENT_PORTAMENTO 19
|
|
||||||
#define MIDI_EVENT_PORTATIME 20
|
|
||||||
#define MIDI_EVENT_PORTANOTE 21
|
|
||||||
#define MIDI_EVENT_MODE 22
|
|
||||||
#define MIDI_EVENT_REVERB 23
|
|
||||||
#define MIDI_EVENT_CHORUS 24
|
|
||||||
#define MIDI_EVENT_CUTOFF 25
|
|
||||||
#define MIDI_EVENT_RESONANCE 26
|
|
||||||
#define MIDI_EVENT_RELEASE 27
|
|
||||||
#define MIDI_EVENT_ATTACK 28
|
|
||||||
#define MIDI_EVENT_DECAY 29
|
|
||||||
#define MIDI_EVENT_REVERB_MACRO 30
|
|
||||||
#define MIDI_EVENT_CHORUS_MACRO 31
|
|
||||||
#define MIDI_EVENT_REVERB_TIME 32
|
|
||||||
#define MIDI_EVENT_REVERB_DELAY 33
|
|
||||||
#define MIDI_EVENT_REVERB_LOCUTOFF 34
|
|
||||||
#define MIDI_EVENT_REVERB_HICUTOFF 35
|
|
||||||
#define MIDI_EVENT_REVERB_LEVEL 36
|
|
||||||
#define MIDI_EVENT_CHORUS_DELAY 37
|
|
||||||
#define MIDI_EVENT_CHORUS_DEPTH 38
|
|
||||||
#define MIDI_EVENT_CHORUS_RATE 39
|
|
||||||
#define MIDI_EVENT_CHORUS_FEEDBACK 40
|
|
||||||
#define MIDI_EVENT_CHORUS_LEVEL 41
|
|
||||||
#define MIDI_EVENT_CHORUS_REVERB 42
|
|
||||||
#define MIDI_EVENT_USERFX 43
|
|
||||||
#define MIDI_EVENT_USERFX_LEVEL 44
|
|
||||||
#define MIDI_EVENT_USERFX_REVERB 45
|
|
||||||
#define MIDI_EVENT_USERFX_CHORUS 46
|
|
||||||
#define MIDI_EVENT_DRUM_FINETUNE 50
|
|
||||||
#define MIDI_EVENT_DRUM_COARSETUNE 51
|
|
||||||
#define MIDI_EVENT_DRUM_PAN 52
|
|
||||||
#define MIDI_EVENT_DRUM_REVERB 53
|
|
||||||
#define MIDI_EVENT_DRUM_CHORUS 54
|
|
||||||
#define MIDI_EVENT_DRUM_CUTOFF 55
|
|
||||||
#define MIDI_EVENT_DRUM_RESONANCE 56
|
|
||||||
#define MIDI_EVENT_DRUM_LEVEL 57
|
|
||||||
#define MIDI_EVENT_DRUM_USERFX 58
|
|
||||||
#define MIDI_EVENT_SOFT 60
|
|
||||||
#define MIDI_EVENT_SYSTEM 61
|
|
||||||
#define MIDI_EVENT_TEMPO 62
|
|
||||||
#define MIDI_EVENT_SCALETUNING 63
|
|
||||||
#define MIDI_EVENT_CONTROL 64
|
|
||||||
#define MIDI_EVENT_CHANPRES_VIBRATO 65
|
|
||||||
#define MIDI_EVENT_CHANPRES_PITCH 66
|
|
||||||
#define MIDI_EVENT_CHANPRES_FILTER 67
|
|
||||||
#define MIDI_EVENT_CHANPRES_VOLUME 68
|
|
||||||
#define MIDI_EVENT_MOD_VIBRATO 69
|
|
||||||
#define MIDI_EVENT_MODRANGE 69
|
|
||||||
#define MIDI_EVENT_BANK_LSB 70
|
|
||||||
#define MIDI_EVENT_KEYPRES 71
|
|
||||||
#define MIDI_EVENT_KEYPRES_VIBRATO 72
|
|
||||||
#define MIDI_EVENT_KEYPRES_PITCH 73
|
|
||||||
#define MIDI_EVENT_KEYPRES_FILTER 74
|
|
||||||
#define MIDI_EVENT_KEYPRES_VOLUME 75
|
|
||||||
#define MIDI_EVENT_SOSTENUTO 76
|
|
||||||
#define MIDI_EVENT_MOD_PITCH 77
|
|
||||||
#define MIDI_EVENT_MOD_FILTER 78
|
|
||||||
#define MIDI_EVENT_MOD_VOLUME 79
|
|
||||||
#define MIDI_EVENT_VIBRATO_RATE 80
|
|
||||||
#define MIDI_EVENT_VIBRATO_DEPTH 81
|
|
||||||
#define MIDI_EVENT_VIBRATO_DELAY 82
|
|
||||||
#define MIDI_EVENT_MIXLEVEL 0x10000
|
|
||||||
#define MIDI_EVENT_TRANSPOSE 0x10001
|
|
||||||
#define MIDI_EVENT_SYSTEMEX 0x10002
|
|
||||||
#define MIDI_EVENT_SPEED 0x10004
|
|
||||||
|
|
||||||
#define MIDI_EVENT_END 0
|
|
||||||
#define MIDI_EVENT_END_TRACK 0x10003
|
|
||||||
|
|
||||||
#define MIDI_EVENT_NOTES 0x20000
|
|
||||||
#define MIDI_EVENT_VOICES 0x20001
|
|
||||||
|
|
||||||
#define MIDI_SYSTEM_DEFAULT 0
|
|
||||||
#define MIDI_SYSTEM_GM1 1
|
|
||||||
#define MIDI_SYSTEM_GM2 2
|
|
||||||
#define MIDI_SYSTEM_XG 3
|
|
||||||
#define MIDI_SYSTEM_GS 4
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
DWORD event; // MIDI_EVENT_xxx
|
|
||||||
DWORD param;
|
|
||||||
DWORD chan;
|
|
||||||
DWORD tick; // event position (ticks)
|
|
||||||
DWORD pos; // event position (bytes)
|
|
||||||
} BASS_MIDI_EVENT;
|
|
||||||
|
|
||||||
// BASS_MIDI_StreamEvents modes
|
|
||||||
#define BASS_MIDI_EVENTS_STRUCT 0 // BASS_MIDI_EVENT structures
|
|
||||||
#define BASS_MIDI_EVENTS_RAW 0x10000 // raw MIDI event data
|
|
||||||
#define BASS_MIDI_EVENTS_SYNC 0x1000000 // flag: trigger event syncs
|
|
||||||
#define BASS_MIDI_EVENTS_NORSTATUS 0x2000000 // flag: no running status
|
|
||||||
#define BASS_MIDI_EVENTS_CANCEL 0x4000000 // flag: cancel pending events
|
|
||||||
#define BASS_MIDI_EVENTS_TIME 0x8000000 // flag: delta-time info is present
|
|
||||||
#define BASS_MIDI_EVENTS_ABSTIME 0x10000000 // flag: absolute time info is present
|
|
||||||
|
|
||||||
// BASS_MIDI_StreamGetChannel special channels
|
|
||||||
#define BASS_MIDI_CHAN_CHORUS (DWORD)-1
|
|
||||||
#define BASS_MIDI_CHAN_REVERB (DWORD)-2
|
|
||||||
#define BASS_MIDI_CHAN_USERFX (DWORD)-3
|
|
||||||
|
|
||||||
// BASS_CHANNELINFO type
|
|
||||||
#define BASS_CTYPE_STREAM_MIDI 0x10d00
|
|
||||||
|
|
||||||
// Additional attributes
|
|
||||||
#define BASS_ATTRIB_MIDI_PPQN 0x12000
|
|
||||||
#define BASS_ATTRIB_MIDI_CPU 0x12001
|
|
||||||
#define BASS_ATTRIB_MIDI_CHANS 0x12002
|
|
||||||
#define BASS_ATTRIB_MIDI_VOICES 0x12003
|
|
||||||
#define BASS_ATTRIB_MIDI_VOICES_ACTIVE 0x12004
|
|
||||||
#define BASS_ATTRIB_MIDI_STATE 0x12005
|
|
||||||
#define BASS_ATTRIB_MIDI_SRC 0x12006
|
|
||||||
#define BASS_ATTRIB_MIDI_KILL 0x12007
|
|
||||||
#define BASS_ATTRIB_MIDI_SPEED 0x12008
|
|
||||||
#define BASS_ATTRIB_MIDI_REVERB 0x12009
|
|
||||||
#define BASS_ATTRIB_MIDI_VOL 0x1200a
|
|
||||||
#define BASS_ATTRIB_MIDI_TRACK_VOL 0x12100 // + track #
|
|
||||||
|
|
||||||
// Additional tag type
|
|
||||||
#define BASS_TAG_MIDI_TRACK 0x11000 // + track #, track text : array of null-terminated ANSI strings
|
|
||||||
|
|
||||||
// BASS_ChannelGetLength/GetPosition/SetPosition mode
|
|
||||||
#define BASS_POS_MIDI_TICK 2 // tick position
|
|
||||||
|
|
||||||
typedef BOOL (CALLBACK MIDIFILTERPROC)(HSTREAM handle, DWORD track, BASS_MIDI_EVENT *event, BOOL seeking, void *user);
|
|
||||||
/* Event filtering callback function.
|
|
||||||
handle : MIDI stream handle
|
|
||||||
track : Track containing the event
|
|
||||||
event : The event
|
|
||||||
seeking: TRUE = the event is being processed while seeking, FALSE = it is being played
|
|
||||||
user : The 'user' parameter value given when calling BASS_MIDI_StreamSetFilter
|
|
||||||
RETURN : TRUE = process the event, FALSE = drop the event */
|
|
||||||
|
|
||||||
// BASS_MIDI_FontLoadEx flags
|
|
||||||
#define BASS_MIDI_FONTLOAD_NOWAIT 1 // don't want for the samples to load
|
|
||||||
#define BASS_MIDI_FONTLOAD_COMPACT 2 // compact samples
|
|
||||||
#define BASS_MIDI_FONTLOAD_NOLOAD 4 // don't load (only compact)
|
|
||||||
#define BASS_MIDI_FONTLOAD_TIME 8 // length is in milliseconds
|
|
||||||
#define BASS_MIDI_FONTLOAD_KEEPDEC 16 // keep decoders
|
|
||||||
|
|
||||||
// BASS_MIDI_FontPack flags
|
|
||||||
#define BASS_MIDI_PACK_NOHEAD 1 // don't send a WAV header to the encoder
|
|
||||||
#define BASS_MIDI_PACK_16BIT 2 // discard low 8 bits of 24-bit sample data
|
|
||||||
#define BASS_MIDI_PACK_48KHZ 4 // set encoding rate to 48000 Hz (else 44100 Hz)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char *name; // description
|
|
||||||
DWORD id;
|
|
||||||
DWORD flags;
|
|
||||||
} BASS_MIDI_DEVICEINFO;
|
|
||||||
|
|
||||||
typedef void (CALLBACK MIDIINPROC)(DWORD device, double time, const BYTE *buffer, DWORD length, void *user);
|
|
||||||
/* MIDI input callback function.
|
|
||||||
device : MIDI input device
|
|
||||||
time : Timestamp
|
|
||||||
buffer : Buffer containing MIDI data
|
|
||||||
length : Number of bytes of data
|
|
||||||
user : The 'user' parameter value given when calling BASS_MIDI_InInit */
|
|
||||||
|
|
||||||
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreate)(DWORD channels, DWORD flags, DWORD freq);
|
|
||||||
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags, DWORD freq);
|
|
||||||
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user, DWORD freq);
|
|
||||||
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *procs, void *user, DWORD freq);
|
|
||||||
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateEvents)(const BASS_MIDI_EVENT *events, DWORD ppqn, DWORD flags, DWORD freq);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_StreamGetMark)(HSTREAM handle, DWORD type, DWORD index, BASS_MIDI_MARK *mark);
|
|
||||||
DWORD BASSMIDIDEF(BASS_MIDI_StreamGetMarks)(HSTREAM handle, int track, DWORD type, BASS_MIDI_MARK *marks);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_StreamSetFonts)(HSTREAM handle, const void *fonts, DWORD count);
|
|
||||||
DWORD BASSMIDIDEF(BASS_MIDI_StreamGetFonts)(HSTREAM handle, void *fonts, DWORD count);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_StreamLoadSamples)(HSTREAM handle);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_StreamEvent)(HSTREAM handle, DWORD chan, DWORD event, DWORD param);
|
|
||||||
DWORD BASSMIDIDEF(BASS_MIDI_StreamEvents)(HSTREAM handle, DWORD mode, const void *events, DWORD length);
|
|
||||||
DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEvent)(HSTREAM handle, DWORD chan, DWORD event);
|
|
||||||
DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEvents)(HSTREAM handle, int track, DWORD filter, BASS_MIDI_EVENT *events);
|
|
||||||
DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEventsEx)(HSTREAM handle, int track, DWORD filter, BASS_MIDI_EVENT *events, DWORD start, DWORD count);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_StreamGetPreset)(HSTREAM handle, DWORD chan, BASS_MIDI_FONT *font);
|
|
||||||
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamGetChannel)(HSTREAM handle, DWORD chan);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_StreamSetFilter)(HSTREAM handle, BOOL seeking, MIDIFILTERPROC *proc, void *user);
|
|
||||||
|
|
||||||
HSOUNDFONT BASSMIDIDEF(BASS_MIDI_FontInit)(const void *file, DWORD flags);
|
|
||||||
HSOUNDFONT BASSMIDIDEF(BASS_MIDI_FontInitUser)(const BASS_FILEPROCS *procs, void *user, DWORD flags);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_FontFree)(HSOUNDFONT handle);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_FontGetInfo)(HSOUNDFONT handle, BASS_MIDI_FONTINFO *info);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_FontGetPresets)(HSOUNDFONT handle, DWORD *presets);
|
|
||||||
const char *BASSMIDIDEF(BASS_MIDI_FontGetPreset)(HSOUNDFONT handle, int preset, int bank);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_FontLoad)(HSOUNDFONT handle, int preset, int bank);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_FontLoadEx)(HSOUNDFONT handle, int preset, int bank, DWORD length, DWORD flags);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_FontUnload)(HSOUNDFONT handle, int preset, int bank);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_FontCompact)(HSOUNDFONT handle);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_FontPack)(HSOUNDFONT handle, const void *outfile, const void *encoder, DWORD flags);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_FontUnpack)(HSOUNDFONT handle, const void *outfile, DWORD flags);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_FontSetVolume)(HSOUNDFONT handle, float volume);
|
|
||||||
float BASSMIDIDEF(BASS_MIDI_FontGetVolume)(HSOUNDFONT handle);
|
|
||||||
|
|
||||||
DWORD BASSMIDIDEF(BASS_MIDI_ConvertEvents)(const BYTE *data, DWORD length, BASS_MIDI_EVENT *events, DWORD count, DWORD flags);
|
|
||||||
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_InGetDeviceInfo)(DWORD device, BASS_MIDI_DEVICEINFO *info);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_InInit)(DWORD device, MIDIINPROC *proc, void *user);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_InFree)(DWORD device);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_InStart)(DWORD device);
|
|
||||||
BOOL BASSMIDIDEF(BASS_MIDI_InStop)(DWORD device);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline BOOL BASS_MIDI_StreamSetFonts(HSTREAM handle, const BASS_MIDI_FONTEX *fonts, DWORD count)
|
|
||||||
{
|
|
||||||
return BASS_MIDI_StreamSetFonts(handle, (const void*)fonts, count|BASS_MIDI_FONT_EX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline DWORD BASS_MIDI_StreamGetFonts(HSTREAM handle, BASS_MIDI_FONTEX *fonts, DWORD count)
|
|
||||||
{
|
|
||||||
return BASS_MIDI_StreamGetFonts(handle, (void*)fonts, count|BASS_MIDI_FONT_EX);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
static inline HSTREAM BASS_MIDI_StreamCreateFile(BOOL mem, const WCHAR *file, QWORD offset, QWORD length, DWORD flags, DWORD freq)
|
|
||||||
{
|
|
||||||
return BASS_MIDI_StreamCreateFile(mem, (const void*)file, offset, length, flags|BASS_UNICODE, freq);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline HSTREAM BASS_MIDI_StreamCreateURL(const WCHAR *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user, DWORD freq)
|
|
||||||
{
|
|
||||||
return BASS_MIDI_StreamCreateURL((const char*)url, offset, flags|BASS_UNICODE, proc, user, freq);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline HSOUNDFONT BASS_MIDI_FontInit(const WCHAR *file, DWORD flags)
|
|
||||||
{
|
|
||||||
return BASS_MIDI_FontInit((const void*)file, flags|BASS_UNICODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline BOOL BASS_MIDI_FontPack(HSOUNDFONT handle, const WCHAR *outfile, const WCHAR *encoder, DWORD flags)
|
|
||||||
{
|
|
||||||
return BASS_MIDI_FontPack(handle, (const void*)outfile, (const void*)encoder, flags|BASS_UNICODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline BOOL BASS_MIDI_FontUnpack(HSOUNDFONT handle, const WCHAR *outfile, DWORD flags)
|
|
||||||
{
|
|
||||||
return BASS_MIDI_FontUnpack(handle, (const void*)outfile, flags|BASS_UNICODE);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
BASSOPUS 2.4 C/C++ header file
|
|
||||||
Copyright (c) 2012-2015 Un4seen Developments Ltd.
|
|
||||||
|
|
||||||
See the BASSOPUS.CHM file for more detailed documentation
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BASSOPUS_H
|
|
||||||
#define BASSOPUS_H
|
|
||||||
|
|
||||||
#include "bass.h"
|
|
||||||
|
|
||||||
#if BASSVERSION != 0x204
|
|
||||||
#error conflicting BASS and BASSOPUS versions
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BASSOPUSDEF
|
|
||||||
#define BASSOPUSDEF(f) WINAPI f
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// BASS_CHANNELINFO type
|
|
||||||
#define BASS_CTYPE_STREAM_OPUS 0x11200
|
|
||||||
|
|
||||||
// Additional attributes
|
|
||||||
#define BASS_ATTRIB_OPUS_ORIGFREQ 0x13000
|
|
||||||
#define BASS_ATTRIB_OPUS_GAIN 0x13001
|
|
||||||
|
|
||||||
HSTREAM BASSOPUSDEF(BASS_OPUS_StreamCreateFile)(BOOL mem, const void *file,
|
|
||||||
QWORD offset, QWORD length,
|
|
||||||
DWORD flags);
|
|
||||||
HSTREAM BASSOPUSDEF(BASS_OPUS_StreamCreateURL)(const char *url, DWORD offset,
|
|
||||||
DWORD flags, DOWNLOADPROC *proc,
|
|
||||||
void *user);
|
|
||||||
HSTREAM BASSOPUSDEF(BASS_OPUS_StreamCreateFileUser)(DWORD system, DWORD flags,
|
|
||||||
const BASS_FILEPROCS *procs,
|
|
||||||
void *user);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(NOBASSOVERLOADS)
|
|
||||||
static inline HSTREAM BASS_OPUS_StreamCreateFile(BOOL mem, const WCHAR *file,
|
|
||||||
QWORD offset, QWORD length,
|
|
||||||
DWORD flags)
|
|
||||||
{
|
|
||||||
return BASS_OPUS_StreamCreateFile(mem, (const void *)file, offset, length,
|
|
||||||
flags | BASS_UNICODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline HSTREAM BASS_OPUS_StreamCreateURL(const WCHAR *url, DWORD offset,
|
|
||||||
DWORD flags, DOWNLOADPROC *proc,
|
|
||||||
void *user)
|
|
||||||
{
|
|
||||||
return BASS_OPUS_StreamCreateURL((const char *)url, offset,
|
|
||||||
flags | BASS_UNICODE, proc, user);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,37 +0,0 @@
|
|||||||
#ifndef CHATLOGPIECE_H
|
|
||||||
#define CHATLOGPIECE_H
|
|
||||||
|
|
||||||
#include <QtWidgets/QApplication>
|
|
||||||
#include <QDateTime>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
class chatlogpiece {
|
|
||||||
Q_DECLARE_TR_FUNCTIONS(chatlogpiece)
|
|
||||||
public:
|
|
||||||
chatlogpiece();
|
|
||||||
chatlogpiece(QString p_name, QString p_showname, QString p_message,
|
|
||||||
QString p_action,int color, bool selfname);
|
|
||||||
chatlogpiece(QString p_name, QString p_showname, QString p_message,
|
|
||||||
QString p_action, int color, bool selfname, QDateTime p_datetime);
|
|
||||||
|
|
||||||
QString get_name() { return name; };
|
|
||||||
QString get_showname() { return showname; };
|
|
||||||
QString get_message() { return message; };
|
|
||||||
QString get_action() { return action; };
|
|
||||||
bool get_selfname() const { return selfname; };
|
|
||||||
QDateTime get_datetime() { return datetime; };
|
|
||||||
QString get_datetime_as_string() { return datetime.toString(); };
|
|
||||||
int get_chat_color() const { return color; };
|
|
||||||
QString get_full();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString name;
|
|
||||||
QString showname;
|
|
||||||
QString message;
|
|
||||||
QString action;
|
|
||||||
bool selfname;
|
|
||||||
QDateTime datetime;
|
|
||||||
int color;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CHATLOGPIECE_H
|
|
@ -1,10 +0,0 @@
|
|||||||
#ifndef DEBUG_FUNCTIONS_H
|
|
||||||
#define DEBUG_FUNCTIONS_H
|
|
||||||
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
void call_error(QString message);
|
|
||||||
void call_notice(QString message);
|
|
||||||
|
|
||||||
#endif // DEBUG_FUNCTIONS_H
|
|
@ -1,60 +0,0 @@
|
|||||||
#ifndef DEMOSERVER_H
|
|
||||||
#define DEMOSERVER_H
|
|
||||||
|
|
||||||
#include "aopacket.h"
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QObject>
|
|
||||||
#include <QQueue>
|
|
||||||
#include <QTcpServer>
|
|
||||||
#include <QTcpSocket>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QMessageBox>
|
|
||||||
|
|
||||||
class DemoServer : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit DemoServer(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
bool server_started = false;
|
|
||||||
int port = 27088;
|
|
||||||
int max_wait = -1;
|
|
||||||
|
|
||||||
void set_demo_file(QString filepath);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void handle_packet(AOPacket *packet);
|
|
||||||
void load_demo(QString filename);
|
|
||||||
void reset_state();
|
|
||||||
|
|
||||||
QTcpServer* tcp_server;
|
|
||||||
QTcpSocket* client_sock = nullptr;
|
|
||||||
bool client_connected = false;
|
|
||||||
bool partial_packet = false;
|
|
||||||
bool debug_mode = false;
|
|
||||||
QString temp_packet = "";
|
|
||||||
QQueue<QString> demo_data;
|
|
||||||
QString sc_packet;
|
|
||||||
int num_chars = 0;
|
|
||||||
QString p_path;
|
|
||||||
QTimer *timer;
|
|
||||||
int elapsed_time = 0;
|
|
||||||
QString filename;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void accept_connection();
|
|
||||||
void destroy_connection();
|
|
||||||
void recv_data();
|
|
||||||
void client_disconnect();
|
|
||||||
void playback();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void start_server();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void skip_timers(qint64 msecs);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // DEMOSERVER_H
|
|
@ -1,87 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
|
|
||||||
#if defined(DISCORD_DYNAMIC_LIB)
|
|
||||||
# if defined(_WIN32)
|
|
||||||
# if defined(DISCORD_BUILDING_SDK)
|
|
||||||
# define DISCORD_EXPORT __declspec(dllexport)
|
|
||||||
# else
|
|
||||||
# define DISCORD_EXPORT __declspec(dllimport)
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# define DISCORD_EXPORT __attribute__((visibility("default")))
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# define DISCORD_EXPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct DiscordRichPresence {
|
|
||||||
const char *state; /* max 128 bytes */
|
|
||||||
const char *details; /* max 128 bytes */
|
|
||||||
int64_t startTimestamp;
|
|
||||||
int64_t endTimestamp;
|
|
||||||
const char *largeImageKey; /* max 32 bytes */
|
|
||||||
const char *largeImageText; /* max 128 bytes */
|
|
||||||
const char *smallImageKey; /* max 32 bytes */
|
|
||||||
const char *smallImageText; /* max 128 bytes */
|
|
||||||
const char *partyId; /* max 128 bytes */
|
|
||||||
int partySize;
|
|
||||||
int partyMax;
|
|
||||||
const char *matchSecret; /* max 128 bytes */
|
|
||||||
const char *joinSecret; /* max 128 bytes */
|
|
||||||
const char *spectateSecret; /* max 128 bytes */
|
|
||||||
int8_t instance;
|
|
||||||
} DiscordRichPresence;
|
|
||||||
|
|
||||||
typedef struct DiscordJoinRequest {
|
|
||||||
const char *userId;
|
|
||||||
const char *username;
|
|
||||||
const char *discriminator;
|
|
||||||
const char *avatar;
|
|
||||||
} DiscordJoinRequest;
|
|
||||||
|
|
||||||
typedef struct DiscordEventHandlers {
|
|
||||||
void (*ready)(void);
|
|
||||||
void (*disconnected)(int errorCode, const char *message);
|
|
||||||
void (*errored)(int errorCode, const char *message);
|
|
||||||
void (*joinGame)(const char *joinSecret);
|
|
||||||
void (*spectateGame)(const char *spectateSecret);
|
|
||||||
void (*joinRequest)(const DiscordJoinRequest *request);
|
|
||||||
} DiscordEventHandlers;
|
|
||||||
|
|
||||||
#define DISCORD_REPLY_NO 0
|
|
||||||
#define DISCORD_REPLY_YES 1
|
|
||||||
#define DISCORD_REPLY_IGNORE 2
|
|
||||||
|
|
||||||
DISCORD_EXPORT void Discord_Initialize(const char *applicationId,
|
|
||||||
DiscordEventHandlers *handlers,
|
|
||||||
int autoRegister,
|
|
||||||
const char *optionalSteamId);
|
|
||||||
DISCORD_EXPORT void Discord_Shutdown(void);
|
|
||||||
|
|
||||||
/* checks for incoming messages, dispatches callbacks */
|
|
||||||
DISCORD_EXPORT void Discord_RunCallbacks(void);
|
|
||||||
|
|
||||||
/* If you disable the lib starting its own io thread, you'll need to call this
|
|
||||||
* from your own */
|
|
||||||
#ifdef DISCORD_DISABLE_IO_THREAD
|
|
||||||
DISCORD_EXPORT void Discord_UpdateConnection(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence *presence);
|
|
||||||
DISCORD_EXPORT void Discord_ClearPresence(void);
|
|
||||||
|
|
||||||
DISCORD_EXPORT void Discord_Respond(const char *userid,
|
|
||||||
/* DISCORD_REPLY_ */ int reply);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
@ -1,28 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#if defined(DISCORD_DYNAMIC_LIB)
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#if defined(DISCORD_BUILDING_SDK)
|
|
||||||
#define DISCORD_EXPORT __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define DISCORD_EXPORT __declspec(dllimport)
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define DISCORD_EXPORT __attribute__((visibility("default")))
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define DISCORD_EXPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DISCORD_EXPORT void Discord_Register(const char *applicationId,
|
|
||||||
const char *command);
|
|
||||||
DISCORD_EXPORT void Discord_RegisterSteamGame(const char *applicationId,
|
|
||||||
const char *steamId);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,89 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
|
|
||||||
#if defined(DISCORD_DYNAMIC_LIB)
|
|
||||||
# if defined(_WIN32)
|
|
||||||
# if defined(DISCORD_BUILDING_SDK)
|
|
||||||
# define DISCORD_EXPORT __declspec(dllexport)
|
|
||||||
# else
|
|
||||||
# define DISCORD_EXPORT __declspec(dllimport)
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# define DISCORD_EXPORT __attribute__((visibility("default")))
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# define DISCORD_EXPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct DiscordRichPresence {
|
|
||||||
const char *state; /* max 128 bytes */
|
|
||||||
const char *details; /* max 128 bytes */
|
|
||||||
int64_t startTimestamp;
|
|
||||||
int64_t endTimestamp;
|
|
||||||
const char *largeImageKey; /* max 32 bytes */
|
|
||||||
const char *largeImageText; /* max 128 bytes */
|
|
||||||
const char *smallImageKey; /* max 32 bytes */
|
|
||||||
const char *smallImageText; /* max 128 bytes */
|
|
||||||
const char *partyId; /* max 128 bytes */
|
|
||||||
int partySize;
|
|
||||||
int partyMax;
|
|
||||||
const char *matchSecret; /* max 128 bytes */
|
|
||||||
const char *joinSecret; /* max 128 bytes */
|
|
||||||
const char *spectateSecret; /* max 128 bytes */
|
|
||||||
int8_t instance;
|
|
||||||
} DiscordRichPresence;
|
|
||||||
|
|
||||||
typedef struct DiscordUser {
|
|
||||||
const char *userId;
|
|
||||||
const char *username;
|
|
||||||
const char *discriminator;
|
|
||||||
const char *avatar;
|
|
||||||
} DiscordUser;
|
|
||||||
|
|
||||||
typedef struct DiscordEventHandlers {
|
|
||||||
void (*ready)(const DiscordUser *request);
|
|
||||||
void (*disconnected)(int errorCode, const char *message);
|
|
||||||
void (*errored)(int errorCode, const char *message);
|
|
||||||
void (*joinGame)(const char *joinSecret);
|
|
||||||
void (*spectateGame)(const char *spectateSecret);
|
|
||||||
void (*joinRequest)(const DiscordUser *request);
|
|
||||||
} DiscordEventHandlers;
|
|
||||||
|
|
||||||
#define DISCORD_REPLY_NO 0
|
|
||||||
#define DISCORD_REPLY_YES 1
|
|
||||||
#define DISCORD_REPLY_IGNORE 2
|
|
||||||
|
|
||||||
DISCORD_EXPORT void Discord_Initialize(const char *applicationId,
|
|
||||||
DiscordEventHandlers *handlers,
|
|
||||||
int autoRegister,
|
|
||||||
const char *optionalSteamId);
|
|
||||||
DISCORD_EXPORT void Discord_Shutdown(void);
|
|
||||||
|
|
||||||
/* checks for incoming messages, dispatches callbacks */
|
|
||||||
DISCORD_EXPORT void Discord_RunCallbacks(void);
|
|
||||||
|
|
||||||
/* If you disable the lib starting its own io thread, you'll need to call this
|
|
||||||
* from your own */
|
|
||||||
#ifdef DISCORD_DISABLE_IO_THREAD
|
|
||||||
DISCORD_EXPORT void Discord_UpdateConnection(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence *presence);
|
|
||||||
DISCORD_EXPORT void Discord_ClearPresence(void);
|
|
||||||
|
|
||||||
DISCORD_EXPORT void Discord_Respond(const char *userid,
|
|
||||||
/* DISCORD_REPLY_ */ int reply);
|
|
||||||
|
|
||||||
DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers *handlers);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
@ -1,36 +0,0 @@
|
|||||||
#ifndef EVENTFILTERS_H
|
|
||||||
#define EVENTFILTERS_H
|
|
||||||
|
|
||||||
#include <QEvent>
|
|
||||||
#include <QLineEdit>
|
|
||||||
|
|
||||||
class AOLineEditFilter : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
bool preserve_selection = false;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool eventFilter(QObject *obj, QEvent *event) override {
|
|
||||||
QLineEdit *lineEdit = qobject_cast<QLineEdit *>(obj);
|
|
||||||
if (event->type() == QEvent::FocusOut && lineEdit != nullptr && preserve_selection) { // lost focus
|
|
||||||
int start = lineEdit->selectionStart();
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
|
||||||
int len = lineEdit->selectionLength();
|
|
||||||
#else
|
|
||||||
int len = lineEdit->selectedText().length();
|
|
||||||
#endif
|
|
||||||
if (start != -1 && len != -1) {
|
|
||||||
lineEdit->setSelection(start, len);\
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
signals:
|
|
||||||
void double_clicked();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // EVENTFILTERS_H
|
|
@ -1,14 +0,0 @@
|
|||||||
#ifndef HARDWARE_FUNCTIONS_H
|
|
||||||
#define HARDWARE_FUNCTIONS_H
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef ANDROID
|
|
||||||
#include <QtAndroidExtras/QtAndroid>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QString get_hdid();
|
|
||||||
|
|
||||||
#endif // HARDWARE_FUNCTIONS_H
|
|
@ -1,21 +0,0 @@
|
|||||||
#include <QDialog>
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef AO_UI_FAVORITESERVERDIALOG
|
|
||||||
#define AO_UI_FAVORITESRRVERDIALOG
|
|
||||||
namespace AttorneyOnline {
|
|
||||||
namespace UI {
|
|
||||||
class FavoriteServerDialog : public QDialog {
|
|
||||||
public:
|
|
||||||
FavoriteServerDialog() = default;
|
|
||||||
~FavoriteServerDialog() = default;
|
|
||||||
|
|
||||||
const QString DEFAULT_UI = "favorite_server_dialog.ui";
|
|
||||||
const int TCP_INDEX = 0;
|
|
||||||
private slots:
|
|
||||||
virtual void onSavePressed() = 0;
|
|
||||||
virtual void onCancelPressed() = 0;
|
|
||||||
};
|
|
||||||
} // namespace UI
|
|
||||||
} // namespace AttorneyOnline
|
|
||||||
#endif // AO_UI_FAVORITESERVERDIALOG
|
|
@ -1,9 +0,0 @@
|
|||||||
#ifndef MISC_FUNCTIONS_H
|
|
||||||
#define MISC_FUNCTIONS_H
|
|
||||||
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <QTime>
|
|
||||||
|
|
||||||
void delay(int p_milliseconds);
|
|
||||||
|
|
||||||
#endif // MISC_FUNCTIONS_H
|
|
@ -1,13 +0,0 @@
|
|||||||
#ifndef TEXT_FILE_FUNCTIONS_H
|
|
||||||
#define TEXT_FILE_FUNCTIONS_H
|
|
||||||
|
|
||||||
#include "aoapplication.h"
|
|
||||||
#include "file_functions.h"
|
|
||||||
#include <QColor>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QSettings>
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QTextStream>
|
|
||||||
#include <QVector>
|
|
||||||
|
|
||||||
#endif // TEXT_FILE_FUNCTIONS_H
|
|
@ -1,46 +0,0 @@
|
|||||||
#ifndef DIRECT_CONNECT_DIALOG_H
|
|
||||||
#define DIRECT_CONNECT_DIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QRegularExpression>
|
|
||||||
|
|
||||||
class QLabel;
|
|
||||||
class QSpinBox;
|
|
||||||
class QLineEdit;
|
|
||||||
class QPushButton;
|
|
||||||
class QComboBox;
|
|
||||||
class QLabel;
|
|
||||||
class NetworkManager;
|
|
||||||
|
|
||||||
class DirectConnectDialog : public QDialog {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
DirectConnectDialog(NetworkManager* p_net_manager);
|
|
||||||
~DirectConnectDialog() = default;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onConnectPressed();
|
|
||||||
void onServerConnected();
|
|
||||||
void onConnectTimeout();
|
|
||||||
|
|
||||||
private:
|
|
||||||
NetworkManager* net_manager;
|
|
||||||
|
|
||||||
QLineEdit* ui_direct_hostname_edit;
|
|
||||||
|
|
||||||
QLabel* ui_direct_connection_status_lbl;
|
|
||||||
QPushButton* ui_direct_connect_button;
|
|
||||||
QPushButton* ui_direct_cancel_button;
|
|
||||||
|
|
||||||
QWidget* ui_widget;
|
|
||||||
QTimer connect_timeout;
|
|
||||||
|
|
||||||
const int TCP_INDEX = 0;
|
|
||||||
const QRegularExpression SCHEME_PATTERN{"^\\w+://.+$"};
|
|
||||||
const int CONNECT_TIMEOUT = 5 * 1000;
|
|
||||||
const QString DEFAULT_UI = "direct_connect_dialog.ui";;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // DIRECT_CONNECT_DIALOG_H
|
|
@ -1 +0,0 @@
|
|||||||
IDI_ICON1 ICON "logo_ao2.ico"
|
|
Before Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 22 KiB |
@ -1,19 +0,0 @@
|
|||||||
<RCC>
|
|
||||||
<qresource prefix="/">
|
|
||||||
<file>resource/fonts/Ace-Attorney.ttf</file>
|
|
||||||
<file>resource/logo_ao2.png</file>
|
|
||||||
<file>resource/translations/ao_de.qm</file>
|
|
||||||
<file>resource/translations/ao_en.qm</file>
|
|
||||||
<file>resource/translations/ao_es.qm</file>
|
|
||||||
<file>resource/translations/ao_jp.qm</file>
|
|
||||||
<file>resource/translations/ao_pl.qm</file>
|
|
||||||
<file>resource/translations/ao_pt.qm</file>
|
|
||||||
<file>resource/translations/ao_ru.qm</file>
|
|
||||||
<file>resource/ui/options_dialog.ui</file>
|
|
||||||
<file>resource/ui/favorite_server_dialog.ui</file>
|
|
||||||
<file>resource/ui/direct_connect_dialog.ui</file>
|
|
||||||
<file>resource/ui/lobby.ui</file>
|
|
||||||
<file>resource/ui/lobby_assets/down-arrow.png</file>
|
|
||||||
<file>resource/ui/lobby_assets/up-arrow.png</file>
|
|
||||||
</qresource>
|
|
||||||
</RCC>
|
|
@ -1,39 +0,0 @@
|
|||||||
target_sources(Attorney_Online PRIVATE
|
|
||||||
aoapplication.cpp
|
|
||||||
aoblipplayer.cpp
|
|
||||||
aobutton.cpp
|
|
||||||
aocaseannouncerdialog.cpp
|
|
||||||
aocharbutton.cpp
|
|
||||||
aoclocklabel.cpp
|
|
||||||
aoemotebutton.cpp
|
|
||||||
aoemotepreview.cpp
|
|
||||||
aoevidencebutton.cpp
|
|
||||||
aoevidencedisplay.cpp
|
|
||||||
aoimage.cpp
|
|
||||||
aolayer.cpp
|
|
||||||
aomusicplayer.cpp
|
|
||||||
aooptionsdialog.cpp
|
|
||||||
aoclocklabel.cpp
|
|
||||||
aopacket.cpp
|
|
||||||
aosfxplayer.cpp
|
|
||||||
aotextarea.cpp
|
|
||||||
aoutils.cpp
|
|
||||||
charselect.cpp
|
|
||||||
chatlogpiece.cpp
|
|
||||||
courtroom.cpp
|
|
||||||
debug_functions.cpp
|
|
||||||
demoserver.cpp
|
|
||||||
discord_rich_presence.cpp
|
|
||||||
emotes.cpp
|
|
||||||
evidence.cpp
|
|
||||||
file_functions.cpp
|
|
||||||
hardware_functions.cpp
|
|
||||||
lobby.cpp
|
|
||||||
main.cpp
|
|
||||||
misc_functions.cpp
|
|
||||||
networkmanager.cpp
|
|
||||||
packet_distribution.cpp
|
|
||||||
path_functions.cpp
|
|
||||||
scrolltext.cpp
|
|
||||||
text_file_functions.cpp
|
|
||||||
)
|
|
@ -11,14 +11,14 @@
|
|||||||
|
|
||||||
static QtMessageHandler original_message_handler;
|
static QtMessageHandler original_message_handler;
|
||||||
static AOApplication *message_handler_context;
|
static AOApplication *message_handler_context;
|
||||||
void message_handler(QtMsgType type, const QMessageLogContext &context,
|
void message_handler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||||
const QString &msg)
|
|
||||||
{
|
{
|
||||||
emit message_handler_context->qt_log_message(type, context, msg);
|
Q_EMIT message_handler_context->qt_log_message(type, context, msg);
|
||||||
original_message_handler(type, context, msg);
|
original_message_handler(type, context, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
AOApplication::AOApplication(int &argc, char **argv) : QApplication(argc, argv)
|
AOApplication::AOApplication(int &argc, char **argv)
|
||||||
|
: QApplication(argc, argv)
|
||||||
{
|
{
|
||||||
net_manager = new NetworkManager(this);
|
net_manager = new NetworkManager(this);
|
||||||
discord = new AttorneyOnline::Discord();
|
discord = new AttorneyOnline::Discord();
|
||||||
@ -42,7 +42,8 @@ AOApplication::~AOApplication()
|
|||||||
|
|
||||||
void AOApplication::construct_lobby()
|
void AOApplication::construct_lobby()
|
||||||
{
|
{
|
||||||
if (lobby_constructed) {
|
if (lobby_constructed)
|
||||||
|
{
|
||||||
qWarning() << "lobby was attempted constructed when it already exists";
|
qWarning() << "lobby was attempted constructed when it already exists";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -56,17 +57,22 @@ void AOApplication::construct_lobby()
|
|||||||
w_lobby->move(x, y);
|
w_lobby->move(x, y);
|
||||||
|
|
||||||
if (Options::getInstance().discordEnabled())
|
if (Options::getInstance().discordEnabled())
|
||||||
|
{
|
||||||
discord->state_lobby();
|
discord->state_lobby();
|
||||||
|
}
|
||||||
|
|
||||||
if (demo_server)
|
if (demo_server)
|
||||||
demo_server->deleteLater();
|
{
|
||||||
|
demo_server->deleteLater();
|
||||||
|
}
|
||||||
demo_server = new DemoServer(this);
|
demo_server = new DemoServer(this);
|
||||||
w_lobby->show();
|
w_lobby->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOApplication::destruct_lobby()
|
void AOApplication::destruct_lobby()
|
||||||
{
|
{
|
||||||
if (!lobby_constructed) {
|
if (!lobby_constructed)
|
||||||
|
{
|
||||||
qWarning() << "lobby was attempted destructed when it did not exist";
|
qWarning() << "lobby was attempted destructed when it did not exist";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -78,7 +84,8 @@ void AOApplication::destruct_lobby()
|
|||||||
|
|
||||||
void AOApplication::construct_courtroom()
|
void AOApplication::construct_courtroom()
|
||||||
{
|
{
|
||||||
if (courtroom_constructed) {
|
if (courtroom_constructed)
|
||||||
|
{
|
||||||
qWarning() << "courtroom was attempted constructed when it already exists";
|
qWarning() << "courtroom was attempted constructed when it already exists";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -91,18 +98,20 @@ void AOApplication::construct_courtroom()
|
|||||||
int y = (geometry.height() - w_courtroom->height()) / 2;
|
int y = (geometry.height() - w_courtroom->height()) / 2;
|
||||||
w_courtroom->move(x, y);
|
w_courtroom->move(x, y);
|
||||||
|
|
||||||
if (demo_server != nullptr) {
|
if (demo_server != nullptr)
|
||||||
QObject::connect(demo_server, &DemoServer::skip_timers,
|
{
|
||||||
w_courtroom, &Courtroom::skip_clocks);
|
QObject::connect(demo_server, &DemoServer::skip_timers, w_courtroom, &Courtroom::skip_clocks);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
qWarning() << "demo server did not exist during courtroom construction";
|
qWarning() << "demo server did not exist during courtroom construction";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOApplication::destruct_courtroom()
|
void AOApplication::destruct_courtroom()
|
||||||
{
|
{
|
||||||
if (!courtroom_constructed) {
|
if (!courtroom_constructed)
|
||||||
|
{
|
||||||
qWarning() << "courtroom was attempted destructed when it did not exist";
|
qWarning() << "courtroom was attempted destructed when it did not exist";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -114,13 +123,13 @@ void AOApplication::destruct_courtroom()
|
|||||||
|
|
||||||
QString AOApplication::get_version_string()
|
QString AOApplication::get_version_string()
|
||||||
{
|
{
|
||||||
return QString::number(RELEASE) + "." + QString::number(MAJOR_VERSION) + "." +
|
return QString::number(RELEASE) + "." + QString::number(MAJOR_VERSION) + "." + QString::number(MINOR_VERSION);
|
||||||
QString::number(MINOR_VERSION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOApplication::server_disconnected()
|
void AOApplication::server_disconnected()
|
||||||
{
|
{
|
||||||
if (courtroom_constructed) {
|
if (courtroom_constructed)
|
||||||
|
{
|
||||||
call_notice(tr("Disconnected from server."));
|
call_notice(tr("Disconnected from server."));
|
||||||
construct_lobby();
|
construct_lobby();
|
||||||
destruct_courtroom();
|
destruct_courtroom();
|
||||||
@ -135,22 +144,21 @@ void AOApplication::loading_cancelled()
|
|||||||
|
|
||||||
void AOApplication::call_settings_menu()
|
void AOApplication::call_settings_menu()
|
||||||
{
|
{
|
||||||
AOOptionsDialog* l_dialog = new AOOptionsDialog(nullptr, this);
|
AOOptionsDialog *l_dialog = new AOOptionsDialog(this);
|
||||||
if (courtroom_constructed) {
|
if (courtroom_constructed)
|
||||||
connect(l_dialog, &AOOptionsDialog::reloadThemeRequest,
|
{
|
||||||
w_courtroom, &Courtroom::on_reload_theme_clicked);
|
connect(l_dialog, &AOOptionsDialog::reloadThemeRequest, w_courtroom, &Courtroom::on_reload_theme_clicked);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lobby_constructed) {
|
if (lobby_constructed)
|
||||||
}
|
{}
|
||||||
l_dialog->exec();
|
l_dialog->exec();
|
||||||
delete l_dialog;
|
delete l_dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback for when BASS device is lost
|
// Callback for when BASS device is lost
|
||||||
// Only actually used for music syncs
|
// Only actually used for music syncs
|
||||||
void CALLBACK AOApplication::BASSreset(HSTREAM handle, DWORD channel,
|
void CALLBACK AOApplication::BASSreset(HSTREAM handle, DWORD channel, DWORD data, void *user)
|
||||||
DWORD data, void *user)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(handle);
|
Q_UNUSED(handle);
|
||||||
Q_UNUSED(channel);
|
Q_UNUSED(channel);
|
||||||
@ -175,16 +183,19 @@ void AOApplication::initBASS()
|
|||||||
unsigned int a = 0;
|
unsigned int a = 0;
|
||||||
BASS_DEVICEINFO info;
|
BASS_DEVICEINFO info;
|
||||||
|
|
||||||
if (Options::getInstance().audioOutputDevice() == "default") {
|
if (Options::getInstance().audioOutputDevice() == "default")
|
||||||
|
{
|
||||||
BASS_Init(-1, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr);
|
BASS_Init(-1, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr);
|
||||||
load_bass_plugins();
|
load_bass_plugins();
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
for (a = 0; BASS_GetDeviceInfo(a, &info); a++) {
|
{
|
||||||
if (Options::getInstance().audioOutputDevice() == info.name) {
|
for (a = 0; BASS_GetDeviceInfo(a, &info); a++)
|
||||||
|
{
|
||||||
|
if (Options::getInstance().audioOutputDevice() == info.name)
|
||||||
|
{
|
||||||
BASS_SetDevice(a);
|
BASS_SetDevice(a);
|
||||||
BASS_Init(static_cast<int>(a), 48000, BASS_DEVICE_LATENCY, nullptr,
|
BASS_Init(static_cast<int>(a), 48000, BASS_DEVICE_LATENCY, nullptr, nullptr);
|
||||||
nullptr);
|
|
||||||
load_bass_plugins();
|
load_bass_plugins();
|
||||||
qInfo() << info.name << "was set as the default audio output device.";
|
qInfo() << info.name << "was set as the default audio output device.";
|
||||||
BASS_SetConfigPtr(BASS_CONFIG_MIDI_DEFFONT, QString(get_base_path() + "soundfont.sf2").toStdString().c_str());
|
BASS_SetConfigPtr(BASS_CONFIG_MIDI_DEFFONT, QString(get_base_path() + "soundfont.sf2").toStdString().c_str());
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
#ifndef AOAPPLICATION_H
|
#pragma once
|
||||||
#define AOAPPLICATION_H
|
|
||||||
|
|
||||||
#include "widgets/aooptionsdialog.h"
|
|
||||||
#include "aopacket.h"
|
#include "aopacket.h"
|
||||||
#include "datatypes.h"
|
#include "datatypes.h"
|
||||||
#include "demoserver.h"
|
#include "demoserver.h"
|
||||||
#include "discord_rich_presence.h"
|
#include "discord_rich_presence.h"
|
||||||
|
#include "widgets/aooptionsdialog.h"
|
||||||
|
|
||||||
#include "bass.h"
|
#include "bass.h"
|
||||||
|
|
||||||
@ -35,18 +34,17 @@ class Lobby;
|
|||||||
class Courtroom;
|
class Courtroom;
|
||||||
class Options;
|
class Options;
|
||||||
|
|
||||||
class VPath : QString {
|
class VPath : QString
|
||||||
|
{
|
||||||
using QString::QString;
|
using QString::QString;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit VPath(const QString &str) : QString(str) {}
|
explicit VPath(const QString &str)
|
||||||
inline QString const &toQString() const { return *this; }
|
: QString(str)
|
||||||
inline bool operator==(const VPath &str) const {
|
{}
|
||||||
return this->toQString() == str.toQString();
|
inline const QString &toQString() const { return *this; }
|
||||||
}
|
inline bool operator==(const VPath &str) const { return this->toQString() == str.toQString(); }
|
||||||
inline VPath operator+(const VPath &str) const {
|
inline VPath operator+(const VPath &str) const { return VPath(this->toQString() + str.toQString()); }
|
||||||
return VPath(this->toQString() + str.toQString());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline uint qHash(const VPath &key, uint seed = qGlobalQHashSeed())
|
inline uint qHash(const VPath &key, uint seed = qGlobalQHashSeed())
|
||||||
@ -54,7 +52,8 @@ inline uint qHash(const VPath &key, uint seed = qGlobalQHashSeed())
|
|||||||
return qHash(key.toQString(), seed);
|
return qHash(key.toQString(), seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
class AOApplication : public QApplication {
|
class AOApplication : public QApplication
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -77,12 +76,11 @@ public:
|
|||||||
void construct_courtroom();
|
void construct_courtroom();
|
||||||
void destruct_courtroom();
|
void destruct_courtroom();
|
||||||
|
|
||||||
void server_packet_received(AOPacket *p_packet);
|
void server_packet_received(AOPacket p_packet);
|
||||||
|
|
||||||
void send_server_packet(AOPacket *p_packet);
|
void send_server_packet(AOPacket p_packet);
|
||||||
|
|
||||||
void call_settings_menu();
|
void call_settings_menu();
|
||||||
void call_announce_menu(Courtroom *court);
|
|
||||||
|
|
||||||
qint64 latency = 0;
|
qint64 latency = 0;
|
||||||
QString window_title;
|
QString window_title;
|
||||||
@ -111,7 +109,7 @@ public:
|
|||||||
// client ID. Not useful, to be removed eventually
|
// client ID. Not useful, to be removed eventually
|
||||||
int client_id = 0;
|
int client_id = 0;
|
||||||
|
|
||||||
QString server_software = "";
|
QString server_software;
|
||||||
|
|
||||||
int char_list_size = 0;
|
int char_list_size = 0;
|
||||||
int loaded_chars = 0;
|
int loaded_chars = 0;
|
||||||
@ -125,25 +123,15 @@ public:
|
|||||||
|
|
||||||
//////////////////versioning///////////////
|
//////////////////versioning///////////////
|
||||||
|
|
||||||
int get_release() const { return RELEASE; }
|
|
||||||
int get_major_version() const { return MAJOR_VERSION; }
|
|
||||||
int get_minor_version() const { return MINOR_VERSION; }
|
|
||||||
QString get_version_string();
|
QString get_version_string();
|
||||||
|
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
|
||||||
// Adds the server to favorite_servers.ini
|
|
||||||
void add_favorite_server(int p_server);
|
|
||||||
void remove_favorite_server(int p_server);
|
|
||||||
|
|
||||||
void set_server_list(QVector<server_type> &servers) { server_list = servers; }
|
void set_server_list(QVector<server_type> &servers) { server_list = servers; }
|
||||||
QVector<server_type> &get_server_list() { return server_list; }
|
QVector<server_type> &get_server_list() { return server_list; }
|
||||||
|
|
||||||
// Returns the character the player has currently selected
|
|
||||||
QString get_current_char();
|
|
||||||
|
|
||||||
// implementation in path_functions.cpp
|
// implementation in path_functions.cpp
|
||||||
VPath get_theme_path(QString p_file, QString p_theme="");
|
VPath get_theme_path(QString p_file, QString p_theme = QString());
|
||||||
VPath get_character_path(QString p_char, QString p_file);
|
VPath get_character_path(QString p_char, QString p_file);
|
||||||
VPath get_misc_path(QString p_misc, QString p_file);
|
VPath get_misc_path(QString p_misc, QString p_file);
|
||||||
VPath get_sounds_path(QString p_file);
|
VPath get_sounds_path(QString p_file);
|
||||||
@ -151,18 +139,17 @@ public:
|
|||||||
VPath get_background_path(QString p_file);
|
VPath get_background_path(QString p_file);
|
||||||
VPath get_default_background_path(QString p_file);
|
VPath get_default_background_path(QString p_file);
|
||||||
VPath get_evidence_path(QString p_file);
|
VPath get_evidence_path(QString p_file);
|
||||||
QVector<VPath> get_asset_paths(QString p_element, QString p_theme="", QString p_subtheme="", QString p_default_theme="", QString p_misc="", QString p_character="", QString p_placeholder="");
|
QVector<VPath> get_asset_paths(QString p_element, QString p_theme = QString(), QString p_subtheme = QString(), QString p_default_theme = QString(), QString p_misc = QString(), QString p_character = QString(), QString p_placeholder = QString());
|
||||||
QString get_asset_path(QVector<VPath> pathlist);
|
QString get_asset_path(QVector<VPath> pathlist);
|
||||||
QString get_image_path(QVector<VPath> pathlist, bool static_image=false);
|
QString get_image_path(QVector<VPath> pathlist, bool static_image = false);
|
||||||
QString get_sfx_path(QVector<VPath> pathlist);
|
QString get_sfx_path(QVector<VPath> pathlist);
|
||||||
QString get_config_value(QString p_identifier, QString p_config, QString p_theme="", QString p_subtheme="", QString p_default_theme="", QString p_misc="");
|
QString get_config_value(QString p_identifier, QString p_config, QString p_theme = QString(), QString p_subtheme = QString(), QString p_default_theme = QString(), QString p_misc = QString());
|
||||||
QString get_asset(QString p_element, QString p_theme="", QString p_subtheme="", QString p_default_theme="", QString p_misc="", QString p_character="", QString p_placeholder="");
|
QString get_asset(QString p_element, QString p_theme = QString(), QString p_subtheme = QString(), QString p_default_theme = QString(), QString p_misc = QString(), QString p_character = QString(), QString p_placeholder = QString());
|
||||||
QString get_image(QString p_element, QString p_theme="", QString p_subtheme="", QString p_default_theme="", QString p_misc="", QString p_character="", QString p_placeholder="", bool static_image=false);
|
QString get_image(QString p_element, QString p_theme = QString(), QString p_subtheme = QString(), QString p_default_theme = QString(), QString p_misc = QString(), QString p_character = QString(), QString p_placeholder = QString(), bool static_image = false);
|
||||||
QString get_sfx(QString p_sfx, QString p_misc="", QString p_character="");
|
QString get_sfx(QString p_sfx, QString p_misc = QString(), QString p_character = QString());
|
||||||
QString get_pos_path(const QString& pos, bool desk = false);
|
QString get_pos_path(const QString &pos, bool desk = false);
|
||||||
QString get_case_sensitive_path(QString p_file);
|
QString get_case_sensitive_path(QString p_file);
|
||||||
QString get_real_path(const VPath &vpath, const QStringList &suffixes={""});
|
QString get_real_path(const VPath &vpath, const QStringList &suffixes = {""});
|
||||||
void invalidate_lookup_cache();
|
|
||||||
|
|
||||||
////// Functions for reading and writing files //////
|
////// Functions for reading and writing files //////
|
||||||
// Implementations file_functions.cpp
|
// Implementations file_functions.cpp
|
||||||
@ -206,15 +193,10 @@ public:
|
|||||||
QPoint get_button_spacing(QString p_identifier, QString p_file);
|
QPoint get_button_spacing(QString p_identifier, QString p_file);
|
||||||
|
|
||||||
// Returns the dimensions of widget with specified identifier from p_file
|
// Returns the dimensions of widget with specified identifier from p_file
|
||||||
pos_size_type get_element_dimensions(QString p_identifier, QString p_file,
|
pos_size_type get_element_dimensions(QString p_identifier, QString p_file, QString p_misc = QString());
|
||||||
QString p_misc = "");
|
|
||||||
|
|
||||||
// Returns the value to you
|
// Returns the value to you
|
||||||
QString get_design_element(QString p_identifier, QString p_file,
|
QString get_design_element(QString p_identifier, QString p_file, QString p_misc = QString());
|
||||||
QString p_misc = "");
|
|
||||||
|
|
||||||
// Returns the value of font_size with p_identifier from p_file
|
|
||||||
int get_font_size(QString p_identifier, QString p_file);
|
|
||||||
|
|
||||||
// Returns the color with p_identifier from p_file
|
// Returns the color with p_identifier from p_file
|
||||||
QColor get_color(QString p_identifier, QString p_file);
|
QColor get_color(QString p_identifier, QString p_file);
|
||||||
@ -230,32 +212,24 @@ public:
|
|||||||
QString get_penalty_value(QString p_identifier);
|
QString get_penalty_value(QString p_identifier);
|
||||||
|
|
||||||
// Returns the sfx with p_identifier from courtroom_sounds.ini in the current theme path
|
// Returns the sfx with p_identifier from courtroom_sounds.ini in the current theme path
|
||||||
QString get_court_sfx(QString p_identifier, QString p_misc="");
|
QString get_court_sfx(QString p_identifier, QString p_misc = QString());
|
||||||
|
|
||||||
// Figure out if we can opus this or if we should fall back to wav
|
// Figure out if we can opus this or if we should fall back to wav
|
||||||
QString get_sfx_suffix(VPath sound_to_check);
|
QString get_sfx_suffix(VPath sound_to_check);
|
||||||
|
|
||||||
// Can we use APNG for this? If not, WEBP? If not, GIF? If not, fall back to
|
// Can we use APNG for this? If not, WEBP? If not, GIF? If not, fall back to
|
||||||
// PNG.
|
// PNG.
|
||||||
QString get_image_suffix(VPath path_to_check, bool static_image=false);
|
QString get_image_suffix(VPath path_to_check, bool static_image = false);
|
||||||
|
|
||||||
// Returns the value of p_search_line within target_tag and terminator_tag
|
// Returns the value of p_search_line within target_tag and terminator_tag
|
||||||
QString read_char_ini(QString p_char, QString p_search_line,
|
QString read_char_ini(QString p_char, QString p_search_line, QString target_tag);
|
||||||
QString target_tag);
|
|
||||||
|
|
||||||
// Returns a QStringList of all key=value definitions on a given tag.
|
// Returns a QStringList of all key=value definitions on a given tag.
|
||||||
QStringList read_ini_tags(VPath p_file, QString target_tag = "");
|
QStringList read_ini_tags(VPath p_file, QString target_tag = QString());
|
||||||
|
|
||||||
// Sets the char.ini p_search_line key under tag target_tag to value.
|
|
||||||
void set_char_ini(QString p_char, QString value, QString p_search_line,
|
|
||||||
QString target_tag);
|
|
||||||
|
|
||||||
// Returns the text between target_tag and terminator_tag in p_file
|
// Returns the text between target_tag and terminator_tag in p_file
|
||||||
QString get_stylesheet(QString p_file);
|
QString get_stylesheet(QString p_file);
|
||||||
|
|
||||||
// Returns the text between target_tag and terminator_tag in p_file
|
|
||||||
QString get_tagged_stylesheet(QString target_tag, QString p_file);
|
|
||||||
|
|
||||||
// Returns the side of the p_char character from that characters ini file
|
// Returns the side of the p_char character from that characters ini file
|
||||||
QString get_char_side(QString p_char);
|
QString get_char_side(QString p_char);
|
||||||
|
|
||||||
@ -312,9 +286,6 @@ public:
|
|||||||
// Returns the sfx of p_char's p_emote
|
// Returns the sfx of p_char's p_emote
|
||||||
QString get_sfx_name(QString p_char, int p_emote);
|
QString get_sfx_name(QString p_char, int p_emote);
|
||||||
|
|
||||||
// Returns the blipsound of p_char's p_emote
|
|
||||||
QString get_emote_blip(QString p_char, int p_emote);
|
|
||||||
|
|
||||||
// Returns if the sfx is defined as looping in char.ini
|
// Returns if the sfx is defined as looping in char.ini
|
||||||
QString get_sfx_looping(QString p_char, int p_emote);
|
QString get_sfx_looping(QString p_char, int p_emote);
|
||||||
|
|
||||||
@ -355,7 +326,7 @@ public:
|
|||||||
// Currently defined subtheme
|
// Currently defined subtheme
|
||||||
QString subtheme;
|
QString subtheme;
|
||||||
|
|
||||||
//Default is always default.
|
// Default is always default.
|
||||||
const QString default_theme = "default";
|
const QString default_theme = "default";
|
||||||
|
|
||||||
// The file name of the log file in base/logs.
|
// The file name of the log file in base/logs.
|
||||||
@ -373,30 +344,26 @@ public:
|
|||||||
|
|
||||||
void initBASS();
|
void initBASS();
|
||||||
static void load_bass_plugins();
|
static void load_bass_plugins();
|
||||||
static void CALLBACK BASSreset(HSTREAM handle, DWORD channel, DWORD data,
|
static void CALLBACK BASSreset(HSTREAM handle, DWORD channel, DWORD data, void *user);
|
||||||
void *user);
|
|
||||||
static void doBASSreset();
|
static void doBASSreset();
|
||||||
|
|
||||||
QElapsedTimer demo_timer;
|
QElapsedTimer demo_timer;
|
||||||
DemoServer* demo_server = nullptr;
|
DemoServer *demo_server = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int RELEASE = 2;
|
const int RELEASE = 2;
|
||||||
const int MAJOR_VERSION = 10;
|
const int MAJOR_VERSION = 11;
|
||||||
const int MINOR_VERSION = 1;
|
const int MINOR_VERSION = 0;
|
||||||
|
|
||||||
QVector<server_type> server_list;
|
QVector<server_type> server_list;
|
||||||
QHash<uint, QString> asset_lookup_cache;
|
QHash<uint, QString> asset_lookup_cache;
|
||||||
QHash<uint, QString> dir_listing_cache;
|
QHash<uint, QString> dir_listing_cache;
|
||||||
QSet<uint> dir_listing_exist_cache;
|
QSet<uint> dir_listing_exist_cache;
|
||||||
|
|
||||||
public slots:
|
public Q_SLOTS:
|
||||||
void server_disconnected();
|
void server_disconnected();
|
||||||
void loading_cancelled();
|
void loading_cancelled();
|
||||||
|
|
||||||
signals:
|
Q_SIGNALS:
|
||||||
void qt_log_message(QtMsgType type, const QMessageLogContext &context,
|
void qt_log_message(QtMsgType type, const QMessageLogContext &context, const QString &msg);
|
||||||
const QString &msg);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AOAPPLICATION_H
|
|
@ -1,24 +1,25 @@
|
|||||||
#include "aoblipplayer.h"
|
#include "aoblipplayer.h"
|
||||||
|
|
||||||
AOBlipPlayer::AOBlipPlayer(QWidget *parent, AOApplication *p_ao_app)
|
AOBlipPlayer::AOBlipPlayer(AOApplication *p_ao_app)
|
||||||
{
|
: ao_app(p_ao_app)
|
||||||
m_parent = parent;
|
{}
|
||||||
ao_app = p_ao_app;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOBlipPlayer::set_blips(QString p_sfx)
|
void AOBlipPlayer::set_blips(QString p_sfx)
|
||||||
{
|
{
|
||||||
QString f_path = ao_app->get_sfx_suffix(ao_app->get_sounds_path(p_sfx));
|
QString f_path = ao_app->get_sfx_suffix(ao_app->get_sounds_path(p_sfx));
|
||||||
|
|
||||||
for (int n_stream = 0; n_stream < 5; ++n_stream) {
|
for (int n_stream = 0; n_stream < 5; ++n_stream)
|
||||||
|
{
|
||||||
BASS_StreamFree(m_stream_list[n_stream]);
|
BASS_StreamFree(m_stream_list[n_stream]);
|
||||||
|
|
||||||
if (f_path.endsWith(".opus"))
|
if (f_path.endsWith(".opus"))
|
||||||
m_stream_list[n_stream] = BASS_OPUS_StreamCreateFile(
|
{
|
||||||
FALSE, f_path.utf16(), 0, 0, BASS_UNICODE | BASS_ASYNCFILE);
|
m_stream_list[n_stream] = BASS_OPUS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, BASS_UNICODE | BASS_ASYNCFILE);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
m_stream_list[n_stream] = BASS_StreamCreateFile(
|
{
|
||||||
FALSE, f_path.utf16(), 0, 0, BASS_UNICODE | BASS_ASYNCFILE);
|
m_stream_list[n_stream] = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, BASS_UNICODE | BASS_ASYNCFILE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_volume_internal(m_volume);
|
set_volume_internal(m_volume);
|
||||||
@ -29,7 +30,9 @@ void AOBlipPlayer::blip_tick()
|
|||||||
int f_cycle = m_cycle++;
|
int f_cycle = m_cycle++;
|
||||||
|
|
||||||
if (m_cycle == 5)
|
if (m_cycle == 5)
|
||||||
|
{
|
||||||
m_cycle = 0;
|
m_cycle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
HSTREAM f_stream = m_stream_list[f_cycle];
|
HSTREAM f_stream = m_stream_list[f_cycle];
|
||||||
|
|
||||||
@ -54,7 +57,8 @@ void AOBlipPlayer::set_volume_internal(qreal p_value)
|
|||||||
// If muted, volume will always be 0
|
// If muted, volume will always be 0
|
||||||
float volume = static_cast<float>(p_value) * !m_muted;
|
float volume = static_cast<float>(p_value) * !m_muted;
|
||||||
|
|
||||||
for (int n_stream = 0; n_stream < 5; ++n_stream) {
|
for (int n_stream = 0; n_stream < 5; ++n_stream)
|
||||||
|
{
|
||||||
BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL, volume);
|
BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL, volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#ifndef AOBLIPPLAYER_H
|
#pragma once
|
||||||
#define AOBLIPPLAYER_H
|
|
||||||
|
|
||||||
#include "bass.h"
|
#include "bass.h"
|
||||||
#include "bassopus.h"
|
#include "bassopus.h"
|
||||||
@ -11,27 +10,22 @@
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
class AOBlipPlayer {
|
class AOBlipPlayer
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
AOBlipPlayer(QWidget *parent, AOApplication *p_ao_app);
|
AOBlipPlayer(AOApplication *p_ao_app);
|
||||||
|
|
||||||
void set_blips(QString p_sfx);
|
void set_blips(QString p_sfx);
|
||||||
void blip_tick();
|
void blip_tick();
|
||||||
void set_volume(int p_volume);
|
void set_volume(int p_volume);
|
||||||
void set_muted(bool toggle);
|
void set_muted(bool toggle);
|
||||||
|
|
||||||
int m_cycle = 0;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QWidget *m_parent;
|
|
||||||
AOApplication *ao_app;
|
AOApplication *ao_app;
|
||||||
qreal m_volume;
|
qreal m_volume = 0.0;
|
||||||
|
int m_cycle = 0;
|
||||||
bool m_muted = false;
|
bool m_muted = false;
|
||||||
|
HSTREAM m_stream_list[5];
|
||||||
|
|
||||||
void set_volume_internal(qreal p_volume);
|
void set_volume_internal(qreal p_volume);
|
||||||
|
|
||||||
HSTREAM m_stream_list[5];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AOBLIPPLAYER_H
|
|
@ -4,40 +4,44 @@
|
|||||||
#include "file_functions.h"
|
#include "file_functions.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
AOButton::AOButton(QWidget *parent, AOApplication *p_ao_app)
|
AOButton::AOButton(AOApplication *p_ao_app, QWidget *parent)
|
||||||
: QPushButton(parent)
|
: QPushButton(parent)
|
||||||
|
, ao_app(p_ao_app)
|
||||||
{
|
{
|
||||||
ao_app = p_ao_app;
|
m_movie = new QMovie(this);
|
||||||
movie = new QMovie(this);
|
|
||||||
connect(movie, &QMovie::frameChanged, [this]{
|
connect(m_movie, &QMovie::frameChanged, this, [this] {
|
||||||
this->setIcon(movie->currentPixmap().scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
this->setIcon(m_movie->currentPixmap().scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
this->setIconSize(QSize(this->width(), this->height()));
|
this->setIconSize(QSize(this->width(), this->height()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
AOButton::~AOButton() {}
|
AOButton::~AOButton()
|
||||||
|
{}
|
||||||
|
|
||||||
void AOButton::set_image(QString p_path, QString p_misc)
|
void AOButton::set_image(QString p_path, QString p_misc)
|
||||||
{
|
{
|
||||||
movie->stop();
|
m_movie->stop();
|
||||||
QString p_image;
|
QString p_image;
|
||||||
p_image = ao_app->get_image(p_path, Options::getInstance().theme(), Options::getInstance().subTheme(),
|
p_image = ao_app->get_image(p_path, Options::getInstance().theme(), Options::getInstance().subTheme(), ao_app->default_theme, p_misc, "", "", !Options::getInstance().animatedThemeEnabled());
|
||||||
ao_app->default_theme, p_misc, "", "", !Options::getInstance().animatedThemeEnabled());
|
if (p_image.isEmpty())
|
||||||
if (p_image.isEmpty()) {
|
{
|
||||||
this->setIcon(QIcon());
|
this->setIcon(QIcon());
|
||||||
this->setIconSize(this->size());
|
this->setIconSize(this->size());
|
||||||
this->setStyleSheet("");
|
this->setStyleSheet("");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->setText("");
|
this->setText("");
|
||||||
this->setStyleSheet("QPushButton { background-color: transparent; border: 0px }");
|
this->setStyleSheet("QPushButton { background-color: transparent; border: 0px }");
|
||||||
movie->setFileName(p_image);
|
m_movie->setFileName(p_image);
|
||||||
// We double-check if the user wants animated themes, so even if an animated image slipped through,
|
// We double-check if the user wants animated themes, so even if an animated image slipped through,
|
||||||
// we still set it static
|
// we still set it static
|
||||||
if (Options::getInstance().animatedThemeEnabled() && movie->frameCount() > 1) {
|
if (Options::getInstance().animatedThemeEnabled() && m_movie->frameCount() > 1)
|
||||||
movie->start();
|
{
|
||||||
|
m_movie->start();
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
this->setIcon(QPixmap(p_image).scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
this->setIcon(QPixmap(p_image).scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
this->setIconSize(this->size());
|
this->setIconSize(this->size());
|
||||||
}
|
}
|
||||||
|
22
src/aobutton.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "aoapplication.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QMovie>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
class AOButton : public QPushButton
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
AOButton(AOApplication *p_ao_app, QWidget *parent = nullptr);
|
||||||
|
~AOButton();
|
||||||
|
|
||||||
|
void set_image(QString p_image, QString p_misc = QString());
|
||||||
|
|
||||||
|
private:
|
||||||
|
AOApplication *ao_app;
|
||||||
|
QMovie *m_movie;
|
||||||
|
};
|
@ -2,35 +2,24 @@
|
|||||||
|
|
||||||
#include "file_functions.h"
|
#include "file_functions.h"
|
||||||
|
|
||||||
AOCharButton::AOCharButton(QWidget *parent, AOApplication *p_ao_app, int x_pos,
|
AOCharButton::AOCharButton(AOApplication *p_ao_app, int x_pos, int y_pos, bool is_taken, QWidget *parent)
|
||||||
int y_pos, bool is_taken)
|
|
||||||
: QPushButton(parent)
|
: QPushButton(parent)
|
||||||
|
, ao_app(p_ao_app)
|
||||||
|
, m_taken(is_taken)
|
||||||
{
|
{
|
||||||
m_parent = parent;
|
|
||||||
|
|
||||||
ao_app = p_ao_app;
|
|
||||||
|
|
||||||
taken = is_taken;
|
|
||||||
|
|
||||||
int size = 60 * Options::getInstance().themeScalingFactor();
|
int size = 60 * Options::getInstance().themeScalingFactor();
|
||||||
int selector_size = 62 * Options::getInstance().themeScalingFactor();
|
int selector_size = 62 * Options::getInstance().themeScalingFactor();
|
||||||
|
|
||||||
this->resize(size, size);
|
this->resize(size, size);
|
||||||
this->move(x_pos, y_pos);
|
this->move(x_pos, y_pos);
|
||||||
|
|
||||||
ui_taken = new AOImage(this, ao_app, true);
|
ui_taken = new AOImage(ao_app, this);
|
||||||
ui_taken->resize(size, size);
|
ui_taken->resize(size, size);
|
||||||
ui_taken->set_image("char_taken");
|
ui_taken->set_image("char_taken");
|
||||||
ui_taken->setAttribute(Qt::WA_TransparentForMouseEvents);
|
ui_taken->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
ui_taken->hide();
|
ui_taken->hide();
|
||||||
|
|
||||||
ui_passworded = new AOImage(this, ao_app, true);
|
ui_selector = new AOImage(ao_app, parent);
|
||||||
ui_passworded->resize(size, size);
|
|
||||||
ui_passworded->set_image("char_passworded");
|
|
||||||
ui_passworded->setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
||||||
ui_passworded->hide();
|
|
||||||
|
|
||||||
ui_selector = new AOImage(parent, ao_app, true);
|
|
||||||
ui_selector->resize(selector_size, selector_size);
|
ui_selector->resize(selector_size, selector_size);
|
||||||
int offset = Options::getInstance().themeScalingFactor();
|
int offset = Options::getInstance().themeScalingFactor();
|
||||||
ui_selector->move(x_pos - offset, y_pos - offset);
|
ui_selector->move(x_pos - offset, y_pos - offset);
|
||||||
@ -42,39 +31,42 @@ AOCharButton::AOCharButton(QWidget *parent, AOApplication *p_ao_app, int x_pos,
|
|||||||
void AOCharButton::reset()
|
void AOCharButton::reset()
|
||||||
{
|
{
|
||||||
ui_taken->hide();
|
ui_taken->hide();
|
||||||
ui_passworded->hide();
|
|
||||||
ui_selector->hide();
|
ui_selector->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOCharButton::set_taken(bool is_taken) { taken = is_taken; }
|
void AOCharButton::set_taken(bool is_taken)
|
||||||
|
{
|
||||||
|
m_taken = is_taken;
|
||||||
|
}
|
||||||
|
|
||||||
void AOCharButton::apply_taken_image()
|
void AOCharButton::apply_taken_image()
|
||||||
{
|
{
|
||||||
if (taken) {
|
if (m_taken)
|
||||||
|
{
|
||||||
ui_taken->move(0, 0);
|
ui_taken->move(0, 0);
|
||||||
ui_taken->show();
|
ui_taken->show();
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui_taken->hide();
|
ui_taken->hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOCharButton::set_passworded() { ui_passworded->show(); }
|
|
||||||
|
|
||||||
void AOCharButton::set_image(QString p_character)
|
void AOCharButton::set_image(QString p_character)
|
||||||
{
|
{
|
||||||
QString image_path = ao_app->get_image_suffix(
|
QString image_path = ao_app->get_image_suffix(ao_app->get_character_path(p_character, "char_icon"), true);
|
||||||
ao_app->get_character_path(p_character, "char_icon"), true);
|
|
||||||
|
|
||||||
this->setText("");
|
this->setText("");
|
||||||
|
|
||||||
if (file_exists(image_path)) {
|
if (file_exists(image_path))
|
||||||
|
{
|
||||||
this->setStyleSheet("QPushButton { border-image: url(\"" + image_path +
|
this->setStyleSheet("QPushButton { border-image: url(\"" + image_path +
|
||||||
"\") 0 0 0 0 stretch stretch; }"
|
"\") 0 0 0 0 stretch stretch; }"
|
||||||
"QToolTip { background-image: url(); color: #000000; "
|
"QToolTip { background-image: url(); color: #000000; "
|
||||||
"background-color: #ffffff; border: 0px; }");
|
"background-color: #ffffff; border: 0px; }");
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
this->setStyleSheet("QPushButton { border-image: url(); }"
|
this->setStyleSheet("QPushButton { border-image: url(); }"
|
||||||
"QToolTip { background-image: url(); color: #000000; "
|
"QToolTip { background-image: url(); color: #000000; "
|
||||||
"background-color: #ffffff; border: 0px; }");
|
"background-color: #ffffff; border: 0px; }");
|
||||||
|
@ -1,42 +1,29 @@
|
|||||||
#ifndef AOCHARBUTTON_H
|
#pragma once
|
||||||
#define AOCHARBUTTON_H
|
|
||||||
|
|
||||||
#include "aoapplication.h"
|
#include "aoapplication.h"
|
||||||
#include "aoimage.h"
|
#include "aoimage.h"
|
||||||
|
|
||||||
|
#include <QEnterEvent>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QEnterEvent>
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class AOCharButton : public QPushButton {
|
class AOCharButton : public QPushButton
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AOCharButton(QWidget *parent, AOApplication *p_ao_app, int x_pos, int y_pos,
|
AOCharButton(AOApplication *p_ao_app, int x_pos, int y_pos, bool is_taken, QWidget *parent);
|
||||||
bool is_taken);
|
|
||||||
|
|
||||||
AOApplication *ao_app;
|
|
||||||
|
|
||||||
void refresh();
|
void refresh();
|
||||||
void reset();
|
void reset();
|
||||||
void set_taken(bool is_taken);
|
void set_taken(bool is_taken);
|
||||||
void set_passworded();
|
|
||||||
|
|
||||||
void apply_taken_image();
|
void apply_taken_image();
|
||||||
|
|
||||||
void set_image(QString p_character);
|
void set_image(QString p_character);
|
||||||
|
|
||||||
private:
|
|
||||||
bool taken;
|
|
||||||
|
|
||||||
QWidget *m_parent;
|
|
||||||
|
|
||||||
AOImage *ui_taken;
|
|
||||||
AOImage *ui_passworded;
|
|
||||||
AOImage *ui_selector;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
void enterEvent(QEvent *e) override;
|
void enterEvent(QEvent *e) override;
|
||||||
@ -44,6 +31,10 @@ protected:
|
|||||||
void enterEvent(QEnterEvent *e) override;
|
void enterEvent(QEnterEvent *e) override;
|
||||||
#endif
|
#endif
|
||||||
void leaveEvent(QEvent *e) override;
|
void leaveEvent(QEvent *e) override;
|
||||||
};
|
|
||||||
|
|
||||||
#endif // AOCHARBUTTON_H
|
private:
|
||||||
|
AOApplication *ao_app;
|
||||||
|
bool m_taken = false;
|
||||||
|
AOImage *ui_taken;
|
||||||
|
AOImage *ui_selector;
|
||||||
|
};
|
@ -1,10 +1,12 @@
|
|||||||
#include "aoclocklabel.h"
|
#include "aoclocklabel.h"
|
||||||
|
|
||||||
AOClockLabel::AOClockLabel(QWidget *parent) : QLabel(parent) {}
|
AOClockLabel::AOClockLabel(QWidget *parent)
|
||||||
|
: QLabel(parent)
|
||||||
|
{}
|
||||||
|
|
||||||
void AOClockLabel::start()
|
void AOClockLabel::start()
|
||||||
{
|
{
|
||||||
timer.start(1000 / 60, this);
|
m_timer.start(1000 / 60, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOClockLabel::start(qint64 msecs)
|
void AOClockLabel::start(qint64 msecs)
|
||||||
@ -15,16 +17,16 @@ void AOClockLabel::start(qint64 msecs)
|
|||||||
|
|
||||||
void AOClockLabel::set(qint64 msecs, bool update_text)
|
void AOClockLabel::set(qint64 msecs, bool update_text)
|
||||||
{
|
{
|
||||||
target_time = QDateTime::currentDateTime().addMSecs(msecs);
|
m_target_time = QDateTime::currentDateTime().addMSecs(msecs);
|
||||||
if (update_text)
|
if (update_text)
|
||||||
{
|
{
|
||||||
if (QDateTime::currentDateTime() >= target_time)
|
if (QDateTime::currentDateTime() >= m_target_time)
|
||||||
{
|
{
|
||||||
this->setText("00:00:00.000");
|
this->setText("00:00:00.000");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qint64 ms_left = QDateTime::currentDateTime().msecsTo(target_time);
|
qint64 ms_left = QDateTime::currentDateTime().msecsTo(m_target_time);
|
||||||
QTime timeleft = QTime(0, 0).addMSecs(ms_left % (1000 * 3600 * 24));
|
QTime timeleft = QTime(0, 0).addMSecs(ms_left % (1000 * 3600 * 24));
|
||||||
QString timestring = timeleft.toString("hh:mm:ss.zzz");
|
QString timestring = timeleft.toString("hh:mm:ss.zzz");
|
||||||
this->setText(timestring);
|
this->setText(timestring);
|
||||||
@ -34,39 +36,42 @@ void AOClockLabel::set(qint64 msecs, bool update_text)
|
|||||||
|
|
||||||
void AOClockLabel::pause()
|
void AOClockLabel::pause()
|
||||||
{
|
{
|
||||||
timer.stop();
|
m_timer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOClockLabel::stop()
|
void AOClockLabel::stop()
|
||||||
{
|
{
|
||||||
this->setText("00:00:00.000");
|
this->setText("00:00:00.000");
|
||||||
timer.stop();
|
m_timer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOClockLabel::skip(qint64 msecs)
|
void AOClockLabel::skip(qint64 msecs)
|
||||||
{
|
{
|
||||||
qint64 ms_left = QDateTime::currentDateTime().msecsTo(target_time);
|
qint64 ms_left = QDateTime::currentDateTime().msecsTo(m_target_time);
|
||||||
this->set(ms_left - msecs, true);
|
this->set(ms_left - msecs, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AOClockLabel::active()
|
bool AOClockLabel::active()
|
||||||
{
|
{
|
||||||
return timer.isActive();
|
return m_timer.isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOClockLabel::timerEvent(QTimerEvent *event)
|
void AOClockLabel::timerEvent(QTimerEvent *event)
|
||||||
{
|
{
|
||||||
if (event->timerId() == timer.timerId()) {
|
if (event->timerId() == m_timer.timerId())
|
||||||
if (QDateTime::currentDateTime() >= target_time)
|
{
|
||||||
|
if (QDateTime::currentDateTime() >= m_target_time)
|
||||||
{
|
{
|
||||||
this->stop();
|
this->stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qint64 ms_left = QDateTime::currentDateTime().msecsTo(target_time);
|
qint64 ms_left = QDateTime::currentDateTime().msecsTo(m_target_time);
|
||||||
QTime timeleft = QTime(0, 0).addMSecs(ms_left % (1000 * 3600 * 24));
|
QTime timeleft = QTime(0, 0).addMSecs(ms_left % (1000 * 3600 * 24));
|
||||||
QString timestring = timeleft.toString("hh:mm:ss.zzz");
|
QString timestring = timeleft.toString("hh:mm:ss.zzz");
|
||||||
this->setText(timestring);
|
this->setText(timestring);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
QWidget::timerEvent(event);
|
QWidget::timerEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
#ifndef AOCLOCKLABEL_H
|
#pragma once
|
||||||
#define AOCLOCKLABEL_H
|
|
||||||
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QBasicTimer>
|
#include <QBasicTimer>
|
||||||
#include <QTimerEvent>
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QTimerEvent>
|
||||||
|
|
||||||
class AOClockLabel : public QLabel {
|
class AOClockLabel : public QLabel
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AOClockLabel(QWidget *parent);
|
AOClockLabel(QWidget *parent);
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
void start(qint64 msecs);
|
void start(qint64 msecs);
|
||||||
void set(qint64 msecs, bool update_text = false);
|
void set(qint64 msecs, bool update_text = false);
|
||||||
@ -24,8 +25,6 @@ protected:
|
|||||||
void timerEvent(QTimerEvent *event) override;
|
void timerEvent(QTimerEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QBasicTimer timer;
|
QBasicTimer m_timer;
|
||||||
QDateTime target_time;
|
QDateTime m_target_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AOCLOCKLABEL_H
|
|
@ -1,13 +1,10 @@
|
|||||||
#include "aoemotebutton.h"
|
#include "aoemotebutton.h"
|
||||||
#include "file_functions.h"
|
#include "file_functions.h"
|
||||||
|
|
||||||
AOEmoteButton::AOEmoteButton(QWidget *p_parent, AOApplication *p_ao_app,
|
AOEmoteButton::AOEmoteButton(AOApplication *p_ao_app, int p_x, int p_y, int p_w, int p_h, QWidget *p_parent)
|
||||||
int p_x, int p_y, int p_w, int p_h)
|
|
||||||
: QPushButton(p_parent)
|
: QPushButton(p_parent)
|
||||||
|
, ao_app(p_ao_app)
|
||||||
{
|
{
|
||||||
parent = p_parent;
|
|
||||||
ao_app = p_ao_app;
|
|
||||||
|
|
||||||
this->move(p_x, p_y);
|
this->move(p_x, p_y);
|
||||||
this->resize(p_w, p_h);
|
this->resize(p_w, p_h);
|
||||||
|
|
||||||
@ -21,27 +18,38 @@ AOEmoteButton::AOEmoteButton(QWidget *p_parent, AOApplication *p_ao_app,
|
|||||||
|
|
||||||
void AOEmoteButton::set_selected_image(QString p_image)
|
void AOEmoteButton::set_selected_image(QString p_image)
|
||||||
{
|
{
|
||||||
if (file_exists(p_image)) {
|
if (file_exists(p_image))
|
||||||
|
{
|
||||||
ui_selected->setStyleSheet("border-image: url(\"" + p_image + "\")");
|
ui_selected->setStyleSheet("border-image: url(\"" + p_image + "\")");
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui_selected->setStyleSheet("background-color: rgba(0, 0, 0, 128)");
|
ui_selected->setStyleSheet("background-color: rgba(0, 0, 0, 128)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AOEmoteButton::set_id(int p_id)
|
||||||
|
{
|
||||||
|
m_id = p_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AOEmoteButton::get_id()
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
void AOEmoteButton::set_image(QString p_image, QString p_emote_comment)
|
void AOEmoteButton::set_image(QString p_image, QString p_emote_comment)
|
||||||
{
|
{
|
||||||
QString tmp_p_image = p_image;
|
if (file_exists(p_image))
|
||||||
|
{
|
||||||
if (file_exists(p_image)) {
|
|
||||||
this->setText("");
|
this->setText("");
|
||||||
this->setStyleSheet(
|
this->setStyleSheet("QPushButton { border: none; }"
|
||||||
"QPushButton { border: none; }"
|
"QToolTip { color: #000000; background-color: #ffffff; border: 0px; }");
|
||||||
"QToolTip { color: #000000; background-color: #ffffff; border: 0px; }");
|
|
||||||
this->setIcon(QPixmap(p_image).scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
this->setIcon(QPixmap(p_image).scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
this->setIconSize(this->size());
|
this->setIconSize(this->size());
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
this->setText(p_emote_comment);
|
this->setText(p_emote_comment);
|
||||||
this->setStyleSheet("QPushButton { border-image: url(); }"
|
this->setStyleSheet("QPushButton { border-image: url(); }"
|
||||||
"QToolTip { background-image: url(); color: #000000; "
|
"QToolTip { background-image: url(); color: #000000; "
|
||||||
@ -54,25 +62,29 @@ void AOEmoteButton::set_image(QString p_image, QString p_emote_comment)
|
|||||||
void AOEmoteButton::set_char_image(QString p_char, int p_emote, bool on)
|
void AOEmoteButton::set_char_image(QString p_char, int p_emote, bool on)
|
||||||
{
|
{
|
||||||
QString emotion_number = QString::number(p_emote + 1);
|
QString emotion_number = QString::number(p_emote + 1);
|
||||||
QStringList suffixes { "_off", "_on" };
|
QStringList suffixes{"_off", "_on"};
|
||||||
QStringList suffixedPaths;
|
QStringList suffixedPaths;
|
||||||
for (const QString &suffix : suffixes) {
|
for (const QString &suffix : suffixes)
|
||||||
suffixedPaths.append(ao_app->get_image_suffix(ao_app->get_character_path(
|
{
|
||||||
p_char, "emotions/button" + emotion_number + suffix)));
|
suffixedPaths.append(ao_app->get_image_suffix(ao_app->get_character_path(p_char, "emotions/button" + emotion_number + suffix)));
|
||||||
}
|
}
|
||||||
QString image = suffixedPaths[static_cast<int>(on)];
|
QString image = suffixedPaths[static_cast<int>(on)];
|
||||||
|
|
||||||
QString emoteComment = ao_app->get_emote_comment(p_char, p_emote);
|
QString emoteComment = ao_app->get_emote_comment(p_char, p_emote);
|
||||||
if (on && !file_exists(suffixedPaths[1])) {;
|
if (on && !file_exists(suffixedPaths[1]))
|
||||||
|
{
|
||||||
ui_selected->show();
|
ui_selected->show();
|
||||||
image = suffixedPaths[0];
|
image = suffixedPaths[0];
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ui_selected->hide();
|
ui_selected->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
set_image(image, emoteComment);
|
set_image(image, emoteComment);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOEmoteButton::on_clicked() { emit emote_clicked(m_id); }
|
void AOEmoteButton::on_clicked()
|
||||||
|
{
|
||||||
|
Q_EMIT emote_clicked(m_id);
|
||||||
|
}
|
||||||
|
@ -1,38 +1,36 @@
|
|||||||
#ifndef AOEMOTEBUTTON_H
|
#pragma once
|
||||||
#define AOEMOTEBUTTON_H
|
|
||||||
|
|
||||||
#include "aoapplication.h"
|
#include "aoapplication.h"
|
||||||
#include <QPainter>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QPushButton>
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
class AOEmoteButton : public QPushButton {
|
class AOEmoteButton : public QPushButton
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AOEmoteButton(QWidget *p_parent, AOApplication *p_ao_app, int p_x, int p_y,
|
AOEmoteButton(AOApplication *p_ao_app, int p_x, int p_y, int p_w, int p_h, QWidget *p_parent);
|
||||||
int p_w, int p_h);
|
|
||||||
|
|
||||||
void set_image(QString p_image, QString p_emote_comment);
|
void set_image(QString p_image, QString p_emote_comment);
|
||||||
void set_char_image(QString p_char, int p_emote, bool on);
|
void set_char_image(QString p_char, int p_emote, bool on);
|
||||||
|
|
||||||
void set_selected_image(QString p_image);
|
void set_selected_image(QString p_image);
|
||||||
|
|
||||||
void set_id(int p_id) { m_id = p_id; }
|
void set_id(int p_id);
|
||||||
int get_id() { return m_id; }
|
int get_id();
|
||||||
|
|
||||||
private:
|
Q_SIGNALS:
|
||||||
QWidget *parent;
|
|
||||||
AOApplication *ao_app;
|
|
||||||
QLabel *ui_selected = nullptr;
|
|
||||||
|
|
||||||
int m_id = 0;
|
|
||||||
signals:
|
|
||||||
void emote_clicked(int p_id);
|
void emote_clicked(int p_id);
|
||||||
|
|
||||||
private slots:
|
private:
|
||||||
|
AOApplication *ao_app;
|
||||||
|
|
||||||
|
int m_id = 0;
|
||||||
|
|
||||||
|
QLabel *ui_selected = nullptr;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
void on_clicked();
|
void on_clicked();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AOEMOTEBUTTON_H
|
|
@ -1,11 +1,11 @@
|
|||||||
#include "aoemotepreview.h"
|
#include "aoemotepreview.h"
|
||||||
|
|
||||||
AOEmotePreview::AOEmotePreview(QWidget *parent, AOApplication *p_ao_app) : QWidget(parent)
|
AOEmotePreview::AOEmotePreview(AOApplication *p_ao_app, QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, ao_app(p_ao_app)
|
||||||
{
|
{
|
||||||
ao_app = p_ao_app;
|
|
||||||
|
|
||||||
ui_viewport = new QWidget(this);
|
ui_viewport = new QWidget(this);
|
||||||
ui_vp_player_char = new CharLayer(ui_viewport, ao_app);
|
ui_vp_player_char = new CharLayer(ao_app, ui_viewport);
|
||||||
ui_vp_player_char->setObjectName("ui_vp_player_char");
|
ui_vp_player_char->setObjectName("ui_vp_player_char");
|
||||||
ui_vp_player_char->masked = false;
|
ui_vp_player_char->masked = false;
|
||||||
ui_size_label = new QLabel(this);
|
ui_size_label = new QLabel(this);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#ifndef AOEMOTEPREVIEW_H
|
#pragma once
|
||||||
#define AOEMOTEPREVIEW_H
|
|
||||||
|
|
||||||
#include "aolayer.h"
|
#include "aolayer.h"
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
@ -7,26 +6,26 @@
|
|||||||
class AOEmotePreview : public QWidget
|
class AOEmotePreview : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AOEmotePreview(QWidget *parent = nullptr,
|
AOEmotePreview(AOApplication *p_ao_app, QWidget *parent = nullptr);
|
||||||
AOApplication *p_ao_app = nullptr);
|
|
||||||
|
|
||||||
void set_widgets();
|
void set_widgets();
|
||||||
void play(QString emote, QString char_name, bool flipped = false, int self_offset = 0, int self_offset_v = 0);
|
void play(QString emote, QString char_name, bool flipped = false, int self_offset = 0, int self_offset_v = 0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent *);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AOApplication *ao_app;
|
AOApplication *ao_app;
|
||||||
|
|
||||||
|
QString m_emote;
|
||||||
|
QString m_char;
|
||||||
|
|
||||||
QWidget *ui_viewport;
|
QWidget *ui_viewport;
|
||||||
BackgroundLayer *ui_vp_background;
|
BackgroundLayer *ui_vp_background;
|
||||||
SplashLayer *ui_vp_speedlines;
|
SplashLayer *ui_vp_speedlines;
|
||||||
CharLayer *ui_vp_player_char;
|
CharLayer *ui_vp_player_char;
|
||||||
BackgroundLayer *ui_vp_desk;
|
BackgroundLayer *ui_vp_desk;
|
||||||
|
|
||||||
QLabel *ui_size_label;
|
QLabel *ui_size_label;
|
||||||
|
|
||||||
QString m_emote = "";
|
|
||||||
QString m_char = "";
|
|
||||||
protected:
|
|
||||||
void resizeEvent(QResizeEvent *);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AOEMOTEPREVIEW_H
|
|
@ -2,21 +2,18 @@
|
|||||||
|
|
||||||
#include "file_functions.h"
|
#include "file_functions.h"
|
||||||
|
|
||||||
AOEvidenceButton::AOEvidenceButton(QWidget *p_parent, AOApplication *p_ao_app,
|
AOEvidenceButton::AOEvidenceButton(AOApplication *p_ao_app, int p_x, int p_y, int p_w, int p_h, QWidget *p_parent)
|
||||||
int p_x, int p_y, int p_w, int p_h)
|
|
||||||
: QPushButton(p_parent)
|
: QPushButton(p_parent)
|
||||||
|
, ao_app(p_ao_app)
|
||||||
{
|
{
|
||||||
ao_app = p_ao_app;
|
ui_selected = new AOImage(ao_app, this);
|
||||||
m_parent = p_parent;
|
|
||||||
|
|
||||||
ui_selected = new AOImage(this, ao_app, true);
|
|
||||||
ui_selected->resize(p_w, p_h);
|
ui_selected->resize(p_w, p_h);
|
||||||
// ui_selected->move(p_x, p_y);
|
// ui_selected->move(p_x, p_y);
|
||||||
ui_selected->set_image("evidence_selected");
|
ui_selected->set_image("evidence_selected");
|
||||||
ui_selected->setAttribute(Qt::WA_TransparentForMouseEvents);
|
ui_selected->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
ui_selected->hide();
|
ui_selected->hide();
|
||||||
|
|
||||||
ui_selector = new AOImage(this, ao_app, true);
|
ui_selector = new AOImage(ao_app, this);
|
||||||
ui_selector->resize(p_w, p_h);
|
ui_selector->resize(p_w, p_h);
|
||||||
// ui_selector->move(p_x - 1, p_y - 1);
|
// ui_selector->move(p_x - 1, p_y - 1);
|
||||||
ui_selector->set_image("evidence_selector");
|
ui_selector->set_image("evidence_selector");
|
||||||
@ -33,21 +30,22 @@ AOEvidenceButton::AOEvidenceButton(QWidget *p_parent, AOApplication *p_ao_app,
|
|||||||
void AOEvidenceButton::set_image(QString p_image)
|
void AOEvidenceButton::set_image(QString p_image)
|
||||||
{
|
{
|
||||||
QString image_path = ao_app->get_real_path(ao_app->get_evidence_path(p_image));
|
QString image_path = ao_app->get_real_path(ao_app->get_evidence_path(p_image));
|
||||||
if (file_exists(p_image)) {
|
if (file_exists(p_image))
|
||||||
|
{
|
||||||
this->setText("");
|
this->setText("");
|
||||||
this->setStyleSheet(
|
this->setStyleSheet("QPushButton { border-image: url(\"" + p_image +
|
||||||
"QPushButton { border-image: url(\"" + p_image +
|
"\") 0 0 0 0 stretch stretch; }"
|
||||||
"\") 0 0 0 0 stretch stretch; }"
|
"QToolTip { color: #000000; background-color: #ffffff; border: 0px; }");
|
||||||
"QToolTip { color: #000000; background-color: #ffffff; border: 0px; }");
|
|
||||||
}
|
}
|
||||||
else if (file_exists(image_path)) {
|
else if (file_exists(image_path))
|
||||||
|
{
|
||||||
this->setText("");
|
this->setText("");
|
||||||
this->setStyleSheet(
|
this->setStyleSheet("QPushButton { border-image: url(\"" + image_path +
|
||||||
"QPushButton { border-image: url(\"" + image_path +
|
"\") 0 0 0 0 stretch stretch; }"
|
||||||
"\") 0 0 0 0 stretch stretch; }"
|
"QToolTip { color: #000000; background-color: #ffffff; border: 0px; }");
|
||||||
"QToolTip { color: #000000; background-color: #ffffff; border: 0px; }");
|
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
this->setText(p_image);
|
this->setText(p_image);
|
||||||
this->setStyleSheet("QPushButton { border-image: url(); }"
|
this->setStyleSheet("QPushButton { border-image: url(); }"
|
||||||
"QToolTip { background-image: url(); color: #000000; "
|
"QToolTip { background-image: url(); color: #000000; "
|
||||||
@ -57,17 +55,19 @@ void AOEvidenceButton::set_image(QString p_image)
|
|||||||
|
|
||||||
void AOEvidenceButton::set_theme_image(QString p_image)
|
void AOEvidenceButton::set_theme_image(QString p_image)
|
||||||
{
|
{
|
||||||
QString theme_image_path = ao_app->get_real_path(
|
QString theme_image_path = ao_app->get_real_path(ao_app->get_theme_path(p_image));
|
||||||
ao_app->get_theme_path(p_image));
|
QString default_image_path = ao_app->get_real_path(ao_app->get_theme_path(p_image, ao_app->default_theme));
|
||||||
QString default_image_path = ao_app->get_real_path(
|
|
||||||
ao_app->get_theme_path(p_image, ao_app->default_theme));
|
|
||||||
|
|
||||||
QString final_image_path;
|
QString final_image_path;
|
||||||
|
|
||||||
if (file_exists(theme_image_path))
|
if (file_exists(theme_image_path))
|
||||||
|
{
|
||||||
final_image_path = theme_image_path;
|
final_image_path = theme_image_path;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
final_image_path = default_image_path;
|
final_image_path = default_image_path;
|
||||||
|
}
|
||||||
|
|
||||||
this->set_image(final_image_path);
|
this->set_image(final_image_path);
|
||||||
}
|
}
|
||||||
@ -75,17 +75,24 @@ void AOEvidenceButton::set_theme_image(QString p_image)
|
|||||||
void AOEvidenceButton::set_selected(bool p_selected)
|
void AOEvidenceButton::set_selected(bool p_selected)
|
||||||
{
|
{
|
||||||
if (p_selected)
|
if (p_selected)
|
||||||
|
{
|
||||||
ui_selected->show();
|
ui_selected->show();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
ui_selected->hide();
|
ui_selected->hide();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOEvidenceButton::on_clicked() { emit evidence_clicked(m_id); }
|
void AOEvidenceButton::on_clicked()
|
||||||
|
{
|
||||||
|
Q_EMIT evidence_clicked(m_id);
|
||||||
|
}
|
||||||
|
|
||||||
void AOEvidenceButton::mouseDoubleClickEvent(QMouseEvent *e)
|
void AOEvidenceButton::mouseDoubleClickEvent(QMouseEvent *e)
|
||||||
{
|
{
|
||||||
QPushButton::mouseDoubleClickEvent(e);
|
QPushButton::mouseDoubleClickEvent(e);
|
||||||
emit evidence_double_clicked(m_id);
|
Q_EMIT evidence_double_clicked(m_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -112,7 +119,7 @@ void AOEvidenceButton::enterEvent(QEnterEvent *e)
|
|||||||
{
|
{
|
||||||
ui_selector->show();
|
ui_selector->show();
|
||||||
|
|
||||||
emit on_hover(m_id, true);
|
Q_EMIT on_hover(m_id, true);
|
||||||
|
|
||||||
setFlat(false);
|
setFlat(false);
|
||||||
QPushButton::enterEvent(e);
|
QPushButton::enterEvent(e);
|
||||||
@ -122,6 +129,6 @@ void AOEvidenceButton::leaveEvent(QEvent *e)
|
|||||||
{
|
{
|
||||||
ui_selector->hide();
|
ui_selector->hide();
|
||||||
|
|
||||||
emit on_hover(m_id, false);
|
Q_EMIT on_hover(m_id, false);
|
||||||
QPushButton::leaveEvent(e);
|
QPushButton::leaveEvent(e);
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,19 @@
|
|||||||
#ifndef AOEVIDENCEBUTTON_H
|
#pragma once
|
||||||
#define AOEVIDENCEBUTTON_H
|
|
||||||
|
|
||||||
#include "aoapplication.h"
|
#include "aoapplication.h"
|
||||||
#include "aoimage.h"
|
#include "aoimage.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QPushButton>
|
|
||||||
#include <QEnterEvent>
|
#include <QEnterEvent>
|
||||||
|
#include <QPushButton>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
class AOEvidenceButton : public QPushButton {
|
class AOEvidenceButton : public QPushButton
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AOEvidenceButton(QWidget *p_parent, AOApplication *p_ao_app, int p_x, int p_y,
|
AOEvidenceButton(AOApplication *p_ao_app, int p_x, int p_y, int p_w, int p_h, QWidget *p_parent = nullptr);
|
||||||
int p_w, int p_h);
|
|
||||||
|
|
||||||
void set_image(QString p_image);
|
void set_image(QString p_image);
|
||||||
void set_theme_image(QString p_image);
|
void set_theme_image(QString p_image);
|
||||||
@ -22,14 +21,10 @@ public:
|
|||||||
|
|
||||||
void set_selected(bool p_selected);
|
void set_selected(bool p_selected);
|
||||||
|
|
||||||
private:
|
Q_SIGNALS:
|
||||||
AOApplication *ao_app;
|
void evidence_clicked(int p_id);
|
||||||
QWidget *m_parent;
|
void evidence_double_clicked(int p_id);
|
||||||
|
void on_hover(int p_id, bool p_state);
|
||||||
AOImage *ui_selected;
|
|
||||||
AOImage *ui_selector;
|
|
||||||
|
|
||||||
int m_id = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
@ -39,18 +34,15 @@ protected:
|
|||||||
#endif
|
#endif
|
||||||
void leaveEvent(QEvent *e) override;
|
void leaveEvent(QEvent *e) override;
|
||||||
void mouseDoubleClickEvent(QMouseEvent *e) override;
|
void mouseDoubleClickEvent(QMouseEvent *e) override;
|
||||||
/*
|
|
||||||
void dragLeaveEvent(QMouseEvent *e);
|
|
||||||
void dragEnterEvent(QMouseEvent *e);
|
|
||||||
*/
|
|
||||||
|
|
||||||
signals:
|
private:
|
||||||
void evidence_clicked(int p_id);
|
AOApplication *ao_app;
|
||||||
void evidence_double_clicked(int p_id);
|
|
||||||
void on_hover(int p_id, bool p_state);
|
|
||||||
|
|
||||||
private slots:
|
int m_id = 0;
|
||||||
|
|
||||||
|
AOImage *ui_selected;
|
||||||
|
AOImage *ui_selector;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
void on_clicked();
|
void on_clicked();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AOEVIDENCEBUTTON_H
|
|
@ -2,77 +2,81 @@
|
|||||||
|
|
||||||
#include "datatypes.h"
|
#include "datatypes.h"
|
||||||
#include "file_functions.h"
|
#include "file_functions.h"
|
||||||
#include "misc_functions.h"
|
|
||||||
|
|
||||||
AOEvidenceDisplay::AOEvidenceDisplay(QWidget *p_parent, AOApplication *p_ao_app)
|
AOEvidenceDisplay::AOEvidenceDisplay(AOApplication *p_ao_app, QWidget *p_parent)
|
||||||
: QLabel(p_parent)
|
: QLabel(p_parent)
|
||||||
|
, ao_app(p_ao_app)
|
||||||
{
|
{
|
||||||
ao_app = p_ao_app;
|
ui_prompt_details = new QPushButton(this);
|
||||||
evidence_icon = new QPushButton(this);
|
ui_prompt_details->hide();
|
||||||
evidence_icon->hide();
|
|
||||||
sfx_player = new AOSfxPlayer(this, ao_app);
|
|
||||||
|
|
||||||
evidence_movie = new InterfaceLayer(this, ao_app);
|
m_sfx_player = new AOSfxPlayer(ao_app);
|
||||||
|
|
||||||
connect(evidence_movie, &InterfaceLayer::done, this, &AOEvidenceDisplay::show_done);
|
m_evidence_movie = new InterfaceLayer(ao_app, this);
|
||||||
connect(evidence_icon, &QPushButton::clicked, this, &AOEvidenceDisplay::icon_clicked);
|
|
||||||
|
connect(m_evidence_movie, &InterfaceLayer::done, this, &AOEvidenceDisplay::show_done);
|
||||||
|
connect(ui_prompt_details, &QPushButton::clicked, this, &AOEvidenceDisplay::icon_clicked);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOEvidenceDisplay::show_evidence(int p_index, QString p_evidence_image,
|
void AOEvidenceDisplay::show_evidence(int p_index, QString p_evidence_image, bool is_left_side, int p_volume)
|
||||||
bool is_left_side, int p_volume)
|
|
||||||
{
|
{
|
||||||
this->reset();
|
this->reset();
|
||||||
|
|
||||||
last_evidence_index = p_index;
|
m_last_evidence_index = p_index;
|
||||||
|
|
||||||
sfx_player->set_volume(p_volume);
|
m_sfx_player->set_volume(p_volume);
|
||||||
|
|
||||||
QString gif_name;
|
QString gif_name;
|
||||||
QString icon_identifier;
|
QString icon_identifier;
|
||||||
|
|
||||||
if (is_left_side) {
|
if (is_left_side)
|
||||||
|
{
|
||||||
icon_identifier = "left_evidence_icon";
|
icon_identifier = "left_evidence_icon";
|
||||||
gif_name = "evidence_appear_left";
|
gif_name = "evidence_appear_left";
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
icon_identifier = "right_evidence_icon";
|
icon_identifier = "right_evidence_icon";
|
||||||
gif_name = "evidence_appear_right";
|
gif_name = "evidence_appear_right";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString f_evidence_path = ao_app->get_real_path(
|
QString f_evidence_path = ao_app->get_real_path(ao_app->get_evidence_path(p_evidence_image));
|
||||||
ao_app->get_evidence_path(p_evidence_image));
|
|
||||||
QPixmap f_pixmap(f_evidence_path);
|
QPixmap f_pixmap(f_evidence_path);
|
||||||
|
|
||||||
pos_size_type icon_dimensions =
|
pos_size_type icon_dimensions = ao_app->get_element_dimensions(icon_identifier, "courtroom_design.ini");
|
||||||
ao_app->get_element_dimensions(icon_identifier, "courtroom_design.ini");
|
|
||||||
|
|
||||||
f_pixmap = f_pixmap.scaled(icon_dimensions.width, icon_dimensions.height);
|
f_pixmap = f_pixmap.scaled(icon_dimensions.width, icon_dimensions.height);
|
||||||
QIcon f_icon(f_pixmap);
|
QIcon f_icon(f_pixmap);
|
||||||
|
|
||||||
evidence_icon->setIcon(f_icon);
|
ui_prompt_details->setIcon(f_icon);
|
||||||
evidence_icon->setIconSize(f_pixmap.rect().size());
|
ui_prompt_details->setIconSize(f_pixmap.rect().size());
|
||||||
evidence_icon->resize(f_pixmap.rect().size());
|
ui_prompt_details->resize(f_pixmap.rect().size());
|
||||||
evidence_icon->move(icon_dimensions.x, icon_dimensions.y);
|
ui_prompt_details->move(icon_dimensions.x, icon_dimensions.y);
|
||||||
evidence_movie->static_duration = 320;
|
m_evidence_movie->static_duration = 320;
|
||||||
evidence_movie->max_duration = 1000;
|
m_evidence_movie->max_duration = 1000;
|
||||||
evidence_movie->set_play_once(true);
|
m_evidence_movie->set_play_once(true);
|
||||||
evidence_movie->load_image(gif_name, "");
|
m_evidence_movie->load_image(gif_name, "");
|
||||||
sfx_player->play(ao_app->get_court_sfx("evidence_present"));
|
m_sfx_player->play(ao_app->get_court_sfx("evidence_present"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOEvidenceDisplay::reset()
|
void AOEvidenceDisplay::reset()
|
||||||
{
|
{
|
||||||
sfx_player->stop();
|
m_sfx_player->stop();
|
||||||
evidence_movie->kill();
|
m_evidence_movie->kill();
|
||||||
evidence_icon->hide();
|
ui_prompt_details->hide();
|
||||||
this->clear();
|
this->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOEvidenceDisplay::show_done() { evidence_icon->show(); }
|
void AOEvidenceDisplay::show_done()
|
||||||
|
{
|
||||||
|
ui_prompt_details->show();
|
||||||
|
}
|
||||||
|
|
||||||
void AOEvidenceDisplay::icon_clicked() {
|
void AOEvidenceDisplay::icon_clicked()
|
||||||
if (last_evidence_index != -1) {
|
{
|
||||||
emit show_evidence_details(last_evidence_index - 1); // i dont know why i have to subtract 1 here
|
if (m_last_evidence_index != -1)
|
||||||
|
{
|
||||||
|
Q_EMIT show_evidence_details(m_last_evidence_index - 1); // i dont know why i have to subtract 1 here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,5 +84,5 @@ void AOEvidenceDisplay::combo_resize(int w, int h)
|
|||||||
{
|
{
|
||||||
QSize f_size(w, h);
|
QSize f_size(w, h);
|
||||||
this->resize(f_size);
|
this->resize(f_size);
|
||||||
evidence_movie->combo_resize(w, h);
|
m_evidence_movie->combo_resize(w, h);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#ifndef AOEVIDENCEDISPLAY_H
|
#pragma once
|
||||||
#define AOEVIDENCEDISPLAY_H
|
|
||||||
|
|
||||||
#include "aoapplication.h"
|
#include "aoapplication.h"
|
||||||
#include "aolayer.h"
|
#include "aolayer.h"
|
||||||
@ -9,29 +8,30 @@
|
|||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
||||||
class AOEvidenceDisplay : public QLabel {
|
class AOEvidenceDisplay : public QLabel
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AOEvidenceDisplay(QWidget *p_parent, AOApplication *p_ao_app);
|
AOEvidenceDisplay(AOApplication *p_ao_app, QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
void show_evidence(int p_index, QString p_evidence_image, bool is_left_side, int p_volume);
|
void show_evidence(int p_index, QString p_evidence_image, bool is_left_side, int p_volume);
|
||||||
void reset();
|
void reset();
|
||||||
void combo_resize(int w, int h);
|
void combo_resize(int w, int h);
|
||||||
|
|
||||||
signals:
|
Q_SIGNALS:
|
||||||
void show_evidence_details(int index);
|
void show_evidence_details(int index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AOApplication *ao_app;
|
AOApplication *ao_app;
|
||||||
InterfaceLayer *evidence_movie;
|
|
||||||
QPushButton *evidence_icon;
|
|
||||||
AOSfxPlayer *sfx_player;
|
|
||||||
int last_evidence_index = -1;
|
|
||||||
|
|
||||||
private slots:
|
int m_last_evidence_index = -1;
|
||||||
|
AOSfxPlayer *m_sfx_player;
|
||||||
|
|
||||||
|
InterfaceLayer *m_evidence_movie;
|
||||||
|
QPushButton *ui_prompt_details;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
void show_done();
|
void show_done();
|
||||||
void icon_clicked();
|
void icon_clicked();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AOEVIDENCEDISPLAY_H
|
|
@ -5,56 +5,33 @@
|
|||||||
|
|
||||||
#include <QBitmap>
|
#include <QBitmap>
|
||||||
|
|
||||||
AOImage::AOImage(QWidget *parent, AOApplication *p_ao_app, bool make_static) : QLabel(parent)
|
AOImage::AOImage(AOApplication *p_ao_app, QWidget *parent)
|
||||||
{
|
: QLabel(parent)
|
||||||
m_parent = parent;
|
, ao_app(p_ao_app)
|
||||||
ao_app = p_ao_app;
|
{}
|
||||||
is_static = make_static;
|
|
||||||
if (!is_static) // Only create the QMovie if we're non-static
|
|
||||||
{
|
|
||||||
movie = new QMovie(this);
|
|
||||||
connect(movie, &QMovie::frameChanged, [this]{
|
|
||||||
QPixmap f_pixmap = movie->currentPixmap();
|
|
||||||
f_pixmap =
|
|
||||||
f_pixmap.scaled(this->size(), Qt::IgnoreAspectRatio);
|
|
||||||
this->setPixmap(f_pixmap);
|
|
||||||
if (masked) {
|
|
||||||
this->setMask(f_pixmap.mask());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AOImage::~AOImage() {}
|
AOImage::~AOImage()
|
||||||
|
{}
|
||||||
|
|
||||||
|
QString AOImage::file_name()
|
||||||
|
{
|
||||||
|
return m_file_name;
|
||||||
|
}
|
||||||
|
|
||||||
bool AOImage::set_image(QString p_image, QString p_misc)
|
bool AOImage::set_image(QString p_image, QString p_misc)
|
||||||
{
|
{
|
||||||
QString p_image_resolved = ao_app->get_image(p_image, Options::getInstance().theme(), Options::getInstance().subTheme(),
|
QString p_image_resolved = ao_app->get_image(p_image, Options::getInstance().theme(), Options::getInstance().subTheme(), ao_app->default_theme, p_misc, "", "", false);
|
||||||
ao_app->default_theme, p_misc, "", "",
|
|
||||||
is_static || !Options::getInstance().animatedThemeEnabled());
|
|
||||||
|
|
||||||
if (!file_exists(p_image_resolved)) {
|
if (!file_exists(p_image_resolved))
|
||||||
|
{
|
||||||
qWarning() << "could not find image" << p_image;
|
qWarning() << "could not find image" << p_image;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
path = p_image_resolved;
|
m_file_name = p_image_resolved;
|
||||||
if (!is_static) {
|
QPixmap f_pixmap(m_file_name);
|
||||||
movie->stop();
|
f_pixmap = f_pixmap.scaled(size(), Qt::IgnoreAspectRatio);
|
||||||
movie->setFileName(path);
|
setPixmap(f_pixmap);
|
||||||
if (Options::getInstance().animatedThemeEnabled() && movie->frameCount() > 1) {
|
|
||||||
movie->start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (is_static || !Options::getInstance().animatedThemeEnabled() || movie->frameCount() <= 1) {
|
|
||||||
QPixmap f_pixmap(path);
|
|
||||||
|
|
||||||
f_pixmap =
|
|
||||||
f_pixmap.scaled(this->size(), Qt::IgnoreAspectRatio);
|
|
||||||
this->setPixmap(f_pixmap);
|
|
||||||
if (masked) {
|
|
||||||
this->setMask(f_pixmap.mask());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
27
src/aoimage.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// This class represents a static theme-dependent image
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "aoapplication.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QMovie>
|
||||||
|
|
||||||
|
class AOImage : public QLabel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
AOImage(AOApplication *p_ao_app, QWidget *parent = nullptr);
|
||||||
|
AOImage(AOApplication *p_ao_app, bool make_static, QWidget *parent = nullptr);
|
||||||
|
~AOImage();
|
||||||
|
|
||||||
|
QString file_name();
|
||||||
|
bool set_image(QString p_image, QString p_misc = QString());
|
||||||
|
|
||||||
|
private:
|
||||||
|
AOApplication *ao_app;
|
||||||
|
|
||||||
|
QString m_file_name;
|
||||||
|
};
|
366
src/aolayer.cpp
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
#include "aoapplication.h"
|
#include "aoapplication.h"
|
||||||
#include "file_functions.h"
|
#include "file_functions.h"
|
||||||
#include "misc_functions.h"
|
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
static QThreadPool *thread_pool;
|
static QThreadPool *thread_pool;
|
||||||
|
|
||||||
AOLayer::AOLayer(QWidget *p_parent, AOApplication *p_ao_app) : QLabel(p_parent)
|
AOLayer::AOLayer(AOApplication *p_ao_app, QWidget *p_parent)
|
||||||
|
: QLabel(p_parent)
|
||||||
{
|
{
|
||||||
ao_app = p_ao_app;
|
ao_app = p_ao_app;
|
||||||
|
|
||||||
@ -26,45 +26,47 @@ AOLayer::AOLayer(QWidget *p_parent, AOApplication *p_ao_app) : QLabel(p_parent)
|
|||||||
preanim_timer->setSingleShot(true);
|
preanim_timer->setSingleShot(true);
|
||||||
connect(preanim_timer, &QTimer::timeout, this, &AOLayer::preanim_done);
|
connect(preanim_timer, &QTimer::timeout, this, &AOLayer::preanim_done);
|
||||||
|
|
||||||
if (!thread_pool) {
|
if (!thread_pool)
|
||||||
|
{
|
||||||
thread_pool = new QThreadPool(p_ao_app);
|
thread_pool = new QThreadPool(p_ao_app);
|
||||||
thread_pool->setMaxThreadCount(8);
|
thread_pool->setMaxThreadCount(8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BackgroundLayer::BackgroundLayer(QWidget *p_parent, AOApplication *p_ao_app)
|
BackgroundLayer::BackgroundLayer(AOApplication *p_ao_app, QWidget *p_parent)
|
||||||
: AOLayer(p_parent, p_ao_app)
|
: AOLayer(p_ao_app, p_parent)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
CharLayer::CharLayer(QWidget *p_parent, AOApplication *p_ao_app)
|
CharLayer::CharLayer(AOApplication *p_ao_app, QWidget *p_parent)
|
||||||
: AOLayer(p_parent, p_ao_app)
|
: AOLayer(p_ao_app, p_parent)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
EffectLayer::EffectLayer(QWidget *p_parent, AOApplication *p_ao_app)
|
EffectLayer::EffectLayer(AOApplication *p_ao_app, QWidget *p_parent)
|
||||||
: AOLayer(p_parent, p_ao_app)
|
: AOLayer(p_ao_app, p_parent)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
SplashLayer::SplashLayer(QWidget *p_parent, AOApplication *p_ao_app)
|
SplashLayer::SplashLayer(AOApplication *p_ao_app, QWidget *p_parent)
|
||||||
: AOLayer(p_parent, p_ao_app)
|
: AOLayer(p_ao_app, p_parent)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
InterfaceLayer::InterfaceLayer(QWidget *p_parent, AOApplication *p_ao_app)
|
InterfaceLayer::InterfaceLayer(AOApplication *p_ao_app, QWidget *p_parent)
|
||||||
: AOLayer(p_parent, p_ao_app)
|
: AOLayer(p_ao_app, p_parent)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
StickerLayer::StickerLayer(QWidget *p_parent, AOApplication *p_ao_app)
|
StickerLayer::StickerLayer(AOApplication *p_ao_app, QWidget *p_parent)
|
||||||
: AOLayer(p_parent, p_ao_app)
|
: AOLayer(p_ao_app, p_parent)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
QString AOLayer::find_image(QStringList p_list)
|
QString AOLayer::find_image(QStringList p_list)
|
||||||
{
|
{
|
||||||
QString image_path;
|
QString image_path;
|
||||||
for (const QString &path : p_list) {
|
for (const QString &path : p_list)
|
||||||
|
{
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
qDebug() << "checking path " << path;
|
qDebug() << "checking path " << path;
|
||||||
#endif
|
#endif
|
||||||
if (file_exists(path)) {
|
if (file_exists(path))
|
||||||
|
{
|
||||||
image_path = path;
|
image_path = path;
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
qDebug() << "found path " << path;
|
qDebug() << "found path " << path;
|
||||||
@ -79,17 +81,28 @@ QPixmap AOLayer::get_pixmap(QImage image)
|
|||||||
{
|
{
|
||||||
QPixmap f_pixmap;
|
QPixmap f_pixmap;
|
||||||
if (m_flipped)
|
if (m_flipped)
|
||||||
|
{
|
||||||
f_pixmap = QPixmap::fromImage(image.mirrored(true, false));
|
f_pixmap = QPixmap::fromImage(image.mirrored(true, false));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
f_pixmap = QPixmap::fromImage(image);
|
f_pixmap = QPixmap::fromImage(image);
|
||||||
|
}
|
||||||
// auto aspect_ratio = Qt::KeepAspectRatio;
|
// auto aspect_ratio = Qt::KeepAspectRatio;
|
||||||
if (!f_pixmap.isNull()) {
|
if (!f_pixmap.isNull())
|
||||||
|
{
|
||||||
if (f_pixmap.height() > f_h) // We are downscaling, use anti-aliasing.
|
if (f_pixmap.height() > f_h) // We are downscaling, use anti-aliasing.
|
||||||
|
{
|
||||||
transform_mode = Qt::SmoothTransformation;
|
transform_mode = Qt::SmoothTransformation;
|
||||||
|
}
|
||||||
if (stretch)
|
if (stretch)
|
||||||
|
{
|
||||||
f_pixmap = f_pixmap.scaled(f_w, f_h);
|
f_pixmap = f_pixmap.scaled(f_w, f_h);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
f_pixmap = f_pixmap.scaledToHeight(f_h, transform_mode);
|
f_pixmap = f_pixmap.scaledToHeight(f_h, transform_mode);
|
||||||
|
}
|
||||||
this->resize(f_pixmap.size());
|
this->resize(f_pixmap.size());
|
||||||
}
|
}
|
||||||
return f_pixmap;
|
return f_pixmap;
|
||||||
@ -101,15 +114,16 @@ void AOLayer::set_frame(QPixmap f_pixmap)
|
|||||||
this->center_pixmap(f_pixmap);
|
this->center_pixmap(f_pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOLayer::center_pixmap(QPixmap f_pixmap) {
|
void AOLayer::center_pixmap(QPixmap f_pixmap)
|
||||||
QLabel::move(
|
{
|
||||||
x + (f_w - f_pixmap.width()) / 2,
|
QLabel::move(x + (f_w - f_pixmap.width()) / 2,
|
||||||
y + (f_h - f_pixmap.height())); // Always center horizontally, always put
|
y + (f_h - f_pixmap.height())); // Always center horizontally, always put
|
||||||
// at the bottom vertically
|
// at the bottom vertically
|
||||||
if (masked)
|
if (masked)
|
||||||
this->setMask(
|
{
|
||||||
QRegion((f_pixmap.width() - f_w) / 2, (f_pixmap.height() - f_h) / 2, f_w,
|
this->setMask(QRegion((f_pixmap.width() - f_w) / 2, (f_pixmap.height() - f_h) / 2, f_w,
|
||||||
f_h)); // make sure we don't escape the area we've been given
|
f_h)); // make sure we don't escape the area we've been given
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOLayer::combo_resize(int w, int h)
|
void AOLayer::combo_resize(int w, int h)
|
||||||
@ -137,9 +151,13 @@ void AOLayer::move_and_center(int ax, int ay)
|
|||||||
x = ax;
|
x = ax;
|
||||||
y = ay;
|
y = ay;
|
||||||
if (movie_frames.isEmpty()) // safeguard
|
if (movie_frames.isEmpty()) // safeguard
|
||||||
QLabel::move(x,y);
|
{
|
||||||
|
QLabel::move(x, y);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
center_pixmap(movie_frames[0]); // just use the first frame since dimensions are all that matter
|
center_pixmap(movie_frames[0]); // just use the first frame since dimensions are all that matter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackgroundLayer::load_image(QString p_filename)
|
void BackgroundLayer::load_image(QString p_filename)
|
||||||
@ -147,15 +165,15 @@ void BackgroundLayer::load_image(QString p_filename)
|
|||||||
play_once = false;
|
play_once = false;
|
||||||
cull_image = false;
|
cull_image = false;
|
||||||
VPath design_path = ao_app->get_background_path("design.ini");
|
VPath design_path = ao_app->get_background_path("design.ini");
|
||||||
transform_mode =
|
transform_mode = ao_app->get_scaling(ao_app->read_design_ini("scaling", design_path));
|
||||||
ao_app->get_scaling(ao_app->read_design_ini("scaling", design_path));
|
|
||||||
stretch = ao_app->read_design_ini("stretch", design_path).startsWith("true");
|
stretch = ao_app->read_design_ini("stretch", design_path).startsWith("true");
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
qDebug() << "[BackgroundLayer] BG loaded: " << p_filename;
|
qDebug() << "[BackgroundLayer] BG loaded: " << p_filename;
|
||||||
#endif
|
#endif
|
||||||
QString final_path = ao_app->get_image_suffix(ao_app->get_background_path(p_filename));
|
QString final_path = ao_app->get_image_suffix(ao_app->get_background_path(p_filename));
|
||||||
|
|
||||||
if (final_path == last_path) {
|
if (final_path == last_path)
|
||||||
|
{
|
||||||
// Don't restart background if background is unchanged
|
// Don't restart background if background is unchanged
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -164,24 +182,20 @@ void BackgroundLayer::load_image(QString p_filename)
|
|||||||
play();
|
play();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharLayer::load_image(QString p_filename, QString p_charname,
|
void CharLayer::load_image(QString p_filename, QString p_charname, int p_duration, bool p_is_preanim)
|
||||||
int p_duration, bool p_is_preanim)
|
|
||||||
{
|
{
|
||||||
duration = p_duration;
|
duration = p_duration;
|
||||||
cull_image = false;
|
cull_image = false;
|
||||||
force_continuous = false;
|
force_continuous = false;
|
||||||
transform_mode = ao_app->get_scaling(
|
transform_mode = ao_app->get_scaling(ao_app->get_emote_property(p_charname, p_filename, "scaling"));
|
||||||
ao_app->get_emote_property(p_charname, p_filename, "scaling"));
|
stretch = ao_app->get_emote_property(p_charname, p_filename, "stretch").startsWith("true");
|
||||||
stretch = ao_app->get_emote_property(p_charname, p_filename, "stretch")
|
if ((p_charname == last_char) && ((p_filename == last_emote) || (p_filename.mid(3, -1) == last_emote.mid(3, -1))) && (!is_preanim) && (!was_preanim))
|
||||||
.startsWith("true");
|
{
|
||||||
if ((p_charname == last_char) &&
|
|
||||||
((p_filename == last_emote) ||
|
|
||||||
(p_filename.mid(3, -1) == last_emote.mid(3, -1))) &&
|
|
||||||
(!is_preanim) && (!was_preanim)) {
|
|
||||||
continuous = true;
|
continuous = true;
|
||||||
force_continuous = true;
|
force_continuous = true;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
continuous = false;
|
continuous = false;
|
||||||
force_continuous = true;
|
force_continuous = true;
|
||||||
}
|
}
|
||||||
@ -194,12 +208,15 @@ void CharLayer::load_image(QString p_filename, QString p_charname,
|
|||||||
last_emote = current_emote;
|
last_emote = current_emote;
|
||||||
last_prefix = prefix;
|
last_prefix = prefix;
|
||||||
is_preanim = p_is_preanim;
|
is_preanim = p_is_preanim;
|
||||||
if ((p_filename.left(3) == "(a)") || (p_filename.left(3) == "(b)")) { // if we are playing an idle or talking animation
|
if ((p_filename.left(3) == "(a)") || (p_filename.left(3) == "(b)"))
|
||||||
|
{ // if we are playing an idle or talking animation
|
||||||
prefix = p_filename.left(3); // separate the prefix from the emote name
|
prefix = p_filename.left(3); // separate the prefix from the emote name
|
||||||
current_emote = p_filename.mid(3, -1);
|
current_emote = p_filename.mid(3, -1);
|
||||||
}
|
}
|
||||||
else if ((duration > 0) || (p_filename.left(3) == "(c)")) { // else if we are playing a preanim or postanim
|
else if ((duration > 0) || (p_filename.left(3) == "(c)"))
|
||||||
if (p_filename.left(3) == "(c)") { // if we are playing a postanim
|
{ // else if we are playing a preanim or postanim
|
||||||
|
if (p_filename.left(3) == "(c)")
|
||||||
|
{ // if we are playing a postanim
|
||||||
prefix = "(c)"; // separate the prefix from the emote name
|
prefix = "(c)"; // separate the prefix from the emote name
|
||||||
current_emote = p_filename.mid(3, -1);
|
current_emote = p_filename.mid(3, -1);
|
||||||
}
|
}
|
||||||
@ -209,29 +226,22 @@ void CharLayer::load_image(QString p_filename, QString p_charname,
|
|||||||
preanim_timer->start(duration);
|
preanim_timer->start(duration);
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
qDebug() << "[CharLayer] anim loaded: prefix " << prefix << " filename "
|
qDebug() << "[CharLayer] anim loaded: prefix " << prefix << " filename " << current_emote << " from character: " << p_charname << " continuous: " << continuous;
|
||||||
<< current_emote << " from character: " << p_charname
|
|
||||||
<< " continuous: " << continuous;
|
|
||||||
#endif
|
#endif
|
||||||
QVector<VPath> pathlist { // cursed character path resolution vector
|
QVector<VPath> pathlist{ // cursed character path resolution vector
|
||||||
ao_app->get_character_path(
|
ao_app->get_character_path(p_charname, prefix + current_emote), // Default path
|
||||||
p_charname, prefix + current_emote), // Default path
|
ao_app->get_character_path(p_charname,
|
||||||
ao_app->get_character_path(
|
prefix + "/" + current_emote), // Path check if it's categorized
|
||||||
p_charname,
|
// into a folder
|
||||||
prefix + "/" + current_emote), // Path check if it's categorized
|
ao_app->get_character_path(p_charname,
|
||||||
// into a folder
|
current_emote), // Just use the non-prefixed image, animated or not
|
||||||
ao_app->get_character_path(
|
VPath(current_emote), // The path by itself after the above fail
|
||||||
p_charname,
|
ao_app->get_theme_path("placeholder"), // Theme placeholder path
|
||||||
current_emote), // Just use the non-prefixed image, animated or not
|
ao_app->get_theme_path("placeholder", ao_app->default_theme)}; // Default theme placeholder path
|
||||||
VPath(current_emote), // The path by itself after the above fail
|
|
||||||
ao_app->get_theme_path("placeholder"), // Theme placeholder path
|
|
||||||
ao_app->get_theme_path(
|
|
||||||
"placeholder", ao_app->default_theme)}; // Default theme placeholder path
|
|
||||||
start_playback(ao_app->get_image_path(pathlist));
|
start_playback(ao_app->get_image_path(pathlist));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplashLayer::load_image(QString p_filename, QString p_charname,
|
void SplashLayer::load_image(QString p_filename, QString p_charname, QString p_miscname)
|
||||||
QString p_miscname)
|
|
||||||
{
|
{
|
||||||
transform_mode = ao_app->get_misc_scaling(p_miscname);
|
transform_mode = ao_app->get_misc_scaling(p_miscname);
|
||||||
QString final_image = ao_app->get_image(p_filename, Options::getInstance().theme(), Options::getInstance().subTheme(), ao_app->default_theme, p_miscname, p_charname, "placeholder");
|
QString final_image = ao_app->get_image(p_filename, Options::getInstance().theme(), Options::getInstance().subTheme(), ao_app->default_theme, p_miscname, p_charname, "placeholder");
|
||||||
@ -242,9 +252,13 @@ void SplashLayer::load_image(QString p_filename, QString p_charname,
|
|||||||
void EffectLayer::load_image(QString p_filename, bool p_looping)
|
void EffectLayer::load_image(QString p_filename, bool p_looping)
|
||||||
{
|
{
|
||||||
if (p_looping)
|
if (p_looping)
|
||||||
|
{
|
||||||
play_once = false;
|
play_once = false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
play_once = true;
|
play_once = true;
|
||||||
|
}
|
||||||
continuous = false;
|
continuous = false;
|
||||||
force_continuous = true;
|
force_continuous = true;
|
||||||
cull_image = false;
|
cull_image = false;
|
||||||
@ -266,7 +280,9 @@ void StickerLayer::load_image(QString p_charname)
|
|||||||
{
|
{
|
||||||
QString p_miscname;
|
QString p_miscname;
|
||||||
if (Options::getInstance().customChatboxEnabled())
|
if (Options::getInstance().customChatboxEnabled())
|
||||||
|
{
|
||||||
p_miscname = ao_app->get_chat(p_charname);
|
p_miscname = ao_app->get_chat(p_charname);
|
||||||
|
}
|
||||||
transform_mode = ao_app->get_misc_scaling(p_miscname);
|
transform_mode = ao_app->get_misc_scaling(p_miscname);
|
||||||
QString final_image = ao_app->get_image("sticker/" + p_charname, Options::getInstance().theme(), Options::getInstance().subTheme(), ao_app->default_theme, p_miscname);
|
QString final_image = ao_app->get_image("sticker/" + p_charname, Options::getInstance().theme(), Options::getInstance().subTheme(), ao_app->default_theme, p_miscname);
|
||||||
start_playback(final_image);
|
start_playback(final_image);
|
||||||
@ -277,33 +293,43 @@ void CharLayer::start_playback(QString p_image)
|
|||||||
{
|
{
|
||||||
movie_effects.clear();
|
movie_effects.clear();
|
||||||
AOLayer::start_playback(p_image);
|
AOLayer::start_playback(p_image);
|
||||||
if (network_strings.size() > 0) // our FX overwritten by networked ones
|
if (m_network_strings.size() > 0) // our FX overwritten by networked ones
|
||||||
|
{
|
||||||
load_network_effects();
|
load_network_effects();
|
||||||
|
}
|
||||||
else // Use default ini FX
|
else // Use default ini FX
|
||||||
|
{
|
||||||
load_effects();
|
load_effects();
|
||||||
|
}
|
||||||
play();
|
play();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOLayer::start_playback(QString p_image)
|
void AOLayer::start_playback(QString p_image)
|
||||||
{
|
{
|
||||||
if (p_image == "") {// image wasn't found by the path resolution function
|
if (p_image == "")
|
||||||
|
{ // image wasn't found by the path resolution function
|
||||||
this->kill();
|
this->kill();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame_loader.isRunning())
|
if (frame_loader.isRunning())
|
||||||
|
{
|
||||||
exit_loop = true; // tell the loader to stop, we have a new image to load
|
exit_loop = true; // tell the loader to stop, we have a new image to load
|
||||||
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&mutex);
|
QMutexLocker locker(&mutex);
|
||||||
this->show();
|
this->show();
|
||||||
|
|
||||||
if (!Options::getInstance().continuousPlaybackEnabled()) {
|
if (!Options::getInstance().continuousPlaybackEnabled())
|
||||||
|
{
|
||||||
continuous = false;
|
continuous = false;
|
||||||
force_continuous = true;
|
force_continuous = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((last_path == p_image) && (!force_continuous)) || p_image == "")
|
if (((last_path == p_image) && (!force_continuous)) || p_image == "")
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
actual_time.restart();
|
actual_time.restart();
|
||||||
@ -312,14 +338,16 @@ void AOLayer::start_playback(QString p_image)
|
|||||||
this->freeze();
|
this->freeze();
|
||||||
movie_frames.clear();
|
movie_frames.clear();
|
||||||
movie_delays.clear();
|
movie_delays.clear();
|
||||||
QString scaling_override =
|
QString scaling_override = ao_app->read_design_ini("scaling", p_image + ".ini");
|
||||||
ao_app->read_design_ini("scaling", p_image + ".ini");
|
|
||||||
if (scaling_override != "")
|
if (scaling_override != "")
|
||||||
|
{
|
||||||
transform_mode = ao_app->get_scaling(scaling_override);
|
transform_mode = ao_app->get_scaling(scaling_override);
|
||||||
QString stretch_override =
|
}
|
||||||
ao_app->read_design_ini("stretch", p_image + ".ini");
|
QString stretch_override = ao_app->read_design_ini("stretch", p_image + ".ini");
|
||||||
if (stretch_override != "")
|
if (stretch_override != "")
|
||||||
|
{
|
||||||
stretch = stretch_override.startsWith("true");
|
stretch = stretch_override.startsWith("true");
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
qDebug() << "[AOLayer::start_playback] Stretch:" << stretch << "Filename:" << p_image;
|
qDebug() << "[AOLayer::start_playback] Stretch:" << stretch << "Filename:" << p_image;
|
||||||
@ -328,35 +356,39 @@ void AOLayer::start_playback(QString p_image)
|
|||||||
last_max_frames = max_frames;
|
last_max_frames = max_frames;
|
||||||
max_frames = m_reader.imageCount();
|
max_frames = m_reader.imageCount();
|
||||||
if (m_reader.loopCount() == 0 && max_frames > 1)
|
if (m_reader.loopCount() == 0 && max_frames > 1)
|
||||||
|
{
|
||||||
play_once = true;
|
play_once = true;
|
||||||
if (!continuous
|
}
|
||||||
|| ((continuous) && (max_frames != last_max_frames))
|
if (!continuous || ((continuous) && (max_frames != last_max_frames)) || max_frames == 0 || frame >= max_frames)
|
||||||
|| max_frames == 0
|
{
|
||||||
|| frame >= max_frames) {
|
|
||||||
frame = 0;
|
frame = 0;
|
||||||
continuous = false;
|
continuous = false;
|
||||||
}
|
}
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
frame_loader = QtConcurrent::run(thread_pool, this, &AOLayer::populate_vectors);
|
frame_loader = QtConcurrent::run(thread_pool, this, &AOLayer::populate_vectors);
|
||||||
#else
|
#else
|
||||||
frame_loader = QtConcurrent::run(thread_pool, &AOLayer::populate_vectors, this);
|
frame_loader = QtConcurrent::run(thread_pool, &AOLayer::populate_vectors, this);
|
||||||
#endif
|
#endif
|
||||||
last_path = p_image;
|
last_path = p_image;
|
||||||
while (movie_frames.size() <= frame) // if we haven't loaded the frame we need yet
|
while (movie_frames.size() <= frame) // if we haven't loaded the frame we need yet
|
||||||
|
{
|
||||||
frameAdded.wait(&mutex); // wait for the frame loader to add another frame, then check again
|
frameAdded.wait(&mutex); // wait for the frame loader to add another frame, then check again
|
||||||
|
}
|
||||||
this->set_frame(movie_frames[frame]);
|
this->set_frame(movie_frames[frame]);
|
||||||
|
|
||||||
if (max_frames <= 1) {
|
if (max_frames <= 1)
|
||||||
|
{
|
||||||
duration = static_duration;
|
duration = static_duration;
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
qDebug() << "[AOLayer::start_playback] max_frames is <= 1, using static duration";
|
qDebug() << "[AOLayer::start_playback] max_frames is <= 1, using static duration";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (duration > 0 && cull_image == true)
|
if (duration > 0 && cull_image == true)
|
||||||
|
{
|
||||||
shfx_timer->start(duration);
|
shfx_timer->start(duration);
|
||||||
|
}
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
qDebug() << "[AOLayer::start_playback] Max frames:" << max_frames << "Setting image to " << p_image
|
qDebug() << "[AOLayer::start_playback] Max frames:" << max_frames << "Setting image to " << p_image << "Time taken to process image:" << actual_time.elapsed();
|
||||||
<< "Time taken to process image:" << actual_time.elapsed();
|
|
||||||
|
|
||||||
actual_time.restart();
|
actual_time.restart();
|
||||||
#endif
|
#endif
|
||||||
@ -364,8 +396,10 @@ void AOLayer::start_playback(QString p_image)
|
|||||||
|
|
||||||
void CharLayer::play()
|
void CharLayer::play()
|
||||||
{
|
{
|
||||||
if (max_frames <= 1) {
|
if (max_frames <= 1)
|
||||||
if (play_once) {
|
{
|
||||||
|
if (play_once)
|
||||||
|
{
|
||||||
preanim_timer->start(qMax(0, duration));
|
preanim_timer->start(qMax(0, duration));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -376,26 +410,42 @@ void CharLayer::play()
|
|||||||
|
|
||||||
void AOLayer::play()
|
void AOLayer::play()
|
||||||
{
|
{
|
||||||
if (max_frames <= 1) {
|
if (max_frames <= 1)
|
||||||
if (play_once) {
|
{
|
||||||
|
if (play_once)
|
||||||
|
{
|
||||||
if (duration > 0)
|
if (duration > 0)
|
||||||
|
{
|
||||||
ticker->start(duration);
|
ticker->start(duration);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
preanim_done();
|
preanim_done();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
this->freeze();
|
this->freeze();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
while (movie_delays.size() <= frame) {
|
{
|
||||||
frameAdded.wait(&mutex);
|
while (movie_delays.size() <= frame)
|
||||||
|
{
|
||||||
|
frameAdded.wait(&mutex);
|
||||||
}
|
}
|
||||||
ticker->start(this->get_frame_delay(movie_delays[frame]));
|
ticker->start(this->get_frame_delay(movie_delays[frame]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOLayer::set_play_once(bool p_play_once) { play_once = p_play_once; }
|
void AOLayer::set_play_once(bool p_play_once)
|
||||||
void AOLayer::set_cull_image(bool p_cull_image) { cull_image = p_cull_image; }
|
{
|
||||||
|
play_once = p_play_once;
|
||||||
|
}
|
||||||
|
void AOLayer::set_cull_image(bool p_cull_image)
|
||||||
|
{
|
||||||
|
cull_image = p_cull_image;
|
||||||
|
}
|
||||||
void AOLayer::set_static_duration(int p_static_duration)
|
void AOLayer::set_static_duration(int p_static_duration)
|
||||||
{
|
{
|
||||||
static_duration = p_static_duration;
|
static_duration = p_static_duration;
|
||||||
@ -409,21 +459,27 @@ void CharLayer::load_effects()
|
|||||||
{
|
{
|
||||||
movie_effects.clear();
|
movie_effects.clear();
|
||||||
if (max_frames <= 1)
|
if (max_frames <= 1)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
movie_effects.resize(max_frames);
|
movie_effects.resize(max_frames);
|
||||||
for (int e_frame = 0; e_frame < max_frames; ++e_frame) {
|
for (int e_frame = 0; e_frame < max_frames; ++e_frame)
|
||||||
|
{
|
||||||
QString effect = ao_app->get_screenshake_frame(m_char, m_emote, e_frame);
|
QString effect = ao_app->get_screenshake_frame(m_char, m_emote, e_frame);
|
||||||
if (effect != "") {
|
if (effect != "")
|
||||||
|
{
|
||||||
movie_effects[e_frame].append("shake");
|
movie_effects[e_frame].append("shake");
|
||||||
}
|
}
|
||||||
|
|
||||||
effect = ao_app->get_flash_frame(m_char, m_emote, e_frame);
|
effect = ao_app->get_flash_frame(m_char, m_emote, e_frame);
|
||||||
if (effect != "") {
|
if (effect != "")
|
||||||
|
{
|
||||||
movie_effects[e_frame].append("flash");
|
movie_effects[e_frame].append("flash");
|
||||||
}
|
}
|
||||||
|
|
||||||
effect = ao_app->get_sfx_frame(m_char, m_emote, e_frame);
|
effect = ao_app->get_sfx_frame(m_char, m_emote, e_frame);
|
||||||
if (effect != "") {
|
if (effect != "")
|
||||||
|
{
|
||||||
movie_effects[e_frame].append("sfx^" + effect);
|
movie_effects[e_frame].append("sfx^" + effect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -433,44 +489,54 @@ void CharLayer::load_network_effects()
|
|||||||
{
|
{
|
||||||
movie_effects.clear();
|
movie_effects.clear();
|
||||||
if (max_frames <= 1)
|
if (max_frames <= 1)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
movie_effects.resize(max_frames);
|
movie_effects.resize(max_frames);
|
||||||
// Order is important!!!
|
// Order is important!!!
|
||||||
QStringList effects_list = {"shake", "flash", "sfx^"};
|
QStringList effects_list = {"shake", "flash", "sfx^"};
|
||||||
|
|
||||||
// Determines which list is smaller - effects_list or network_strings - and
|
// Determines which list is smaller - effects_list or m_network_strings - and
|
||||||
// uses it as basis for the loop. This way, incomplete network_strings would
|
// uses it as basis for the loop. This way, incomplete m_network_strings would
|
||||||
// still be parsed, and excess/unaccounted for networked information is
|
// still be parsed, and excess/unaccounted for networked information is
|
||||||
// omitted.
|
// omitted.
|
||||||
int effects_size = qMin(effects_list.size(), network_strings.size());
|
int effects_size = qMin(effects_list.size(), m_network_strings.size());
|
||||||
|
|
||||||
for (int i = 0; i < effects_size; ++i) {
|
for (int i = 0; i < effects_size; ++i)
|
||||||
QString netstring = network_strings.at(i);
|
{
|
||||||
|
QString netstring = m_network_strings.at(i);
|
||||||
QStringList emote_splits = netstring.split("^");
|
QStringList emote_splits = netstring.split("^");
|
||||||
for (const QString &emote : emote_splits) {
|
for (const QString &emote : emote_splits)
|
||||||
|
{
|
||||||
QStringList parsed = emote.split("|");
|
QStringList parsed = emote.split("|");
|
||||||
if (parsed.size() <= 0 || parsed.at(0) != m_emote)
|
if (parsed.size() <= 0 || parsed.at(0) != m_emote)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
foreach (QString frame_data, parsed) {
|
}
|
||||||
|
foreach (QString frame_data, parsed)
|
||||||
|
{
|
||||||
QStringList frame_split = frame_data.split("=");
|
QStringList frame_split = frame_data.split("=");
|
||||||
if (frame_split.size() <=
|
if (frame_split.size() <= 1) // We might still be hanging at the emote itself (entry 0).
|
||||||
1) // We might still be hanging at the emote itself (entry 0).
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
int f_frame = frame_split.at(0).toInt();
|
int f_frame = frame_split.at(0).toInt();
|
||||||
if (f_frame >= max_frames || f_frame < 0) {
|
if (f_frame >= max_frames || f_frame < 0)
|
||||||
qWarning() << "out of bounds" << effects_list[i] << "frame"
|
{
|
||||||
<< f_frame << "out of" << max_frames << "for" << m_emote;
|
qWarning() << "out of bounds" << effects_list[i] << "frame" << f_frame << "out of" << max_frames << "for" << m_emote;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
QString f_data = frame_split.at(1);
|
QString f_data = frame_split.at(1);
|
||||||
if (f_data != "") {
|
if (f_data != "")
|
||||||
|
{
|
||||||
QString effect = effects_list[i];
|
QString effect = effects_list[i];
|
||||||
if (effect == "sfx^") // Currently the only frame result that feeds us
|
if (effect == "sfx^") // Currently the only frame result that feeds us
|
||||||
// data, let's yank it in.
|
// data, let's yank it in.
|
||||||
|
{
|
||||||
effect += f_data;
|
effect += f_data;
|
||||||
|
}
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
qDebug() << "[CharLayer::load_network_effects]" << effect << f_data << "frame" << f_frame << "for"
|
qDebug() << "[CharLayer::load_network_effects]" << effect << f_data << "frame" << f_frame << "for" << m_emote;
|
||||||
<< m_emote;
|
|
||||||
#endif
|
#endif
|
||||||
movie_effects[f_frame].append(effect);
|
movie_effects[f_frame].append(effect);
|
||||||
}
|
}
|
||||||
@ -481,29 +547,35 @@ void CharLayer::load_network_effects()
|
|||||||
|
|
||||||
void CharLayer::play_frame_effect(int p_frame)
|
void CharLayer::play_frame_effect(int p_frame)
|
||||||
{
|
{
|
||||||
if (p_frame >= movie_effects.size()) {
|
if (p_frame >= movie_effects.size())
|
||||||
|
{
|
||||||
qWarning() << "Attempted to play a frame effect bigger than the size of movie_effects";
|
qWarning() << "Attempted to play a frame effect bigger than the size of movie_effects";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (p_frame < max_frames) {
|
if (p_frame < max_frames)
|
||||||
foreach (QString effect, movie_effects[p_frame]) {
|
{
|
||||||
if (effect == "shake") {
|
foreach (QString effect, movie_effects[p_frame])
|
||||||
emit shake();
|
{
|
||||||
|
if (effect == "shake")
|
||||||
|
{
|
||||||
|
Q_EMIT shake();
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
qDebug() << "[CharLayer::play_frame_effect] Attempting to play shake on frame" << frame;
|
qDebug() << "[CharLayer::play_frame_effect] Attempting to play shake on frame" << frame;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (effect == "flash") {
|
if (effect == "flash")
|
||||||
emit flash();
|
{
|
||||||
|
Q_EMIT flash();
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
qDebug() << "[CharLayer::play_frame_effect] Attempting to play flash on frame" << frame;
|
qDebug() << "[CharLayer::play_frame_effect] Attempting to play flash on frame" << frame;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (effect.startsWith("sfx^")) {
|
if (effect.startsWith("sfx^"))
|
||||||
|
{
|
||||||
QString sfx = effect.section("^", 1);
|
QString sfx = effect.section("^", 1);
|
||||||
emit play_sfx(sfx);
|
Q_EMIT play_sfx(sfx);
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
qDebug() << "[CharLayer::play_frame_effect] Attempting to play sfx" << sfx << "on frame" << frame;
|
qDebug() << "[CharLayer::play_frame_effect] Attempting to play sfx" << sfx << "on frame" << frame;
|
||||||
#endif
|
#endif
|
||||||
@ -549,36 +621,47 @@ void CharLayer::movie_ticker()
|
|||||||
void AOLayer::movie_ticker()
|
void AOLayer::movie_ticker()
|
||||||
{
|
{
|
||||||
++frame;
|
++frame;
|
||||||
if (frame >= max_frames) {
|
if (frame >= max_frames)
|
||||||
if (play_once) {
|
{
|
||||||
|
if (play_once)
|
||||||
|
{
|
||||||
if (cull_image)
|
if (cull_image)
|
||||||
|
{
|
||||||
this->stop();
|
this->stop();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
this->freeze();
|
this->freeze();
|
||||||
|
}
|
||||||
preanim_done();
|
preanim_done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
frame = 0;
|
frame = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
QMutexLocker locker(&mutex);
|
||||||
while (frame >= movie_frames.size() && frame < max_frames) // oops! our frame isn't ready yet
|
while (frame >= movie_frames.size() && frame < max_frames) // oops! our frame isn't ready yet
|
||||||
|
{
|
||||||
frameAdded.wait(&mutex); // wait for a new frame to be added, then check again
|
frameAdded.wait(&mutex); // wait for a new frame to be added, then check again
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
qDebug() << "[AOLayer::movie_ticker] Frame:" << frame << "Delay:" << movie_delays[frame]
|
qDebug() << "[AOLayer::movie_ticker] Frame:" << frame << "Delay:" << movie_delays[frame] << "Actual time taken from last frame:" << actual_time.restart();
|
||||||
<< "Actual time taken from last frame:" << actual_time.restart();
|
|
||||||
#endif
|
#endif
|
||||||
this->set_frame(movie_frames[frame]);
|
this->set_frame(movie_frames[frame]);
|
||||||
ticker->setInterval(this->get_frame_delay(movie_delays[frame]));
|
ticker->setInterval(this->get_frame_delay(movie_delays[frame]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOLayer::populate_vectors() {
|
void AOLayer::populate_vectors()
|
||||||
|
{
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
qDebug() << "[AOLayer::populate_vectors] Started thread";
|
qDebug() << "[AOLayer::populate_vectors] Started thread";
|
||||||
#endif
|
#endif
|
||||||
while (!exit_loop && movie_frames.size() < max_frames) {
|
while (!exit_loop && movie_frames.size() < max_frames)
|
||||||
|
{
|
||||||
load_next_frame();
|
load_next_frame();
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
qDebug() << "[AOLayer::populate_vectors] Loaded frame" << movie_frames.size();
|
qDebug() << "[AOLayer::populate_vectors] Loaded frame" << movie_frames.size();
|
||||||
@ -586,12 +669,15 @@ void AOLayer::populate_vectors() {
|
|||||||
}
|
}
|
||||||
#ifdef DEBUG_MOVIE
|
#ifdef DEBUG_MOVIE
|
||||||
if (exit_loop)
|
if (exit_loop)
|
||||||
|
{
|
||||||
qDebug() << "[AOLayer::populate_vectors] Exit requested";
|
qDebug() << "[AOLayer::populate_vectors] Exit requested";
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
exit_loop = false;
|
exit_loop = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOLayer::load_next_frame() {
|
void AOLayer::load_next_frame()
|
||||||
|
{
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
QMutexLocker locker(&mutex);
|
||||||
movie_frames.append(this->get_pixmap(m_reader.read()));
|
movie_frames.append(this->get_pixmap(m_reader.read()));
|
||||||
@ -603,16 +689,20 @@ void AOLayer::load_next_frame() {
|
|||||||
void CharLayer::preanim_done()
|
void CharLayer::preanim_done()
|
||||||
{
|
{
|
||||||
if (is_preanim)
|
if (is_preanim)
|
||||||
|
{
|
||||||
AOLayer::preanim_done();
|
AOLayer::preanim_done();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOLayer::preanim_done()
|
void AOLayer::preanim_done()
|
||||||
{
|
{
|
||||||
ticker->stop();
|
ticker->stop();
|
||||||
preanim_timer->stop();
|
preanim_timer->stop();
|
||||||
emit done();
|
Q_EMIT done();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOLayer::shfx_timer_done()
|
void AOLayer::shfx_timer_done()
|
||||||
@ -622,5 +712,5 @@ void AOLayer::shfx_timer_done()
|
|||||||
qDebug() << "shfx timer signaled done";
|
qDebug() << "shfx timer signaled done";
|
||||||
#endif
|
#endif
|
||||||
// signal connected to courtroom object, let it figure out what to do
|
// signal connected to courtroom object, let it figure out what to do
|
||||||
emit done();
|
Q_EMIT done();
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
#ifndef AOLAYER_H
|
#pragma once
|
||||||
#define AOLAYER_H
|
|
||||||
|
|
||||||
|
#include <QBitmap>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
#include <QImageReader>
|
#include <QImageReader>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QTimer>
|
|
||||||
#include <QBitmap>
|
|
||||||
#include <QtConcurrent/QtConcurrentRun>
|
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
#include <QTimer>
|
||||||
#include <QWaitCondition>
|
#include <QWaitCondition>
|
||||||
|
#include <QtConcurrent/QtConcurrentRun>
|
||||||
|
|
||||||
class AOApplication;
|
class AOApplication;
|
||||||
class VPath;
|
class VPath;
|
||||||
@ -19,13 +18,13 @@ class VPath;
|
|||||||
// AOLayer handles all animations both inside and outside
|
// AOLayer handles all animations both inside and outside
|
||||||
// the viewport. It was originally devised as a layering
|
// the viewport. It was originally devised as a layering
|
||||||
// system, but turned into a full refactor of the existing
|
// system, but turned into a full refactor of the existing
|
||||||
// animation code.
|
// animation code.
|
||||||
//
|
//
|
||||||
// AOLayer has six subclasses, all of which differ mainly in
|
// AOLayer has six subclasses, all of which differ mainly in
|
||||||
// how they handle path resolution.
|
// how they handle path resolution.
|
||||||
//
|
//
|
||||||
// - BackgroundLayer: self-explanatory, handles files found in base/background
|
// - BackgroundLayer: self-explanatory, handles files found in base/background
|
||||||
// - CharLayer: handles all the "wonderful" quirks of character path resolution
|
// - CharLayer: handles all the "wonderful" quirks of character path resolution
|
||||||
// - SplashLayer: handles elements that can either be provided by a misc/ directory
|
// - SplashLayer: handles elements that can either be provided by a misc/ directory
|
||||||
// or by the theme - speedlines, shouts, WT/CE, et cetera
|
// or by the theme - speedlines, shouts, WT/CE, et cetera
|
||||||
// - EffectLayer: this is basically a dummy layer since effects do their own wonky
|
// - EffectLayer: this is basically a dummy layer since effects do their own wonky
|
||||||
@ -35,28 +34,29 @@ class VPath;
|
|||||||
//
|
//
|
||||||
// For questions comments or concerns, bother someone else
|
// For questions comments or concerns, bother someone else
|
||||||
|
|
||||||
class AOLayer : public QLabel {
|
class AOLayer : public QLabel
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AOLayer(QWidget *p_parent, AOApplication *p_ao_app);
|
AOLayer(AOApplication *p_ao_app, QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
QString filename; // file name without extension, i.e. "witnesstestimony"
|
QString filename; // file name without extension, i.e. "witnesstestimony"
|
||||||
int static_duration; // time in ms for static images to be displayed, if
|
int static_duration; // time in ms for static images to be displayed, if
|
||||||
// applicable. set to 0 for infinite
|
// applicable. set to 0 for infinite
|
||||||
int max_duration; // maximum duration in ms, image will be culled if it is
|
int max_duration; // maximum duration in ms, image will be culled if it is
|
||||||
// exceeded. set this to 0 for infinite duration
|
// exceeded. set this to 0 for infinite duration
|
||||||
bool play_once = false; // Whether to loop this animation or not
|
bool play_once = false; // Whether to loop this animation or not
|
||||||
bool cull_image = true; // if we're done playing this animation, should we
|
bool cull_image = true; // if we're done playing this animation, should we
|
||||||
// hide it? also controls durational culling
|
// hide it? also controls durational culling
|
||||||
// Are we loading this from the same frame we left off on?
|
// Are we loading this from the same frame we left off on?
|
||||||
bool continuous = false;
|
bool continuous = false;
|
||||||
// Whether or not to forcibly bypass the simple check done by start_playback
|
// Whether or not to forcibly bypass the simple check done by start_playback
|
||||||
// and use the existent value of continuous instead
|
// and use the existent value of continuous instead
|
||||||
bool force_continuous = false;
|
bool force_continuous = false;
|
||||||
Qt::TransformationMode transform_mode = Qt::FastTransformation; // transformation mode to use for this image
|
Qt::TransformationMode transform_mode = Qt::FastTransformation; // transformation mode to use for this image
|
||||||
bool stretch = false; // Should we stretch/squash this image to fill the screen?
|
bool stretch = false; // Should we stretch/squash this image to fill the screen?
|
||||||
bool masked = true; // Set a mask to the dimensions of the widget?
|
bool masked = true; // Set a mask to the dimensions of the widget?
|
||||||
|
|
||||||
// Set the movie's image to provided paths, preparing for playback.
|
// Set the movie's image to provided paths, preparing for playback.
|
||||||
void start_playback(QString p_image);
|
void start_playback(QString p_image);
|
||||||
@ -75,9 +75,6 @@ public:
|
|||||||
// Set the m_flipped variable to true/false
|
// Set the m_flipped variable to true/false
|
||||||
void set_flipped(bool p_flipped) { m_flipped = p_flipped; }
|
void set_flipped(bool p_flipped) { m_flipped = p_flipped; }
|
||||||
|
|
||||||
// Set the movie's playback speed (between 10% and 1000%)
|
|
||||||
void set_speed(int modifier) { speed = qMax(10, qMin(modifier, 1000)); }
|
|
||||||
|
|
||||||
// Move the label itself around
|
// Move the label itself around
|
||||||
void move(int ax, int ay);
|
void move(int ax, int ay);
|
||||||
|
|
||||||
@ -148,44 +145,49 @@ private:
|
|||||||
|
|
||||||
// used in populate_vectors
|
// used in populate_vectors
|
||||||
void load_next_frame();
|
void load_next_frame();
|
||||||
std::atomic_bool exit_loop { false }; //awful solution but i'm not fucking using QThread
|
std::atomic_bool exit_loop{false}; // awful solution but i'm not fucking using QThread
|
||||||
QFuture<void> frame_loader;
|
QFuture<void> frame_loader;
|
||||||
QMutex mutex;
|
QMutex mutex;
|
||||||
QWaitCondition frameAdded;
|
QWaitCondition frameAdded;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
signals:
|
|
||||||
void done();
|
void done();
|
||||||
|
|
||||||
protected slots:
|
protected Q_SLOTS:
|
||||||
virtual void preanim_done();
|
virtual void preanim_done();
|
||||||
void shfx_timer_done();
|
void shfx_timer_done();
|
||||||
virtual void movie_ticker();
|
virtual void movie_ticker();
|
||||||
};
|
};
|
||||||
|
|
||||||
class BackgroundLayer : public AOLayer {
|
class BackgroundLayer : public AOLayer
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
BackgroundLayer(QWidget *p_parent, AOApplication *p_ao_app);
|
BackgroundLayer(AOApplication *p_ao_app, QWidget *p_parent);
|
||||||
void load_image(QString p_filename);
|
void load_image(QString p_filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CharLayer : public AOLayer {
|
class CharLayer : public AOLayer
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CharLayer(QWidget *p_parent, AOApplication *p_ao_app);
|
CharLayer(AOApplication *p_ao_app, QWidget *p_parent = nullptr);
|
||||||
QString current_emote = ""; // name of the emote we're using
|
|
||||||
bool is_preanim; // equivalent to the old play_once, if true we don't want
|
QStringList &network_strings2() { return m_network_strings; }
|
||||||
// to loop this
|
void set_network_string(QStringList list) { m_network_strings = list; }
|
||||||
QString prefix = ""; // prefix, left blank if it's a preanim
|
|
||||||
|
|
||||||
void load_image(QString p_filename, QString p_charname, int p_duration, bool p_is_preanim);
|
void load_image(QString p_filename, QString p_charname, int p_duration, bool p_is_preanim);
|
||||||
|
|
||||||
void play(); // overloaded so we can play effects
|
void play(); // overloaded so we can play effects
|
||||||
|
|
||||||
// networked frame fx string
|
|
||||||
QStringList network_strings;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QString current_emote; // name of the emote we're using
|
||||||
|
bool is_preanim; // equivalent to the old play_once, if true we don't want
|
||||||
|
// to loop this
|
||||||
|
QString prefix; // prefix, left blank if it's a preanim
|
||||||
|
QStringList m_network_strings;
|
||||||
|
|
||||||
QString last_char; // name of the last character we used
|
QString last_char; // name of the last character we used
|
||||||
QString last_emote; // name of the last animation we used
|
QString last_emote; // name of the last animation we used
|
||||||
QString last_prefix; // prefix of the last animation we played
|
QString last_prefix; // prefix of the last animation we played
|
||||||
@ -197,8 +199,8 @@ private:
|
|||||||
QVector<QVector<QString>> movie_effects;
|
QVector<QVector<QString>> movie_effects;
|
||||||
|
|
||||||
// used for effect loading
|
// used for effect loading
|
||||||
QString m_char = "";
|
QString m_char;
|
||||||
QString m_emote = "";
|
QString m_emote;
|
||||||
|
|
||||||
// overloaded for effects reasons
|
// overloaded for effects reasons
|
||||||
void start_playback(QString p_image);
|
void start_playback(QString p_image);
|
||||||
@ -214,42 +216,52 @@ private:
|
|||||||
// frame.
|
// frame.
|
||||||
void play_frame_effect(int p_frame);
|
void play_frame_effect(int p_frame);
|
||||||
|
|
||||||
private slots:
|
private Q_SLOTS:
|
||||||
void preanim_done() override; // overridden so we don't accidentally cull characters
|
void preanim_done() override; // overridden so we don't accidentally cull characters
|
||||||
void movie_ticker() override; // overridden so we can play effects
|
void movie_ticker() override; // overridden so we can play effects
|
||||||
|
|
||||||
signals:
|
Q_SIGNALS:
|
||||||
void shake();
|
void shake();
|
||||||
void flash();
|
void flash();
|
||||||
void play_sfx(QString sfx);
|
void play_sfx(QString sfx);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SplashLayer : public AOLayer {
|
class SplashLayer : public AOLayer
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SplashLayer(QWidget *p_parent, AOApplication *p_ao_app);
|
SplashLayer(AOApplication *p_ao_app, QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
void load_image(QString p_filename, QString p_charname, QString p_miscname);
|
void load_image(QString p_filename, QString p_charname, QString p_miscname);
|
||||||
};
|
};
|
||||||
|
|
||||||
class EffectLayer : public AOLayer {
|
class EffectLayer : public AOLayer
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EffectLayer(QWidget *p_parent, AOApplication *p_ao_app);
|
EffectLayer(AOApplication *p_ao_app, QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
void load_image(QString p_filename, bool p_looping);
|
void load_image(QString p_filename, bool p_looping);
|
||||||
};
|
};
|
||||||
|
|
||||||
class InterfaceLayer : public AOLayer {
|
class InterfaceLayer : public AOLayer
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InterfaceLayer(QWidget *p_parent, AOApplication *p_ao_app);
|
InterfaceLayer(AOApplication *p_ao_app, QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
void load_image(QString p_filename, QString p_miscname);
|
void load_image(QString p_filename, QString p_miscname);
|
||||||
};
|
};
|
||||||
|
|
||||||
class StickerLayer : public AOLayer {
|
class StickerLayer : public AOLayer
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StickerLayer(QWidget *p_parent, AOApplication *p_ao_app);
|
StickerLayer(AOApplication *p_ao_app, QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
void load_image(QString p_charname);
|
void load_image(QString p_charname);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AOLAYER_H
|
|
@ -1,74 +1,92 @@
|
|||||||
#include "aomusicplayer.h"
|
#include "aomusicplayer.h"
|
||||||
|
|
||||||
|
#include "file_functions.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
#include "bass.h"
|
#include <bass.h>
|
||||||
#include "file_functions.h"
|
|
||||||
|
|
||||||
AOMusicPlayer::AOMusicPlayer(QWidget *parent, AOApplication *p_ao_app)
|
#include <QDebug>
|
||||||
{
|
#include <QFuture>
|
||||||
m_parent = parent;
|
#include <QWidget>
|
||||||
ao_app = p_ao_app;
|
|
||||||
}
|
AOMusicPlayer::AOMusicPlayer(AOApplication *p_ao_app)
|
||||||
|
: ao_app(p_ao_app)
|
||||||
|
{}
|
||||||
|
|
||||||
AOMusicPlayer::~AOMusicPlayer()
|
AOMusicPlayer::~AOMusicPlayer()
|
||||||
{
|
{
|
||||||
for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) {
|
for (int n_stream = 0; n_stream < CHANNEL_COUNT; ++n_stream)
|
||||||
|
{
|
||||||
BASS_ChannelStop(m_stream_list[n_stream]);
|
BASS_ChannelStop(m_stream_list[n_stream]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AOMusicPlayer::play(QString p_song, int channel, bool loop,
|
QString AOMusicPlayer::play(QString p_song, int channel, bool loop, int effect_flags)
|
||||||
int effect_flags)
|
|
||||||
{
|
{
|
||||||
channel = channel % m_channelmax;
|
channel = channel % CHANNEL_COUNT;
|
||||||
if (channel < 0) // wtf?
|
if (channel < 0) // wtf?
|
||||||
|
{
|
||||||
return "[ERROR] Invalid Channel";
|
return "[ERROR] Invalid Channel";
|
||||||
unsigned int flags = BASS_STREAM_PRESCAN | BASS_STREAM_AUTOFREE |
|
}
|
||||||
BASS_UNICODE | BASS_ASYNCFILE;
|
unsigned int flags = BASS_STREAM_PRESCAN | BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE;
|
||||||
unsigned int streaming_flags = BASS_STREAM_AUTOFREE;
|
unsigned int streaming_flags = BASS_STREAM_AUTOFREE;
|
||||||
if (loop) {
|
if (loop)
|
||||||
|
{
|
||||||
flags |= BASS_SAMPLE_LOOP;
|
flags |= BASS_SAMPLE_LOOP;
|
||||||
streaming_flags |= BASS_SAMPLE_LOOP;
|
streaming_flags |= BASS_SAMPLE_LOOP;
|
||||||
}
|
}
|
||||||
QString f_path = p_song;
|
QString f_path = p_song;
|
||||||
DWORD newstream;
|
DWORD newstream;
|
||||||
if (f_path.startsWith("http")) {
|
if (f_path.startsWith("http"))
|
||||||
|
{
|
||||||
if (!Options::getInstance().streamingEnabled()) {
|
if (!Options::getInstance().streamingEnabled())
|
||||||
BASS_ChannelStop(m_stream_list[channel]);
|
{
|
||||||
return QObject::tr("[MISSING] Streaming disabled.");
|
BASS_ChannelStop(m_stream_list[channel]);
|
||||||
|
return QObject::tr("[MISSING] Streaming disabled.");
|
||||||
}
|
}
|
||||||
QUrl l_url = QUrl(f_path);
|
QUrl l_url = QUrl(f_path);
|
||||||
newstream = BASS_StreamCreateURL(l_url.toEncoded().toStdString().c_str(), 0, streaming_flags, nullptr, 0);
|
newstream = BASS_StreamCreateURL(l_url.toEncoded().toStdString().c_str(), 0, streaming_flags, nullptr, 0);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
f_path = ao_app->get_real_path(ao_app->get_music_path(p_song));
|
f_path = ao_app->get_real_path(ao_app->get_music_path(p_song));
|
||||||
if (f_path.endsWith(".mo3") || f_path.endsWith(".xm") || f_path.endsWith(".mod") || f_path.endsWith(".s3m") || f_path.endsWith(".it") || f_path.endsWith(".mtm") || f_path.endsWith(".umx") )
|
if (f_path.endsWith(".mo3") || f_path.endsWith(".xm") || f_path.endsWith(".mod") || f_path.endsWith(".s3m") || f_path.endsWith(".it") || f_path.endsWith(".mtm") || f_path.endsWith(".umx"))
|
||||||
newstream = BASS_MusicLoad(FALSE,f_path.utf16(), 0, 0, flags, 1);
|
{
|
||||||
|
newstream = BASS_MusicLoad(FALSE, f_path.utf16(), 0, 0, flags, 1);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
newstream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags);
|
newstream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int error_code = BASS_ErrorGetCode();
|
int error_code = BASS_ErrorGetCode();
|
||||||
|
|
||||||
if (Options::getInstance().audioOutputDevice() != "default")
|
if (Options::getInstance().audioOutputDevice() != "default")
|
||||||
|
{
|
||||||
BASS_ChannelSetDevice(m_stream_list[channel], BASS_GetDevice());
|
BASS_ChannelSetDevice(m_stream_list[channel], BASS_GetDevice());
|
||||||
|
}
|
||||||
|
|
||||||
QString d_path = f_path + ".txt";
|
QString d_path = f_path + ".txt";
|
||||||
|
|
||||||
loop_start[channel] = 0;
|
m_loop_start[channel] = 0;
|
||||||
loop_end[channel] = 0;
|
m_loop_end[channel] = 0;
|
||||||
if (loop && file_exists(d_path)) // Contains loop/etc. information file
|
if (loop && file_exists(d_path)) // Contains loop/etc. information file
|
||||||
{
|
{
|
||||||
QStringList lines = ao_app->read_file(d_path).split("\n");
|
QStringList lines = ao_app->read_file(d_path).split("\n");
|
||||||
bool seconds_mode = false;
|
bool seconds_mode = false;
|
||||||
foreach (QString line, lines) {
|
foreach (QString line, lines)
|
||||||
|
{
|
||||||
QStringList args = line.split("=");
|
QStringList args = line.split("=");
|
||||||
if (args.size() < 2)
|
if (args.size() < 2)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
QString arg = args[0].trimmed();
|
QString arg = args[0].trimmed();
|
||||||
if (arg == "seconds") {
|
if (arg == "seconds")
|
||||||
if (args[1].trimmed() == "true") {
|
{
|
||||||
|
if (args[1].trimmed() == "true")
|
||||||
|
{
|
||||||
seconds_mode = true; // Use new epic behavior
|
seconds_mode = true; // Use new epic behavior
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -86,64 +104,71 @@ QString AOMusicPlayer::play(QString p_song, int channel, bool loop,
|
|||||||
|
|
||||||
// Calculate the bytes for loop_start/loop_end to use with the sync proc
|
// Calculate the bytes for loop_start/loop_end to use with the sync proc
|
||||||
QWORD bytes;
|
QWORD bytes;
|
||||||
if (seconds_mode) {
|
if (seconds_mode)
|
||||||
bytes =
|
{
|
||||||
BASS_ChannelSeconds2Bytes(newstream, args[1].trimmed().toDouble());
|
bytes = BASS_ChannelSeconds2Bytes(newstream, args[1].trimmed().toDouble());
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
bytes = static_cast<QWORD>(args[1].trimmed().toUInt() * sample_size *
|
{
|
||||||
num_channels);
|
bytes = static_cast<QWORD>(args[1].trimmed().toUInt() * sample_size * num_channels);
|
||||||
}
|
}
|
||||||
if (arg == "loop_start")
|
if (arg == "loop_start")
|
||||||
loop_start[channel] = bytes;
|
{
|
||||||
|
m_loop_start[channel] = bytes;
|
||||||
|
}
|
||||||
else if (arg == "loop_length")
|
else if (arg == "loop_length")
|
||||||
loop_end[channel] = loop_start[channel] + bytes;
|
{
|
||||||
|
m_loop_end[channel] = m_loop_start[channel] + bytes;
|
||||||
|
}
|
||||||
else if (arg == "loop_end")
|
else if (arg == "loop_end")
|
||||||
loop_end[channel] = bytes;
|
{
|
||||||
|
m_loop_end[channel] = bytes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
qDebug() << "Found data file for song" << p_song << "length"
|
qDebug() << "Found data file for song" << p_song << "length" << BASS_ChannelGetLength(newstream, BASS_POS_BYTE) << "loop start" << m_loop_start[channel] << "loop end" << m_loop_end[channel];
|
||||||
<< BASS_ChannelGetLength(newstream, BASS_POS_BYTE) << "loop start"
|
|
||||||
<< loop_start[channel] << "loop end" << loop_end[channel];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BASS_ChannelIsActive(m_stream_list[channel]) == BASS_ACTIVE_PLAYING) {
|
if (BASS_ChannelIsActive(m_stream_list[channel]) == BASS_ACTIVE_PLAYING)
|
||||||
|
{
|
||||||
DWORD oldstream = m_stream_list[channel];
|
DWORD oldstream = m_stream_list[channel];
|
||||||
|
|
||||||
if (effect_flags & SYNC_POS) {
|
if (effect_flags & SYNC_POS)
|
||||||
|
{
|
||||||
BASS_ChannelLock(oldstream, true);
|
BASS_ChannelLock(oldstream, true);
|
||||||
// Sync it with the new sample
|
// Sync it with the new sample
|
||||||
BASS_ChannelSetPosition(newstream,
|
BASS_ChannelSetPosition(newstream, BASS_ChannelGetPosition(oldstream, BASS_POS_BYTE), BASS_POS_BYTE);
|
||||||
BASS_ChannelGetPosition(oldstream, BASS_POS_BYTE),
|
|
||||||
BASS_POS_BYTE);
|
|
||||||
BASS_ChannelLock(oldstream, false);
|
BASS_ChannelLock(oldstream, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((effect_flags & FADE_OUT) && m_volume[channel] > 0) {
|
if ((effect_flags & FADE_OUT) && m_volume[channel] > 0)
|
||||||
|
{
|
||||||
// Fade out the other sample and stop it (due to -1)
|
// Fade out the other sample and stop it (due to -1)
|
||||||
BASS_ChannelSlideAttribute(oldstream, BASS_ATTRIB_VOL | BASS_SLIDE_LOG,
|
BASS_ChannelSlideAttribute(oldstream, BASS_ATTRIB_VOL | BASS_SLIDE_LOG, -1, 4000);
|
||||||
-1, 4000);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
BASS_ChannelStop(
|
{
|
||||||
oldstream); // Stop the sample since we don't need it anymore
|
BASS_ChannelStop(oldstream); // Stop the sample since we don't need it anymore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
BASS_ChannelStop(m_stream_list[channel]);
|
BASS_ChannelStop(m_stream_list[channel]);
|
||||||
|
}
|
||||||
|
|
||||||
m_stream_list[channel] = newstream;
|
m_stream_list[channel] = newstream;
|
||||||
BASS_ChannelPlay(newstream, false);
|
BASS_ChannelPlay(newstream, false);
|
||||||
if (effect_flags & FADE_IN) {
|
if (effect_flags & FADE_IN)
|
||||||
|
{
|
||||||
// Fade in our sample
|
// Fade in our sample
|
||||||
BASS_ChannelSetAttribute(newstream, BASS_ATTRIB_VOL, 0);
|
BASS_ChannelSetAttribute(newstream, BASS_ATTRIB_VOL, 0);
|
||||||
BASS_ChannelSlideAttribute(newstream, BASS_ATTRIB_VOL,
|
BASS_ChannelSlideAttribute(newstream, BASS_ATTRIB_VOL, static_cast<float>(m_volume[channel] / 100.0f), 1000);
|
||||||
static_cast<float>(m_volume[channel] / 100.0f),
|
|
||||||
1000);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
this->set_volume(m_volume[channel], channel);
|
this->set_volume(m_volume[channel], channel);
|
||||||
|
}
|
||||||
|
|
||||||
BASS_ChannelSetSync(newstream, BASS_SYNC_DEV_FAIL, 0,
|
BASS_ChannelSetSync(newstream, BASS_SYNC_DEV_FAIL, 0, ao_app->BASSreset, 0);
|
||||||
ao_app->BASSreset, 0);
|
|
||||||
|
|
||||||
this->set_looping(loop, channel); // Have to do this here due to any
|
this->set_looping(loop, channel); // Have to do this here due to any
|
||||||
// crossfading-related changes, etc.
|
// crossfading-related changes, etc.
|
||||||
@ -152,20 +177,25 @@ QString AOMusicPlayer::play(QString p_song, int channel, bool loop,
|
|||||||
QString p_song_clear = QUrl(p_song).fileName();
|
QString p_song_clear = QUrl(p_song).fileName();
|
||||||
p_song_clear = p_song_clear.left(p_song_clear.lastIndexOf('.'));
|
p_song_clear = p_song_clear.left(p_song_clear.lastIndexOf('.'));
|
||||||
|
|
||||||
if (is_stop && channel == 0) { // don't send text on channels besides 0
|
if (is_stop && channel == 0)
|
||||||
|
{ // don't send text on channels besides 0
|
||||||
return QObject::tr("None");
|
return QObject::tr("None");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error_code == BASS_ERROR_HANDLE) { // Cheap hack to see if file missing
|
if (error_code == BASS_ERROR_HANDLE)
|
||||||
|
{ // Cheap hack to see if file missing
|
||||||
return QObject::tr("[MISSING] %1").arg(p_song_clear);
|
return QObject::tr("[MISSING] %1").arg(p_song_clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_song.startsWith("http") && channel == 0) {
|
if (p_song.startsWith("http") && channel == 0)
|
||||||
|
{
|
||||||
return QObject::tr("[STREAM] %1").arg(p_song_clear);
|
return QObject::tr("[STREAM] %1").arg(p_song_clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel == 0)
|
if (channel == 0)
|
||||||
|
{
|
||||||
return p_song_clear;
|
return p_song_clear;
|
||||||
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -179,7 +209,8 @@ void AOMusicPlayer::set_muted(bool toggle)
|
|||||||
{
|
{
|
||||||
m_muted = toggle;
|
m_muted = toggle;
|
||||||
// Update all volume based on the mute setting
|
// Update all volume based on the mute setting
|
||||||
for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) {
|
for (int n_stream = 0; n_stream < CHANNEL_COUNT; ++n_stream)
|
||||||
|
{
|
||||||
set_volume(m_volume[n_stream], n_stream);
|
set_volume(m_volume[n_stream], n_stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,13 +220,15 @@ void AOMusicPlayer::set_volume(int p_value, int channel)
|
|||||||
m_volume[channel] = p_value;
|
m_volume[channel] = p_value;
|
||||||
// If muted, volume will always be 0
|
// If muted, volume will always be 0
|
||||||
float volume = (m_volume[channel] / 100.0f) * !m_muted;
|
float volume = (m_volume[channel] / 100.0f) * !m_muted;
|
||||||
if (channel < 0) {
|
if (channel < 0)
|
||||||
for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) {
|
{
|
||||||
BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL,
|
for (int n_stream = 0; n_stream < CHANNEL_COUNT; ++n_stream)
|
||||||
volume);
|
{
|
||||||
|
BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL, volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
BASS_ChannelSetAttribute(m_stream_list[channel], BASS_ATTRIB_VOL, volume);
|
BASS_ChannelSetAttribute(m_stream_list[channel], BASS_ATTRIB_VOL, volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,35 +245,35 @@ void CALLBACK loopProc(HSYNC handle, DWORD channel, DWORD data, void *user)
|
|||||||
|
|
||||||
void AOMusicPlayer::set_looping(bool loop_song, int channel)
|
void AOMusicPlayer::set_looping(bool loop_song, int channel)
|
||||||
{
|
{
|
||||||
if (!loop_song) {
|
if (!loop_song)
|
||||||
|
{
|
||||||
if (BASS_ChannelFlags(m_stream_list[channel], 0, 0) & BASS_SAMPLE_LOOP)
|
if (BASS_ChannelFlags(m_stream_list[channel], 0, 0) & BASS_SAMPLE_LOOP)
|
||||||
|
{
|
||||||
BASS_ChannelFlags(m_stream_list[channel], 0,
|
BASS_ChannelFlags(m_stream_list[channel], 0,
|
||||||
BASS_SAMPLE_LOOP); // remove the LOOP flag
|
BASS_SAMPLE_LOOP); // remove the LOOP flag
|
||||||
BASS_ChannelRemoveSync(m_stream_list[channel], loop_sync[channel]);
|
}
|
||||||
loop_sync[channel] = 0;
|
BASS_ChannelRemoveSync(m_stream_list[channel], m_loop_sync[channel]);
|
||||||
|
m_loop_sync[channel] = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BASS_ChannelFlags(m_stream_list[channel], BASS_SAMPLE_LOOP,
|
BASS_ChannelFlags(m_stream_list[channel], BASS_SAMPLE_LOOP,
|
||||||
BASS_SAMPLE_LOOP); // set the LOOP flag
|
BASS_SAMPLE_LOOP); // set the LOOP flag
|
||||||
if (loop_sync[channel] != 0) {
|
if (m_loop_sync[channel] != 0)
|
||||||
|
{
|
||||||
BASS_ChannelRemoveSync(m_stream_list[channel],
|
BASS_ChannelRemoveSync(m_stream_list[channel],
|
||||||
loop_sync[channel]); // remove the sync
|
m_loop_sync[channel]); // remove the sync
|
||||||
loop_sync[channel] = 0;
|
m_loop_sync[channel] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loop_start[channel] < loop_end[channel])
|
if (m_loop_start[channel] < m_loop_end[channel])
|
||||||
{
|
{
|
||||||
//Loop when the endpoint is reached.
|
// Loop when the endpoint is reached.
|
||||||
loop_sync[channel] = BASS_ChannelSetSync(
|
m_loop_sync[channel] = BASS_ChannelSetSync(m_stream_list[channel], BASS_SYNC_POS | BASS_SYNC_MIXTIME, m_loop_end[channel], loopProc, &m_loop_start[channel]);
|
||||||
m_stream_list[channel], BASS_SYNC_POS | BASS_SYNC_MIXTIME,
|
|
||||||
loop_end[channel], loopProc, &loop_start[channel]);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Loop when the end of the file is reached.
|
// Loop when the end of the file is reached.
|
||||||
loop_sync[channel] = BASS_ChannelSetSync(
|
m_loop_sync[channel] = BASS_ChannelSetSync(m_stream_list[channel], BASS_SYNC_END | BASS_SYNC_MIXTIME, 0, loopProc, &m_loop_start[channel]);
|
||||||
m_stream_list[channel], BASS_SYNC_END | BASS_SYNC_MIXTIME,
|
|
||||||
0, loopProc, &loop_start[channel]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,53 +1,44 @@
|
|||||||
#ifndef AOMUSICPLAYER_H
|
#pragma once
|
||||||
#define AOMUSICPLAYER_H
|
|
||||||
#include "aoapplication.h"
|
#include "aoapplication.h"
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QWidget>
|
|
||||||
#include <string.h>
|
|
||||||
#include <QFuture>
|
|
||||||
#include <QFutureWatcher>
|
#include <QFutureWatcher>
|
||||||
|
|
||||||
class AOMusicPlayer {
|
class AOMusicPlayer
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
AOMusicPlayer(QWidget *parent, AOApplication *p_ao_app);
|
// Channel 0 = music
|
||||||
|
// Channel 1 = ambience
|
||||||
|
static constexpr int CHANNEL_COUNT = 2;
|
||||||
|
|
||||||
|
AOMusicPlayer(AOApplication *p_ao_app);
|
||||||
virtual ~AOMusicPlayer();
|
virtual ~AOMusicPlayer();
|
||||||
|
|
||||||
void set_volume(int p_value, int channel = -1);
|
void set_volume(int p_value, int channel = -1);
|
||||||
void set_looping(bool loop_song, int channel = 0);
|
void set_looping(bool loop_song, int channel = 0);
|
||||||
void set_muted(bool toggle);
|
void set_muted(bool toggle);
|
||||||
|
|
||||||
const int m_channelmax = 4;
|
|
||||||
|
|
||||||
QFutureWatcher<QString> music_watcher;
|
QFutureWatcher<QString> music_watcher;
|
||||||
|
|
||||||
public slots:
|
public Q_SLOTS:
|
||||||
QString play(QString p_song, int channel = 0, bool loop = false,
|
QString play(QString p_song, int channel = 0, bool loop = false, int effect_flags = 0);
|
||||||
int effect_flags = 0);
|
|
||||||
void stop(int channel = 0);
|
void stop(int channel = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QWidget *m_parent;
|
|
||||||
AOApplication *ao_app;
|
AOApplication *ao_app;
|
||||||
|
|
||||||
bool m_muted = false;
|
bool m_muted = false;
|
||||||
int m_volume[4] = {0, 0, 0, 0};
|
int m_volume[CHANNEL_COUNT] = {0, 0};
|
||||||
|
HSTREAM m_stream_list[CHANNEL_COUNT];
|
||||||
// Channel 0 = music
|
HSYNC m_loop_sync[CHANNEL_COUNT];
|
||||||
// Channel 1 = ambience
|
|
||||||
// Channel 2 = extra
|
|
||||||
// Channel 3 = extra
|
|
||||||
HSTREAM m_stream_list[4];
|
|
||||||
HSYNC loop_sync[4];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The starting sample of the AB-Loop.
|
* @brief The starting sample of the AB-Loop.
|
||||||
*/
|
*/
|
||||||
unsigned int loop_start[4] = {0, 0, 0, 0};
|
unsigned int m_loop_start[CHANNEL_COUNT] = {0, 0};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The end sample of the AB-Loop.
|
* @brief The end sample of the AB-Loop.
|
||||||
*/
|
*/
|
||||||
unsigned int loop_end[4] = {0, 0, 0, 0};
|
unsigned int m_loop_end[CHANNEL_COUNT] = {0, 0};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AOMUSICPLAYER_H
|
|
@ -1,42 +1,48 @@
|
|||||||
#include "aopacket.h"
|
#include "aopacket.h"
|
||||||
|
|
||||||
QString AOPacket::to_string(bool encoded)
|
QString AOPacket::encode(QString data)
|
||||||
{
|
{
|
||||||
QStringList contents = m_contents;
|
return data.replace("#", "<num>").replace("%", "<percent>").replace("$", "<dollar>").replace("&", "<and>");
|
||||||
if (encoded) {
|
}
|
||||||
escape(contents);
|
|
||||||
|
QString AOPacket::decode(QString data)
|
||||||
|
{
|
||||||
|
return data.replace("<num>", "#").replace("<percent>", "%").replace("<dollar>", "$").replace("<and>", "&");
|
||||||
|
}
|
||||||
|
|
||||||
|
AOPacket::AOPacket(QString header)
|
||||||
|
: m_header(header)
|
||||||
|
{}
|
||||||
|
|
||||||
|
AOPacket::AOPacket(QString header, QStringList content)
|
||||||
|
: m_header(header)
|
||||||
|
, m_content(content)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QString AOPacket::get_header()
|
||||||
|
{
|
||||||
|
return m_header;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList &AOPacket::get_content()
|
||||||
|
{
|
||||||
|
return m_content;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AOPacket::to_string(bool ensureEncoded)
|
||||||
|
{
|
||||||
|
QString message = m_header;
|
||||||
|
if (!m_content.isEmpty())
|
||||||
|
{
|
||||||
|
for (QString item : qAsConst(m_content))
|
||||||
|
{
|
||||||
|
if (ensureEncoded)
|
||||||
|
{
|
||||||
|
item = encode(item);
|
||||||
|
}
|
||||||
|
message += "#" + item;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Our packet is just the header by itself
|
|
||||||
if (contents.isEmpty()) {
|
return message + "#%";
|
||||||
return m_header + "#%";
|
|
||||||
}
|
|
||||||
return m_header + "#" + contents.join("#") + "#%";
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOPacket::net_encode()
|
|
||||||
{
|
|
||||||
escape(m_contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOPacket::net_decode()
|
|
||||||
{
|
|
||||||
unescape(m_contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOPacket::escape(QStringList &contents)
|
|
||||||
{
|
|
||||||
contents.replaceInStrings("#", "<num>")
|
|
||||||
.replaceInStrings("%", "<percent>")
|
|
||||||
.replaceInStrings("$", "<dollar>")
|
|
||||||
.replaceInStrings("&", "<and>");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOPacket::unescape(QStringList &contents)
|
|
||||||
{
|
|
||||||
contents.replaceInStrings("<num>", "#")
|
|
||||||
.replaceInStrings("<percent>", "%")
|
|
||||||
.replaceInStrings("<dollar>", "$")
|
|
||||||
.replaceInStrings("<and>", "&");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
22
src/aopacket.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
class AOPacket
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static QString encode(QString data);
|
||||||
|
static QString decode(QString data);
|
||||||
|
|
||||||
|
AOPacket(QString header);
|
||||||
|
AOPacket(QString header, QStringList content);
|
||||||
|
|
||||||
|
QString get_header();
|
||||||
|
QStringList &get_content();
|
||||||
|
QString to_string(bool ensureEncoded = false);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_header;
|
||||||
|
QStringList m_content;
|
||||||
|
};
|
@ -1,15 +1,15 @@
|
|||||||
#include "aosfxplayer.h"
|
#include "aosfxplayer.h"
|
||||||
|
|
||||||
#include "file_functions.h"
|
#include "file_functions.h"
|
||||||
|
|
||||||
AOSfxPlayer::AOSfxPlayer(QWidget *parent, AOApplication *p_ao_app)
|
AOSfxPlayer::AOSfxPlayer(AOApplication *p_ao_app)
|
||||||
{
|
: ao_app(p_ao_app)
|
||||||
m_parent = parent;
|
{}
|
||||||
ao_app = p_ao_app;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOSfxPlayer::clear()
|
void AOSfxPlayer::clear()
|
||||||
{
|
{
|
||||||
for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) {
|
for (int n_stream = 0; n_stream < CHANNEL_COUNT; ++n_stream)
|
||||||
|
{
|
||||||
BASS_ChannelStop(m_stream_list[n_stream]);
|
BASS_ChannelStop(m_stream_list[n_stream]);
|
||||||
}
|
}
|
||||||
set_volume_internal(m_volume);
|
set_volume_internal(m_volume);
|
||||||
@ -17,44 +17,51 @@ void AOSfxPlayer::clear()
|
|||||||
|
|
||||||
void AOSfxPlayer::loop_clear()
|
void AOSfxPlayer::loop_clear()
|
||||||
{
|
{
|
||||||
for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) {
|
for (int n_stream = 0; n_stream < CHANNEL_COUNT; ++n_stream)
|
||||||
|
{
|
||||||
if ((BASS_ChannelFlags(m_stream_list[n_stream], 0, 0) & BASS_SAMPLE_LOOP))
|
if ((BASS_ChannelFlags(m_stream_list[n_stream], 0, 0) & BASS_SAMPLE_LOOP))
|
||||||
|
{
|
||||||
BASS_ChannelStop(m_stream_list[n_stream]);
|
BASS_ChannelStop(m_stream_list[n_stream]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
set_volume_internal(m_volume);
|
set_volume_internal(m_volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOSfxPlayer::play(QString p_sfx, QString p_character, QString p_misc)
|
void AOSfxPlayer::play(QString p_sfx, QString p_character, QString p_misc)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < m_channelmax; ++i) {
|
for (int i = 0; i < CHANNEL_COUNT; ++i)
|
||||||
|
{
|
||||||
if (BASS_ChannelIsActive(m_stream_list[i]) == BASS_ACTIVE_PLAYING)
|
if (BASS_ChannelIsActive(m_stream_list[i]) == BASS_ACTIVE_PLAYING)
|
||||||
m_channel = (i + 1) % m_channelmax;
|
{
|
||||||
else {
|
m_channel = (i + 1) % CHANNEL_COUNT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
m_channel = i;
|
m_channel = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QString path = ao_app->get_sfx(p_sfx, p_misc, p_character);
|
QString path = ao_app->get_sfx(p_sfx, p_misc, p_character);
|
||||||
if (path.endsWith(".opus"))
|
if (path.endsWith(".opus"))
|
||||||
m_stream_list[m_channel] = BASS_OPUS_StreamCreateFile(
|
{
|
||||||
FALSE, path.utf16(), 0, 0,
|
m_stream_list[m_channel] = BASS_OPUS_StreamCreateFile(FALSE, path.utf16(), 0, 0, BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE);
|
||||||
BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE);
|
}
|
||||||
else
|
else
|
||||||
m_stream_list[m_channel] = BASS_StreamCreateFile(
|
{
|
||||||
FALSE, path.utf16(), 0, 0,
|
m_stream_list[m_channel] = BASS_StreamCreateFile(FALSE, path.utf16(), 0, 0, BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE);
|
||||||
BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE);
|
}
|
||||||
|
|
||||||
set_volume_internal(m_volume);
|
set_volume_internal(m_volume);
|
||||||
|
|
||||||
BASS_ChannelSetDevice(m_stream_list[m_channel], BASS_GetDevice());
|
BASS_ChannelSetDevice(m_stream_list[m_channel], BASS_GetDevice());
|
||||||
BASS_ChannelPlay(m_stream_list[m_channel], false);
|
BASS_ChannelPlay(m_stream_list[m_channel], false);
|
||||||
BASS_ChannelSetSync(m_stream_list[m_channel], BASS_SYNC_DEV_FAIL, 0,
|
BASS_ChannelSetSync(m_stream_list[m_channel], BASS_SYNC_DEV_FAIL, 0, ao_app->BASSreset, 0);
|
||||||
ao_app->BASSreset, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOSfxPlayer::stop(int channel)
|
void AOSfxPlayer::stop(int channel)
|
||||||
{
|
{
|
||||||
if (channel == -1) {
|
if (channel == -1)
|
||||||
|
{
|
||||||
channel = m_channel;
|
channel = m_channel;
|
||||||
}
|
}
|
||||||
BASS_ChannelStop(m_stream_list[channel]);
|
BASS_ChannelStop(m_stream_list[channel]);
|
||||||
@ -67,6 +74,11 @@ void AOSfxPlayer::set_muted(bool toggle)
|
|||||||
set_volume_internal(m_volume);
|
set_volume_internal(m_volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AOSfxPlayer::get_volume()
|
||||||
|
{
|
||||||
|
return m_volume * 100;
|
||||||
|
}
|
||||||
|
|
||||||
void AOSfxPlayer::set_volume(qreal p_value)
|
void AOSfxPlayer::set_volume(qreal p_value)
|
||||||
{
|
{
|
||||||
m_volume = p_value * 0.01;
|
m_volume = p_value * 0.01;
|
||||||
@ -77,25 +89,33 @@ void AOSfxPlayer::set_volume_internal(qreal p_value)
|
|||||||
{
|
{
|
||||||
// If muted, volume will always be 0
|
// If muted, volume will always be 0
|
||||||
float volume = static_cast<float>(p_value) * !m_muted;
|
float volume = static_cast<float>(p_value) * !m_muted;
|
||||||
for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) {
|
for (int n_stream = 0; n_stream < CHANNEL_COUNT; ++n_stream)
|
||||||
|
{
|
||||||
BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL, volume);
|
BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL, volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOSfxPlayer::set_looping(bool toggle, int channel)
|
void AOSfxPlayer::set_looping(bool toggle, int channel)
|
||||||
{
|
{
|
||||||
if (channel == -1) {
|
if (channel == -1)
|
||||||
|
{
|
||||||
channel = m_channel;
|
channel = m_channel;
|
||||||
}
|
}
|
||||||
m_looping = toggle;
|
m_looping = toggle;
|
||||||
if (BASS_ChannelFlags(m_stream_list[channel], 0, 0) & BASS_SAMPLE_LOOP) {
|
if (BASS_ChannelFlags(m_stream_list[channel], 0, 0) & BASS_SAMPLE_LOOP)
|
||||||
|
{
|
||||||
if (m_looping == false)
|
if (m_looping == false)
|
||||||
|
{
|
||||||
BASS_ChannelFlags(m_stream_list[channel], 0,
|
BASS_ChannelFlags(m_stream_list[channel], 0,
|
||||||
BASS_SAMPLE_LOOP); // remove the LOOP flag
|
BASS_SAMPLE_LOOP); // remove the LOOP flag
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
if (m_looping == true)
|
if (m_looping == true)
|
||||||
|
{
|
||||||
BASS_ChannelFlags(m_stream_list[channel], BASS_SAMPLE_LOOP,
|
BASS_ChannelFlags(m_stream_list[channel], BASS_SAMPLE_LOOP,
|
||||||
BASS_SAMPLE_LOOP); // set the LOOP flag
|
BASS_SAMPLE_LOOP); // set the LOOP flag
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#ifndef AOSFXPLAYER_H
|
#pragma once
|
||||||
#define AOSFXPLAYER_H
|
|
||||||
|
|
||||||
#include "bass.h"
|
#include "bass.h"
|
||||||
#include "bassopus.h"
|
#include "bassopus.h"
|
||||||
@ -8,33 +7,32 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
class AOSfxPlayer {
|
class AOSfxPlayer
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
AOSfxPlayer(QWidget *parent, AOApplication *p_ao_app);
|
static constexpr int CHANNEL_COUNT = 5;
|
||||||
|
|
||||||
|
AOSfxPlayer(AOApplication *p_ao_app);
|
||||||
|
|
||||||
|
int get_volume();
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
void loop_clear();
|
void loop_clear();
|
||||||
void play(QString p_sfx, QString p_char = "", QString shout = "");
|
void play(QString p_sfx, QString p_char = QString(), QString shout = QString());
|
||||||
void stop(int channel = -1);
|
void stop(int channel = -1);
|
||||||
void set_volume(qreal p_volume);
|
void set_volume(qreal p_volume);
|
||||||
void set_looping(bool toggle, int channel = -1);
|
void set_looping(bool toggle, int channel = -1);
|
||||||
void set_muted(bool toggle);
|
void set_muted(bool toggle);
|
||||||
int m_channel = 0;
|
|
||||||
int get_volume() { return m_volume * 100; };
|
|
||||||
private:
|
|
||||||
QWidget *m_parent;
|
|
||||||
AOApplication *ao_app;
|
|
||||||
qreal m_volume = 0;
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
AOApplication *ao_app;
|
||||||
|
|
||||||
|
qreal m_volume = 0.0;
|
||||||
bool m_looping = true;
|
bool m_looping = true;
|
||||||
bool m_muted = false;
|
bool m_muted = false;
|
||||||
|
int m_channel = 0;
|
||||||
|
HSTREAM m_stream_list[CHANNEL_COUNT]{};
|
||||||
|
|
||||||
void set_volume_internal(qreal p_volume);
|
void set_volume_internal(qreal p_volume);
|
||||||
|
|
||||||
const int m_channelmax = 5;
|
|
||||||
|
|
||||||
HSTREAM m_stream_list[5];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AOSFXPLAYER_H
|
|