diff --git a/.gitignore b/.gitignore index f9f69301..f3461be1 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,7 @@ CMakeLists.txt.user.* # Ignore Visual Studio Code files /.vscode + +# Ignore Visual Studio files +/CMakeSettings.json +/.vs diff --git a/CMakeLists.txt b/CMakeLists.txt index 234c201a..0c40e085 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ project(colobot C CXX) set(COLOBOT_VERSION_CODENAME "Gold") set(COLOBOT_VERSION_MAJOR 0) set(COLOBOT_VERSION_MINOR 1) -set(COLOBOT_VERSION_REVISION 11.1) +set(COLOBOT_VERSION_REVISION 12) # Used on official releases set(COLOBOT_VERSION_RELEASE_CODENAME "-alpha") @@ -124,6 +124,9 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) # Include cmake directory with some additional scripts set(CMAKE_MODULE_PATH "${colobot_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) +# MSVC needs different flags if linking statically +option(MSVC_STATIC "Link statically when using MSVC" OFF) + # Compiler detection if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) @@ -160,14 +163,19 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") message(STATUS "Detected MSVC compiler") set(NORMAL_CXX_FLAGS "/wd\"4244\" /wd\"4309\" /wd\"4800\" /wd\"4996\" /wd\"4351\" /EHsc") # disable some useless warnings - set(RELEASE_CXX_FLAGS "/MD") - set(DEBUG_CXX_FLAGS "/MDd /ZI") + if(MSVC_STATIC) + set(RELEASE_CXX_FLAGS "/MT /Ox") + set(DEBUG_CXX_FLAGS "/MTd /ZI") + else(MSVC_STATIC) + set(RELEASE_CXX_FLAGS "/MD /Ox") + set(DEBUG_CXX_FLAGS "/MDd /ZI") + endif() set(TEST_CXX_FLAGS "") add_definitions(-DNOEXCEPT= -DHAS_MSVC_EXCEPTION_BUG) # Needed for Debug information (it's set to "No" by default for some reason) - set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG") - set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/DEBUG") + set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS} /DEBUG") + set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS} /DEBUG") else() message(FATAL_ERROR "Your C++ compiler doesn't seem to be supported.") endif() @@ -196,11 +204,14 @@ option(DEV_BUILD "Enable development build (enables some debugging tools, local # Official build - changes text on the crash screen # PLEASE DO NOT USE ON UNOFFICIAL BUILDS. Thanks. -option(OFFICIAL_BUILD "Official build (changes crash screen text)" OFF) +option(OFFICIAL_COLOBOT_BUILD "Official build (changes crash screen text)" OFF) # Portable build - load all data from current directory option(PORTABLE "Portable build" OFF) +# Portable saves - suitable for e.g. putting the whole game on external storage and moving your saves with it +option(PORTABLE_SAVES "Portable saves" OFF) + # Building tests can be enabled/disabled option(TESTS "Build tests" OFF) @@ -312,6 +323,11 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") set(CBOT_STATIC 1) # only this works for some reason set(WINGETOPT 1) # use wingetopt library + + # Hide console in release builds + if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + set(CMAKE_WIN32_EXECUTABLE 1) + endif() endif() ## @@ -350,21 +366,19 @@ endif() ## # Installation paths defined before compiling sources -if(PLATFORM_WINDOWS) - if(MXE) - # We need to use STRING because PATH doesn't accept relative paths - set(COLOBOT_INSTALL_BIN_DIR ./ CACHE STRING "Colobot binary directory") - set(COLOBOT_INSTALL_LIB_DIR ./ CACHE STRING "Colobot libraries directory") - set(COLOBOT_INSTALL_DATA_DIR ./data CACHE STRING "Colobot shared data directory") - set(COLOBOT_INSTALL_I18N_DIR ./lang CACHE STRING "Colobot translations directory") - set(COLOBOT_INSTALL_DOC_DIR ./doc CACHE STRING "Colobot documentation directory") - else() - set(COLOBOT_INSTALL_BIN_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE PATH "Colobot binary directory") - set(COLOBOT_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE PATH "Colobot libraries directory") - set(COLOBOT_INSTALL_DATA_DIR ${CMAKE_INSTALL_PREFIX}/data CACHE PATH "Colobot shared data directory") - set(COLOBOT_INSTALL_I18N_DIR ${CMAKE_INSTALL_PREFIX}/lang CACHE PATH "Colobot translations directory") - set(COLOBOT_INSTALL_DOC_DIR ${CMAKE_INSTALL_PREFIX}/doc CACHE PATH "Colobot documentation directory") - endif() +if(PORTABLE OR (PLATFORM_WINDOWS AND MXE)) + # We need to use STRING because PATH doesn't accept relative paths + set(COLOBOT_INSTALL_BIN_DIR ./ CACHE STRING "Colobot binary directory") + set(COLOBOT_INSTALL_LIB_DIR ./ CACHE STRING "Colobot libraries directory") + set(COLOBOT_INSTALL_DATA_DIR ./data CACHE STRING "Colobot shared data directory") + set(COLOBOT_INSTALL_I18N_DIR ./lang CACHE STRING "Colobot translations directory") + set(COLOBOT_INSTALL_DOC_DIR ./doc CACHE STRING "Colobot documentation directory") +elseif(PLATFORM_WINDOWS) + set(COLOBOT_INSTALL_BIN_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE PATH "Colobot binary directory") + set(COLOBOT_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE PATH "Colobot libraries directory") + set(COLOBOT_INSTALL_DATA_DIR ${CMAKE_INSTALL_PREFIX}/data CACHE PATH "Colobot shared data directory") + set(COLOBOT_INSTALL_I18N_DIR ${CMAKE_INSTALL_PREFIX}/lang CACHE PATH "Colobot translations directory") + set(COLOBOT_INSTALL_DOC_DIR ${CMAKE_INSTALL_PREFIX}/doc CACHE PATH "Colobot documentation directory") elseif(PLATFORM_MACOSX) set(COLOBOT_INSTALL_BIN_DIR ../MacOS CACHE STRING "Colobot binary directory") set(COLOBOT_INSTALL_LIB_DIR ../MacOS CACHE STRING "Colobot libraries directory") diff --git a/Jenkinsfile b/Jenkinsfile index 9ba966a7..95b567a8 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,7 +1,7 @@ #!/usr/bin/env groovy pipeline { - agent { label 'colobot-build' } + agent none options { buildDiscarder(logRotator(artifactDaysToKeepStr: '30', artifactNumToKeepStr: '20')) } @@ -19,13 +19,17 @@ pipeline { stage('Build') { parallel { stage('Build Windows') { + agent { + docker { image 'krzysh/colobot-build:latest' } + } steps { sh 'mkdir -p build/windows' dir('build/windows') { sh ''' - cmake \ + # FIXME: without -lsetupapi linking sdl2 fails + /opt/mxe/usr/bin/i686-w64-mingw32.static-cmake \ + -DCMAKE_CXX_STANDARD_LIBRARIES="-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -lsetupapi" \ -DCMAKE_INSTALL_PREFIX=/install \ - -DCMAKE_TOOLCHAIN_FILE=/opt/mxe/usr/i686-w64-mingw32.static/share/cmake/mxe-conf.cmake \ -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDEV_BUILD=1 -DPORTABLE=1 -DTOOLS=1 -DTESTS=0 ../.. make rm -rf install @@ -42,14 +46,16 @@ pipeline { } stage('Build Linux') { + agent { + docker { image 'krzysh/colobot-build:latest' } + } steps { sh 'mkdir -p build/linux' dir('build/linux') { sh ''' cmake \ - -DCMAKE_INSTALL_PREFIX=/install -DCOLOBOT_INSTALL_BIN_DIR=/install -DCOLOBOT_INSTALL_LIB_DIR=/install -DCOLOBOT_INSTALL_DATA_DIR=/install/data -DCOLOBOT_INSTALL_I18N_DIR=/install/lang -DCMAKE_SKIP_INSTALL_RPATH=ON \ - -DBOOST_STATIC=ON -DGLEW_STATIC=ON -DGLEW_LIBRARY=/usr/lib64/libGLEW.a \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDEV_BUILD=1 -DPORTABLE=1 -DTOOLS=1 -DTESTS=1 -DDESKTOP=0 ../.. + -DCMAKE_INSTALL_PREFIX=/install -DCMAKE_SKIP_INSTALL_RPATH=ON \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDEV_BUILD=1 -DPORTABLE=1 -DTOOLS=1 -DTESTS=1 -DDESKTOP=1 ../.. make rm -rf install DESTDIR=. make install @@ -60,7 +66,31 @@ pipeline { post { success { sh 'rm -f linux-debug.zip' - zip zipFile: 'linux-debug.zip', archive: true, dir: 'build/linux/install' + dir('build/linux') { + sh ''' + # Clean up + rm -rf squashfs-root + rm -rf colobot.AppDir + rm -rf appimage + rm -f Colobot-x86_64.AppImage + + # Download app image tool + wget -N https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage + chmod +x linuxdeploy-x86_64.AppImage + ./linuxdeploy-x86_64.AppImage --appimage-extract + + # Create AppImage + NO_STRIP=1 ./squashfs-root/AppRun -e colobot --output appimage --appdir colobot.AppDir -d desktop/colobot.desktop -i ../../desktop/colobot.svg + chmod +x Colobot-x86_64.AppImage + + # Prepare folder for zip + mkdir -p appimage + cp -rp install/data appimage/data + cp -rp install/lang appimage/lang + cp -p Colobot-x86_64.AppImage appimage/colobot + ''' + } + zip zipFile: 'linux-debug.zip', archive: true, dir: 'build/linux/appimage' } } } @@ -68,6 +98,9 @@ pipeline { } stage('Generate docs') { + agent { + docker { image 'krzysh/colobot-build:latest' } + } steps { dir('build/linux') { sh 'make doc' @@ -81,6 +114,9 @@ pipeline { } stage('Run tests') { + agent { + docker { image 'krzysh/colobot-build:latest' } + } steps { dir('build/linux') { sh './colobot_ut --gtest_output=xml:gtestresults.xml || true' @@ -91,6 +127,9 @@ pipeline { } stage('Run colobot-lint') { + agent { + label 'colobot-build' + } environment { CC = '/usr/lib/llvm-3.6/bin/clang' CXX = '/usr/lib/llvm-3.6/bin/clang++' @@ -245,11 +284,10 @@ exit $ret } } - // TODO: cppcheck publisher STILL doesn't have pipeline support - // There is an open pull request though, merged but no release yet... https://github.com/jenkinsci/cppcheck-plugin/pull/36 - + publishCppcheck pattern: 'build/lint/colobot_lint_report.xml' publishHTML([reportName: 'Colobot-lint HTML report', reportDir: 'build/lint/html_report', reportFiles: 'index.html', reportTitles: '', allowMissing: false, alwaysLinkToLastBuild: true, keepAll: true]) } } } } + diff --git a/cmake/FindLibSndFile.cmake b/cmake/FindLibSndFile.cmake index 8666c66f..7a6d32b6 100644 --- a/cmake/FindLibSndFile.cmake +++ b/cmake/FindLibSndFile.cmake @@ -5,7 +5,7 @@ FIND_PATH(LIBSNDFILE_INCLUDE_DIR sndfile.h) -SET(LIBSNDFILE_NAMES ${LIBSNDFILE_NAMES} sndfile libsndfile) +SET(LIBSNDFILE_NAMES ${LIBSNDFILE_NAMES} sndfile libsndfile libsndfile-1) FIND_LIBRARY(LIBSNDFILE_LIBRARY NAMES ${LIBSNDFILE_NAMES} PATH) IF(LIBSNDFILE_INCLUDE_DIR AND LIBSNDFILE_LIBRARY) diff --git a/cmake/FindPhysFS.cmake b/cmake/FindPhysFS.cmake index fae83786..6d4c93d4 100644 --- a/cmake/FindPhysFS.cmake +++ b/cmake/FindPhysFS.cmake @@ -7,7 +7,7 @@ IF (WIN32) FIND_PATH( PHYSFS_INCLUDE_PATH physfs.h DOC "The directory where physfs.h resides") FIND_LIBRARY( PHYSFS_LIBRARY - NAMES physfs + NAMES physfs physfs-static PATHS /mingw/lib DOC "The PhysFS library") ELSE (WIN32) diff --git a/data b/data index 3cbab714..c467bd99 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit 3cbab7144e6bf940015b2c33fdd17c7c2bfa804b +Subproject commit c467bd994e60fb54cf977fbe8583f92957330695 diff --git a/desktop/CMakeLists.txt b/desktop/CMakeLists.txt index b49ef2d3..af704932 100644 --- a/desktop/CMakeLists.txt +++ b/desktop/CMakeLists.txt @@ -70,6 +70,12 @@ if(PLATFORM_GNU) DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications/ ) + # Install appdata + install( + FILES info.colobot.Colobot.appdata.xml + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo/ + ) + # Install Icon install( FILES ${COLOBOT_ICON_FILE} diff --git a/desktop/info.colobot.Colobot.appdata.xml b/desktop/info.colobot.Colobot.appdata.xml new file mode 100644 index 00000000..8a2a75d6 --- /dev/null +++ b/desktop/info.colobot.Colobot.appdata.xml @@ -0,0 +1,38 @@ + + + info.colobot.Colobot + CC0-1.0 + GPL-3.0 + TerranovaTeam + contact@colobot.info + Colobot + Colonize with bots + + +

Colobot (Colonize with Bots) is an educational game aiming to teach programming through entertainment. You are playing as an astronaut on a journey with robot helpers to find a planet for colonization. It features 3D real-time graphics and a C++ and Java-like, object-oriented language, CBOT, which can be used to program the robots available in the game.

+
+ + colobot.desktop + + + + Alpha 0.1.5 + https://colobot.info/wordpress/wp-content/uploads/alpha-0.1.5.png + + + + https://colobot.info/ + https://github.com/colobot/colobot/issues + http://colobot.info/forum/ + https://colobot.info/donate/ + + + moderate + moderate + mild + + + + + +
diff --git a/po/colobot.pot b/po/colobot.pot index 5d71af8c..b91aba04 100644 --- a/po/colobot.pot +++ b/po/colobot.pot @@ -451,6 +451,9 @@ msgstr "" msgid "Shadow resolution\\Higher means better range and quality, but slower" msgstr "" +msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency" +msgstr "" + msgid "Standard controls\\Standard key functions" msgstr "" diff --git a/po/cs.po b/po/cs.po index 555df720..b5c41e3a 100644 --- a/po/cs.po +++ b/po/cs.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: 0.1.11\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: DATE\n" -"PO-Revision-Date: 2018-02-24 20:39+01\n" +"PO-Revision-Date: 2018-08-20 22:48+02\n" "Last-Translator: next_ghost \n" "Language-Team: Czech \n" "Language: Czech\n" @@ -1193,7 +1193,7 @@ msgid "Programming help\\Gives more detailed help with programming" msgstr "Nápověda\\Zobrazí nápovědu pro psaní programů" msgid "Programs dispatched by Houston" -msgstr "Program poslaný z Houstonu" +msgstr "Programy poslané z Houstonu" msgid "Public required" msgstr "Tato definice musí být veřejná (public)" @@ -1548,7 +1548,7 @@ msgstr "Buchar" #, c-format msgid "Time: %s" -msgstr "" +msgstr "Čas: %s" msgid "Titanium" msgstr "Titan" @@ -1664,6 +1664,9 @@ msgstr "Proměnná nebyla nastavena" msgid "Vault" msgstr "Trezor" +msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency" +msgstr "" + msgid "Violet flag" msgstr "Fialová vlajka" @@ -1741,7 +1744,7 @@ msgid "You cannot use \"%s\" in this exercise (used: %d)" msgstr "V tomto cvičení nesmíte použít \"%s\" (použito: %dx)" msgid "You found a usable object" -msgstr "Našli jste fungující objekt" +msgstr "Našli jste použitelný objekt" #, c-format msgid "You have to use \"%1$s\" at least once in this exercise (used: %2$d)" diff --git a/po/de.po b/po/de.po index 553ead83..66d9918a 100644 --- a/po/de.po +++ b/po/de.po @@ -1681,6 +1681,9 @@ msgstr "Der Wert dieser Variable wurde nicht definiert" msgid "Vault" msgstr "Bunker" +msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency" +msgstr "" + msgid "Violet flag" msgstr "Violette Fahne" diff --git a/po/fr.po b/po/fr.po index ce3f5fdf..c8d48217 100644 --- a/po/fr.po +++ b/po/fr.po @@ -1,19 +1,21 @@ # Didier Raboud , 2012, 2015, 2016. # Martin Quinson , 2016 # B-CE, 2018 +# Pascal Audoux , 2018 msgid "" msgstr "" "Project-Id-Version: Colobot 0.1.11\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: DATE\n" -"PO-Revision-Date: 2018-02-28 20:00+0100\n" +"PO-Revision-Date: 2019-01-09 23:07+0100\n" "Last-Translator: B-CE\n" +"Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Lokalize 2.0\n" +"X-Generator: Poedit 2.0.6\n" "X-Language: fr_FR\n" "X-Source-Language: en_US\n" @@ -384,9 +386,8 @@ msgstr "Fermer" msgid "Closing bracket missing" msgstr "Il manque une parenthèse fermante" -#, fuzzy msgid "Code battle" -msgstr "Batailles de code" +msgstr "Bataille de code" msgid "Code battles" msgstr "Batailles de code" @@ -501,7 +502,7 @@ msgid "Dynamic shadows ++\\Dynamic shadows + self shadowing" msgstr "Ombres dynamiques ++\\Active les ombres dynamiques et l'auto-ombrage" msgid "Dynamic shadows\\Beautiful shadows!" -msgstr "Ombres dynamiques\\Magnifiques ombres !" +msgstr "Ombres dynamiques\\Magnifiques ombres !" msgid "Edit the selected program" msgstr "Éditer le programme sélectionné" @@ -647,7 +648,7 @@ msgid "Generating" msgstr "Génération" msgid "Gold Edition development by:" -msgstr "Édition Gold développée par :" +msgstr "Édition Gold développée par :" msgid "Goto: destination occupied" msgstr "Goto: destination occupée" @@ -685,9 +686,8 @@ msgstr "Bulles d'aide\\Bulles explicatives" msgid "Hex value out of range" msgstr "Valeur hexadécimale impossible" -#, fuzzy msgid "Higher speed\\Doubles speed" -msgstr "Vitesse 2.0x\\Deux fois plus rapide" +msgstr "Vitesse augmentée\\Deux fois plus rapide" msgid "Highest\\Highest graphic quality (lowest frame rate)" msgstr "Maxi\\Haute qualité (+ lent)" @@ -831,7 +831,7 @@ msgid "Loading basic level settings" msgstr "Chargement des configurations de base du niveau" msgid "Loading finished!" -msgstr "Chargement terminé !" +msgstr "Chargement terminé !" msgid "Loading music" msgstr "Chargement de la musique" @@ -980,7 +980,7 @@ msgid "No uranium to transform" msgstr "Pas de minerai d'uranium à transformer" msgid "No userlevels installed!" -msgstr "Pas de niveaux spéciaux installés !" +msgstr "Pas de niveaux spéciaux installés !" msgid "Non-void function needs \"return;\"" msgstr "Les fonctions avec retour autre que void doivent comporter l'instruction \"return;\"" @@ -1228,12 +1228,11 @@ msgstr "Chargement rapide\\Chargement direct d'une sauvegarde" msgid "Quick save\\Immediately save game" msgstr "Sauvegarde rapide\\Sauvegarde direct" -#, fuzzy msgid "Quicksave slot not found" -msgstr "Objet n'existe pas" +msgstr "Emplacement de sauvegarde rapide non trouvé" msgid "Quit\\Quit Colobot: Gold Edition" -msgstr "Quitter\\Quitter Colobot : Édition Gold" +msgstr "Quitter\\Quitter Colobot : Édition Gold" msgid "Quit\\Quit the current mission or exercise" msgstr "Quitter la mission en cours\\Terminer un exercice ou une mssion" @@ -1568,7 +1567,7 @@ msgstr "Robot secoueur" #, c-format msgid "Time: %s" -msgstr "" +msgstr "Temps : %s" msgid "Titanium" msgstr "Titane" @@ -1655,7 +1654,7 @@ msgid "Unknown command" msgstr "Commande inconnue" msgid "Unknown escape sequence" -msgstr "" +msgstr "Séquence d'échappement inconnue" msgid "Unknown function" msgstr "Routine inconnue" @@ -1684,6 +1683,9 @@ msgstr "Variable non initialisée" msgid "Vault" msgstr "Coffre-fort" +msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency" +msgstr "" + msgid "Violet flag" msgstr "Drapeau violet" @@ -1827,7 +1829,7 @@ msgid "\\Red flags" msgstr "\\Drapeaux rouges" msgid "\\Return to Colobot: Gold Edition" -msgstr "\\Revenir à Colobot : Édition Gold" +msgstr "\\Revenir à Colobot : Édition Gold" msgid "\\SatCom on standby" msgstr "\\Mettre le SatCom en veille" diff --git a/po/pl.po b/po/pl.po index f9f76de8..073c7b58 100644 --- a/po/pl.po +++ b/po/pl.po @@ -1663,6 +1663,9 @@ msgstr "Zmienna nie została zainicjalizowana" msgid "Vault" msgstr "Skrytka" +msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency" +msgstr "Synchronizacja pionowa\\Ogranicza ilość klatek na sekundę do wartości odświeżania ekranu" + msgid "Violet flag" msgstr "Fioletowa flaga" diff --git a/po/pt.po b/po/pt.po new file mode 100644 index 00000000..f99a9cbf --- /dev/null +++ b/po/pt.po @@ -0,0 +1,2049 @@ +# José Robson Mariano Alves , 2018. +msgid "" +msgstr "" +"Project-Id-Version: Colobot Alpha\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: DATE\n" +"PO-Revision-Date: 2018-04-17 10:39-0300\n" +"Last-Translator: José Robson Mariano Alves \n" +"Language-Team: Portuguese \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 2.0\n" +"X-Language: pt_BR\n" +"X-Source-Language: en_US\n" + +msgid " or " +msgstr " ou " + +msgid "\" [ \" expected" +msgstr "\" [ \" esperado" + +msgid "\" ] \" missing" +msgstr "\" ] \" faltando" + +#, c-format +msgid "%s: %d pts" +msgstr "" + +msgid "..behind" +msgstr "..atrás" + +msgid "..in front" +msgstr "..em frente" + +msgid "..power cell" +msgstr "..célula de energia" + +msgid "1) First click on the key you want to redefine." +msgstr "1) Primeiro clique na chave que você quer redefinir." + +msgid "2) Then press the key you want to use instead." +msgstr "2) Então pressione a chave que você quer usar no lugar." + +msgid "<< Back \\Back to the previous screen" +msgstr "<< Voltar \\Voltar para a tela anterior" + +msgid "<<< Sorry; mission failed >>>" +msgstr "<<< Desculpe; missão fracassada >>>" + +#, c-format +msgid "<<< Team %s finished! >>>" +msgstr "<<< Time %s terminou! >>>" + +#, c-format +msgid "<<< Team %s lost! >>>" +msgstr "<<< Time %s perdeu! >>>" + +#, c-format +msgid "<<< Team %s recieved %d points >>>" +msgstr "<<< Time %s recebeu %d pontos >>>" + +msgid "<<< Well done; mission accomplished >>>" +msgstr "<<< Bem feito; missão cumprida >>>" + +msgid "A label must be followed by \"for\"; \"while\"; \"do\" or \"switch\"" +msgstr "Um rótulo deve ser precedido por um \"for\"; \"while\"; \"do\" ou um \"switch\"" + +msgid "A variable can not be declared twice" +msgstr "Uma variável não pode ser declarada duas vezes" + +msgid "Abort\\Abort the current mission" +msgstr "Abortar\\Abortar a missão atual" + +msgid "Access beyond array limit" +msgstr "Acesso além dos limites da matriz" + +msgid "Access to solution\\Shows the solution (detailed instructions for missions)" +msgstr "Acesso a solução\\Exibe a solução (instruções detalhadas para missões)" + +msgid "Access to solutions\\Show program \"4: Solution\" in the exercises" +msgstr "Acesso as soluções\\Exibir programa \"4: Solução\" nos exercícios" + +msgid "Add new program" +msgstr "Adicionar novo programa" + +msgid "Alien Queen" +msgstr "Rainha Alienígena" + +msgid "Alien Queen killed" +msgstr "Rainha Alienígena morta" + +msgid "Already carrying something" +msgstr "Já está carregando algo" + +msgid "Alternative camera mode\\Move sideways instead of rotating (in free camera)" +msgstr "Modo de câmera alternativo\\Move de lado em vez de rotacionar (em câmera livre)" + +msgid "Ambiguous call to overloaded function" +msgstr "Chamada ambígua a uma função sobrecarregada" + +msgid "Analysis already performed" +msgstr "Análise já realizada" + +msgid "Analysis performed" +msgstr "Análise realizada" + +msgid "Analyzes only organic matter" +msgstr "Analisa apenas matéria orgânica" + +msgid "Anisotropy level\\Anisotropy level" +msgstr "Nível de anisotropia\\Nível de anisotropia" + +msgid "Ant" +msgstr "Formiga" + +msgid "Ant fatally wounded" +msgstr "Formiga gravemente ferida" + +msgid "Appearance\\Choose your appearance" +msgstr "Aparência\\Escolha sua aparência" + +msgid "Apply changes\\Activates the changed settings" +msgstr "Aplicar mudanças\\Ativa as configurações alteradas" + +msgid "Appropriate constructor missing" +msgstr "Construtor apropriado faltando" + +msgid "Assignment impossible" +msgstr "Tarefa impossível" + +msgid "Autolab" +msgstr "Laboratório de matérias orgânicas" + +msgid "Automatic indent\\When program editing" +msgstr "Indentação automática\\Enquanto editando programa" + +msgid "Autosave interval\\How often your game will autosave" +msgstr "Intervalo de salvamento automático\\Com que frequência seu jogo irá auto-salvar" + +msgid "Autosave slots\\How many autosave slots you'll have" +msgstr "Slots de salvamento automático\\Quantos slots de salvamento automático você terá" + +msgid "Autosave\\Enables autosave" +msgstr "Salvamento automático\\Ativa o salvamento automático" + +msgid "Back" +msgstr "Voltar" + +msgid "Background sound:\\Volume of audio tracks" +msgstr "Som de fundo:\\Volume das trilhas de áudio" + +msgid "Backward (\\key down;)" +msgstr "Retroceder (\\key down;)" + +msgid "Backward\\Moves backward" +msgstr "Retroceder\\Move para trás" + +msgid "Bad argument for \"new\"" +msgstr "Argumento inválido para \"new\"" + +msgid "Big indent\\Indent 2 or 4 spaces per level defined by braces" +msgstr "Grande indentação\\Indente 2 ou 4 espaços por nível definido por colchetes" + +msgid "Black box" +msgstr "Caixa preta" + +msgid "Blood\\Display blood when the astronaut is hit" +msgstr "Sangue\\Exibe sangue quando o astronauta é atingido" + +msgid "Blue" +msgstr "Azul" + +msgid "Blue flag" +msgstr "Bandeira azul" + +msgid "Bot destroyed" +msgstr "Robo destruido" + +msgid "Bot factory" +msgstr "Fábrica de robos" + +msgid "Build a bot factory" +msgstr "Construir uma fábrica de robos" + +msgid "Build a converter" +msgstr "Construir um conversor" + +msgid "Build a defense tower" +msgstr "Construir uma torre de defesa" + +msgid "Build a derrick" +msgstr "Construir um extrator" + +msgid "Build a destroyer" +msgstr "Construir um destruidor" + +msgid "Build a exchange post" +msgstr "Construir um posto de troca" + +msgid "Build a legged grabber" +msgstr "Construir um agarrador com pernas" + +msgid "Build a legged orga shooter" +msgstr "Construir um atirador orgânico com pernas" + +msgid "Build a legged shooter" +msgstr "Construir um atirador com pernas" + +msgid "Build a legged sniffer" +msgstr "Construir um farejador com pernas" + +msgid "Build a lightning conductor" +msgstr "Construir um condutor elétrico" + +msgid "Build a nuclear power plant" +msgstr "Construir uma planta de energia nuclear" + +msgid "Build a phazer shooter" +msgstr "Construir um atirador phazer" + +msgid "Build a power cell factory" +msgstr "Construir uma fábrica de células de energia" + +msgid "Build a power station" +msgstr "Construir uma estação de energia" + +msgid "Build a radar station" +msgstr "Construir uma estação de radar" + +msgid "Build a recycler" +msgstr "Construir um reciclador" + +msgid "Build a repair center" +msgstr "Construir um centro de reparação" + +msgid "Build a research center" +msgstr "Construir um centro de pesquisa" + +msgid "Build a shielder" +msgstr "Construir um defensor" + +msgid "Build a subber" +msgstr "Construir um mergulhador" + +msgid "Build a thumper" +msgstr "Construir um batedor" + +msgid "Build a tracked grabber" +msgstr "Construir um agarrador com esteiras" + +msgid "Build a tracked orga shooter" +msgstr "Construir um atirador orgânico com esteiras" + +msgid "Build a tracked shooter" +msgstr "Construir um atirador com esteiras" + +msgid "Build a tracked sniffer" +msgstr "Construir um farejador com esteiras" + +msgid "Build a wheeled grabber" +msgstr "Construir um agarrador com rodas" + +msgid "Build a wheeled orga shooter" +msgstr "Construir um atirador orgânico com rodas" + +msgid "Build a wheeled shooter" +msgstr "Construir um atirador com rodas" + +msgid "Build a wheeled sniffer" +msgstr "Construir um farejador com rodas" + +msgid "Build a winged grabber" +msgstr "Construir um agarrador alado" + +msgid "Build a winged orga shooter" +msgstr "Construir um atirador orgânico alado" + +msgid "Build a winged shooter" +msgstr "Construir um atirador alado" + +msgid "Build a winged sniffer" +msgstr "Construir um farejador alado" + +msgid "Build an autolab" +msgstr "Construir um laboratório" + +msgid "Building completed" +msgstr "Construção completada" + +msgid "Building destroyed" +msgstr "Construção destruida" + +msgid "Button %1" +msgstr "Botão %1" + +msgid "Calling an unknown function" +msgstr "Chamando uma função desconhecida" + +msgid "Camera (\\key camera;)" +msgstr "Câmera (\\key camera;)" + +msgid "Camera back\\Moves the camera backward" +msgstr "Voltar câmera\\Move a câmera para trás" + +msgid "Camera border scrolling\\Scrolling when the mouse touches right or left border" +msgstr "Rolagem de borda da câmera\\Rola quando o mouse toca a borda esquerda ou direita" + +msgid "Camera closer\\Moves the camera forward" +msgstr "Câmera mais perto\\Move a câmera para frente" + +msgid "Camera down\\Turns the camera down" +msgstr "Baixar câmera\\Vira a câmera para baixo" + +msgid "Camera left\\Turns the camera left" +msgstr "Câmera a esquerda\\Gira a câmera para a esquerda" + +msgid "Camera right\\Turns the camera right" +msgstr "Câmera a direita\\Gira a câmera para a direita" + +msgid "Camera up\\Turns the camera up" +msgstr "Subir câmera\\Gira a câmera para cima" + +msgid "Can not produce not researched object" +msgstr "Impossível produzir objetos não pesquisados" + +msgid "Can not produce this object in this mission" +msgstr "Impossível produzir este objeto nesta missão" + +msgid "Can't open file" +msgstr "Não é possível abrir o arquivo" + +msgid "Cancel" +msgstr "Cancelar" + +msgid "Cancel\\Cancel all changes" +msgstr "Cancelar\\Cancela todas as mudanças" + +msgid "Challenges" +msgstr "Desafios" + +msgid "Challenges in the chapter:" +msgstr "Desafios no capítulo:" + +msgid "Challenges\\Programming challenges" +msgstr "Desafios\\Desafios de programação" + +msgid "Change camera\\Switches between onboard camera and following camera" +msgstr "Mudar câmera\\Alterna entre câmera incorporada e câmera seguidora" + +msgid "Change player\\Change player" +msgstr "Mudar jogador\\Mudar jogador" + +msgid "Chapters:" +msgstr "Capítulos:" + +msgid "Cheat console\\Show cheat console" +msgstr "Console de cheats\\Mostrar console de cheats" + +msgid "Checkpoint" +msgstr "Ponto de verificação" + +msgid "Class name expected" +msgstr "Nome de classe experado" + +msgid "Climb\\Increases the power of the jet" +msgstr "Subir\\Aumenta o poder do jato" + +msgid "Clone program" +msgstr "Clonar programa" + +msgid "Clone selected program" +msgstr "Clonar o programa selecionado" + +msgid "Close" +msgstr "Fechar" + +msgid "Closing bracket missing" +msgstr "Colchete de fechamento ausente" + +#, fuzzy +msgid "Code battle" +msgstr "Batalha de código" + +msgid "Code battles" +msgstr "Batalhas de código" + +msgid "Code battles\\Program your robot to be the best of them all!" +msgstr "Batalhas de código\\Programe seu robô para ser o melhor de todos!" + +msgid "Colobot rules!" +msgstr "Regras Colobot!" + +msgid "Colobot: Gold Edition" +msgstr "Colobot: Edição de ouro" + +msgid "Command line" +msgstr "Linha de comando" + +msgid "Compilation ok (0 errors)" +msgstr "Compilação ok (0 erros)" + +msgid "Compile" +msgstr "Compilar" + +msgid "Continue" +msgstr "Continuar" + +msgid "Continue\\Continue the current mission" +msgstr "Continuar\\Continua a missão atual" + +msgid "Controls\\Keyboard, joystick and mouse settings" +msgstr "Controles\\Configurações de teclado, mouse e controles" + +msgid "Converts ore to titanium" +msgstr "Converter minério para titânio" + +msgid "Copy" +msgstr "Copiar" + +msgid "Copy (Ctrl+C)" +msgstr "Copiar (Ctrl+C)" + +msgid "Current mission saved" +msgstr "Missão atual salva" + +msgid "Custom levels:" +msgstr "Níveis personalizados:" + +msgid "Custom levels\\Levels from mods created by the users" +msgstr "Níveis personalizados\\Níveis criados pelos usuários" + +msgid "Customize your appearance" +msgstr "Personalize sua aparência" + +msgid "Cut (Ctrl+X)" +msgstr "Recortar (Ctrl+X)" + +msgid "Defense tower" +msgstr "Torre de defesa" + +msgid "Delete mark" +msgstr "Excluir marca" + +msgid "Delete player\\Deletes the player from the list" +msgstr "Excluir jogador\\Exclui o jogador da lista" + +msgid "Delete\\Deletes the selected file" +msgstr "Excluir\\Exclui o arquivo selecionado" + +msgid "Derrick" +msgstr "Extrator" + +msgid "Descend\\Reduces the power of the jet" +msgstr "Descer\\Diminui o poder do jato" + +msgid "Destroy" +msgstr "Destruir" + +msgid "Destroy the building" +msgstr "Destroi a construção" + +msgid "Destroyer" +msgstr "Destruidor" + +msgid "Device\\Driver and resolution settings" +msgstr "Dispositivo\\Configurações de driver e resolução" + +msgid "Dividing by zero" +msgstr "Dividindo por zero" + +msgid "Do you really want to destroy the selected building?" +msgstr "Você realmente deseja destruir o prédio selecionado?" + +#, c-format +msgid "Do you want to delete %s's saved games?" +msgstr "Você quer deletar os %'s jogos salvos?" + +msgid "Doors blocked by a robot or another object" +msgstr "Portas bloqueadas por um robô ou outro objeto" + +msgid "Down (\\key gdown;)" +msgstr "Baixo (\\key gdown;)" + +msgid "Drawer bot" +msgstr "Robô cartoonista" + +msgid "Dust\\Dust and dirt on bots and buildings" +msgstr "Poeira\\Poeira e sujeira nos robôs e prédios" + +msgid "Dynamic lighting\\Mobile light sources" +msgstr "Iluminação dinâmica\\Fontes móveis de luz" + +msgid "Dynamic shadows ++\\Dynamic shadows + self shadowing" +msgstr "Sombras dinâmicas ++\\Sombras dinâmicas + auto-sombreamento" + +msgid "Dynamic shadows\\Beautiful shadows!" +msgstr "Sombras dinâmicas\\Sombras magníficas!" + +msgid "Edit the selected program" +msgstr "Alterar o programa selecionado" + +msgid "Egg" +msgstr "Ovo" + +msgid "End of block missing" +msgstr "Fim do bloco ausente" + +msgid "Energy deposit (site for power station)" +msgstr "Depósito de energia (local para estação de energia)" + +msgid "Energy level" +msgstr "Nível de energia" + +msgid "Engineer" +msgstr "Engenheiro" + +msgid "Error in instruction move" +msgstr "Deslocamento impossível" + +msgid "Execute the selected program" +msgstr "Execute o programa selecionado" + +msgid "Execute/stop" +msgstr "Executar/Parar" + +msgid "Exercises in the chapter:" +msgstr "Lista de exercícios do capítulo:" + +msgid "Exercises\\Programming exercises" +msgstr "Exercícios\\Exercícios de programação" + +msgid "Explode (\\key action;)" +msgstr "Explodir (\\key action;)" + +msgid "Explosive" +msgstr "Explosivo" + +msgid "Expression expected after =" +msgstr "Expressão experada após =" + +msgid "Extend shield (\\key action;)" +msgstr "Estender escudo (\\key action;)" + +msgid "Eyeglasses:" +msgstr "Óculos:" + +msgid "Face type:" +msgstr "Tipo de face:" + +msgid "File not open" +msgstr "Arquivo não aberto" + +msgid "Filename:" +msgstr "Nome do arquivo:" + +msgid "Film sequences\\Films before and after the missions" +msgstr "Filmes de sequência\\Filmes antes de depois das missões" + +msgid "Finish" +msgstr "Finalizar" + +msgid "Fixed mine" +msgstr "Mina fixa" + +msgid "Flat ground not large enough" +msgstr "Terra plana não larga o suficiente" + +msgid "Fog\\Fog" +msgstr "Neblina\\Neblina" + +msgid "Folder:" +msgstr "Pasta:" + +#, c-format +msgid "Folder: %s" +msgstr "Pasta: %s" + +msgid "Font size" +msgstr "Tamanho da fonte" + +msgid "Forward" +msgstr "Avançar" + +msgid "Forward (\\key up;)" +msgstr "Avançar (\\key up;)" + +msgid "Forward\\Moves forward" +msgstr "Avançar\\Move para frente" + +msgid "Found a site for a derrick" +msgstr "Encontrou um local para o extrator" + +msgid "Found a site for power station" +msgstr "Encontrou um local para um estação de energia" + +msgid "Found key A (site for derrick)" +msgstr "Encontrou uma chave A (local para extrator)" + +msgid "Found key B (site for derrick)" +msgstr "Encontrou uma chave B (local para extrator)" + +msgid "Found key C (site for derrick)" +msgstr "Encontrou uma chave C (local para extrator)" + +msgid "Found key D (site for derrick)" +msgstr "Encontrou uma chave D (local para extrator)" + +msgid "Free game" +msgstr "Jogo livre" + +msgid "Free game on this planet:" +msgstr "Logo livre neste planeta:" + +msgid "Free game\\Free game without a specific goal" +msgstr "Jogo livre\\Jogo livre sem um objetivo específico" + +msgid "Full screen\\Full screen or window mode" +msgstr "Tela cheia\\Tela cheia ou modo janela" + +msgid "Function already exists" +msgstr "Função já existe" + +msgid "Function name missing" +msgstr "Falta o nome da função" + +msgid "Function needs return type \"void\"" +msgstr "Função precisa de um tipo de retorno \"void\"" + +msgid "Game speed" +msgstr "Velocidade do jogo" + +msgid "Game\\Game settings" +msgstr "Jogo\\Opções de jogabilidade" + +msgid "Gantry crane" +msgstr "Guindaste pórtico" + +msgid "Generating" +msgstr "Gerando" + +msgid "Gold Edition development by:" +msgstr "Versão de ouro desenvolvida por:" + +msgid "Goto: destination occupied" +msgstr "Vá para: destino ocupado" + +msgid "Goto: inaccessible destination" +msgstr "Vá para: destino inacessível" + +msgid "Grab or drop (\\key action;)" +msgstr "Pegar ou soltar (\\key action;)" + +msgid "Graphics\\Graphics settings" +msgstr "Gráficos\\Opções gráficas" + +msgid "Green" +msgstr "Verde" + +msgid "Green flag" +msgstr "Bandeira verde" + +msgid "Ground not flat enough" +msgstr "Chão não plano o suficiente" + +msgid "Hair color:" +msgstr "Cor do cabelo:" + +msgid "Head\\Face and hair" +msgstr "Cabeça\\Face e cabelo" + +msgid "Help about selected object" +msgstr "Ajuda sobre o objeto selecionado" + +msgid "Help balloons\\Explain the function of the buttons" +msgstr "Balões de ajuda\\Explica a função dos botões" + +msgid "Hex value out of range" +msgstr "Valor hexadecimal fora de alcance" + +#, fuzzy +msgid "Higher speed\\Doubles speed" +msgstr "Alta velocidade\\Dobra a velocidade" + +msgid "Highest\\Highest graphic quality (lowest frame rate)" +msgstr "Elevado\\Alta qualidade gráfica (baixa taxa de quadros)" + +msgid "Home" +msgstr "Início" + +msgid "Houston Mission Control" +msgstr "Centro de controle de missões Houston" + +msgid "Illegal object" +msgstr "Objeto inacessível" + +msgid "Impossible under water" +msgstr "Impossível debaixo d'água" + +msgid "Impossible when carrying an object" +msgstr "Impossível enquanto carregando um objeto" + +msgid "Impossible when flying" +msgstr "Impossível enquanto voando" + +msgid "Impossible when moving" +msgstr "Impossível enquanto movendo" + +msgid "Impossible when swimming" +msgstr "Impossível enquanto nadando" + +msgid "Inappropriate bot" +msgstr "Robô inapropriado" + +msgid "Inappropriate cell type" +msgstr "Tipo de célula inapropriada" + +msgid "Inappropriate object" +msgstr "Objeto inapropiado" + +msgid "Incorrect index type" +msgstr "Tipo de índice inválido" + +msgid "Infected by a virus; temporarily out of order" +msgstr "Infectado por vírus; temporariamento fora de serviço" + +msgid "Information exchange post" +msgstr "Posto de troca de informação" + +msgid "Instruction \"break\" outside a loop" +msgstr "Intrução \"break\" fora de um laço" + +msgid "Instruction \"case\" missing" +msgstr "Instrução \"case\" faltando" + +msgid "Instruction \"case\" outside a block \"switch\"" +msgstr "Instrução \"case\" fora de um bloco \"switch\"" + +msgid "Instruction \"else\" without corresponding \"if\"" +msgstr "Instrução \"else\" sem o \"if\" correspondente" + +msgid "Instructions (\\key help;)" +msgstr "Instruções (\\key help;)" + +msgid "Instructions after the final closing brace" +msgstr "Instruções depois do último colchete de fechamento" + +msgid "Instructions for the mission (\\key help;)" +msgstr "Instruções para a missão (\\key help;)" + +msgid "Instructions from Houston" +msgstr "Instruções de Houston" + +msgid "Instructions\\Shows the instructions for the current mission" +msgstr "Instruções\\Mostra as instruções para a missão atual" + +msgid "Internal error - tell the developers" +msgstr "Erro interno - contacte os desenvolvedores" + +msgid "Invalid universal character name" +msgstr "Nome de carácter universal inválido" + +msgid "Invert\\Invert values on this axis" +msgstr "Inverter\\Inverte os valores neste eixo" + +msgid "Jet temperature" +msgstr "Temperatura do jato" + +msgid "Key A" +msgstr "Tecla A" + +msgid "Key B" +msgstr "Tecla B" + +msgid "Key C" +msgstr "Tecla C" + +msgid "Key D" +msgstr "Tecla D" + +msgid "Keyword \"while\" missing" +msgstr "Palavra-chave \"while\" faltando" + +msgid "Keyword help(\\key cbot;)" +msgstr "Palavra-chave ajuda (\\key cbot;)" + +msgid "LOADING" +msgstr "CARREGANDO" + +msgid "Legged grabber" +msgstr "Agarrador com pernas" + +msgid "Legged orga shooter" +msgstr "Atirador orgânico com pernas" + +msgid "Legged shooter" +msgstr "Atirador com pernas" + +msgid "Legged sniffer" +msgstr "Farejador com pernas" + +msgid "Levels in this chapter:" +msgstr "Níveis neste capítulo:" + +msgid "Lightning conductor" +msgstr "Condutor elétrico" + +msgid "List of objects" +msgstr "Lista dos objetos" + +msgid "List of saved missions" +msgstr "Lista das missões salvas" + +msgid "Load a saved mission" +msgstr "Carregar uma missão salva" + +msgid "Load\\Load a saved mission" +msgstr "Carregar\\Carregar uma missão salva" + +msgid "Load\\Loads the selected mission" +msgstr "Carregar\\Carrega a missão selecionada" + +msgid "Loading basic level settings" +msgstr "Carregando configurações de nível básico" + +msgid "Loading finished!" +msgstr "Carregamento finalizado!" + +msgid "Loading music" +msgstr "Carregando música" + +msgid "Loading objects" +msgstr "Carregando objetos" + +msgid "Loading terrain" +msgstr "Carregando terreno" + +# msgid "Speed 0.5x\\Half speed" +# msgstr "" +# msgid "Speed 1.0x\\Normal speed" +# msgstr "" +# msgid "Speed 1.5x\\1.5 times faster" +# msgstr "" +# msgid "Speed 2.0x\\Double speed" +# msgstr "" +# msgid "Speed 3.0x\\Triple speed" +# msgstr "" +# msgid "Speed 4.0x\\Quadruple speed" +# msgstr "" +# msgid "Speed 6.0x\\Sextuple speed" +# msgstr "" +msgid "Lower speed\\Decrease speed by half" +msgstr "Velocidade baixa\\Diminuir velocidade pela metade" + +msgid "Lowest\\Minimum graphic quality (highest frame rate)" +msgstr "Mínimo\\Qualidade gráfica mínima (alta taxa de quadros)" + +msgid "Lunar Roving Vehicle" +msgstr "Veículo rotativo Lunar" + +msgid "MSAA\\Multisample anti-aliasing" +msgstr "MSAA\\Antisserrilhamento multiamostragem" + +msgid "Maximize" +msgstr "Maximizar" + +msgid "Minimize" +msgstr "Minimizar" + +msgid "Mipmap level\\Mipmap level" +msgstr "Nível do mini-mapa\\Nível do mini-mapa" + +msgid "Missing end quote" +msgstr "Aspas de fechamento ausentes" + +msgid "Missing hex digits after escape sequence" +msgstr "Digitos hexademais ausentes após sequência de escape" + +msgid "Mission name" +msgstr "Nome da missão" + +msgid "Missions" +msgstr "Missões" + +msgid "Missions on this planet:" +msgstr "Lista de missões neste planeta:" + +msgid "Missions\\Select mission" +msgstr "Missões\\Selecione uma missão" + +msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis" +msgstr "Inversão de mouse X\\Inverte a direção da rolagem no eixo X" + +msgid "Mouse inversion Y\\Inversion of the scrolling direction on the Y axis" +msgstr "Inversão de mouse Y\\Inverte a direção da rolagem no eixo Y" + +msgid "Move selected program down" +msgstr "Move o programa selecionado para baixo" + +msgid "Move selected program up" +msgstr "Move o programa selecionado para cima" + +msgid "Mute\\No sound" +msgstr "Mudo\\Sem som" + +msgid "Name:" +msgstr "Nome:" + +msgid "Negative value rejected by \"throw\"" +msgstr "Valor negativo rejeitado por \"throw\"" + +msgid "Nest" +msgstr "Ninho" + +msgid "New" +msgstr "Novo" + +msgid "New ..." +msgstr "Novo ..." + +msgid "New bot available" +msgstr "Novo robô disponível" + +msgid "Next" +msgstr "Próximo" + +msgid "Next object\\Selects the next object" +msgstr "Próximo objeto\\Selecionar o próximo objeto" + +msgid "No" +msgstr "Não" + +msgid "No energy in the subsoil" +msgstr "Nenhuma energia no subsolo" + +msgid "No flag nearby" +msgstr "Nenhuma bandeira próxima" + +msgid "No function running" +msgstr "Nenhuma função executando" + +msgid "No function with this name accepts this kind of parameter" +msgstr "Nenhuma função com este nome aceita este tipo de parâmetro" + +msgid "No function with this name accepts this number of parameters" +msgstr "Nenhuma função com este nome aceita este número de parâmetros" + +msgid "No information exchange post within range" +msgstr "Nenhum posto de troca de informação ao alcance" + +msgid "No more energy" +msgstr "Não há mais energia" + +msgid "No ore in the subsoil" +msgstr "Nenhum mineral no subsolo" + +msgid "No power cell" +msgstr "Sem célula de energia" + +msgid "No titanium" +msgstr "Sem titânio" + +msgid "No titanium around" +msgstr "Nenhum titânio ao redor" + +msgid "No titanium ore to convert" +msgstr "Sem minério de titânio para converter" + +msgid "No titanium to transform" +msgstr "Nenhum titânio para transformar" + +msgid "No uranium to transform" +msgstr "Nenhum urânio para transformar" + +msgid "No userlevels installed!" +msgstr "Nenhum nível de usuário instalado!" + +msgid "Non-void function needs \"return;\"" +msgstr "Funções não void precisam de \"return;\"" + +msgid "Normal size" +msgstr "Tamanho normal" + +msgid "Normal\\Normal graphic quality" +msgstr "Normal\\Qualidade gráfica normal" + +msgid "Normal\\Normal sound volume" +msgstr "Normal\\Volume de som normal" + +msgid "Not enough energy" +msgstr "Sem energia suficiente" + +msgid "Not enough energy yet" +msgstr "Ainda sem energia suficiente" + +msgid "Not found anything to destroy" +msgstr "Não encontrou nada para destruir" + +msgid "Nothing to analyze" +msgstr "Nada para analisar" + +msgid "Nothing to drop" +msgstr "Nada para largar" + +msgid "Nothing to grab" +msgstr "Nada para pegar" + +msgid "Nothing to recycle" +msgstr "Nada para reciclar" + +msgid "Nuclear power cell" +msgstr "Célula de energia núclear" + +msgid "Nuclear power cell available" +msgstr "Célula de energia núclear disponível" + +msgid "Nuclear power station" +msgstr "Estação de energia núclear" + +msgid "Number missing" +msgstr "Número ausente" + +msgid "Number of insects detected" +msgstr "Número de insetos detectados" + +msgid "Number of particles\\Explosions, dust, reflections, etc." +msgstr "Quantidade de particulas\\Explosões, poeira, reflexões, etc." + +msgid "OK" +msgstr "OK" + +msgid "OK\\Choose the selected player" +msgstr "OK\\Escolher o jogador selecionado" + +msgid "OK\\Close program editor and return to game" +msgstr "OK\\Fechar o editor e retornar ao jogo" + +msgid "Object too close" +msgstr "Objeto muito próximo" + +msgid "Octal value out of range" +msgstr "Valor octal fora do limite" + +msgid "One step" +msgstr "Um passo" + +msgid "Open" +msgstr "Abrir" + +msgid "Open (Ctrl+O)" +msgstr "Abrir (Ctrl+O)" + +msgid "Opening brace missing" +msgstr "Chave de abertura ausente" + +msgid "Opening bracket missing" +msgstr "Colchete de abertura ausente" + +msgid "Operation impossible with value \"nan\"" +msgstr "Operação impossível com o valor \"nan\"" + +msgid "Options" +msgstr "Opções" + +msgid "Options\\Preferences" +msgstr "Opções\\Preferências" + +msgid "Organic matter" +msgstr "Matéria orgânica" + +msgid "Origin of last message\\Shows where the last message was sent from" +msgstr "Origem da última mensagem\\Mostra de onde a última mensagem foi enviada" + +msgid "Original game developed by:" +msgstr "Jogo original desenvolvido por:" + +msgid "Parameters missing" +msgstr "Parâmetros ausentes" + +msgid "Particles in the interface\\Steam clouds and sparks in the interface" +msgstr "Partículas na interface\\Núvens de vapor e faíscas na interface" + +msgid "Paste (Ctrl+V)" +msgstr "Colar (Ctrl+V)" + +msgid "Pause blur\\Blur the background on the pause screen" +msgstr "Borrão de pausa\\Borra o fundo na tela de pausa" + +msgid "Pause in background\\Pause the game when the window is unfocused" +msgstr "Pausar quando em background\\Pausa o jogo quando a janela está sem foco" + +msgid "Pause/continue" +msgstr "Pausar/Continuar" + +msgid "Pause\\Pause the game without opening menu" +msgstr "Pausar\\Pausa o jogo sem abrir o menu" + +msgid "Phazer shooter" +msgstr "Atirador phazer" + +msgid "Photography" +msgstr "Fotografia" + +msgid "Place occupied" +msgstr "Local ocupado" + +msgid "Planets:" +msgstr "Planetas:" + +msgid "Plans for defense tower available" +msgstr "Planos para a torre de defesa disponíveis" + +msgid "Plans for nuclear power plant available" +msgstr "Planos para a planta nuclear disponíveis" + +msgid "Plans for phazer shooter available" +msgstr "Planos para o atirador phazer disponíveis" + +msgid "Plans for shielder available" +msgstr "Planos para o defensor disponíveis" + +msgid "Plans for shooter available" +msgstr "Planos para o atirador disponíveis" + +msgid "Plans for thumper available" +msgstr "Planos para o batedor disponíveis" + +msgid "Plans for tracked robots available" +msgstr "Planos para robôs com esteiras disponíveis" + +msgid "Plant a flag" +msgstr "Colocar uma bandeira" + +msgid "Play\\Start mission!" +msgstr "Jogar\\Iniciar missão!" + +msgid "Player" +msgstr "Jogador" + +msgid "Player name" +msgstr "Nome do jogador" + +msgid "Player's name" +msgstr "Nome dos jogadores" + +msgid "Power cell" +msgstr "Célula de energia" + +msgid "Power cell available" +msgstr "Célula de energia disponível" + +msgid "Power cell factory" +msgstr "Fábrica de células de energia" + +msgid "Power station" +msgstr "Estação de energia" + +msgid "Practice bot" +msgstr "Robô de prática" + +msgid "Press \\key help; to read instructions on your SatCom" +msgstr "Pressione \\key help; para ler as intruções no seu SatCom" + +msgid "Previous" +msgstr "Anterior" + +msgid "Previous object\\Selects the previous object" +msgstr "Objeto anterior\\Seleciona o objeto anterior" + +msgid "Previous selection (\\key desel;)" +msgstr "Seleção anterior (\\key desel;)" + +msgid "Private element" +msgstr "Elemento privado" + +msgid "Private\\Private folder" +msgstr "Privado\\Pasta privada" + +msgid "Processing level file" +msgstr "Processando o arquivo de nível" + +msgid "Program cloned" +msgstr "Programa clonado" + +msgid "Program editor" +msgstr "Editor" + +msgid "Program finished" +msgstr "Programa finalizado" + +msgid "Program infected by a virus" +msgstr "Programa infectado por vírus" + +msgid "Programming exercises" +msgstr "Exercícios de programação" + +msgid "Programming help" +msgstr "Ajuda de programação" + +msgid "Programming help (\\key prog;)" +msgstr "Ajuda de programação (\\key prog;)" + +msgid "Programming help\\Gives more detailed help with programming" +msgstr "Ajuda de programação\\Fornece uma ajuda mais detalhada sobre programação" + +msgid "Programs dispatched by Houston" +msgstr "Programas enviados por Houston" + +msgid "Public required" +msgstr "Necessário público" + +msgid "Public\\Common folder" +msgstr "Público\\Pasta comum" + +msgid "Quake at explosions\\The screen shakes at explosions" +msgstr "Tremer em explosões\\A tela sacode em explosões" + +msgid "Quick load\\Immediately load game" +msgstr "Carregando rápido\\Imediatamente carrega o jogo" + +msgid "Quick save\\Immediately save game" +msgstr "Salvamento rápido\\Imediatamente salva o jogo" + +#, fuzzy +msgid "Quicksave slot not found" +msgstr "Slot para salvamento rápido não encontrado" + +msgid "Quit\\Quit Colobot: Gold Edition" +msgstr "Sair\\Fecha Colobot: ediçao de ouro" + +msgid "Quit\\Quit the current mission or exercise" +msgstr "Sair\\Termina a missão atual ou exercício" + +msgid "Radar station" +msgstr "Estação de radar" + +msgid "Read error" +msgstr "Erro de leitura" + +msgid "Recorder" +msgstr "Gravador" + +msgid "Recycle (\\key action;)" +msgstr "Reciclar (\\key action;)" + +msgid "Recycler" +msgstr "Reciclador" + +msgid "Red" +msgstr "Vermelho" + +msgid "Red flag" +msgstr "Bandeira vermelha" + +msgid "Reflections on the buttons \\Shiny buttons" +msgstr "Reflexões nos botões\\Botões brilhantes" + +msgid "Remains of Apollo mission" +msgstr "Restos da missão Apollo" + +msgid "Remove a flag" +msgstr "Remover a bandeira" + +msgid "Remove selected program" +msgstr "Remover o programa selecionado" + +msgid "Render distance\\Maximum visibility" +msgstr "Distância de renderização\\Visibilidade máxima" + +msgid "Repair center" +msgstr "Centro de reparos" + +msgid "Research center" +msgstr "Centro de pesquisa" + +msgid "Research program already performed" +msgstr "Programa de pesquisa já realizado" + +msgid "Research program completed" +msgstr "Programa de pesquisa completado" + +msgid "Reserved keyword of CBOT language" +msgstr "Palavra-chave reservada para a linguagem CBOT" + +msgid "Resolution" +msgstr "Resolução" + +msgid "Resolution:" +msgstr "Resolução:" + +msgid "Resources" +msgstr "Recursos" + +msgid "Restart\\Restart the mission from the beginning" +msgstr "Reiniciar\\Reinicia a missão do começo" + +msgid "Restoring CBot execution state" +msgstr "Restaura o estado de execução do CBot" + +msgid "Restoring saved objects" +msgstr "Restaurando objetos salvos" + +msgid "Results" +msgstr "Resultados" + +msgid "Return to start" +msgstr "Retornar para o início" + +msgid "Robbie" +msgstr "Robbie" + +msgid "Ruin" +msgstr "Ruína" + +msgid "Run research program for defense tower" +msgstr "Executar programa de pesquisa para torre de defesa" + +msgid "Run research program for legged bots" +msgstr "Executar programa de pesquisa para robôs com pernas" + +msgid "Run research program for nuclear power" +msgstr "Executar programa de pesquisa para energia nuclear" + +msgid "Run research program for orga shooter" +msgstr "Executar programa de pesquisa para atirador orgânico" + +msgid "Run research program for phazer shooter" +msgstr "Executar programa de pesquisa para atirador phazer" + +msgid "Run research program for shielder" +msgstr "Executar programa de pesquisa para defensor" + +msgid "Run research program for shooter" +msgstr "Executar programa de pesquisa para atirador" + +msgid "Run research program for thumper" +msgstr "Executar programa de pesquisa para batedor" + +msgid "Run research program for tracked bots" +msgstr "Executar programa de pesquisa para robôs com esteira" + +msgid "Run research program for winged bots" +msgstr "Executar programa de pesquisa para robôs alados" + +msgid "SatCom" +msgstr "SatCom" + +msgid "Satellite report" +msgstr "Relatório do satélite" + +msgid "Save" +msgstr "Salvar" + +msgid "Save (Ctrl+S)" +msgstr "Salvar (Ctrl+S)" + +msgid "Save the current mission" +msgstr "Salve a missão atual" + +msgid "Save\\Save the current mission" +msgstr "Salvar\\Salve a missão atual" + +msgid "Save\\Saves the current mission" +msgstr "Salvar\\Salva a missão atual" + +msgid "Select the astronaut\\Selects the astronaut" +msgstr "Selecione o astronauta\\Seleciona o astronauta" + +msgid "Semicolon terminator missing" +msgstr "Falta o terminador ponto e vírgula" + +msgid "Shadow resolution\\Higher means better range and quality, but slower" +msgstr "Resolução das sombras\\Valores altos significam alcance e qualidade melhores, porém mais devagar" + +msgid "Shield level" +msgstr "Nível de escudo" + +msgid "Shield radius" +msgstr "Raio do escudo" + +msgid "Shielder" +msgstr "Defensor" + +msgid "Shoot (\\key action;)" +msgstr "Atirar (\\key action;)" + +msgid "Show if the ground is flat" +msgstr "Mostre se o solo é plano" + +msgid "Show the place" +msgstr "Mostre o local" + +msgid "Show the range" +msgstr "Mostre o alcance" + +msgid "Show the solution" +msgstr "Mostre a solução" + +msgid "Sign \" : \" missing" +msgstr "Sinal \" : \" ausente" + +msgid "Simple shadows\\Shadows spots on the ground" +msgstr "Sombras simples\\Pontos de sombra no chão" + +msgid "Size 1" +msgstr "Tamanho 1" + +msgid "Size 2" +msgstr "Tamanho 2" + +msgid "Size 3" +msgstr "Tamanho 3" + +msgid "Size 4" +msgstr "Tamanho 4" + +msgid "Size 5" +msgstr "Tamanho 5" + +msgid "Sniff (\\key action;)" +msgstr "Farejar (\\key action;)" + +msgid "Solution" +msgstr "Solução" + +msgid "Sound effects:\\Volume of engines, voice, shooting, etc." +msgstr "Efeitos sonoros:\\Volume dos motores, voz, tiros, etc." + +msgid "Sound\\Music and game sound volume" +msgstr "Som\\Volume do som das músicas e do jogo" + +msgid "Spaceship" +msgstr "Nave espacial" + +msgid "Spaceship ruin" +msgstr "Ruína de nave espacial" + +msgid "Spider" +msgstr "Aranha" + +msgid "Spider fatally wounded" +msgstr "Aranha fatalmente ferida" + +msgid "Stack overflow" +msgstr "Estouro de pilha" + +msgid "Standard action\\Standard action of the bot (take/grab, shoot, sniff, etc)" +msgstr "Ação padrão\\Ação padrão do robô (pegar/agarrar, atirar, farejar, etc)" + +msgid "Standard controls\\Standard key functions" +msgstr "Controles padrões\\Funções padrões das teclas" + +msgid "Standard speed\\Reset speed to normal" +msgstr "Velocidade padrão\\Reiniciar a velocidade para o normal" + +msgid "Standard\\Standard appearance settings" +msgstr "Padrão\\Configurações de aparência padrão" + +msgid "Start" +msgstr "Iniciar" + +msgid "Starting..." +msgstr "Iniciando..." + +msgid "Still working ..." +msgstr "Ainda trabalhando ..." + +msgid "String missing" +msgstr "Carácteres ausentes" + +msgid "Strip color:" +msgstr "Cor da tira:" + +msgid "Subber" +msgstr "Mergulhador" + +msgid "Suit color:" +msgstr "Cor do traje:" + +msgid "Suit\\Astronaut suit" +msgstr "Traje\\Traje de astronauta" + +msgid "Summary:" +msgstr "Sumário:" + +msgid "Survival kit" +msgstr "Kit de sobrevivência" + +msgid "Switch bots <-> buildings" +msgstr "Trocar robôs <-> prédios" + +msgid "Take off to finish the mission" +msgstr "Decole para finalizar a missão" + +msgid "Target" +msgstr "Alvo" + +msgid "Target bot" +msgstr "Robô alvo" + +msgid "Terrain relief" +msgstr "Relevo do terreno" + +msgid "Texture filtering\\Texture filtering" +msgstr "Filtragem de textura\\Filtragem de textura" + +msgid "Textures" +msgstr "Texturas" + +msgid "The battle has ended" +msgstr "A batalha acabou" + +msgid "The expression must return a boolean value" +msgstr "A expressão deve retornar um valor booleano" + +msgid "The function returned no value" +msgstr "A função não retornou nenhum valor" + +msgid "The mission is not accomplished yet (press \\key help; for more details)" +msgstr "A missão não foi completada ainda (pressione \\key help; para mais detalhes)" + +msgid "The types of the two operands are incompatible" +msgstr "Os tipos dos dois operandos são incompativeis" + +msgid "This class already exists" +msgstr "Esta classe já existe" + +msgid "This class does not exist" +msgstr "Esta classe não existe" + +msgid "This is example code that cannot be run directly" +msgstr "Este é um código de exemplo que não pode ser executado diretamente" + +msgid "This is not a member of this class" +msgstr "Este não é um membro desta classe" + +msgid "This label does not exist" +msgstr "Este rótulo não existe" + +msgid "This menu is for userlevels from mods, but you didn't install any" +msgstr "Este menu é para níveis de usuários, mas você não instalou nenhum." + +msgid "This object is currently busy" +msgstr "Este objeto está ocupado atualmente" + +msgid "This object is not a member of a class" +msgstr "Este objeto não é um membro de uma classe" + +msgid "This parameter needs a default value" +msgstr "Este parâmetro necessita de um valor padrão" + +msgid "This program is read-only, clone it to edit" +msgstr "Este programa é somente-leitura, clone-o para edita-lo" + +msgid "Thump (\\key action;)" +msgstr "Bater (\\key action;)" + +msgid "Thumper" +msgstr "Batedor" + +#, c-format +msgid "Time: %s" +msgstr "Tempo: %s" + +msgid "Titanium" +msgstr "Titânio" + +msgid "Titanium available" +msgstr "Titânio disponível" + +msgid "Titanium deposit (site for derrick)" +msgstr "Depósito de titânio (local para extrator)" + +msgid "Titanium ore" +msgstr "Mineral de titânio" + +msgid "Titanium too close" +msgstr "Titânio muito perto" + +msgid "Titanium too far away" +msgstr "Titânio muito longe" + +msgid "Too close to a building" +msgstr "Muito perto de um prédio" + +msgid "Too close to an existing flag" +msgstr "Muito perto de uma bandeira" + +msgid "Too close to space ship" +msgstr "Muito perto da nave espacial" + +msgid "Too many flags of this color (maximum 5)" +msgstr "Muitas bandeiras dessa cor (máximo 5)" + +msgid "Too many parameters" +msgstr "Muitos parâmetros" + +msgid "Tracked grabber" +msgstr "Pegador com esteiras" + +msgid "Tracked orga shooter" +msgstr "Atirador orgânico com esteiras" + +msgid "Tracked shooter" +msgstr "Atirador com esteiras" + +msgid "Tracked sniffer" +msgstr "Farejador com esteiras" + +msgid "Transforms only titanium" +msgstr "Transformar somente titânio" + +msgid "Transforms only uranium" +msgstr "Transformar somente urânio" + +msgid "Transmitted information" +msgstr "Informação transmitida" + +msgid "Turn left (\\key left;)" +msgstr "Vire a esquerda (\\key left;)" + +msgid "Turn left\\turns the bot to the left" +msgstr "Vire a esquerda\\vira o robô para a esquerda" + +msgid "Turn right (\\key right;)" +msgstr "Vire a direita (\\key right;)" + +msgid "Turn right\\turns the bot to the right" +msgstr "Vire a direita\\vira o robô para a direita" + +msgid "Type declaration missing" +msgstr "Declaração de tipo ausente" + +msgid "Unable to control enemy objects" +msgstr "Impossível controlar objetos inimigos" + +msgid "Undo (Ctrl+Z)" +msgstr "Desfazer (Ctrl+Z)" + +msgid "Unit" +msgstr "Unidade" + +msgid "Unknown Object" +msgstr "Objeto desconhecido" + +msgid "Unknown command" +msgstr "Comando desconhecido" + +msgid "Unknown escape sequence" +msgstr "Sequência de escape desconhecidade" + +msgid "Unknown function" +msgstr "Função desconhecida" + +msgid "Up (\\key gup;)" +msgstr "Cima (\\key gup;)" + +msgid "Uranium deposit (site for derrick)" +msgstr "Depósito de urânio (local para extrator)" + +msgid "Uranium ore" +msgstr "Mineral de urânio" + +msgid "User levels" +msgstr "Níveis de usuário" + +msgid "Variable name missing" +msgstr "Nome de variável ausente" + +msgid "Variable not declared" +msgstr "Variável não declarada" + +msgid "Variable not initialized" +msgstr "Variável não inicializada" + +msgid "Vault" +msgstr "Cofre" + +msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency" +msgstr "" + +msgid "Violet flag" +msgstr "Bandeira violeta" + +msgid "Void parameter" +msgstr "Parâmetro vazio" + +msgid "Wasp" +msgstr "Vespa" + +msgid "Wasp fatally wounded" +msgstr "Vespa fatalmente ferida" + +msgid "Waste" +msgstr "Desperdício" + +msgid "Wheeled grabber" +msgstr "Agarrador com rodas" + +msgid "Wheeled orga shooter" +msgstr "Atirador orgânico com rodas" + +msgid "Wheeled shooter" +msgstr "Atirador com rodas" + +msgid "Wheeled sniffer" +msgstr "Farejador com rodas" + +msgid "Winged grabber" +msgstr "Agarrador alado" + +msgid "Winged orga shooter" +msgstr "Atirador orgânico alado" + +msgid "Winged shooter" +msgstr "Atirador alado" + +msgid "Winged sniffer" +msgstr "Farejador alado" + +msgid "Withdraw shield (\\key action;)" +msgstr "Retirar escudo (\\key action;)" + +msgid "Worm" +msgstr "Verme" + +msgid "Worm fatally wounded" +msgstr "Verme fatalmente ferido" + +msgid "Wreckage" +msgstr "Destroços" + +msgid "Write error" +msgstr "Erro de escrita" + +msgid "Wrong type for the assignment" +msgstr "Tipo errado para a tarefa" + +msgid "Yellow flag" +msgstr "Bandeira amarela" + +msgid "Yes" +msgstr "Sim" + +msgid "You can fly with the keys (\\key gup;) and (\\key gdown;)" +msgstr "Você pode voar com as teclas (\\key gup;) e (\\key gdown;)" + +msgid "You can not carry a radioactive object" +msgstr "Você não pode carregar um objeto radioativo" + +msgid "You can not carry an object under water" +msgstr "Você não pode carregar um objeto debaixo d'água" + +#, c-format +msgid "You cannot use \"%s\" in this exercise (used: %d)" +msgstr "Você não pode usar \"%s\" neste exercício (usado: %d)" + +msgid "You found a usable object" +msgstr "Você encontrou um objeto utilizável" + +#, c-format +msgid "You have to use \"%1$s\" at least once in this exercise (used: %2$d)" +msgid_plural "You have to use \"%1$s\" at least %3$d times in this exercise (used: %2$d)" +msgstr[0] "Você deve usar \"%1$s\" pelo menos uma vez neste exercício (usado: %2$d)" +msgstr[1] "Você deve usar \"%1$s\" pelo menos %3$d vezes neste exercício (usado: %2$d)" + +#, c-format +msgid "You have to use \"%1$s\" at most once in this exercise (used: %2$d)" +msgid_plural "You have to use \"%1$s\" at most %3$d times in this exercise (used: %2$d)" +msgstr[0] "Você deve usar \"%1$s\" pelo menos uma vez neste exercício (usado: %2$d)" +msgstr[1] "Você deve usar \"%1$s\" pelo menos %3$d vezes neste exercício (usado: %2$d)" + +msgid "You must get on the spaceship to take off" +msgstr "Você deve estar na nave espacial para decolar" + +msgid "Zoom mini-map" +msgstr "Zoom no mini-mapa" + +msgid "\\Blue flags" +msgstr "\\Bandeiras azuis" + +msgid "\\Eyeglasses 1" +msgstr "\\Óculos 1" + +msgid "\\Eyeglasses 2" +msgstr "\\Óculos 2" + +msgid "\\Eyeglasses 3" +msgstr "\\Óculos 3" + +msgid "\\Eyeglasses 4" +msgstr "\\Óculos 4" + +msgid "\\Eyeglasses 5" +msgstr "\\Óculos 5" + +msgid "\\Face 1" +msgstr "\\Face 1" + +msgid "\\Face 2" +msgstr "\\Face 2" + +msgid "\\Face 3" +msgstr "\\Face 3" + +msgid "\\Face 4" +msgstr "\\Face 4" + +msgid "\\Green flags" +msgstr "\\Bandeiras verdes" + +msgid "\\New player name" +msgstr "\\Nome do novo jogador" + +msgid "\\No eyeglasses" +msgstr "\\Sem óculos" + +msgid "\\Raise the pencil" +msgstr "\\Levante o lápis" + +msgid "\\Red flags" +msgstr "\\Bandeiras vermelhas" + +msgid "\\Return to Colobot: Gold Edition" +msgstr "\\Voltar a Colobot: edição de ouro" + +msgid "\\SatCom on standby" +msgstr "\\SatCom em espera" + +msgid "\\Start recording" +msgstr "\\Iniciar gravação" + +msgid "\\Stop recording" +msgstr "\\Parar gravação" + +msgid "\\Turn left" +msgstr "\\Virar a esquerda" + +msgid "\\Turn right" +msgstr "\\Virar a direita" + +msgid "\\Use the black pencil" +msgstr "\\Use o lápis preto" + +msgid "\\Use the blue pencil" +msgstr "\\Use o lápis azul" + +msgid "\\Use the brown pencil" +msgstr "\\Use o lápis marrom" + +msgid "\\Use the green pencil" +msgstr "\\Use o lápis verde" + +msgid "\\Use the orange pencil" +msgstr "\\Use o lápis laranja" + +msgid "\\Use the purple pencil" +msgstr "\\Use o lápis roxo" + +msgid "\\Use the red pencil" +msgstr "\\Use o lápis vermelho" + +msgid "\\Use the yellow pencil" +msgstr "\\Use o lápis amarelo" + +msgid "\\Violet flags" +msgstr "\\Bandeiras violetas" + +msgid "\\Yellow flags" +msgstr "\\Bandeiras amarelas" + +msgid "colobot.info" +msgstr "colobot.info" + +msgid "epsitec.com" +msgstr "epsitec.com" + +#~ msgid " " +#~ msgstr " " + +#~ msgid " Drivers:" +#~ msgstr " Pilotes :" + +#~ msgid " Missions on this level:" +#~ msgstr " Missions du niveau :" + +#~ msgid "\"%s\" missing in this exercise" +#~ msgstr "Il manque \"%s\" dans le programme" + +#~ msgid "3D sound\\3D positioning of the sound" +#~ msgstr "Bruitages 3D\\Positionnement sonore dans l'espace" + +#~ msgid "Building too close" +#~ msgstr "Bâtiment trop proche" + +#~ msgid "COLOBOT" +#~ msgstr "COLOBOT" + +#~ msgid "Camera awayest" +#~ msgstr "Caméra plus loin" + +#~ msgid "Camera down\\Decrease camera angle while visiting message origin" +#~ msgstr "Caméra plus basse\\Réduit l'angle de caméra lors de la vue de l'origine des messages" + +#~ msgid "Camera nearest" +#~ msgstr "Caméra plus proche" + +#~ msgid "Camera to left" +#~ msgstr "Caméra à gauche" + +#~ msgid "Camera to right" +#~ msgstr "Caméra à droite" + +#~ msgid "Camera up\\Increase camera angle while visiting message origin" +#~ msgstr "Caméra plus haute\\Augmente l'angle de caméra lors de la vue de l'origine des messages" + +#~ msgid "Can not create this; there are too many objects" +#~ msgstr "Création impossible; il y a trop d'objets" + +#~ msgid "Cancel\\Keep current player name" +#~ msgstr "Annuler\\Conserver le joueur actuel" + +#~ msgid "Checkpoint crossed" +#~ msgstr "Indicateur atteint" + +#~ msgid "Compass" +#~ msgstr "Boussole" + +#~ msgid "Continue\\Continue the game" +#~ msgstr "Continuer\\Continuer de jouer" + +#~ msgid "Delete" +#~ msgstr "Détruire" + +#~ msgid "Details\\Visual quality of 3D objects" +#~ msgstr "Détails des objets\\Qualité des objets en 3D" + +#~ msgid "Developed by :" +#~ msgstr "Développé par :" + +#~ msgid "Do you want to quit Colobot: Gold Edition?" +#~ msgstr "Voulez-vous quitter Colobot: Édition Gold ?" + +#~ msgid "Exit film\\Film at the exit of exercises" +#~ msgstr "Retour animé\\Retour animé dans les exercices" + +#~ msgid "Friendly fire\\Your shooting can damage your own objects " +#~ msgstr "Dégâts à soi-même\\Vos tirs infligent des dommages à vos unités" + +#~ msgid "Ground inappropriate" +#~ msgstr "Terrain inadapté" + +#~ msgid "Key word help\\More detailed help about key words" +#~ msgstr "Instructions mot-clé\\Explication sur le mot-clé" + +#~ msgid "Marks on the ground\\Marks on the ground" +#~ msgstr "Marques sur le sol\\Marques dessinées sur le sol" + +#~ msgid "Mouse shadow\\Gives the mouse a shadow" +#~ msgstr "Souris ombrée\\Jolie souris avec une ombre" + +#~ msgid "No other robot" +#~ msgstr "Pas d'autre robot" + +#~ msgid "Not yet enough energy" +#~ msgstr "Pas encore assez d'énergie" + +#~ msgid "Num of decorative objects\\Number of purely ornamental objects" +#~ msgstr "Nb d'objets décoratifs\\Qualité d'objets non indispensables" + +#~ msgid "Planets and stars\\Astronomical objects in the sky" +#~ msgstr "Planètes et étoiles\\Motifs mobiles dans le ciel" + +#~ msgid "Quit the mission?" +#~ msgstr "Quitter la mission ?" + +#~ msgid "Quit\\Quit COLOBOT" +#~ msgstr "Quitter\\Quitter COLOBOT" + +#~ msgid "Robbie\\Your assistant" +#~ msgstr "Robbie\\Votre assistant" + +#~ msgid "Sky\\Clouds and nebulae" +#~ msgstr "Ciel\\Ciel et nuages" + +#~ msgid "Speed 0.5x\\Half speed" +#~ msgstr "Vitesse 0.5x\\Demi-vitesse" + +#~ msgid "Speed 1.0x\\Normal speed" +#~ msgstr "Vitesse 1.0x\\Vitesse normale" + +#~ msgid "Speed 1.5x\\1.5 times faster" +#~ msgstr "Vitesse 1.5x\\Une fois et demi plus rapide" + +#~ msgid "Speed 3.0x\\Three times faster" +#~ msgstr "Vitesse 3.0x\\Trois fois plus rapide" + +#~ msgid "Speed 3.0x\\Triple speed" +#~ msgstr "Vitesse 3.0x\\Trois fois plus rapide " + +#~ msgid "Speed 4.0x\\Quadruple speed" +#~ msgstr "Vitesse 4.0x\\Quatre fois plus rapide" + +#~ msgid "Speed 6.0x\\Sextuple speed" +#~ msgstr "Vitesse 6.0x\\Six fois plus rapide" + +#~ msgid "Sunbeams\\Sunbeams in the sky" +#~ msgstr "Rayons du soleil\\Rayons selon l'orientation" + +#~ msgid "System mouse\\Use system mouse cursor" +#~ msgstr "Souris système\\Utiliser le curseur de la souris système" + +#~ msgid "Textures\\Quality of textures " +#~ msgstr "Qualité des textures\\Qualité des images" + +#~ msgid "The list is only available if a \\l;radar station\\u object\\radar; is working.\n" +#~ msgstr "Liste non disponible sans \\l;radar\\u object\\radar;.\n" + +#~ msgid "Use a joystick\\Joystick or keyboard" +#~ msgstr "Utilise un joystick\\Joystick ou clavier" + +#~ msgid "User\\User levels" +#~ msgstr "Suppl.\\Niveaux supplémentaires" + +#~ msgid "\\Return to COLOBOT" +#~ msgstr "\\Retourner dans COLOBOT" + +#~ msgid "\\b;Aliens\n" +#~ msgstr "\\b;Listes des ennemis\n" + +#~ msgid "\\b;Buildings\n" +#~ msgstr "\\b;Listes des bâtiments\n" + +#~ msgid "\\b;Error\n" +#~ msgstr "\\b;Erreur\n" + +#~ msgid "\\b;List of objects\n" +#~ msgstr "\\b;Listes des objets\n" + +#~ msgid "\\b;Moveable objects\n" +#~ msgstr "\\b;Listes des objets transportables\n" + +#~ msgid "\\b;Robots\n" +#~ msgstr "\\b;Listes des robots\n" + +#~ msgid "\\c; (none)\\n;\n" +#~ msgstr "\\c; (aucun)\\n;\n" diff --git a/po/ru.po b/po/ru.po index 0763e742..ca44c0c5 100644 --- a/po/ru.po +++ b/po/ru.po @@ -1694,6 +1694,9 @@ msgstr "Переменная не инициализирована" msgid "Vault" msgstr "Хранилище" +msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency" +msgstr "" + msgid "Violet flag" msgstr "Фиолетовый флаг" diff --git a/src/CBot/CBotDebug.cpp b/src/CBot/CBotDebug.cpp index 892d1d0e..bef509b0 100644 --- a/src/CBot/CBotDebug.cpp +++ b/src/CBot/CBotDebug.cpp @@ -23,6 +23,7 @@ #include "CBot/CBotInstr/CBotFunction.h" #include "CBot/CBotInstr/CBotInstrCall.h" +#include #include #include #include diff --git a/src/CBot/CMakeLists.txt b/src/CBot/CMakeLists.txt index dcb39e1a..a9a83e2e 100644 --- a/src/CBot/CMakeLists.txt +++ b/src/CBot/CMakeLists.txt @@ -151,7 +151,12 @@ set(LOCAL_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/.. ) +set(SYSTEM_INCLUDES + ${Boost_INCLUDE_DIRS} +) + include_directories(${LOCAL_INCLUDES}) +include_directories(SYSTEM ${SYSTEM_INCLUDES}) if(CBOT_STATIC) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e0857506..c58172bd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,8 +44,51 @@ if(MXE) # MXE requires special treatment elseif(PLATFORM_WINDOWS) # because it isn't included in standard linking libraries if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - find_library(LIBINTL_LIBRARY NAMES intl.lib) - set(PLATFORM_LIBS ${LIBINTL_LIBRARY}) + find_library(LIBINTL_LIBRARY NAMES intl.lib libintl) + + if(${MSVC_STATIC}) + if (${OPENAL_SOUND}) + find_library(FLAC_LIBRARY NAMES flac.lib) + find_library(VORBIS_LIBRARY NAMES vorbis.lib) + find_library(VORBISENC_LIBRARY NAMES vorbisenc.lib) + find_library(OGG_LIBRARY NAMES ogg.lib) + set(OPENAL_MSVC_LIBS + ${FLAC_LIBRARY} + ${VORBIS_LIBRARY} + ${VORBISENC_LIBRARY} + ${OGG_LIBRARY} + ) + endif() + + find_library(BZ2_LIBRARY NAMES bz2.lib) + find_library(JPEG_LIBRARY NAMES jpeg.lib) + find_library(TIFF_LIBRARY NAMES tiff.lib) + find_library(WEBP_LIBRARY NAMES webp.lib) + find_library(LZMA_LIBRARY NAMES lzma.lib) + find_library(FREETYPE_LIBRARY NAMES freetype.lib) + set(MSVC_LIBS + ${LIBINTL_LIBRARY} + ${OPENAL_MSVC_LIBS} + ${JPEG_LIBRARY} + ${TIFF_LIBRARY} + ${BZ2_LIBRARY} + ${WEBP_LIBRARY} + ${LZMA_LIBRARY} + ${FREETYPE_LIBRARY} + winmm.lib + dxguid.lib + imm32.lib + ole32.lib + oleaut32.lib + version.lib + wsock32.lib + ws2_32.lib + ) + else(${MSVC_STATIC}) + set(MSVC_LIBS ${LIBINTL_LIBRARY}) + endif() + + set(PLATFORM_LIBS ${MSVC_LIBS}) else() set(PLATFORM_LIBS "-lintl") endif() @@ -106,6 +149,8 @@ set(BASE_SOURCES common/error.h common/event.cpp common/event.h + common/font_loader.h + common/font_loader.cpp common/global.h common/image.cpp common/image.h diff --git a/src/app/app.cpp b/src/app/app.cpp index 3444481c..6f864572 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -815,11 +815,29 @@ bool CApplication::CreateVideoSurface() m_private->glcontext = SDL_GL_CreateContext(m_private->window); int vsync = 0; - if (GetConfigFile().GetIntProperty("Experimental", "VSync", vsync)) + if (GetConfigFile().GetIntProperty("Setup", "VSync", vsync)) { - SDL_GL_SetSwapInterval(vsync); + while (SDL_GL_SetSwapInterval(vsync) == -1) + { + switch(vsync) + { + case -1: //failed with adaptive sync? + GetLogger()->Warn("Adaptive sync not supported.\n"); + vsync = 1; + break; + case 1: //failed with VSync enabled? + GetLogger()->Warn("Couldn't enable VSync.\n"); + vsync = 0; + break; + case 0: //failed with VSync disabled? + GetLogger()->Warn("Couldn't disable VSync.\n"); + vsync = 1; + break; + } + } + GetConfigFile().SetIntProperty("Setup", "VSync", vsync); - GetLogger()->Info("Using Vsync: %s\n", (vsync ? "true" : "false")); + GetLogger()->Info("Using Vsync: %s\n", (vsync == -1 ? "adaptive" : (vsync ? "true" : "false"))); } return true; @@ -833,6 +851,27 @@ bool CApplication::ChangeVideoConfig(const Gfx::DeviceConfig &newConfig) SDL_SetWindowSize(m_private->window, m_deviceConfig.size.x, m_deviceConfig.size.y); SDL_SetWindowFullscreen(m_private->window, m_deviceConfig.fullScreen ? SDL_WINDOW_FULLSCREEN : 0); + int vsync = m_engine->GetVSync(); + while (SDL_GL_SetSwapInterval(vsync) == -1) + { + switch(vsync) + { + case -1: //failed with adaptive sync? + GetLogger()->Warn("Adaptive sync not supported.\n"); + vsync = 1; + break; + case 1: //failed with VSync enabled? + GetLogger()->Warn("Couldn't enable VSync.\n"); + vsync = 0; + break; + case 0: //failed with VSync disabled? + GetLogger()->Warn("Couldn't disable VSync.\n"); + vsync = 1; + break; + } + } + m_engine->SetVSync(vsync); + m_device->ConfigChanged(m_deviceConfig); m_eventQueue->AddEvent(Event(EVENT_RESOLUTION_CHANGED)); @@ -1718,6 +1757,11 @@ char CApplication::GetLanguageChar() const case LANGUAGE_RUSSIAN: langChar = 'R'; break; + + case LANGUAGE_PORTUGUESE_BRAZILIAN: + langChar = 'B'; + break; + } return langChar; } @@ -1774,6 +1818,10 @@ void CApplication::SetLanguage(Language language) { m_language = LANGUAGE_RUSSIAN; } + else if (strncmp(envLang,"pt",2) == 0) + { + m_language = LANGUAGE_PORTUGUESE_BRAZILIAN; + } else { GetLogger()->Warn("Enviromnent locale ('%s') is not supported, setting default language\n", envLang); @@ -1812,6 +1860,10 @@ void CApplication::SetLanguage(Language language) case LANGUAGE_RUSSIAN: locale = "ru_RU.utf8"; break; + + case LANGUAGE_PORTUGUESE_BRAZILIAN: + locale = "pt_BR.utf8"; + break; } std::string langStr = "LANGUAGE="; @@ -1832,7 +1884,12 @@ void CApplication::SetLanguage(Language language) // Update C++ locale try { +#if defined(_MSC_VER) && defined(_DEBUG) + // Avoids failed assertion in VS debugger + throw -1; +#else std::locale::global(std::locale(systemLocale.c_str())); +#endif } catch (...) { diff --git a/src/app/pathman.cpp b/src/app/pathman.cpp index e86780e5..60715ac1 100644 --- a/src/app/pathman.cpp +++ b/src/app/pathman.cpp @@ -38,46 +38,41 @@ #include CPathManager::CPathManager(CSystemUtils* systemUtils) - : m_systemUtils(systemUtils) + : m_dataPath(systemUtils->GetDataPath()) + , m_langPath(systemUtils->GetLangPath()) + , m_savePath(systemUtils->GetSaveDir()) + , m_modAutoloadDir{ m_dataPath + "/mods", m_savePath + "/mods" } + , m_mods{} { - #ifdef PORTABLE - m_dataPath = "./data"; - m_langPath = "./lang"; - m_savePath = "./saves"; - #else - m_dataPath = m_systemUtils->GetDataPath(); - m_langPath = m_systemUtils->GetLangPath(); - #ifdef DEV_BUILD - m_savePath = "./saves"; - #else - m_savePath = m_systemUtils->GetSaveDir(); - #endif - #endif } CPathManager::~CPathManager() { } -void CPathManager::SetDataPath(std::string dataPath) +void CPathManager::SetDataPath(const std::string &dataPath) { m_dataPath = dataPath; } -void CPathManager::SetLangPath(std::string langPath) +void CPathManager::SetLangPath(const std::string &langPath) { m_langPath = langPath; } -void CPathManager::SetSavePath(std::string savePath) +void CPathManager::SetSavePath(const std::string &savePath) { m_savePath = savePath; } -void CPathManager::AddMod(std::string modPath) +void CPathManager::AddModAutoloadDir(const std::string &modAutoloadDirPath) { - GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str()); - CResourceManager::AddLocation(modPath, true); + m_modAutoloadDir.push_back(modAutoloadDirPath); +} + +void CPathManager::AddMod(const std::string &modPath) +{ + m_mods.push_back(modPath); } const std::string& CPathManager::GetDataPath() @@ -106,8 +101,8 @@ std::string CPathManager::VerifyPaths() { GetLogger()->Error("Data directory '%s' doesn't exist or is not a directory\n", m_dataPath.c_str()); return std::string("Could not read from data directory:\n") + - std::string("'") + m_dataPath + std::string("'\n") + - std::string("Please check your installation, or supply a valid data directory by -datadir option."); + std::string("'") + m_dataPath + std::string("'\n") + + std::string("Please check your installation, or supply a valid data directory by -datadir option."); } #if PLATFORM_WINDOWS @@ -133,19 +128,51 @@ std::string CPathManager::VerifyPaths() void CPathManager::InitPaths() { - LoadModsFromDir(m_dataPath+"/mods"); - LoadModsFromDir(m_savePath+"/mods"); - GetLogger()->Info("Data path: %s\n", m_dataPath.c_str()); GetLogger()->Info("Save path: %s\n", m_savePath.c_str()); - CResourceManager::AddLocation(m_dataPath, false); + if (!m_modAutoloadDir.empty()) + { + GetLogger()->Info("Mod autoload dirs:\n"); + for(const std::string& modAutoloadDir : m_modAutoloadDir) + GetLogger()->Info(" * %s\n", modAutoloadDir.c_str()); + } + if (!m_mods.empty()) + { + GetLogger()->Info("Mods:\n"); + for(const std::string& modPath : m_mods) + GetLogger()->Info(" * %s\n", modPath.c_str()); + } + + CResourceManager::AddLocation(m_dataPath); + + for (const std::string& modAutoloadDir : m_modAutoloadDir) + { + GetLogger()->Trace("Searching for mods in '%s'...\n", modAutoloadDir.c_str()); + for (const std::string& modPath : FindModsInDir(modAutoloadDir)) + { + GetLogger()->Info("Autoloading mod: '%s'\n", modPath.c_str()); + CResourceManager::AddLocation(modPath); + } + } + + for (const std::string& modPath : m_mods) + { + GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str()); + CResourceManager::AddLocation(modPath); + } + CResourceManager::SetSaveLocation(m_savePath); - CResourceManager::AddLocation(m_savePath, true); + CResourceManager::AddLocation(m_savePath); + + GetLogger()->Debug("Finished initalizing data paths\n"); + GetLogger()->Debug("PHYSFS search path is:\n"); + for (const std::string& path : CResourceManager::GetLocations()) + GetLogger()->Debug(" * %s\n", path.c_str()); } -void CPathManager::LoadModsFromDir(const std::string &dir) +std::vector CPathManager::FindModsInDir(const std::string &dir) { - GetLogger()->Trace("Looking for mods in '%s' ...\n", dir.c_str()); + std::vector ret; try { #if PLATFORM_WINDOWS @@ -156,9 +183,9 @@ void CPathManager::LoadModsFromDir(const std::string &dir) for(; iterator != boost::filesystem::directory_iterator(); ++iterator) { #if PLATFORM_WINDOWS - AddMod(CSystemUtilsWindows::UTF8_Encode(iterator->path().wstring())); + ret.push_back(CSystemUtilsWindows::UTF8_Encode(iterator->path().wstring())); #else - AddMod(iterator->path().string()); + ret.push_back(iterator->path().string()); #endif } } @@ -166,4 +193,5 @@ void CPathManager::LoadModsFromDir(const std::string &dir) { GetLogger()->Warn("Unable to load mods from directory '%s': %s\n", dir.c_str(), e.what()); } + return ret; } diff --git a/src/app/pathman.h b/src/app/pathman.h index 39c780df..dd18d66e 100644 --- a/src/app/pathman.h +++ b/src/app/pathman.h @@ -17,16 +17,10 @@ * along with this program. If not, see http://gnu.org/licenses */ -/** - * \file app/pathman.h - * \brief Class for managing data/lang/save paths - */ - #pragma once -#include "common/singleton.h" - #include +#include class CSystemUtils; @@ -34,16 +28,17 @@ class CSystemUtils; * \class CPathManager * \brief Class for managing data/lang/save paths */ -class CPathManager : public CSingleton +class CPathManager { public: CPathManager(CSystemUtils* systemUtils); ~CPathManager(); - void SetDataPath(std::string dataPath); - void SetLangPath(std::string langPath); - void SetSavePath(std::string savePath); - void AddMod(std::string modPath); + void SetDataPath(const std::string &dataPath); + void SetLangPath(const std::string &langPath); + void SetSavePath(const std::string &savePath); + void AddModAutoloadDir(const std::string &modAutoloadDirPath); + void AddMod(const std::string &modPath); const std::string& GetDataPath(); const std::string& GetLangPath(); @@ -56,14 +51,17 @@ public: private: //! Loads all mods from given directory - void LoadModsFromDir(const std::string &dir); + std::vector FindModsInDir(const std::string &dir); private: - CSystemUtils* m_systemUtils; //! Data path std::string m_dataPath; //! Lang path std::string m_langPath; //! Save path std::string m_savePath; + //! Mod autoload paths + std::vector m_modAutoloadDir; + //! Mod paths + std::vector m_mods; }; diff --git a/src/app/signal_handlers.cpp b/src/app/signal_handlers.cpp index 1974ba3f..03771dab 100644 --- a/src/app/signal_handlers.cpp +++ b/src/app/signal_handlers.cpp @@ -133,7 +133,7 @@ void CSignalHandlers::ReportError(const std::string& errorMessage) msg << "including information on what you were doing before this happened and all the information below." << std::endl; msg << "==============================" << std::endl; #if BUILD_NUMBER == 0 - #ifdef OFFICIAL_BUILD + #ifdef OFFICIAL_COLOBOT_BUILD msg << "You are running official " << COLOBOT_VERSION_DISPLAY << " build." << std::endl; #else // COLOBOT_VERSION_DISPLAY doesn't update if you don't run CMake after "git pull" diff --git a/src/common/config.h.cmake b/src/common/config.h.cmake index b4767724..f6d0bcae 100644 --- a/src/common/config.h.cmake +++ b/src/common/config.h.cmake @@ -16,7 +16,7 @@ #cmakedefine OPENAL_SOUND -#cmakedefine PORTABLE @PORTABLE@ +#cmakedefine PORTABLE_SAVES @PORTABLE_SAVES@ #define COLOBOT_DEFAULT_DATADIR "@COLOBOT_INSTALL_DATA_DIR@" #define COLOBOT_I18N_DIR "@COLOBOT_INSTALL_I18N_DIR@" diff --git a/src/common/event.cpp b/src/common/event.cpp index 8dded9e1..302c2702 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -232,6 +232,7 @@ void InitializeEventTypeTexts() EVENT_TYPE_TEXT[EVENT_INTERFACE_SHADOW_MAPPING_QUALITY] = "EVENT_INTERFACE_SHADOW_MAPPING_QUALITY"; EVENT_TYPE_TEXT[EVENT_INTERFACE_SHADOW_MAPPING_BUFFER] = "EVENT_INTERFACE_SHADOW_MAPPING_BUFFER"; EVENT_TYPE_TEXT[EVENT_INTERFACE_LANGUAGE] = "EVENT_INTERFACE_LANGUAGE"; + EVENT_TYPE_TEXT[EVENT_INTERFACE_VSYNC] = "EVENT_INTERFACE_VSYNC"; EVENT_TYPE_TEXT[EVENT_INTERFACE_KINFO1] = "EVENT_INTERFACE_KINFO1"; EVENT_TYPE_TEXT[EVENT_INTERFACE_KINFO2] = "EVENT_INTERFACE_KINFO2"; diff --git a/src/common/event.h b/src/common/event.h index 64c52e41..a9353e5e 100644 --- a/src/common/event.h +++ b/src/common/event.h @@ -268,6 +268,7 @@ enum EventType EVENT_INTERFACE_SHADOW_MAPPING_QUALITY = 788, EVENT_INTERFACE_SHADOW_MAPPING_BUFFER = 789, EVENT_INTERFACE_LANGUAGE = 790, + EVENT_INTERFACE_VSYNC = 791, EVENT_INTERFACE_KINFO1 = 500, EVENT_INTERFACE_KINFO2 = 501, diff --git a/src/common/font_loader.cpp b/src/common/font_loader.cpp new file mode 100644 index 00000000..79b9375c --- /dev/null +++ b/src/common/font_loader.cpp @@ -0,0 +1,115 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2018, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#include "common/font_loader.h" + +#include "common/logger.h" +#include "common/make_unique.h" + +#include "common/resources/inputstream.h" +#include "common/resources/outputstream.h" + +#include "common/system/system.h" + +#include "graphics/engine/text.h" + +#include +#include +#include +#include +#include +#include + +namespace bp = boost::property_tree; + +const std::map DEFAULT_FONT = +{ + { Gfx::FONT_COMMON, "dvu_sans.ttf" }, + { Gfx::FONT_COMMON_BOLD, "dvu_sans_bold.ttf" }, + { Gfx::FONT_COMMON_ITALIC, "dvu_sans_italic.ttf" }, + { Gfx::FONT_STUDIO, "dvu_sans_mono.ttf" }, + { Gfx::FONT_STUDIO_BOLD, "dvu_sans_mono_bold.ttf" }, + { Gfx::FONT_STUDIO_ITALIC, "dvu_sans_mono.ttf" }, //placeholder for future use, DejaVu Sans Mono doesn't have italic variant + { Gfx::FONT_SATCOM, "dvu_sans.ttf" }, + { Gfx::FONT_SATCOM_BOLD, "dvu_sans_bold.ttf" }, + { Gfx::FONT_SATCOM_ITALIC, "dvu_sans_italic.ttf" }, +}; + +const std::map FONT_TYPE = +{ + { Gfx::FONT_COMMON, "FontCommon" }, + { Gfx::FONT_COMMON_BOLD, "FontCommonBold" }, + { Gfx::FONT_COMMON_ITALIC, "FontCommonItalic" }, + { Gfx::FONT_STUDIO, "FontStudio" }, + { Gfx::FONT_STUDIO_BOLD, "FontStudioBold" }, + { Gfx::FONT_STUDIO_ITALIC, "FontStudioItalic" }, + { Gfx::FONT_SATCOM, "FontSatCom" }, + { Gfx::FONT_SATCOM_BOLD, "FontSatComBold" }, + { Gfx::FONT_SATCOM_ITALIC, "FontSatComItalic" }, +}; + +CFontLoader::CFontLoader() +{ +} + +CFontLoader::~CFontLoader() +{ +} + +bool CFontLoader::Init() +{ + try + { + std::unique_ptr stream; + auto inputStream = MakeUnique("/fonts/fonts.ini"); + bool good = inputStream->is_open(); + stream = std::move(inputStream); + + if (good) + { + bp::ini_parser::read_ini(*stream, m_propertyTree); + GetLogger()->Debug("Fonts config file loaded correctly. \n"); + } + else + { + return false; + } + } + catch (std::exception & e) + { + GetLogger()->Error("Error on parsing config file: %s\n", e.what()); + return false; + } + return true; +} + +std::string CFontLoader::GetFont(Gfx::FontType type) +{ + return std::string("/fonts/") + m_propertyTree.get(GetFontType(type), GetDefaultFont(type)); +} + +std::string CFontLoader::GetDefaultFont(Gfx::FontType type) const +{ + return DEFAULT_FONT.at(type); +} + +std::string CFontLoader::GetFontType(Gfx::FontType type) const +{ + return FONT_TYPE.at(type); +} diff --git a/src/common/font_loader.h b/src/common/font_loader.h new file mode 100644 index 00000000..a68fc0ad --- /dev/null +++ b/src/common/font_loader.h @@ -0,0 +1,72 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2018, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + + /** + * \file common/font_loader.h + * \brief Class for loading fonts from /data/fonts/fonts.ini + */ + +#pragma once + +#include "common/singleton.h" + +#include "graphics/engine/text.h" + +#include + +#include + +/** +* \class CFontLoader +* +* \brief Class for loading config file +* +*/ + +class CFontLoader +{ +public: + CFontLoader(); + virtual ~CFontLoader(); + + /** Loads fonts.ini + * \return return true on success + */ + bool Init(); + + /** Reads given font from file + * \return return path to font file + */ + std::string GetFont(Gfx::FontType type); + + /** Const type method to read filenames of fonts from defaultFont map + * used as a fallback if it wasn't possible to read font from fonts.ini + * \return return filename of default path + */ + std::string GetDefaultFont(Gfx::FontType type) const; + + /** Const type method converting Gfx::FontType to string + * \return return id of font used in fonts.ini file + */ + + std::string GetFontType(Gfx::FontType type) const; + +private: + boost::property_tree::ptree m_propertyTree; +}; diff --git a/src/common/language.cpp b/src/common/language.cpp index a9f62419..37a8dca1 100644 --- a/src/common/language.cpp +++ b/src/common/language.cpp @@ -27,7 +27,8 @@ const std::map LANGUAGE_MAP = { { LANGUAGE_GERMAN, "de" }, { LANGUAGE_FRENCH, "fr" }, { LANGUAGE_POLISH, "pl" }, - { LANGUAGE_RUSSIAN, "ru" } + { LANGUAGE_RUSSIAN, "ru" }, + { LANGUAGE_PORTUGUESE_BRAZILIAN, "pt" } }; bool ParseLanguage(const std::string& str, Language& language) diff --git a/src/common/language.h b/src/common/language.h index f25f7f77..0310cb73 100644 --- a/src/common/language.h +++ b/src/common/language.h @@ -33,7 +33,8 @@ enum Language LANGUAGE_GERMAN = 2, LANGUAGE_POLISH = 3, LANGUAGE_RUSSIAN = 4, - LANGUAGE_CZECH = 5 + LANGUAGE_CZECH = 5, + LANGUAGE_PORTUGUESE_BRAZILIAN = 6 }; bool ParseLanguage(const std::string& str, Language& language); diff --git a/src/common/resources/resourcemanager.cpp b/src/common/resources/resourcemanager.cpp index 820495b8..0ad82816 100644 --- a/src/common/resources/resourcemanager.cpp +++ b/src/common/resources/resourcemanager.cpp @@ -85,6 +85,16 @@ bool CResourceManager::RemoveLocation(const std::string &location) return true; } +std::vector CResourceManager::GetLocations() +{ + std::vector ret; + char **list = PHYSFS_getSearchPath(); + for (char **it = list; *it != nullptr; ++it) + ret.push_back(*it); + PHYSFS_freeList(list); + return ret; +} + bool CResourceManager::SetSaveLocation(const std::string &location) { diff --git a/src/common/resources/resourcemanager.h b/src/common/resources/resourcemanager.h index d0b4ab24..95661a4f 100644 --- a/src/common/resources/resourcemanager.h +++ b/src/common/resources/resourcemanager.h @@ -35,8 +35,12 @@ public: static std::string CleanPath(const std::string &path); + //! Add a location to the search path static bool AddLocation(const std::string &location, bool prepend = true); + //! Remove a location from the search path static bool RemoveLocation(const std::string &location); + //! List all locations in the search path + static std::vector GetLocations(); static bool SetSaveLocation(const std::string &location); static std::string GetSaveLocation(); diff --git a/src/common/restext.cpp b/src/common/restext.cpp index 9bac8434..4aa21564 100644 --- a/src/common/restext.cpp +++ b/src/common/restext.cpp @@ -48,6 +48,9 @@ const char* stringsCbot[CBot::CBotErrMAX] = { nullptr }; */ #define TR(x) x +/* Please run `make update-pot` after changing this file + * in order to update translation files. Thank you. + */ void InitializeRestext() { @@ -216,6 +219,7 @@ void InitializeRestext() stringsEvent[EVENT_INTERFACE_SHADOW_MAPPING] = TR("Dynamic shadows\\Beautiful shadows!"); stringsEvent[EVENT_INTERFACE_SHADOW_MAPPING_QUALITY]= TR("Dynamic shadows ++\\Dynamic shadows + self shadowing"); stringsEvent[EVENT_INTERFACE_SHADOW_MAPPING_BUFFER] = TR("Shadow resolution\\Higher means better range and quality, but slower"); + stringsEvent[EVENT_INTERFACE_VSYNC] = TR("Vertical Synchronization\\Limits the number of frames per second to display frequency"); stringsEvent[EVENT_INTERFACE_KDEF] = TR("Standard controls\\Standard key functions"); assert(INPUT_SLOT_MAX < EVENT_INTERFACE_KEY_END-EVENT_INTERFACE_KEY); diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 93db8102..488666d2 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -112,6 +112,7 @@ void CSettings::SaveSettings() // Experimental settings GetConfigFile().SetBoolProperty("Experimental", "TerrainShadows", engine->GetTerrainShadows()); + GetConfigFile().SetIntProperty("Setup", "VSync", engine->GetVSync()); CInput::GetInstancePointer()->SaveKeyBindings(); @@ -274,6 +275,10 @@ void CSettings::LoadSettings() if (GetConfigFile().GetBoolProperty("Experimental", "TerrainShadows", bValue)) engine->SetTerrainShadows(bValue); + if (GetConfigFile().GetIntProperty("Setup", "VSync", iValue)) + { + engine->SetVSync(iValue); + } CInput::GetInstancePointer()->LoadKeyBindings(); diff --git a/src/common/system/system.cpp b/src/common/system/system.cpp index 01b633cc..12dc1d36 100644 --- a/src/common/system/system.cpp +++ b/src/common/system/system.cpp @@ -20,8 +20,6 @@ #include "common/system/system.h" -#include "common/config.h" - #include "common/make_unique.h" #if defined(PLATFORM_WINDOWS) @@ -190,5 +188,5 @@ std::string CSystemUtils::GetLangPath() std::string CSystemUtils::GetSaveDir() { - return std::string("saves"); + return "./saves"; } diff --git a/src/common/system/system.h b/src/common/system/system.h index aaf54954..36e736c9 100644 --- a/src/common/system/system.h +++ b/src/common/system/system.h @@ -24,6 +24,8 @@ #pragma once +#include "common/config.h" + #include #include #include diff --git a/src/common/system/system_linux.cpp b/src/common/system/system_linux.cpp index 3cd25ed2..9bfe431a 100644 --- a/src/common/system/system_linux.cpp +++ b/src/common/system/system_linux.cpp @@ -96,16 +96,20 @@ long long CSystemUtilsLinux::TimeStampExactDiff(SystemTimeStamp *before, SystemT std::string CSystemUtilsLinux::GetSaveDir() { +#if PORTABLE_SAVES || DEV_BUILD + return CSystemUtils::GetSaveDir(); +#else std::string savegameDir; // Determine savegame dir according to XDG Base Directory Specification - char *envXDG_DATA_HOME = getenv("XDG_CONFIG_DATA"); + char *envXDG_DATA_HOME = getenv("XDG_DATA_HOME"); if (envXDG_DATA_HOME == nullptr) { char *envHOME = getenv("HOME"); if (envHOME == nullptr) { - savegameDir = "/tmp/colobot-save"; + GetLogger()->Warn("Unable to find directory for saves - using current directory"); + savegameDir = "./saves"; } else { @@ -119,6 +123,7 @@ std::string CSystemUtilsLinux::GetSaveDir() GetLogger()->Trace("Saved game files are going to %s\n", savegameDir.c_str()); return savegameDir; +#endif } void CSystemUtilsLinux::Usleep(int usec) diff --git a/src/common/system/system_macosx.cpp b/src/common/system/system_macosx.cpp index ede5b481..9ef7ce1d 100644 --- a/src/common/system/system_macosx.cpp +++ b/src/common/system/system_macosx.cpp @@ -102,10 +102,15 @@ std::string CSystemUtilsMacOSX::GetLangPath() std::string CSystemUtilsMacOSX::GetSaveDir() { +#if PORTABLE_SAVES || DEV_BUILD + // TODO: I have no idea if this actually works on Mac OS + return "./saves"; +#else std::string savegameDir = m_ASPath; GetLogger()->Trace("Saved game files are going to %s\n", savegameDir.c_str()); return savegameDir; +#endif } void CSystemUtilsMacOSX::Usleep(int usec) diff --git a/src/common/system/system_windows.cpp b/src/common/system/system_windows.cpp index f51959b4..a20bfcf1 100644 --- a/src/common/system/system_windows.cpp +++ b/src/common/system/system_windows.cpp @@ -110,11 +110,15 @@ std::wstring CSystemUtilsWindows::UTF8_Decode(const std::string& str) std::string CSystemUtilsWindows::GetSaveDir() { +#if PORTABLE_SAVES || DEV_BUILD + return CSystemUtils::GetSaveDir(); +#else std::string savegameDir; wchar_t* envUSERPROFILE = _wgetenv(L"USERPROFILE"); if (envUSERPROFILE == nullptr) { + GetLogger()->Warn("Unable to find directory for saves - using current directory"); savegameDir = "./saves"; } else @@ -124,6 +128,7 @@ std::string CSystemUtilsWindows::GetSaveDir() GetLogger()->Trace("Saved game files are going to %s\n", savegameDir.c_str()); return savegameDir; +#endif } void CSystemUtilsWindows::Usleep(int usec) diff --git a/src/common/version.h.cmake b/src/common/version.h.cmake index ad3714b3..ca377e4f 100644 --- a/src/common/version.h.cmake +++ b/src/common/version.h.cmake @@ -4,4 +4,4 @@ #define COLOBOT_VERSION_DISPLAY "@COLOBOT_VERSION_DISPLAY@" #define BUILD_NUMBER @BUILD_NUMBER@ -#cmakedefine OFFICIAL_BUILD +#cmakedefine OFFICIAL_COLOBOT_BUILD diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h index 3302488c..2cc94992 100644 --- a/src/graphics/core/device.h +++ b/src/graphics/core/device.h @@ -416,14 +416,6 @@ public: //! Sets only the texture wrap modes (for faster than thru stage params) virtual void SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode wrapT) = 0; - //! Renders primitive composed of generic vertices - virtual void DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) = 0; - - //! Renders multiple primitives composed of generic vertices - virtual void DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) = 0; - //! Renders primitive composed of vertices with single texture virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) = 0; diff --git a/src/graphics/core/framebuffer.h b/src/graphics/core/framebuffer.h index e668b036..3c5e6de8 100644 --- a/src/graphics/core/framebuffer.h +++ b/src/graphics/core/framebuffer.h @@ -41,10 +41,15 @@ struct FramebufferParams int depth = 16; //! Requested number of samples for multisampling int samples = 1; - //! true requests color texture - bool colorTexture = false; - //! true requests depth texture - bool depthTexture = false; + + enum class AttachmentType + { + Texture, + Renderbuffer, + None, + }; + AttachmentType colorAttachment = AttachmentType::Renderbuffer; + AttachmentType depthAttachment = AttachmentType::Renderbuffer; //! Loads default values void LoadDefault() diff --git a/src/graphics/core/nulldevice.cpp b/src/graphics/core/nulldevice.cpp index 1fd1a09b..cf9f5a67 100644 --- a/src/graphics/core/nulldevice.cpp +++ b/src/graphics/core/nulldevice.cpp @@ -168,16 +168,6 @@ void CNullDevice::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i { } -void CNullDevice::DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) -{ -} - -void CNullDevice::DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) -{ -} - void CNullDevice::DrawPrimitives(PrimitiveType type, const Vertex *vertices, int first[], int count[], int drawCount, Color color) { diff --git a/src/graphics/core/nulldevice.h b/src/graphics/core/nulldevice.h index 4816251b..0d6c7ab8 100644 --- a/src/graphics/core/nulldevice.h +++ b/src/graphics/core/nulldevice.h @@ -81,11 +81,6 @@ public: void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT) override; - void DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) override; - void DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) override; - void DrawPrimitive(PrimitiveType type, const Vertex* vertices, int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; void DrawPrimitive(PrimitiveType type, const VertexTex2* vertices, int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; void DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount) override; diff --git a/src/graphics/core/vertex.h b/src/graphics/core/vertex.h index 1af5832e..e5b71733 100644 --- a/src/graphics/core/vertex.h +++ b/src/graphics/core/vertex.h @@ -39,57 +39,11 @@ namespace Gfx { - -/** -* \struct VertexAttribute -* \brief Vertex attribute -* -* This structure contains parameters for a vertex attribute. -*/ -struct VertexAttribute +enum VertexType { - //! true enables vertex attribute - bool enabled = false; - //! true means normalized value (integer types only) - bool normalized = false; - //! Number of elements in the vertex attribute. - //! Valid values are 1, 2, 3, and 4. Depends on specific attribute. - unsigned char size = 0; - //! Type of values in vertex attribute - Type type = Type::UBYTE; - //! Offset to the vertex attribute - int offset = 0; - //! Stride of vertex attribute - int stride = 0; - //! Default values used when attribute is disabled - float values[4] = {0.0f, 0.0f, 0.0f, 0.0f}; -}; - -/** -* \struct VertexFormat -* \brief Vertex format -* -* This structure defines vertex formats for generic vertex arrays. -* -* It contains: -* - vertex coordinate specification -* - color specification -* - normal specification -* - texture coordinate 1 specification -* - texture coordinate 2 specification -*/ -struct VertexFormat -{ - //! Vertex coordinate - VertexAttribute vertex{}; - //! Color - VertexAttribute color{}; - //! Normal - VertexAttribute normal{}; - //! Texture coordinate 1 - VertexAttribute tex1{}; - //! Texture coordinate 2 - VertexAttribute tex2{}; + VERTEX_TYPE_NORMAL, + VERTEX_TYPE_TEX2, + VERTEX_TYPE_COL, }; /** @@ -105,6 +59,8 @@ struct VertexFormat */ struct Vertex { + static constexpr VertexType VERTEX_TYPE = VERTEX_TYPE_NORMAL; + Math::Vector coord; Math::Vector normal; Math::Point texCoord; @@ -137,6 +93,8 @@ struct Vertex */ struct VertexCol { + static constexpr VertexType VERTEX_TYPE = VERTEX_TYPE_COL; + Math::Vector coord; Color color; @@ -166,6 +124,8 @@ struct VertexCol */ struct VertexTex2 { + static constexpr VertexType VERTEX_TYPE = VERTEX_TYPE_TEX2; + Math::Vector coord; Math::Vector normal; Math::Point texCoord; diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 40d4d1d1..348514bb 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -197,6 +197,7 @@ CEngine::CEngine(CApplication *app, CSystemUtils* systemUtils) m_terrainShadows = false; m_shadowRange = 0.0f; m_multisample = 2; + m_vsync = 0; m_backForce = true; m_lightMode = true; @@ -323,6 +324,7 @@ bool CEngine::Create() SetShadowMappingOffscreen(m_offscreenShadowRendering); SetShadowMappingOffscreenResolution(m_offscreenShadowRenderingResolution); SetMultiSample(m_multisample); + SetVSync(m_vsync); m_modelManager = MakeUnique(this); m_pyroManager = MakeUnique(); @@ -431,7 +433,7 @@ bool CEngine::ProcessEvent(const Event &event) { auto data = event.GetData(); - if (data->key == KEY(F12)) + if (data->key == KEY(F11) || data->key == KEY(F12)) { m_showStats = !m_showStats; return false; @@ -3023,6 +3025,19 @@ bool CEngine::GetTerrainShadows() return m_terrainShadows; } +void CEngine::SetVSync(int value) +{ + if (value < -1) value = -1; + if (value > 1) value = 1; + if(m_vsync == value) return; + m_vsync = value; +} + +int CEngine::GetVSync() +{ + return m_vsync; +} + void CEngine::SetBackForce(bool present) { m_backForce = present; @@ -3786,7 +3801,8 @@ void CEngine::RenderShadowMap() FramebufferParams params; params.width = params.height = width; params.depth = depth = 32; - params.depthTexture = true; + params.colorAttachment = FramebufferParams::AttachmentType::None; + params.depthAttachment = FramebufferParams::AttachmentType::Texture; CFramebuffer *framebuffer = m_device->CreateFramebuffer("shadow", params); if (framebuffer == nullptr) @@ -4032,7 +4048,10 @@ void CEngine::UseMSAA(bool enable) } } - framebuffer->Bind(); + if (framebuffer != nullptr) + { + framebuffer->Bind(); + } m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, true); m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, true); @@ -5117,7 +5136,7 @@ void CEngine::DrawStats() if (!m_showStats) return; - float height = m_text->GetAscent(FONT_COLOBOT, 13.0f); + float height = m_text->GetAscent(FONT_COMMON, 13.0f); float width = 0.4f; const int TOTAL_LINES = 22; @@ -5144,13 +5163,13 @@ void CEngine::DrawStats() auto drawStatsLine = [&](const std::string& name, const std::string& value, const std::string& value2) { if (!name.empty()) - m_text->DrawText(name+":", FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + m_text->DrawText(name+":", FONT_COMMON, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); pos.x += 0.25f; if (!value.empty()) - m_text->DrawText(value, FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + m_text->DrawText(value, FONT_COMMON, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); pos.x += 0.15f; if (!value2.empty()) - m_text->DrawText(value2, FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_RIGHT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + m_text->DrawText(value2, FONT_COMMON, 12.0f, pos, 1.0f, TEXT_ALIGN_RIGHT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); pos.x -= 0.4f; pos.y -= height; }; @@ -5218,8 +5237,8 @@ void CEngine::DrawTimer() { SetState(ENG_RSTATE_TEXT); - Math::Point pos(0.98f, 0.98f-m_text->GetAscent(FONT_COLOBOT, 15.0f)); - m_text->DrawText(m_timerText, FONT_COLOBOT, 15.0f, pos, 1.0f, TEXT_ALIGN_RIGHT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + Math::Point pos(0.98f, 0.98f-m_text->GetAscent(FONT_COMMON, 15.0f)); + m_text->DrawText(m_timerText, FONT_COMMON, 15.0f, pos, 1.0f, TEXT_ALIGN_RIGHT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); } void CEngine::AddBaseObjTriangles(int baseObjRank, const std::vector& triangles) diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index 794bd9e8..88a35dda 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -1072,6 +1072,13 @@ public: bool GetTerrainShadows(); //@} + //@{ + //! Management of vertical synchronization + // NOTE: This is an user configuration setting + void SetVSync(int value); + int GetVSync(); + //@} + //@{ //! Management of shadow color // NOTE: This is a setting configurable only in INI file @@ -1336,6 +1343,9 @@ protected: //! Texture bias for sampling shadow maps Math::Matrix m_shadowBias; + //! Vertical synchronization controll + int m_vsync; + //! World matrix for 2D interface Math::Matrix m_matWorldInterface; //! Projection matrix for 2D interface diff --git a/src/graphics/engine/particle.cpp b/src/graphics/engine/particle.cpp index 233e5974..5c6d169f 100644 --- a/src/graphics/engine/particle.cpp +++ b/src/graphics/engine/particle.cpp @@ -3301,7 +3301,7 @@ void CParticle::DrawParticleCylinder(int i) void CParticle::DrawParticleText(int i) { - CharTexture tex = m_engine->GetText()->GetCharTexture(static_cast(m_particle[i].text), FONT_COURIER, FONT_SIZE_BIG*2.0f); + CharTexture tex = m_engine->GetText()->GetCharTexture(static_cast(m_particle[i].text), FONT_STUDIO, FONT_SIZE_BIG*2.0f); if (tex.id == 0) return; m_device->SetTexture(0, tex.id); diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 045cdc4c..df284160 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -22,6 +22,7 @@ #include "app/app.h" +#include "common/font_loader.h" #include "common/image.h" #include "common/logger.h" #include "common/stringutils.h" @@ -32,6 +33,7 @@ #include "math/func.h" +#include #include #include @@ -174,7 +176,7 @@ CText::CText(CEngine* engine) m_defaultSize = 12.0f; m_tabSize = 4; - m_lastFontType = FONT_COLOBOT; + m_lastFontType = FONT_COMMON; m_lastFontSize = 0; m_lastCachedFont = nullptr; @@ -189,18 +191,23 @@ CText::~CText() bool CText::Create() { + CFontLoader fontLoader; + if (!fontLoader.Init()) + { + GetLogger()->Warn("Error on parsing fonts config file: failed to open file\n"); + } if (TTF_Init() != 0) { m_error = std::string("TTF_Init error: ") + std::string(TTF_GetError()); return false; } - m_fonts[FONT_COLOBOT] = MakeUnique("fonts/dvu_sans.ttf"); - m_fonts[FONT_COLOBOT_BOLD] = MakeUnique("fonts/dvu_sans_bold.ttf"); - m_fonts[FONT_COLOBOT_ITALIC] = MakeUnique("fonts/dvu_sans_italic.ttf"); - - m_fonts[FONT_COURIER] = MakeUnique("fonts/dvu_sans_mono.ttf"); - m_fonts[FONT_COURIER_BOLD] = MakeUnique("fonts/dvu_sans_mono_bold.ttf"); + for (auto type : {FONT_COMMON, FONT_STUDIO, FONT_SATCOM}) + { + m_fonts[static_cast(type)] = MakeUnique(fontLoader.GetFont(type)); + m_fonts[static_cast(type|FONT_BOLD)] = MakeUnique(fontLoader.GetFont(static_cast(type|FONT_BOLD))); + m_fonts[static_cast(type|FONT_ITALIC)] = MakeUnique(fontLoader.GetFont(static_cast(type|FONT_ITALIC))); + } for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it) { @@ -218,7 +225,7 @@ void CText::Destroy() m_fonts.clear(); m_lastCachedFont = nullptr; - m_lastFontType = FONT_COLOBOT; + m_lastFontType = FONT_COMMON; m_lastFontSize = 0; TTF_Quit(); @@ -253,7 +260,7 @@ void CText::FlushCache() } m_lastCachedFont = nullptr; - m_lastFontType = FONT_COLOBOT; + m_lastFontType = FONT_COMMON; m_lastFontSize = 0; } @@ -336,8 +343,8 @@ void CText::SizeText(const std::string &text, std::vector::iterato end.x -= sw; } - start.y -= GetDescent(FONT_COLOBOT, size); - end.y += GetAscent(FONT_COLOBOT, size); + start.y -= GetDescent(FONT_COMMON, size); + end.y += GetAscent(FONT_COMMON, size); } void CText::SizeText(const std::string &text, FontType font, @@ -417,7 +424,7 @@ float CText::GetStringWidth(const std::string &text, unsigned int fmtIndex = 0; while (index < text.length()) { - FontType font = FONT_COLOBOT; + FontType font = FONT_COMMON; if (format + fmtIndex != end) font = static_cast(*(format + fmtIndex) & FONT_MASK_FONT); @@ -464,7 +471,7 @@ float CText::GetCharWidth(UTF8Char ch, FontType font, float size, float offset) if (font == FONT_BUTTON) { Math::IntPoint windowSize = m_engine->GetWindowSize(); - float height = GetHeight(FONT_COLOBOT, size); + float height = GetHeight(FONT_COMMON, size); float width = height*(static_cast(windowSize.y)/windowSize.x); return width; } @@ -506,7 +513,7 @@ int CText::GetCharWidthInt(UTF8Char ch, FontType font, float size, float offset) if (font == FONT_BUTTON) { Math::IntPoint windowSize = m_engine->GetWindowSize(); - int height = GetHeightInt(FONT_COLOBOT, size); + int height = GetHeightInt(FONT_COMMON, size); int width = height*(static_cast(windowSize.y)/windowSize.x); return width; } @@ -552,7 +559,7 @@ int CText::Justify(const std::string &text, std::vector::iterator unsigned int fmtIndex = 0; while (index < text.length()) { - FontType font = FONT_COLOBOT; + FontType font = FONT_COMMON; if (format + fmtIndex != end) font = static_cast(*(format + fmtIndex) & FONT_MASK_FONT); @@ -636,7 +643,7 @@ int CText::Detect(const std::string &text, std::vector::iterator f unsigned int fmtIndex = 0; while (index < text.length()) { - FontType font = FONT_COLOBOT; + FontType font = FONT_COMMON; if (format + fmtIndex != end) font = static_cast(*(format + fmtIndex) & FONT_MASK_FONT); @@ -773,7 +780,7 @@ void CText::DrawString(const std::string &text, std::vector::itera StringToUTFCharList(text, chars, format, end); for (auto it = chars.begin(); it != chars.end(); ++it) { - FontType font = FONT_COLOBOT; + FontType font = FONT_COMMON; if (format + fmtIndex != end) font = static_cast(*(format + fmtIndex) & FONT_MASK_FONT); @@ -846,7 +853,7 @@ void CText::DrawString(const std::string &text, std::vector::itera if (eol != 0) { - FontType font = FONT_COLOBOT; + FontType font = FONT_COMMON; UTF8Char ch = TranslateSpecialChar(eol); color = Color(1.0f, 0.0f, 0.0f); DrawCharAndAdjustPos(ch, font, size, pos, color); @@ -887,7 +894,7 @@ void CText::StringToUTFCharList(const std::string &text, std::vector & { UTF8Char ch; - FontType font = FONT_COLOBOT; + FontType font = FONT_COMMON; if (format + index != end) font = static_cast(*(format + index) & FONT_MASK_FONT); @@ -993,7 +1000,7 @@ void CText::DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::I if (font == FONT_BUTTON) { Math::IntPoint windowSize = m_engine->GetWindowSize(); - int height = GetHeightInt(FONT_COLOBOT, size); + int height = GetHeightInt(FONT_COMMON, size); int width = height * (static_cast(windowSize.y)/windowSize.x); Math::IntPoint p1(pos.x, pos.y - height); @@ -1246,13 +1253,13 @@ FontTexture CText::CreateFontTexture(Math::IntPoint tileSize) Math::IntPoint CText::GetNextTilePos(const FontTexture& fontTexture) { - int horizontalTiles = FONT_TEXTURE_SIZE.x / fontTexture.tileSize.x; - int verticalTiles = FONT_TEXTURE_SIZE.y / fontTexture.tileSize.y; + int horizontalTiles = FONT_TEXTURE_SIZE.x / std::max(1, fontTexture.tileSize.x); //this should prevent crashes in some combinations of resolution and font size, see issue #1128 + int verticalTiles = FONT_TEXTURE_SIZE.y / std::max(1, fontTexture.tileSize.y); int totalTiles = horizontalTiles * verticalTiles; int tileNumber = totalTiles - fontTexture.freeSlots; - int verticalTileIndex = tileNumber / horizontalTiles; + int verticalTileIndex = tileNumber / std::max(1, horizontalTiles); int horizontalTileIndex = tileNumber % horizontalTiles; return Math::IntPoint(horizontalTileIndex * fontTexture.tileSize.x, diff --git a/src/graphics/engine/text.h b/src/graphics/engine/text.h index 40fb90fa..0405c7d2 100644 --- a/src/graphics/engine/text.h +++ b/src/graphics/engine/text.h @@ -77,18 +77,25 @@ enum FontType FONT_ITALIC = 0x08, //! Default colobot font used for interface - FONT_COLOBOT = 0x00, + FONT_COMMON = 0x00, //! Alias for bold colobot font - FONT_COLOBOT_BOLD = FONT_COLOBOT | FONT_BOLD, + FONT_COMMON_BOLD = FONT_COMMON | FONT_BOLD, //! Alias for italic colobot font - FONT_COLOBOT_ITALIC = FONT_COLOBOT | FONT_ITALIC, + FONT_COMMON_ITALIC = FONT_COMMON | FONT_ITALIC, - //! Courier (monospace) font used mainly in code editor (only regular & bold) - FONT_COURIER = 0x01, - //! Alias for bold courier font - FONT_COURIER_BOLD = FONT_COURIER | FONT_BOLD, + //! Studio font used mainly in code editor + FONT_STUDIO = 0x01, + //! Alias for bold studio font + FONT_STUDIO_BOLD = FONT_STUDIO | FONT_BOLD, + //! Alias for italic studio font (at this point not used anywhere) + FONT_STUDIO_ITALIC = FONT_STUDIO | FONT_ITALIC, - // 0x02 left for possible another font + //! SatCom font used for interface (currently bold and italic wariants aren't used anywhere) + FONT_SATCOM = 0x02, + //! Alias for bold satcom font + FONT_SATCOM_BOLD = FONT_SATCOM | FONT_BOLD, + //! Alias for italic satcom font + FONT_SATCOM_ITALIC = FONT_SATCOM | FONT_ITALIC, //! Pseudo-font loaded from textures for buttons, icons, etc. FONT_BUTTON = 0x03, diff --git a/src/graphics/model/model_io_structs.h b/src/graphics/model/model_io_structs.h index 36f4f7f1..5646bafd 100644 --- a/src/graphics/model/model_io_structs.h +++ b/src/graphics/model/model_io_structs.h @@ -188,7 +188,7 @@ struct OldModelTriangleV1 Vertex p2; Vertex p3; Material material; - char texName[20] = {}; + char texName[21] = {'\0'}; float min = 0; float max = 0; }; @@ -207,7 +207,7 @@ struct OldModelTriangleV2 Vertex p2; Vertex p3; Material material; - char texName[20] = {}; + char texName[21] = {'\0'}; float min = 0.0f; float max = 0.0f; long state = 0; @@ -231,7 +231,7 @@ struct OldModelTriangleV3 VertexTex2 p2; VertexTex2 p3; Material material; - char texName[20] = {}; + char texName[21] = {'\0'}; float min = 0.0f; float max = 0.0f; long state = 0; diff --git a/src/graphics/model/model_output.cpp b/src/graphics/model/model_output.cpp index 15ebeb75..ef94a3a5 100644 --- a/src/graphics/model/model_output.cpp +++ b/src/graphics/model/model_output.cpp @@ -328,7 +328,10 @@ void ModelOutput::WriteOldModel(const CModel& model, std::ostream &stream) t.material.ambient = triangle.ambient; t.material.diffuse = triangle.diffuse; t.material.specular = triangle.specular; - strncpy(t.texName, triangle.tex1Name.c_str(), 20); + + strncpy(t.texName, triangle.tex1Name.c_str(), sizeof(t.texName)-1); + t.texName[sizeof(t.texName)-1] = '\0'; + t.min = 0.0f; t.max = 1000000.0f; t.state = ConvertToOldState(triangle); diff --git a/src/graphics/opengl/gl14device.cpp b/src/graphics/opengl/gl14device.cpp index fc950f49..3a8b6dca 100644 --- a/src/graphics/opengl/gl14device.cpp +++ b/src/graphics/opengl/gl14device.cpp @@ -257,7 +257,6 @@ bool CGL14Device::Create() if (glVersion >= 15) { GetLogger()->Info("Core VBO supported\n", glMajor, glMinor); - m_vertexBufferType = VBT_VBO_CORE; // Set function pointers m_glGenBuffers = glGenBuffers; @@ -269,7 +268,6 @@ bool CGL14Device::Create() else if (vboARB) // VBO ARB extension available { GetLogger()->Info("ARB VBO supported\n"); - m_vertexBufferType = VBT_VBO_ARB; // Set function pointers m_glGenBuffers = glGenBuffersARB; @@ -280,8 +278,11 @@ bool CGL14Device::Create() } else // no VBO support { - GetLogger()->Info("VBO not supported\n"); - m_vertexBufferType = VBT_DISPLAY_LIST; + m_errorMessage = "Your graphics card or drivers don't support OpenGL 1.5 or vertex buffer objects.\n" + "Ensure you have the latest graphics drivers for your graphics card.\n\n"; + GetLogger()->Error(m_errorMessage.c_str()); + m_errorMessage += GetHardwareInfo(); + return false; } // This is mostly done in all modern hardware by default @@ -1299,255 +1300,93 @@ void CGL14Device::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode else assert(false); } +namespace +{ +void SetVertexAttributes(const Vertex* bufferBase, const std::vector& textureRemapping) +{ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast(bufferBase) + offsetof(Vertex, coord)); + + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast(bufferBase) + offsetof(Vertex, normal)); + + glClientActiveTexture(GL_TEXTURE0 + textureRemapping[1]); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE0 + textureRemapping[0]); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast(bufferBase) + offsetof(Vertex, texCoord)); + + glDisableClientState(GL_COLOR_ARRAY); +} + +void SetVertexAttributes(const VertexTex2* bufferBase, const std::vector& textureRemapping) +{ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, coord)); + + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, normal)); + + glClientActiveTexture(GL_TEXTURE0 + textureRemapping[1]); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, texCoord2)); + glClientActiveTexture(GL_TEXTURE0 + textureRemapping[0]); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, texCoord)); + + glDisableClientState(GL_COLOR_ARRAY); +} + +void SetVertexAttributes(const VertexCol* bufferBase, const std::vector& textureRemapping) +{ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(bufferBase) + offsetof(VertexCol, coord)); + + glDisableClientState(GL_NORMAL_ARRAY); + + glClientActiveTexture(GL_TEXTURE0 + textureRemapping[1]); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE0 + textureRemapping[0]); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(bufferBase) + offsetof(VertexCol, color)); +} +} // namespace + void CGL14Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int vertexCount, Color color) { - Vertex* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].texCoord)); - + m_glBindBuffer(GL_ARRAY_BUFFER, 0); + SetVertexAttributes(vertices, m_remap); glColor4fv(color.Array()); glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0 } void CGL14Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, Color color) { - VertexTex2* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord2)); - + m_glBindBuffer(GL_ARRAY_BUFFER, 0); + SetVertexAttributes(vertices, m_remap); glColor4fv(color.Array()); glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - - glDisableClientState(GL_TEXTURE_COORD_ARRAY); } void CGL14Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount) { - VertexCol* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].color)); + m_glBindBuffer(GL_ARRAY_BUFFER, 0); + SetVertexAttributes(vertices, m_remap); glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); -} - -void CGL14Device::DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) -{ - const char *ptr = reinterpret_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(format.vertex.size, - TransformType(format.vertex.type), - format.vertex.stride, - ptr + format.vertex.offset); - - if (format.color.enabled) - { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(format.color.size, - TransformType(format.color.type), - format.color.stride, - ptr + format.color.offset); - } - else - glColor4fv(format.color.values); - - if (format.normal.enabled) - { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(TransformType(format.normal.type), - format.normal.stride, - ptr + format.normal.offset); - } - else - glNormal3fv(format.normal.values); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - if (format.tex1.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex1.size, - TransformType(format.tex1.type), - format.tex1.stride, - ptr + format.tex1.offset); - } - else - glTexCoord2fv(format.tex1.values); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); - if (format.tex2.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex2.size, - TransformType(format.tex2.type), - format.tex2.stride, - ptr + format.tex2.offset); - } - else - glTexCoord2fv(format.tex2.values); - - glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - - if (format.color.enabled) glDisableClientState(GL_COLOR_ARRAY); - if (format.normal.enabled) glDisableClientState(GL_NORMAL_ARRAY); - - if (format.tex1.enabled) - { - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - - if (format.tex2.enabled) - { - glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } -} - -void CGL14Device::DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) -{ - const char *ptr = reinterpret_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(format.vertex.size, - TransformType(format.vertex.type), - format.vertex.stride, - ptr + format.vertex.offset); - - if (format.color.enabled) - { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(format.color.size, - TransformType(format.color.type), - format.color.stride, - ptr + format.color.offset); - } - else - glColor4fv(format.color.values); - - if (format.normal.enabled) - { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(TransformType(format.normal.type), - format.normal.stride, - ptr + format.normal.offset); - } - else - glNormal3fv(format.normal.values); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - if (format.tex1.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex1.size, - TransformType(format.tex1.type), - format.tex1.stride, - ptr + format.tex1.offset); - } - else - glTexCoord2fv(format.tex1.values); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); - if (format.tex2.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex2.size, - TransformType(format.tex2.type), - format.tex2.stride, - ptr + format.tex2.offset); - } - else - glTexCoord2fv(format.tex2.values); - - GLenum t = TranslateGfxPrimitive(type); - - if (m_multiDrawArrays) - { - glMultiDrawArrays(t, first, count, drawCount); - } - else - { - for (int i = 0; i < drawCount; i++) - glDrawArrays(t, first[i], count[i]); - } - - glDisableClientState(GL_VERTEX_ARRAY); - - if (format.color.enabled) glDisableClientState(GL_COLOR_ARRAY); - if (format.normal.enabled) glDisableClientState(GL_NORMAL_ARRAY); - - if (format.tex1.enabled) - { - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - - if (format.tex2.enabled) - { - glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } } void CGL14Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, int first[], int count[], int drawCount, Color color) { - Vertex* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].texCoord)); - + m_glBindBuffer(GL_ARRAY_BUFFER, 0); + SetVertexAttributes(vertices, m_remap); glColor4fv(color.Array()); GLenum t = TranslateGfxPrimitive(type); @@ -1561,31 +1400,13 @@ void CGL14Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, for (int i = 0; i < drawCount; i++) glDrawArrays(t, first[i], count[i]); } - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0 } void CGL14Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices, int first[], int count[], int drawCount, Color color) { - VertexTex2* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord2)); - + m_glBindBuffer(GL_ARRAY_BUFFER, 0); + SetVertexAttributes(vertices, m_remap); glColor4fv(color.Array()); GLenum t = TranslateGfxPrimitive(type); @@ -1599,25 +1420,13 @@ void CGL14Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices, for (int i = 0; i < drawCount; i++) glDrawArrays(t, first[i], count[i]); } - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); } void CGL14Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, int first[], int count[], int drawCount) { - VertexCol* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].color)); + m_glBindBuffer(GL_ARRAY_BUFFER, 0); + SetVertexAttributes(vertices, m_remap); GLenum t = TranslateGfxPrimitive(type); @@ -1630,289 +1439,81 @@ void CGL14Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, for (int i = 0; i < drawCount; i++) glDrawArrays(t, first[i], count[i]); } - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); } -unsigned int CGL14Device::CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) +template +unsigned int CGL14Device::CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { - unsigned int id = 0; - if (m_vertexBufferType != VBT_DISPLAY_LIST) - { - id = ++m_lastVboId; + unsigned int id = ++m_lastVboId; - VboObjectInfo info; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_NORMAL; - info.vertexCount = vertexCount; - info.bufferId = 0; + VboObjectInfo info; + info.primitiveType = primitiveType; + info.vertexType = Vertex::VERTEX_TYPE; + info.vertexCount = vertexCount; + info.bufferId = 0; - m_glGenBuffers(1, &info.bufferId); - m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); - m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW); - m_glBindBuffer(GL_ARRAY_BUFFER, 0); + m_glGenBuffers(1, &info.bufferId); + m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); + m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW); + m_glBindBuffer(GL_ARRAY_BUFFER, 0); - m_vboObjects[id] = info; - } - else - { - id = glGenLists(1); - - glNewList(id, GL_COMPILE); - - DrawPrimitive(primitiveType, vertices, vertexCount); - - glEndList(); - } + m_vboObjects[id] = info; return id; } -unsigned int CGL14Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) +template +void CGL14Device::UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { - unsigned int id = 0; - if (m_vertexBufferType != VBT_DISPLAY_LIST) - { - id = ++m_lastVboId; + auto it = m_vboObjects.find(bufferId); + if (it == m_vboObjects.end()) + return; - VboObjectInfo info; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_TEX2; - info.vertexCount = vertexCount; - info.bufferId = 0; + VboObjectInfo& info = (*it).second; + info.primitiveType = primitiveType; + info.vertexType = Vertex::VERTEX_TYPE; + info.vertexCount = vertexCount; - m_glGenBuffers(1, &info.bufferId); - m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); - m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexTex2), vertices, GL_STATIC_DRAW); - m_glBindBuffer(GL_ARRAY_BUFFER, 0); - - m_vboObjects[id] = info; - } - else - { - id = glGenLists(1); - - glNewList(id, GL_COMPILE); - - DrawPrimitive(primitiveType, vertices, vertexCount); - - glEndList(); - } - - return id; -} - -unsigned int CGL14Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) -{ - unsigned int id = 0; - if (m_vertexBufferType != VBT_DISPLAY_LIST) - { - id = ++m_lastVboId; - - VboObjectInfo info; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_COL; - info.vertexCount = vertexCount; - info.bufferId = 0; - - m_glGenBuffers(1, &info.bufferId); - m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); - m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexCol), vertices, GL_STATIC_DRAW); - m_glBindBuffer(GL_ARRAY_BUFFER, 0); - - m_vboObjects[id] = info; - } - else - { - id = glGenLists(1); - - glNewList(id, GL_COMPILE); - - DrawPrimitive(primitiveType, vertices, vertexCount); - - glEndList(); - } - - return id; -} - -void CGL14Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) -{ - if (m_vertexBufferType != VBT_DISPLAY_LIST) - { - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; - - VboObjectInfo& info = (*it).second; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_NORMAL; - info.vertexCount = vertexCount; - - m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); - m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW); - m_glBindBuffer(GL_ARRAY_BUFFER, 0); - } - else - { - glNewList(bufferId, GL_COMPILE); - - DrawPrimitive(primitiveType, vertices, vertexCount); - - glEndList(); - } -} - -void CGL14Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) -{ - if (m_vertexBufferType != VBT_DISPLAY_LIST) - { - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; - - VboObjectInfo& info = (*it).second; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_TEX2; - info.vertexCount = vertexCount; - - m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); - m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexTex2), vertices, GL_STATIC_DRAW); - m_glBindBuffer(GL_ARRAY_BUFFER, 0); - } - else - { - glNewList(bufferId, GL_COMPILE); - - DrawPrimitive(primitiveType, vertices, vertexCount); - - glEndList(); - } -} - -void CGL14Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) -{ - if (m_vertexBufferType != VBT_DISPLAY_LIST) - { - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; - - VboObjectInfo& info = (*it).second; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_COL; - info.vertexCount = vertexCount; - - m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); - m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexCol), vertices, GL_STATIC_DRAW); - m_glBindBuffer(GL_ARRAY_BUFFER, 0); - } - else - { - glNewList(bufferId, GL_COMPILE); - - DrawPrimitive(primitiveType, vertices, vertexCount); - - glEndList(); - } + m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); + m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW); + m_glBindBuffer(GL_ARRAY_BUFFER, 0); } void CGL14Device::DrawStaticBuffer(unsigned int bufferId) { - if (m_vertexBufferType != VBT_DISPLAY_LIST) + auto it = m_vboObjects.find(bufferId); + if (it == m_vboObjects.end()) + return; + + m_glBindBuffer(GL_ARRAY_BUFFER, (*it).second.bufferId); + + if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) { - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; - - m_glBindBuffer(GL_ARRAY_BUFFER, (*it).second.bufferId); - - if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) - { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, normal)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, texCoord)); - } - else if ((*it).second.vertexType == VERTEX_TYPE_TEX2) - { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, normal)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord2)); - } - else if ((*it).second.vertexType == VERTEX_TYPE_COL) - { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), static_cast(nullptr) + offsetof(VertexCol, coord)); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, sizeof(VertexCol), static_cast(nullptr) + offsetof(VertexCol, color)); - } - - GLenum mode = TranslateGfxPrimitive((*it).second.primitiveType); - glDrawArrays(mode, 0, (*it).second.vertexCount); - - if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0 - } - else if ((*it).second.vertexType == VERTEX_TYPE_TEX2) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - else if ((*it).second.vertexType == VERTEX_TYPE_COL) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - } - - m_glBindBuffer(GL_ARRAY_BUFFER, 0); + SetVertexAttributes(static_cast(nullptr), m_remap); } - else + else if ((*it).second.vertexType == VERTEX_TYPE_TEX2) { - glCallList(bufferId); + SetVertexAttributes(static_cast(nullptr), m_remap); } + else if ((*it).second.vertexType == VERTEX_TYPE_COL) + { + SetVertexAttributes(static_cast(nullptr), m_remap); + } + + GLenum mode = TranslateGfxPrimitive((*it).second.primitiveType); + + glDrawArrays(mode, 0, (*it).second.vertexCount); } void CGL14Device::DestroyStaticBuffer(unsigned int bufferId) { - if (m_vertexBufferType != VBT_DISPLAY_LIST) - { - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; + auto it = m_vboObjects.find(bufferId); + if (it == m_vboObjects.end()) + return; - m_glDeleteBuffers(1, &(*it).second.bufferId); + m_glDeleteBuffers(1, &(*it).second.bufferId); - m_vboObjects.erase(it); - } - else - { - glDeleteLists(bufferId, 1); - } + m_vboObjects.erase(it); } /* Based on libwine's implementation */ diff --git a/src/graphics/opengl/gl14device.h b/src/graphics/opengl/gl14device.h index 7bc533af..39785efd 100644 --- a/src/graphics/opengl/gl14device.h +++ b/src/graphics/opengl/gl14device.h @@ -43,17 +43,6 @@ namespace Gfx { -/** - \enum VertexBufferType - \brief Specifies type of vertex buffer to use - */ -enum VertexBufferType -{ - VBT_DISPLAY_LIST, //! use display lists - VBT_VBO_CORE, //! use core OpenGL 1.5 VBOs - VBT_VBO_ARB //! use ARB extension VBOs -}; - enum ShadowMappingSupport { SMS_NONE, //! No support for depth textures @@ -119,11 +108,6 @@ public: void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT) override; - virtual void DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) override; - virtual void DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) override; - virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; virtual void DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, @@ -139,12 +123,31 @@ public: virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices, int first[], int count[], int drawCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override; + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } + void DrawStaticBuffer(unsigned int bufferId) override; void DestroyStaticBuffer(unsigned int bufferId) override; @@ -214,6 +217,11 @@ private: //! Disables shadows void DisableShadows(); + template + unsigned int CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); + template + void UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); + private: //! Current config DeviceConfig m_config; @@ -260,14 +268,6 @@ private: //! Map of framebuffers std::map> m_framebuffers; - //! Type of vertex structure - enum VertexType - { - VERTEX_TYPE_NORMAL, - VERTEX_TYPE_TEX2, - VERTEX_TYPE_COL, - }; - //! Info about static VBO buffers struct VboObjectInfo { @@ -284,8 +284,6 @@ private: bool m_multiDrawArrays = false; //! Framebuffer support FramebufferSupport m_framebufferSupport = FBS_NONE; - //! Which vertex buffer type to use - VertexBufferType m_vertexBufferType = VBT_DISPLAY_LIST; //! Map of saved VBO objects std::map m_vboObjects; //! Last ID of VBO object diff --git a/src/graphics/opengl/gl21device.cpp b/src/graphics/opengl/gl21device.cpp index f0bbdbb5..41660578 100644 --- a/src/graphics/opengl/gl21device.cpp +++ b/src/graphics/opengl/gl21device.cpp @@ -1115,33 +1115,70 @@ void CGL21Device::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode else assert(false); } +namespace +{ +void SetVertexAttributes(const Vertex* bufferBase) +{ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast(bufferBase) + offsetof(Vertex, coord)); + + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast(bufferBase) + offsetof(Vertex, normal)); + + glClientActiveTexture(GL_TEXTURE1); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast(bufferBase) + offsetof(Vertex, texCoord)); + + glDisableClientState(GL_COLOR_ARRAY); +} + +void SetVertexAttributes(const VertexTex2* bufferBase) +{ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, coord)); + + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, normal)); + + glClientActiveTexture(GL_TEXTURE1); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, texCoord2)); + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, texCoord)); + + glDisableClientState(GL_COLOR_ARRAY); +} + +void SetVertexAttributes(const VertexCol* bufferBase) +{ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(bufferBase) + offsetof(VertexCol, coord)); + + glDisableClientState(GL_NORMAL_ARRAY); + + glClientActiveTexture(GL_TEXTURE1); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(bufferBase) + offsetof(VertexCol, color)); +} +} // namespace + void CGL21Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int vertexCount, Color color) { if (m_updateLights) UpdateLights(); BindVBO(0); - - Vertex* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0); - - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].texCoord)); - + SetVertexAttributes(vertices); glColor4fv(color.Array()); glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0 } void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, @@ -1150,33 +1187,10 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, if (m_updateLights) UpdateLights(); BindVBO(0); - - VertexTex2* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord)); - - glClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord2)); - + SetVertexAttributes(vertices); glColor4fv(color.Array()); glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 - - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); } void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount) @@ -1184,179 +1198,8 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i if (m_updateLights) UpdateLights(); BindVBO(0); - - VertexCol* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].color)); - + SetVertexAttributes(vertices); glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); -} - -void CGL21Device::DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) -{ - if (m_updateLights) UpdateLights(); - - BindVBO(0); - - const char *ptr = reinterpret_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(format.vertex.size, - TransformType(format.vertex.type), - format.vertex.stride, - ptr + format.vertex.offset); - - if (format.color.enabled) - { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(format.color.size, - TransformType(format.color.type), - format.color.stride, - ptr + format.color.offset); - } - else - glColor4fv(format.color.values); - - if (format.normal.enabled) - { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(TransformType(format.normal.type), - format.normal.stride, - ptr + format.normal.offset); - } - else - glNormal3fv(format.normal.values); - - glClientActiveTexture(GL_TEXTURE0); - if (format.tex1.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex1.size, - TransformType(format.tex1.type), - format.tex1.stride, - ptr + format.tex1.offset); - } - else - glTexCoord2fv(format.tex1.values); - - glClientActiveTexture(GL_TEXTURE1); - if (format.tex2.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex2.size, - TransformType(format.tex2.type), - format.tex2.stride, - ptr + format.tex2.offset); - } - else - glTexCoord2fv(format.tex2.values); - - glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - - if (format.color.enabled) glDisableClientState(GL_COLOR_ARRAY); - if (format.normal.enabled) glDisableClientState(GL_NORMAL_ARRAY); - - if (format.tex1.enabled) - { - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - - if (format.tex2.enabled) - { - glClientActiveTexture(GL_TEXTURE1); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } -} - -void CGL21Device::DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) -{ - if (m_updateLights) UpdateLights(); - - BindVBO(0); - - const char *ptr = reinterpret_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(format.vertex.size, - TransformType(format.vertex.type), - format.vertex.stride, - ptr + format.vertex.offset); - - if (format.color.enabled) - { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(format.color.size, - TransformType(format.color.type), - format.color.stride, - ptr + format.color.offset); - } - else - glColor4fv(format.color.values); - - if (format.normal.enabled) - { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(TransformType(format.normal.type), - format.normal.stride, - ptr + format.normal.offset); - } - else - glNormal3fv(format.normal.values); - - glClientActiveTexture(GL_TEXTURE0); - if (format.tex1.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex1.size, - TransformType(format.tex1.type), - format.tex1.stride, - ptr + format.tex1.offset); - } - else - glTexCoord2fv(format.tex1.values); - - glClientActiveTexture(GL_TEXTURE1); - if (format.tex2.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex2.size, - TransformType(format.tex2.type), - format.tex2.stride, - ptr + format.tex2.offset); - } - else - glTexCoord2fv(format.tex2.values); - - glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); - - glDisableClientState(GL_VERTEX_ARRAY); - - if (format.color.enabled) glDisableClientState(GL_COLOR_ARRAY); - if (format.normal.enabled) glDisableClientState(GL_NORMAL_ARRAY); - - if (format.tex1.enabled) - { - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - - if (format.tex2.enabled) - { - glClientActiveTexture(GL_TEXTURE1); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } } void CGL21Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, @@ -1365,26 +1208,10 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, if (m_updateLights) UpdateLights(); BindVBO(0); - - Vertex* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].texCoord)); - + SetVertexAttributes(vertices); glColor4fv(color.Array()); glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0 } void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices, @@ -1393,33 +1220,10 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices, if (m_updateLights) UpdateLights(); BindVBO(0); - - VertexTex2* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord)); - - glClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord2)); - + SetVertexAttributes(vertices); glColor4fv(color.Array()); glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 - - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); } void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, @@ -1428,28 +1232,20 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, if (m_updateLights) UpdateLights(); BindVBO(0); - - VertexCol* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].color)); + SetVertexAttributes(vertices); glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); } -unsigned int CGL21Device::CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) + +template +unsigned int CGL21Device::CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { unsigned int id = ++m_lastVboId; VboObjectInfo info; info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_NORMAL; + info.vertexType = Vertex::VERTEX_TYPE; info.vertexCount = vertexCount; info.bufferId = 0; info.size = vertexCount * sizeof(Vertex); @@ -1463,47 +1259,8 @@ unsigned int CGL21Device::CreateStaticBuffer(PrimitiveType primitiveType, const return id; } -unsigned int CGL21Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) -{ - unsigned int id = ++m_lastVboId; - - VboObjectInfo info; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_TEX2; - info.vertexCount = vertexCount; - info.bufferId = 0; - info.size = vertexCount * sizeof(VertexTex2); - - glGenBuffers(1, &info.bufferId); - BindVBO(info.bufferId); - glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW); - - m_vboObjects[id] = info; - - return id; -} - -unsigned int CGL21Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) -{ - unsigned int id = ++m_lastVboId; - - VboObjectInfo info; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_COL; - info.vertexCount = vertexCount; - info.bufferId = 0; - info.size = vertexCount * sizeof(VertexCol); - - glGenBuffers(1, &info.bufferId); - BindVBO(info.bufferId); - glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW); - - m_vboObjects[id] = info; - - return id; -} - -void CGL21Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) +template +void CGL21Device::UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { auto it = m_vboObjects.find(bufferId); if (it == m_vboObjects.end()) @@ -1513,7 +1270,7 @@ void CGL21Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primit VboObjectInfo& info = (*it).second; info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_NORMAL; + info.vertexType = Vertex::VERTEX_TYPE; info.vertexCount = vertexCount; BindVBO(info.bufferId); @@ -1529,58 +1286,6 @@ void CGL21Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primit } } -void CGL21Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) -{ - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; - - VboObjectInfo& info = (*it).second; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_TEX2; - info.vertexCount = vertexCount; - - int newSize = vertexCount * sizeof(VertexTex2); - - BindVBO(info.bufferId); - - if (info.size < newSize) - { - glBufferData(GL_ARRAY_BUFFER, newSize, vertices, GL_STATIC_DRAW); - info.size = newSize; - } - else - { - glBufferSubData(GL_ARRAY_BUFFER, 0, newSize, vertices); - } -} - -void CGL21Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) -{ - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; - - VboObjectInfo& info = (*it).second; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_COL; - info.vertexCount = vertexCount; - - int newSize = vertexCount * sizeof(VertexCol); - - BindVBO(info.bufferId); - - if (info.size < newSize) - { - glBufferData(GL_ARRAY_BUFFER, newSize, vertices, GL_STATIC_DRAW); - info.size = newSize; - } - else - { - glBufferSubData(GL_ARRAY_BUFFER, 0, newSize, vertices); - } -} - void CGL21Device::DrawStaticBuffer(unsigned int bufferId) { auto it = m_vboObjects.find(bufferId); @@ -1593,64 +1298,20 @@ void CGL21Device::DrawStaticBuffer(unsigned int bufferId) if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, normal)); - - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, texCoord)); + SetVertexAttributes(static_cast(nullptr)); } else if ((*it).second.vertexType == VERTEX_TYPE_TEX2) { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, normal)); - - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord)); - - glClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord2)); + SetVertexAttributes(static_cast(nullptr)); } else if ((*it).second.vertexType == VERTEX_TYPE_COL) { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), static_cast(nullptr) + offsetof(VertexCol, coord)); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, sizeof(VertexCol), static_cast(nullptr) + offsetof(VertexCol, color)); + SetVertexAttributes(static_cast(nullptr)); } GLenum mode = TranslateGfxPrimitive((*it).second.primitiveType); + glDrawArrays(mode, 0, (*it).second.vertexCount); - - if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0 - } - else if ((*it).second.vertexType == VERTEX_TYPE_TEX2) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 - - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - else if ((*it).second.vertexType == VERTEX_TYPE_COL) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - } } void CGL21Device::DestroyStaticBuffer(unsigned int bufferId) diff --git a/src/graphics/opengl/gl21device.h b/src/graphics/opengl/gl21device.h index 6e1bf261..873afdf7 100644 --- a/src/graphics/opengl/gl21device.h +++ b/src/graphics/opengl/gl21device.h @@ -100,11 +100,6 @@ public: void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT) override; - virtual void DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) override; - virtual void DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) override; - virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; virtual void DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, @@ -120,12 +115,30 @@ public: virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices, int first[], int count[], int drawCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override; + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } void DrawStaticBuffer(unsigned int bufferId) override; void DestroyStaticBuffer(unsigned int bufferId) override; @@ -192,6 +205,11 @@ private: //! Binds texture inline void BindTexture(int index, GLuint texture); + template + unsigned int CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); + template + void UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); + private: //! Current config DeviceConfig m_config; @@ -232,14 +250,6 @@ private: //! Map of framebuffers std::map> m_framebuffers; - //! Type of vertex structure - enum VertexType - { - VERTEX_TYPE_NORMAL, - VERTEX_TYPE_TEX2, - VERTEX_TYPE_COL, - }; - //! Info about static VBO buffers struct VboObjectInfo { diff --git a/src/graphics/opengl/gl33device.cpp b/src/graphics/opengl/gl33device.cpp index 776f1547..0180f247 100644 --- a/src/graphics/opengl/gl33device.cpp +++ b/src/graphics/opengl/gl33device.cpp @@ -1158,50 +1158,6 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); } -void CGL33Device::DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) -{ - if (m_updateLights) UpdateLights(); - - DynamicBuffer& buffer = m_dynamicBuffer; - - BindVAO(buffer.vao); - BindVBO(buffer.vbo); - - unsigned int offset = UploadVertexData(buffer, vertices, size); - - // Update vertex attribute bindings - UpdateVertexAttribute(0, format.vertex, offset); - UpdateVertexAttribute(1, format.normal, offset); - UpdateVertexAttribute(2, format.color, offset); - UpdateVertexAttribute(3, format.tex1, offset); - UpdateVertexAttribute(4, format.tex2, offset); - - glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); -} - -void CGL33Device::DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) -{ - if (m_updateLights) UpdateLights(); - - DynamicBuffer& buffer = m_dynamicBuffer; - - BindVAO(buffer.vao); - BindVBO(buffer.vbo); - - unsigned int offset = UploadVertexData(buffer, vertices, size); - - // Update vertex attribute bindings - UpdateVertexAttribute(0, format.vertex, offset); - UpdateVertexAttribute(1, format.normal, offset); - UpdateVertexAttribute(2, format.color, offset); - UpdateVertexAttribute(3, format.tex1, offset); - UpdateVertexAttribute(4, format.tex2, offset); - - glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); -} - void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, int first[], int count[], int drawCount, Color color) { @@ -1358,27 +1314,12 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); } -unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) +namespace { - unsigned int id = 0; - - id = ++m_lastVboId; - - VertexBufferInfo info; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_NORMAL; - info.vertexCount = vertexCount; - info.size = vertexCount * sizeof(Vertex); - - glGenVertexArrays(1, &info.vao); - BindVAO(info.vao); - - glGenBuffers(1, &info.vbo); - BindVBO(info.vbo); - - glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW); - m_vboMemory += info.size; +template void SetVertexAttributes(); +template <> void SetVertexAttributes() +{ // Vertex coordinate glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast(offsetof(Vertex, coord))); @@ -1398,33 +1339,10 @@ unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const // Texture coordinate 1 glDisableVertexAttribArray(4); glVertexAttrib2f(4, 0.0f, 0.0f); - - m_vboObjects[id] = info; - - return id; } -unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) +template <> void SetVertexAttributes() { - unsigned int id = 0; - - id = ++m_lastVboId; - - VertexBufferInfo info; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_TEX2; - info.vertexCount = vertexCount; - info.size = vertexCount * sizeof(VertexTex2); - - glGenVertexArrays(1, &info.vao); - BindVAO(info.vao); - - glGenBuffers(1, &info.vbo); - BindVBO(info.vbo); - - glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW); - m_vboMemory += info.size; - // Vertex coordinate glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, coord))); @@ -1444,31 +1362,10 @@ unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const // Texture coordinate 1 glEnableVertexAttribArray(4); glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, texCoord2))); - - m_vboObjects[id] = info; - - return id; } -unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) +template <> void SetVertexAttributes() { - unsigned int id = ++m_lastVboId; - - VertexBufferInfo info; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_COL; - info.vertexCount = vertexCount; - info.size = vertexCount * sizeof(VertexCol); - - glGenVertexArrays(1, &info.vao); - BindVAO(info.vao); - - glGenBuffers(1, &info.vbo); - BindVBO(info.vbo); - - glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW); - m_vboMemory += info.size; - // Vertex coordinate glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol), reinterpret_cast(offsetof(VertexCol, coord))); @@ -1488,13 +1385,40 @@ unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const // Texture coordinate 1 glDisableVertexAttribArray(4); glVertexAttrib2f(4, 0.0f, 0.0f); +} +} // namespace + +template +unsigned int CGL33Device::CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) +{ + unsigned int id = 0; + + id = ++m_lastVboId; + + VertexBufferInfo info; + info.primitiveType = primitiveType; + info.vertexType = Vertex::VERTEX_TYPE; + info.vertexCount = vertexCount; + info.size = vertexCount * sizeof(Vertex); + + glGenVertexArrays(1, &info.vao); + BindVAO(info.vao); + + glGenBuffers(1, &info.vbo); + BindVBO(info.vbo); + + glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW); + m_vboMemory += info.size; + + SetVertexAttributes(); m_vboObjects[id] = info; return id; } -void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) +template +void CGL33Device::UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { auto it = m_vboObjects.find(bufferId); if (it == m_vboObjects.end()) @@ -1504,12 +1428,12 @@ void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primit unsigned int size = vertexCount * sizeof(Vertex); - bool changed = (info.vertexType != VERTEX_TYPE_NORMAL) || (size > info.size); + bool changed = (info.vertexType != Vertex::VERTEX_TYPE) || (size > info.size); - if (info.vertexType != VERTEX_TYPE_NORMAL) CLogger::GetInstance().Debug("Changing static buffer type\n"); + if (info.vertexType != Vertex::VERTEX_TYPE) CLogger::GetInstance().Debug("Changing static buffer type\n"); info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_NORMAL; + info.vertexType = Vertex::VERTEX_TYPE; info.vertexCount = vertexCount; BindVBO(info.vbo); @@ -1531,143 +1455,7 @@ void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primit { BindVAO(info.vao); - // Vertex coordinate - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast(offsetof(Vertex, coord))); - - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast(offsetof(Vertex, normal))); - - // Color - glDisableVertexAttribArray(2); - glVertexAttrib4f(2, 1.0f, 1.0f, 1.0f, 1.0f); - - // Texture coordinate 0 - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast(offsetof(Vertex, texCoord))); - - // Texture coordinate 1 - glDisableVertexAttribArray(4); - glVertexAttrib2f(4, 0.0f, 0.0f); - } -} - -void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) -{ - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; - - VertexBufferInfo& info = (*it).second; - - unsigned int size = vertexCount * sizeof(VertexTex2); - - bool changed = (info.vertexType != VERTEX_TYPE_TEX2) || (size > info.size); - - if (info.vertexType != VERTEX_TYPE_TEX2) CLogger::GetInstance().Debug("Changing static buffer type\n"); - - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_TEX2; - info.vertexCount = vertexCount; - - BindVBO(info.vbo); - - if (info.size < size) - { - CLogger::GetInstance().Debug("Resizing static buffer: %d->%d\n", info.size, size); - glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW); - m_vboMemory -= info.size; - info.size = size; - m_vboMemory += info.size; - } - else - { - glBufferSubData(GL_ARRAY_BUFFER, 0, size, vertices); - } - - if (changed) // Update vertex array bindings - { - BindVAO(info.vao); - - // Vertex coordinate - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, coord))); - - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, normal))); - - // Color - glDisableVertexAttribArray(2); - glVertexAttrib4f(2, 1.0f, 1.0f, 1.0f, 1.0f); - - // Texture coordinate 0 - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, texCoord))); - - // Texture coordinate 1 - glEnableVertexAttribArray(4); - glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, texCoord2))); - } -} - -void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) -{ - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; - - VertexBufferInfo& info = (*it).second; - - unsigned int size = vertexCount * sizeof(VertexCol); - - bool changed = (info.vertexType != VERTEX_TYPE_COL) || (size > info.size); - - if (info.vertexType != VERTEX_TYPE_NORMAL) CLogger::GetInstance().Debug("Changing static buffer type\n"); - - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_COL; - info.vertexCount = vertexCount; - - BindVBO(info.vbo); - - if (info.size < size) - { - CLogger::GetInstance().Debug("Resizing static buffer: %d->%d\n", info.size, size); - glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW); - m_vboMemory -= info.size; - info.size = size; - m_vboMemory += info.size; - } - else - { - glBufferSubData(GL_ARRAY_BUFFER, 0, size, vertices); - } - - if (changed) // Update vertex array bindings - { - BindVAO(info.vao); - - // Vertex coordinate - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol), reinterpret_cast(offsetof(VertexCol, coord))); - - // Normal - glDisableVertexAttribArray(1); - glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f); - - // Color - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol), reinterpret_cast(offsetof(VertexCol, color))); - - // Texture coordinate 0 - glDisableVertexAttribArray(3); - glVertexAttrib2f(3, 0.0f, 0.0f); - - // Texture coordinate 1 - glDisableVertexAttribArray(4); - glVertexAttrib2f(4, 0.0f, 0.0f); + SetVertexAttributes(); } } @@ -2092,25 +1880,6 @@ unsigned int CGL33Device::UploadVertexData(DynamicBuffer& buffer, const void* da return currentOffset; } -void CGL33Device::UpdateVertexAttribute(int index, const VertexAttribute &attribute, int offset) -{ - if (attribute.enabled) - { - glEnableVertexAttribArray(index); - glVertexAttribPointer(index, - attribute.size, - TranslateType(attribute.type), - attribute.normalized ? GL_TRUE : GL_FALSE, - attribute.stride, - reinterpret_cast(offset + attribute.offset)); - } - else - { - glDisableVertexAttribArray(index); - glVertexAttrib4fv(index, attribute.values); - } -} - bool CGL33Device::IsAnisotropySupported() { return m_capabilities.anisotropySupported; diff --git a/src/graphics/opengl/gl33device.h b/src/graphics/opengl/gl33device.h index b0b452e0..7b3aa26a 100644 --- a/src/graphics/opengl/gl33device.h +++ b/src/graphics/opengl/gl33device.h @@ -115,11 +115,6 @@ public: void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT) override; - virtual void DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) override; - virtual void DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) override; - virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; virtual void DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, @@ -135,12 +130,30 @@ public: virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices, int first[], int count[], int drawCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override; + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } void DrawStaticBuffer(unsigned int bufferId) override; void DestroyStaticBuffer(unsigned int bufferId) override; @@ -213,7 +226,10 @@ private: //! Uploads data to dynamic buffer and returns offset to it unsigned int UploadVertexData(DynamicBuffer& buffer, const void* data, unsigned int size); - inline void UpdateVertexAttribute(int index, const VertexAttribute &attribute, int offset); + template + unsigned int CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); + template + void UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); private: //! Current config @@ -256,14 +272,6 @@ private: //! Free texture unit const int m_freeTexture = 3; - //! Type of vertex structure - enum VertexType - { - VERTEX_TYPE_NORMAL, - VERTEX_TYPE_TEX2, - VERTEX_TYPE_COL, - }; - //! Info about static VBO buffers struct VertexBufferInfo { diff --git a/src/graphics/opengl/glframebuffer.cpp b/src/graphics/opengl/glframebuffer.cpp index c58d90d7..75fe020a 100644 --- a/src/graphics/opengl/glframebuffer.cpp +++ b/src/graphics/opengl/glframebuffer.cpp @@ -55,7 +55,7 @@ bool CGLFramebuffer::Create() glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); // create color texture - if (m_params.colorTexture) + if (m_params.colorAttachment == FramebufferParams::AttachmentType::Texture) { GLint previous; glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous); @@ -76,7 +76,7 @@ bool CGLFramebuffer::Create() glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorTexture, 0); } // create color renderbuffer - else + else if (m_params.colorAttachment == FramebufferParams::AttachmentType::Renderbuffer) { glGenRenderbuffers(1, &m_colorRenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer); @@ -92,6 +92,10 @@ bool CGLFramebuffer::Create() glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRenderbuffer); } + else + { + glDrawBuffer(GL_NONE); + } GLuint depthFormat = 0; @@ -104,7 +108,7 @@ bool CGLFramebuffer::Create() } // create depth texture - if (m_params.depthTexture) + if (m_params.depthAttachment == FramebufferParams::AttachmentType::Texture) { GLint previous; glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous); @@ -132,7 +136,7 @@ bool CGLFramebuffer::Create() GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0); } // create depth renderbuffer - else + else if (m_params.depthAttachment == FramebufferParams::AttachmentType::Renderbuffer) { glGenRenderbuffers(1, &m_depthRenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer); @@ -323,7 +327,7 @@ bool CGLFramebufferEXT::Create() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); // create color texture - if (m_params.colorTexture) + if (m_params.colorAttachment == FramebufferParams::AttachmentType::Texture) { GLint previous; glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous); @@ -346,7 +350,7 @@ bool CGLFramebufferEXT::Create() GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_colorTexture, 0); } // create color renderbuffer - else + else if (m_params.colorAttachment == FramebufferParams::AttachmentType::Renderbuffer) { glGenRenderbuffersEXT(1, &m_colorRenderbuffer); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_colorRenderbuffer); @@ -363,6 +367,10 @@ bool CGLFramebufferEXT::Create() glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_colorRenderbuffer); } + else + { + glDrawBuffer(GL_NONE); + } GLuint depthFormat = 0; @@ -375,7 +383,7 @@ bool CGLFramebufferEXT::Create() } // create depth texture - if (m_params.depthTexture) + if (m_params.depthAttachment == FramebufferParams::AttachmentType::Texture) { GLint previous; glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous); @@ -403,7 +411,7 @@ bool CGLFramebufferEXT::Create() GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, m_depthTexture, 0); } // create depth renderbuffer - else + else if (m_params.depthAttachment == FramebufferParams::AttachmentType::Renderbuffer) { glGenRenderbuffersEXT(1, &m_depthRenderbuffer); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthRenderbuffer); diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index 2cabcccf..58d90541 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -60,6 +60,7 @@ #include "level/parser/parser.h" #include "math/const.h" +#include "math/func.h" #include "math/geometry.h" #include "object/object.h" @@ -119,6 +120,10 @@ const float UNIT = 4.0f; // default for g_unit float g_unit; // conversion factor +// Min/max values for the game speed. +const float MIN_SPEED = 1/8.0f; +const float MAX_SPEED = 256.0f; + // Reference colors used when recoloring textures, see ChangeColor() const Gfx::Color COLOR_REF_BOT = Gfx::Color( 10.0f/256.0f, 166.0f/256.0f, 254.0f/256.0f); // blue const Gfx::Color COLOR_REF_ALIEN = Gfx::Color(135.0f/256.0f, 170.0f/256.0f, 13.0f/256.0f); // green @@ -589,7 +594,7 @@ void CRobotMain::ChangePhase(Phase phase) ddim.x = dim.x*15; ddim.y = dim.y*3.0f; pe = m_interface->CreateEdit(pos, ddim, 0, EVENT_EDIT0); pe->SetGenericMode(true); - pe->SetFontType(Gfx::FONT_COLOBOT); + pe->SetFontType(Gfx::FONT_COMMON); pe->SetEditCap(false); pe->SetHighlightCap(false); pe->ReadText(std::string("help/") + m_app->GetLanguageChar() + std::string("/win.txt")); @@ -779,7 +784,7 @@ bool CRobotMain::ProcessEvent(Event &event) if (IsPhaseWithWorld(m_phase)) { - if (data->key == KEY(F11)) + if (data->key == KEY(F10)) { m_debugMenu->ToggleInterface(); return false; @@ -2127,7 +2132,7 @@ void CRobotMain::CreateTooltip(Math::Point pos, const std::string& text) Math::Point start, end; - m_engine->GetText()->SizeText(text, Gfx::FONT_COLOBOT, Gfx::FONT_SIZE_SMALL, + m_engine->GetText()->SizeText(text, Gfx::FONT_COMMON, Gfx::FONT_SIZE_SMALL, corner, Gfx::TEXT_ALIGN_LEFT, start, end); @@ -2162,7 +2167,7 @@ void CRobotMain::CreateTooltip(Math::Point pos, const std::string& text) pw->SetState(Ui::STATE_SHADOW); pw->SetTrashEvent(false); - pos.y -= m_engine->GetText()->GetHeight(Gfx::FONT_COLOBOT, Gfx::FONT_SIZE_SMALL) / 2.0f; + pos.y -= m_engine->GetText()->GetHeight(Gfx::FONT_COMMON, Gfx::FONT_SIZE_SMALL) / 2.0f; pw->CreateLabel(pos, dim, -1, EVENT_LABEL2, text); } } @@ -5358,10 +5363,11 @@ void CRobotMain::UpdateChapterPassed() return m_ui->UpdateChapterPassed(); } - //! Changes game speed void CRobotMain::SetSpeed(float speed) { + speed = Math::Clamp(speed, MIN_SPEED, MAX_SPEED); + m_app->SetSimulationSpeed(speed); UpdateSpeedLabel(); } @@ -5913,7 +5919,7 @@ void CRobotMain::CreateCodeBattleInterface() int numTeams = m_scoreboard ? GetAllTeams().size() : 0; assert(numTeams < EVENT_SCOREBOARD_MAX-EVENT_SCOREBOARD+1); - float textHeight = m_engine->GetText()->GetHeight(Gfx::FONT_COLOBOT, Gfx::FONT_SIZE_SMALL); + float textHeight = m_engine->GetText()->GetHeight(Gfx::FONT_COMMON, Gfx::FONT_SIZE_SMALL); //window ddim.x = 100.0f/640.0f; diff --git a/src/object/auto/autopowerplant.cpp b/src/object/auto/autopowerplant.cpp index 37b2d7d5..d7294b93 100644 --- a/src/object/auto/autopowerplant.cpp +++ b/src/object/auto/autopowerplant.cpp @@ -82,12 +82,14 @@ void CAutoPowerPlant::DeleteObject(bool all) CObject* cargo = SearchMetal(); if ( cargo != nullptr ) { + m_object->SetPower(nullptr); CObjectManager::GetInstancePointer()->DeleteObject(cargo); } cargo = SearchPower(); if ( cargo != nullptr ) { + m_object->SetPower(nullptr); CObjectManager::GetInstancePointer()->DeleteObject(cargo); } } diff --git a/src/object/old_object.cpp b/src/object/old_object.cpp index 3acf608a..3ecbb0e8 100644 --- a/src/object/old_object.cpp +++ b/src/object/old_object.cpp @@ -284,13 +284,19 @@ void COldObject::DeleteObject(bool bAll) if (m_power != nullptr) { if (m_power->Implements(ObjectInterfaceType::Old)) + { + dynamic_cast(m_power)->SetTransporter(nullptr); dynamic_cast(m_power)->DeleteObject(bAll); + } m_power = nullptr; } if (m_cargo != nullptr) { if (m_cargo->Implements(ObjectInterfaceType::Old)) + { + dynamic_cast(m_cargo)->SetTransporter(nullptr); dynamic_cast(m_cargo)->DeleteObject(bAll); + } m_cargo = nullptr; } } diff --git a/src/script/cbottoken.cpp b/src/script/cbottoken.cpp index 06b6ea14..24b60a09 100644 --- a/src/script/cbottoken.cpp +++ b/src/script/cbottoken.cpp @@ -372,6 +372,9 @@ std::string GetHelpFilename(const char *token) if ( strcmp(token, "synchronized" ) == 0 ) helpfile = "cbot/synchro"; if ( strcmp(token, "new" ) == 0 ) helpfile = "cbot/new"; if ( strcmp(token, "this" ) == 0 ) helpfile = "cbot/this"; + if ( strcmp(token, "switch" ) == 0 || + strcmp(token, "case" ) == 0 || + strcmp(token, "default" ) == 0 ) helpfile = "cbot/switch"; if (helpfile.empty()) return ""; @@ -491,11 +494,14 @@ bool IsFunction(const char *token) const char* GetHelpText(const char *token) { - if ( strcmp(token, "if" ) == 0 ) return "if ( condition ) { bloc }"; - if ( strcmp(token, "else" ) == 0 ) return "else { bloc }"; + if ( strcmp(token, "if" ) == 0 ) return "if ( condition ) { code }"; + if ( strcmp(token, "else" ) == 0 ) return "else { code }"; if ( strcmp(token, "for" ) == 0 ) return "for ( before ; condition ; end )"; - if ( strcmp(token, "while" ) == 0 ) return "while ( condition ) { bloc }"; - if ( strcmp(token, "do" ) == 0 ) return "do { bloc } while ( condition );"; + if ( strcmp(token, "while" ) == 0 ) return "while ( condition ) { code }"; + if ( strcmp(token, "do" ) == 0 ) return "do { code } while ( condition );"; + if ( strcmp(token, "switch" ) == 0 ) return "switch ( value ) { code }"; + if ( strcmp(token, "case" ) == 0 ) return "case label: { code }"; + if ( strcmp(token, "default" ) == 0 ) return "default: { code } "; if ( strcmp(token, "break" ) == 0 ) return "break;"; if ( strcmp(token, "continue" ) == 0 ) return "continue;"; if ( strcmp(token, "return" ) == 0 ) return "return;"; diff --git a/src/script/scriptfunc.cpp b/src/script/scriptfunc.cpp index 20a85bb2..0816cce8 100644 --- a/src/script/scriptfunc.cpp +++ b/src/script/scriptfunc.cpp @@ -3412,9 +3412,9 @@ void CScriptFunctions::uObject(CBotVar* botThis, void* user) pVar = pVar->GetNext(); // "orientation" pVar->SetValFloat(Math::NormAngle(2*Math::PI - pos.y)*180.0f/Math::PI); pVar = pVar->GetNext(); // "pitch" - pVar->SetValFloat(Math::NormAngle(pos.z)*180.0f/Math::PI); + pVar->SetValFloat((Math::NormAngle(pos.z + Math::PI) - Math::PI)*180.0f/Math::PI); pVar = pVar->GetNext(); // "roll" - pVar->SetValFloat(Math::NormAngle(pos.x)*180.0f/Math::PI); + pVar->SetValFloat((Math::NormAngle(pos.x + Math::PI) - Math::PI)*180.0f/Math::PI); // Updates the energy level of the object. pVar = pVar->GetNext(); // "energyLevel" diff --git a/src/ui/controls/control.cpp b/src/ui/controls/control.cpp index 9a110e42..588c136d 100644 --- a/src/ui/controls/control.cpp +++ b/src/ui/controls/control.cpp @@ -44,7 +44,7 @@ CControl::CControl() m_eventType = EVENT_NULL; m_state = STATE_ENABLE|STATE_VISIBLE|STATE_GLINT; m_fontSize = Gfx::FONT_SIZE_SMALL; - m_fontType = Gfx::FONT_COLOBOT; + m_fontType = Gfx::FONT_COMMON; m_textAlign = Gfx::TEXT_ALIGN_CENTER; //instead m_justify m_bFocus = false; m_bCapture = false; diff --git a/src/ui/controls/edit.cpp b/src/ui/controls/edit.cpp index b666b070..2fa9e8ab 100644 --- a/src/ui/controls/edit.cpp +++ b/src/ui/controls/edit.cpp @@ -109,7 +109,7 @@ CEdit::CEdit() { m_len = 0; - m_fontType = Gfx::FONT_COURIER; + m_fontType = Gfx::FONT_STUDIO; m_bEdit = true; m_bHilite = true; m_bInsideScroll = true; @@ -1326,13 +1326,13 @@ void CEdit::SetText(const std::string& text, bool bNew) if ( text[i+1] == 'n' ) // normal ? { font &= ~Gfx::FONT_MASK_FONT; - font |= Gfx::FONT_COLOBOT; + font |= Gfx::FONT_COMMON; i += 2; } else if ( text[i+1] == 'c' ) // cbot ? { font &= ~Gfx::FONT_MASK_FONT; - font |= Gfx::FONT_COURIER; + font |= Gfx::FONT_STUDIO; i += 2; } else if ( text[i+1] == 'b' ) // big title ? @@ -1522,7 +1522,7 @@ bool CEdit::ReadText(std::string filename) if ( m_bSoluce || !bInSoluce ) { font &= ~Gfx::FONT_MASK_FONT; - font |= Gfx::FONT_COLOBOT; + font |= Gfx::FONT_COMMON; inCbot = false; } i += 3; @@ -1532,7 +1532,7 @@ bool CEdit::ReadText(std::string filename) if ( m_bSoluce || !bInSoluce ) { font &= ~Gfx::FONT_MASK_FONT; - font |= Gfx::FONT_COURIER; + font |= Gfx::FONT_STUDIO; if (!inCbot) { if (inCbotBackground) @@ -1636,7 +1636,7 @@ bool CEdit::ReadText(std::string filename) //? iWidth = m_lineHeight*RetValueParam(buffer.data()+i+7, 1); iWidth = static_cast(GetValueParam(buffer.data()+i+7, 1)); - iWidth *= m_engine->GetText()->GetHeight(Gfx::FONT_COLOBOT, Gfx::FONT_SIZE_SMALL); + iWidth *= m_engine->GetText()->GetHeight(Gfx::FONT_COMMON, Gfx::FONT_SIZE_SMALL); iLines = GetValueParam(buffer.data()+i+7, 2); // A part of image per line of text. @@ -2540,6 +2540,8 @@ bool CEdit::Paste() { char c; char* text; + int iTabToInsert=0; + int iTmp; //temp for tab space equivalant insertion if ( !m_bEdit ) { @@ -2554,20 +2556,36 @@ bool CEdit::Paste() } UndoMemorize(OPERUNDO_SPEC); - for ( unsigned int i = 0; i < strlen(text); i++ ) + for (unsigned int i = 0; iGetEditIndentValue()*iTabToInsert; iTmp>0; --iTmp) + InsertOne(' '); + iTabToInsert=0; } InsertOne(c); } - + if (0=m_len || '\n'!=m_text[m_cursor1])) + for (iTmp=m_engine->GetEditIndentValue() ; iTmp>0; --iTmp) + InsertOne(' '); SDL_free(text); Justif(); ColumnFix(); @@ -2872,7 +2890,7 @@ int CEdit::IndentTabCount() return nb; } -// Adds or removes qq tabs. +// Adds or removes some tabs. void CEdit::IndentTabAdjust(int number) { diff --git a/src/ui/debug_menu.cpp b/src/ui/debug_menu.cpp index 28caab22..52f5efeb 100644 --- a/src/ui/debug_menu.cpp +++ b/src/ui/debug_menu.cpp @@ -65,7 +65,7 @@ void CDebugMenu::ToggleInterface() { CreateInterface(); CLabel* pl = m_interface->CreateLabel(Math::Point(0.0f, 0.9f), Math::Point(1.0f, 0.1f), -1, EVENT_LABEL19, "??"); - pl->SetFontType(Gfx::FONT_COURIER); + pl->SetFontType(Gfx::FONT_STUDIO); } else { diff --git a/src/ui/debug_menu.h b/src/ui/debug_menu.h index e3ee0933..ecc6f81e 100644 --- a/src/ui/debug_menu.h +++ b/src/ui/debug_menu.h @@ -39,7 +39,7 @@ class CInterface; /** * \class CDebugMenu - * \brief Handles debug menu (F11) + * \brief Handles debug menu (F10) * * There should always be only one instance of this class for each associated CRobotMain class. */ diff --git a/src/ui/displayinfo.cpp b/src/ui/displayinfo.cpp index 5d66b099..b1e6220e 100644 --- a/src/ui/displayinfo.cpp +++ b/src/ui/displayinfo.cpp @@ -383,7 +383,7 @@ void CDisplayInfo::StartDisplayInfo(std::string filename, int index, bool bSoluc edit->SetState(STATE_SHADOW); edit->SetMultiFont(true); edit->SetMaxChar(10000); - edit->SetFontType(Gfx::FONT_COLOBOT); + edit->SetFontType(Gfx::FONT_SATCOM); edit->SetSoluceMode(bSoluce); edit->ReadText(filename.c_str()); edit->HyperHome(filename.c_str()); diff --git a/src/ui/displaytext.cpp b/src/ui/displaytext.cpp index c2c90cfb..6bd8dcf7 100644 --- a/src/ui/displaytext.cpp +++ b/src/ui/displaytext.cpp @@ -197,7 +197,7 @@ void CDisplayText::DisplayText(const char *text, Math::Vector goal, float height } hBox = 0.045f; - hLine = m_engine->GetText()->GetHeight(Gfx::FONT_COLOBOT, FONTSIZE); + hLine = m_engine->GetText()->GetHeight(Gfx::FONT_COMMON, FONTSIZE); nLine = 0; for ( i=0 ; iCreateLabel(pos, ddim, -1, EVENT_DIALOG_LABEL, text); - pl->SetFontType(Gfx::FONT_COLOBOT_BOLD); + pl->SetFontType(Gfx::FONT_COMMON_BOLD); //TODO: Add \n support in CLabel pos.y -= ddim.y; pl = pw->CreateLabel(pos, ddim, -1, EVENT_DIALOG_LABEL1, details); diff --git a/src/ui/screen/screen.cpp b/src/ui/screen/screen.cpp index 181bf756..a5d8fbb0 100644 --- a/src/ui/screen/screen.cpp +++ b/src/ui/screen/screen.cpp @@ -71,7 +71,7 @@ void CScreen::CreateVersionDisplay() ddim.x = 90.0f/640.0f; ddim.y = 10.0f/480.0f; CLabel* pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, COLOBOT_VERSION_DISPLAY); - pl->SetFontType(Gfx::FONT_COURIER); + pl->SetFontType(Gfx::FONT_STUDIO); pl->SetFontSize(9.0f); } } diff --git a/src/ui/screen/screen_io.cpp b/src/ui/screen/screen_io.cpp index 06db0339..d3df8fdb 100644 --- a/src/ui/screen/screen_io.cpp +++ b/src/ui/screen/screen_io.cpp @@ -58,7 +58,7 @@ void CScreenIO::IOReadName() CEdit* pe; std::string resume; char line[100]; - char name[100]; + std::string name; time_t now; pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); @@ -81,10 +81,10 @@ void CScreenIO::IOReadName() time(&now); strftime(line, 99, "%y.%m.%d %H:%M", localtime(&now)); - sprintf(name, "%s - %s %d", line, resume.c_str(), m_main->GetLevelRank()); + name = StrUtils::Format("%s - %s %d", line, resume.c_str(), m_main->GetLevelRank()); pe->SetText(name); - pe->SetCursor(strlen(name), 0); + pe->SetCursor(name.length(), 0); m_interface->SetFocus(pe); } diff --git a/src/ui/screen/screen_io_write.cpp b/src/ui/screen/screen_io_write.cpp index 126c69a2..b39a2227 100644 --- a/src/ui/screen/screen_io_write.cpp +++ b/src/ui/screen/screen_io_write.cpp @@ -85,7 +85,7 @@ void CScreenIOWrite::CreateInterface() ddim.y = 18.0f/480.0f; pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_IONAME); pe->SetState(STATE_SHADOW); - pe->SetFontType(Gfx::FONT_COLOBOT); + pe->SetFontType(Gfx::FONT_COMMON); pe->SetMaxChar(35); IOReadName(); diff --git a/src/ui/screen/screen_main_menu.cpp b/src/ui/screen/screen_main_menu.cpp index 76b50710..4ad270dc 100644 --- a/src/ui/screen/screen_main_menu.cpp +++ b/src/ui/screen/screen_main_menu.cpp @@ -159,7 +159,7 @@ void CScreenMainMenu::CreateInterface() pg->SetState(STATE_SHADOW); pos.y -= 5.0f/480.0f; pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, "TerranovaTeam"); - pl->SetFontType(Gfx::FONT_COURIER); + pl->SetFontType(Gfx::FONT_STUDIO); pl->SetFontSize(Gfx::FONT_SIZE_SMALL); // SatCom button diff --git a/src/ui/screen/screen_quit.cpp b/src/ui/screen/screen_quit.cpp index 5bfa93b5..0928c6bc 100644 --- a/src/ui/screen/screen_quit.cpp +++ b/src/ui/screen/screen_quit.cpp @@ -61,7 +61,7 @@ void CScreenQuit::CreateInterface() pe->SetGenericMode(true); pe->SetEditCap(false); pe->SetHighlightCap(false); - pe->SetFontType(Gfx::FONT_COURIER); + pe->SetFontType(Gfx::FONT_STUDIO); pe->SetFontSize(Gfx::FONT_SIZE_SMALL); pe->ReadText(std::string("help/") + m_app->GetLanguageChar() + std::string("/authors.txt")); @@ -71,13 +71,13 @@ void CScreenQuit::CreateInterface() ddim.y = 16.0f/480.0f; GetResource(RES_TEXT, RT_GENERIC_DEV1, name); pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name); - pl->SetFontType(Gfx::FONT_COURIER); + pl->SetFontType(Gfx::FONT_STUDIO); pl->SetFontSize(Gfx::FONT_SIZE_SMALL); pos.y = 13.0f/480.0f; GetResource(RES_TEXT, RT_GENERIC_DEV2, name); pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL2, name); - pl->SetFontType(Gfx::FONT_COURIER); + pl->SetFontType(Gfx::FONT_STUDIO); pl->SetFontSize(Gfx::FONT_SIZE_SMALL); pos.x = 355.0f/640.0f; @@ -86,13 +86,13 @@ void CScreenQuit::CreateInterface() ddim.y = 16.0f/480.0f; GetResource(RES_TEXT, RT_GENERIC_EDIT1, name); pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL3, name); - pl->SetFontType(Gfx::FONT_COURIER); + pl->SetFontType(Gfx::FONT_STUDIO); pl->SetFontSize(Gfx::FONT_SIZE_SMALL); pos.y = 13.0f/480.0f; GetResource(RES_TEXT, RT_GENERIC_EDIT2, name); pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL4, name); - pl->SetFontType(Gfx::FONT_COURIER); + pl->SetFontType(Gfx::FONT_STUDIO); pl->SetFontSize(Gfx::FONT_SIZE_SMALL); pos.x = 306.0f/640.0f; diff --git a/src/ui/screen/screen_setup_display.cpp b/src/ui/screen/screen_setup_display.cpp index bf31baa6..d015a58c 100644 --- a/src/ui/screen/screen_setup_display.cpp +++ b/src/ui/screen/screen_setup_display.cpp @@ -101,6 +101,36 @@ void CScreenSetupDisplay::CreateInterface() pc->SetState(STATE_SHADOW); pc->SetState(STATE_CHECK, m_setupFull); + pos.x = ox+sx*10; + pos.y = oy+sy*6.75f; + ddim.x = dim.x*6; + ddim.y = dim.y*1; + GetResource(RES_EVENT, EVENT_INTERFACE_VSYNC, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL2, name); + pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT); + + pos.x = ox+sx*10; + pos.y = oy+sy*5.2f; + ddim.x = dim.x*6; + ddim.y = dim.y*2; + pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_VSYNC); + pli->SetState(STATE_SHADOW); + pli->SetItemName(0, "Off"); + pli->SetItemName(1, "Adaptive"); + pli->SetItemName(2, "On"); + switch(m_engine->GetVSync()) + { + case -1: //Adaptive? + pli->SetSelect(1); + break; + case 0: //Off? + pli->SetSelect(0); + break; + case 1: //On? + pli->SetSelect(2); + break; + } + ddim.x = dim.x*6; ddim.y = dim.y*1; pos.x = ox+sx*10; @@ -117,6 +147,7 @@ bool CScreenSetupDisplay::EventProcess(const Event &event) CWindow* pw; CCheck* pc; CButton* pb; + CList* pl; switch( event.type ) { @@ -153,6 +184,27 @@ bool CScreenSetupDisplay::EventProcess(const Event &event) UpdateApply(); break; + case EVENT_INTERFACE_VSYNC: + pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); + if ( pw == nullptr ) break; + pl = static_cast(pw->SearchControl(EVENT_INTERFACE_VSYNC)); + if (pl == nullptr ) break; + switch(pl->GetSelect()) + { + case 0: //Off? + m_engine->SetVSync(0); + break; + case 1: //Adaptive? + m_engine->SetVSync(-1); + break; + case 2: //On? + m_engine->SetVSync(1); + break; + } + ChangeDisplay(); + UpdateApply(); + break; + default: return true; } diff --git a/src/ui/screen/screen_setup_game.cpp b/src/ui/screen/screen_setup_game.cpp index cb4af8f4..a076ab59 100644 --- a/src/ui/screen/screen_setup_game.cpp +++ b/src/ui/screen/screen_setup_game.cpp @@ -149,6 +149,7 @@ void CScreenSetupGame::CreateInterface() pli->SetItemName(1+LANGUAGE_GERMAN, "German"); pli->SetItemName(1+LANGUAGE_POLISH, "Polish"); pli->SetItemName(1+LANGUAGE_RUSSIAN, "Russian"); + pli->SetItemName(1+LANGUAGE_PORTUGUESE_BRAZILIAN, "Brazilian Portuguese"); UpdateSetupButtons(); } diff --git a/src/ui/studio.cpp b/src/ui/studio.cpp index 6f2a1978..3602aeac 100644 --- a/src/ui/studio.cpp +++ b/src/ui/studio.cpp @@ -627,7 +627,7 @@ void CStudio::StartEditScript(CScript *script, std::string name, Program* progra edit->SetState(STATE_SHADOW); edit->SetInsideScroll(false); //? if ( m_bRunning ) edit->SetEdit(false); - edit->SetFontType(Gfx::FONT_COURIER); + edit->SetFontType(Gfx::FONT_STUDIO); edit->SetFontStretch(1.0f); edit->SetDisplaySpec(true); edit->SetAutoIndent(m_engine->GetEditIndentMode()); @@ -639,7 +639,7 @@ void CStudio::StartEditScript(CScript *script, std::string name, Program* progra list = pw->CreateList(pos, dim, 1, EVENT_STUDIO_LIST, 1.2f); list->SetState(STATE_SHADOW); - list->SetFontType(Gfx::FONT_COURIER); + list->SetFontType(Gfx::FONT_STUDIO); list->SetSelectCap(false); list->SetFontSize(Gfx::FONT_SIZE_SMALL*0.85f); //? list->SetFontStretch(1.0f); diff --git a/tools/release.py b/tools/release.py index 918b230a..3797fe90 100755 --- a/tools/release.py +++ b/tools/release.py @@ -73,7 +73,7 @@ codename = None data = open('CMakeLists.txt', 'r').readlines() for i in range(len(data)): - m = re.match(r'^set\(COLOBOT_VERSION_(MAJOR|MINOR|REVISION)( +)([0-9]+)\)$', data[i]) + m = re.match(r'^set\(COLOBOT_VERSION_(MAJOR|MINOR|REVISION)( +)([0-9]+(\.[0-9]+)?)\)$', data[i]) if m: x = m.group(3) if m.group(1) == 'MAJOR':