665 changes: 339 additions & 326 deletions data/languages/korean.txt

Large diffs are not rendered by default.

57 changes: 33 additions & 24 deletions data/languages/kyrgyz.txt
Expand Up @@ -147,9 +147,6 @@ Dynamic Camera
Emoticon
== Эмоциялар

Enter
== Кирүү

Error
== Ката

Expand Down Expand Up @@ -619,6 +616,9 @@ Replay feature is disabled!
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
==

The format of texture %s is not RGBA which will cause visual bugs.
==

Warning
==

Expand Down Expand Up @@ -670,18 +670,6 @@ Welcome to DDNet
DDraceNetwork is a cooperative online game where the goal is for you and your group of tees to reach the finish line of the map. As a newcomer you should start on Novice servers, which host the easiest maps. Consider the ping to choose a server close to you.
==

The maps contain freeze, which temporarily make a tee unable to move. You have to work together to get through these parts.
==

The mouse wheel changes weapons. Hammer (left mouse) can be used to hit other tees and wake them up from being frozen.
==

Hook (right mouse) can be used to swing through the map and to hook other tees to you.
==

Most importantly communication is key: There is no tutorial so you'll have to chat (t key) with other players to learn the basics and tricks of the game.
==

Use k key to kill (restart), q to pause and watch other players. See settings for other key binds.
==

Expand Down Expand Up @@ -715,6 +703,12 @@ Speed
Video name:
==

Join Tutorial Server
==

Skip Tutorial
==

Show DDNet map finishes in server browser
==

Expand Down Expand Up @@ -979,6 +973,9 @@ Windowed
Windowed borderless
==

Windowed fullscreen
==

Desktop fullscreen
==

Expand All @@ -988,16 +985,22 @@ may cause delay
Screen
==

Use modern OpenGL
Use high DPI
==

Preinit VBO (iGPUs only)
Renderer
==

Multiple texture units (disable for macOS)
default
==

Use high DPI
custom
==

Graphics cards
==

auto
==

Enable game sounds
Expand Down Expand Up @@ -1087,6 +1090,9 @@ Laser Inner Color
Hookline
==

Size
==

No hit
==

Expand Down Expand Up @@ -1126,10 +1132,10 @@ Preview
Save the best demo of each race
==

Default length: %d
Enable replays
==

Enable replays
Default length: %d
==

Show ghost
Expand All @@ -1144,9 +1150,6 @@ Gameplay
Overlay entities
==

Size
==

Show text entities
==

Expand Down Expand Up @@ -1249,6 +1252,12 @@ Learn
https://wiki.ddnet.tw/
==

Tutorial
==

Can't find a Tutorial server
==

Website
==

Expand Down
53 changes: 31 additions & 22 deletions data/languages/norwegian.txt
Expand Up @@ -144,9 +144,6 @@ Dynamic Camera
Emoticon
== Uttrykksikoner

Enter
== Enter

Error
== Feil

Expand Down Expand Up @@ -666,18 +663,6 @@ Welcome to DDNet
DDraceNetwork is a cooperative online game where the goal is for you and your group of tees to reach the finish line of the map. As a newcomer you should start on Novice servers, which host the easiest maps. Consider the ping to choose a server close to you.
== DDraceNetwork er et kooperativt onlinespill der målet er at du og gruppen din skal nå banens målstrek. Som nybegynner anbefales det at du starter på Novice-serverne, som har de letteste banene. Se på serverens ping for å finne en som er nærme deg.

The maps contain freeze, which temporarily make a tee unable to move. You have to work together to get through these parts.
== Banene inneholder freeze, som midlertidig gjør at en tee ikke kan bevege seg. Du må samarbeide med andre for å komme gjennom disse partiene.

The mouse wheel changes weapons. Hammer (left mouse) can be used to hit other tees and wake them up from being frozen.
== Scrollehjulet bytter våpen. Hammer (venstre museknapp) kan brukes til å slå andre tees og vekke dem opp fra freeze.

Hook (right mouse) can be used to swing through the map and to hook other tees to you.
== Gripekrok (høyre museknapp) kan brukes til å svinge seg gjennom banen og til å dra andre spillere mot deg.

Most importantly communication is key: There is no tutorial so you'll have to chat (t key) with other players to learn the basics and tricks of the game.
== Viktigst av alt er kommunikasjon: Det fins ingen tutorial, så du er nødt til å snakke (t-knappen) med andre spillere for å lære det grunnleggende og triksene i spillet.

It's recommended that you check the settings to adjust them to your liking before joining a server.
== Det anbefales å sjekke innstillingene og justere dem slik det passer deg før du går inn på en server.

Expand Down Expand Up @@ -894,12 +879,6 @@ may cause delay
Screen
== Skjerm

Preinit VBO (iGPUs only)
== Preinit. VBO (kun iGPU)

Multiple texture units (disable for macOS)
== Multiple texture units (slå av for macOS)

Use high DPI
== Bruk høy DPI

Expand Down Expand Up @@ -1231,9 +1210,18 @@ Play
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
==

The format of texture %s is not RGBA which will cause visual bugs.
==

Are you sure that you want to disconnect and switch to a different server?
==

Join Tutorial Server
==

Skip Tutorial
==

AFR
==

Expand Down Expand Up @@ -1282,10 +1270,25 @@ Windowed
Windowed borderless
==

Windowed fullscreen
==

Desktop fullscreen
==

Use modern OpenGL
Renderer
==

default
==

custom
==

Graphics cards
==

auto
==

Show client IDs
Expand Down Expand Up @@ -1344,3 +1347,9 @@ Discord

https://ddnet.tw/discord
==

Tutorial
==

Can't find a Tutorial server
==
44 changes: 27 additions & 17 deletions data/languages/persian.txt
Expand Up @@ -93,8 +93,6 @@ Dynamic Camera
== کﺮﺤﺘﻣ ﻦﯿﺑﺭﻭﺩ
Emoticon
== ﺎﻫ ﻚﻠﻜﺷ
Enter
== ﻥﺪﺷ ﺩﺭﺍﻭ
Error
== ﺎﻄﺧ
Error loading demo
Expand Down Expand Up @@ -309,9 +307,6 @@ Welcome to DDNet
DDraceNetwork is a cooperative online game where the goal is for you and your group of tees to reach the finish line of the map. As a newcomer you should start on Novice servers, which host the easiest maps. Consider the ping to choose a server close to you.
== ﺪﯿﻨﮐ ﻩﺩﺎﻔﺘﺳﺍ ﺪﻫﺪﯿﻣ ﺍﺭ ﮓﻨﯿﭘ ﻦﯾﺮﺗ ﻦﯿﯾﺎﭘ ﻪﮐ ﯼﺭﻭﺮﺳ ﺎﻤﺘﺣ ﻭ ﺪﯿﻨﮑﺑ ﻥﺩﺮﮐ ﯼﺯﺎﺑ ﻪﺑ ﻉﻭﺮﺷ Novice ﯼﺎﻫ ﺭﻭﺮﺳ ﺯﺍ ﺪﯾﺎﺑ ﺪﯿﺘﺴﻫ ﺩﺭﺍﻭ ﻩﺯﺎﺗ ﻪﮐ ﺎﻤﺷ.ﺖﺳﺍ ﻥﺎﯾﺎﭘ ﻂﺧ ﻪﺑ ﻉﻭﺮﺷ ﻂﺧ ﺯﺍ ﻥﺎﺘﻤﯿﺗ ﻭ ﺎﻤﺷ ﻥﺪﯿﺳﺭ ﻥﺁ ﻑﺪﻫ ﻪﮐ ﺖﺳﺍ ﯽﻤﯿﺗ ﻦﯾﻼﻧﺁ ﯼﺯﺎﺑ ﮏﯾ DDraceNetwork

The maps contain freeze, which temporarily make a tee unable to move. You have to work together to get through these parts.
== .ﺪﯾﻮﺷ ﺝﺭﺎﺧ ﻥﺎﺘﻧﺎﺘﺳﻭﺩ ﮏﻤﮐ ﻪﺑ ﺪﯾﺎﺑ ﻭ ﻩﺩﺯ ﺦﯾ ﺪﯾﻮﺸﺑ ﺎﻬﻧﺁ ﺩﺭﺍﻭ ﺮﮔﺍ ﻪﮐ ﺩﺭﺍﺩ ﺩﻮﺟﻭ ﺰﯾﺮﻓ ﻥﺍﻮﻨﻋ ﺎﺑ ﯽﯾﺎﻫ ﺖﻤﺴﻗ ﯼﺎﻫ ﭗﻣ ﺭﺩ

Existing Player
== ﺩﺭﺍﺩ ﺩﻮﺟﻭ ﻦﮑﯾﺯﺎﺑ

Expand Down Expand Up @@ -823,6 +818,9 @@ Saving ddnet-settings.cfg failed
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
==

The format of texture %s is not RGBA which will cause visual bugs.
==

Debug mode enabled. Press Ctrl+Shift+D to disable debug mode.
==

Expand All @@ -835,22 +833,19 @@ The server is running a non-standard tuning on a pure game type.
The audio device couldn't be initialised.
==

The mouse wheel changes weapons. Hammer (left mouse) can be used to hit other tees and wake them up from being frozen.
==

Hook (right mouse) can be used to swing through the map and to hook other tees to you.
Use k key to kill (restart), q to pause and watch other players. See settings for other key binds.
==

Most importantly communication is key: There is no tutorial so you'll have to chat (t key) with other players to learn the basics and tricks of the game.
It's recommended that you check the settings to adjust them to your liking before joining a server.
==

Use k key to kill (restart), q to pause and watch other players. See settings for other key binds.
Please enter your nickname below.
==

It's recommended that you check the settings to adjust them to your liking before joining a server.
Join Tutorial Server
==

Please enter your nickname below.
Skip Tutorial
==

transmits your player name to info2.ddnet.tw
Expand Down Expand Up @@ -976,6 +971,9 @@ Windowed
Windowed borderless
==

Windowed fullscreen
==

V-Sync
==

Expand All @@ -985,16 +983,22 @@ may cause delay
FSAA samples
==

Use modern OpenGL
Use high DPI
==

Preinit VBO (iGPUs only)
Renderer
==

Multiple texture units (disable for macOS)
default
==

Use high DPI
custom
==

Graphics cards
==

auto
==

Enable long pain sound (used when shooting in freeze)
Expand Down Expand Up @@ -1180,6 +1184,12 @@ https://ddnet.tw/discord
https://wiki.ddnet.tw/
==

Tutorial
==

Can't find a Tutorial server
==

Server executable not found, can't run server
==

Expand Down
53 changes: 31 additions & 22 deletions data/languages/polish.txt
Expand Up @@ -145,9 +145,6 @@ Dynamic Camera
Emoticon
== Emotikona

Enter
== Wejdź

Error
== Błąd

Expand Down Expand Up @@ -805,9 +802,6 @@ Destination file already exist
Reload
== Przeładuj

Multiple texture units (disable for macOS)
== Jednostki z wieloma teksturami (wyłącz dla macOS)

Replay feature is disabled!
== Funkcja odtwarzania jest wyłączona!

Expand Down Expand Up @@ -1039,9 +1033,6 @@ Dummy copy
9+ new mentions
== 9+ razy wspomniano o tobie

Preinit VBO (iGPUs only)
== Zainicjuj VBO (tylko iGPU)

Statboard
== Tabela wyników

Expand All @@ -1066,18 +1057,6 @@ Reconnect in %d sec
DDraceNetwork is a cooperative online game where the goal is for you and your group of tees to reach the finish line of the map. As a newcomer you should start on Novice servers, which host the easiest maps. Consider the ping to choose a server close to you.
== DDraceNetwork jest grą online polegającą na współpracy z innymi graczami, gdzie twoim i ich zadaniem jest dotrzeć do mety na końcu mapy. Jako nowy gracz powinieneś zacząć od serwerów Novice, które hostują najłatwiejsze mapy. Weź pod uwagę ping, aby wybrać serwer najbliżej siebie.

The maps contain freeze, which temporarily make a tee unable to move. You have to work together to get through these parts.
== Mapy zawierają freeze, który tymczasowo uniemożliwia poruszanie się tee. Powienieneś współpracować z innymi, aby ukończyć wszystkie części mapy.

The mouse wheel changes weapons. Hammer (left mouse) can be used to hit other tees and wake them up from being frozen.
== Rolka myszki zmienia narzędzie (broń). Młotek (lewy przycisk myszki) może być użyty do uderzania innych tee i odmrażania ich, gdy są unieruchomieni po kontakcie z freezem.

Hook (right mouse) can be used to swing through the map and to hook other tees to you.
== Hak (prawy przycisk myszki) może być użyty do wspinania się po mapie i łapania innych tee (przyciągania ich do siebie).

Most importantly communication is key: There is no tutorial so you'll have to chat (t key) with other players to learn the basics and tricks of the game.
== Najważniejszym przyciskiem jest T. Dzięki niemu możesz rozmawiać z innymi, aby nauczyć się podstaw i trików związanych z grą.

It's recommended that you check the settings to adjust them to your liking before joining a server.
== Przed wejściem na dowolny serwer zalecane jest sprawdzenie ustawień w celu dostosowania ich do własnych upodobań.

Expand Down Expand Up @@ -1232,9 +1211,18 @@ Play
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
==

The format of texture %s is not RGBA which will cause visual bugs.
==

Are you sure that you want to disconnect and switch to a different server?
==

Join Tutorial Server
==

Skip Tutorial
==

AFR
==

Expand Down Expand Up @@ -1283,10 +1271,25 @@ Windowed
Windowed borderless
==

Windowed fullscreen
==

Desktop fullscreen
==

Use modern OpenGL
Renderer
==

default
==

custom
==

Graphics cards
==

auto
==

Show client IDs
Expand Down Expand Up @@ -1345,3 +1348,9 @@ Discord

https://ddnet.tw/discord
==

Tutorial
==

Can't find a Tutorial server
==
346 changes: 179 additions & 167 deletions data/languages/portuguese.txt

Large diffs are not rendered by default.

57 changes: 33 additions & 24 deletions data/languages/romanian.txt
Expand Up @@ -148,9 +148,6 @@ Dynamic Camera
Emoticon
== Figurine

Enter
== Intră

Error
== Eroare

Expand Down Expand Up @@ -634,6 +631,9 @@ Replay feature is disabled!
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
==

The format of texture %s is not RGBA which will cause visual bugs.
==

Warning
==

Expand Down Expand Up @@ -685,18 +685,6 @@ Welcome to DDNet
DDraceNetwork is a cooperative online game where the goal is for you and your group of tees to reach the finish line of the map. As a newcomer you should start on Novice servers, which host the easiest maps. Consider the ping to choose a server close to you.
==

The maps contain freeze, which temporarily make a tee unable to move. You have to work together to get through these parts.
==

The mouse wheel changes weapons. Hammer (left mouse) can be used to hit other tees and wake them up from being frozen.
==

Hook (right mouse) can be used to swing through the map and to hook other tees to you.
==

Most importantly communication is key: There is no tutorial so you'll have to chat (t key) with other players to learn the basics and tricks of the game.
==

Use k key to kill (restart), q to pause and watch other players. See settings for other key binds.
==

Expand Down Expand Up @@ -730,6 +718,12 @@ Speed
Video name:
==

Join Tutorial Server
==

Skip Tutorial
==

Show DDNet map finishes in server browser
==

Expand Down Expand Up @@ -994,6 +988,9 @@ Windowed
Windowed borderless
==

Windowed fullscreen
==

Desktop fullscreen
==

Expand All @@ -1003,16 +1000,22 @@ may cause delay
Screen
==

Use modern OpenGL
Use high DPI
==

Preinit VBO (iGPUs only)
Renderer
==

Multiple texture units (disable for macOS)
default
==

Use high DPI
custom
==

Graphics cards
==

auto
==

Enable game sounds
Expand Down Expand Up @@ -1102,6 +1105,9 @@ Laser Inner Color
Hookline
==

Size
==

No hit
==

Expand Down Expand Up @@ -1141,10 +1147,10 @@ Preview
Save the best demo of each race
==

Default length: %d
Enable replays
==

Enable replays
Default length: %d
==

Show ghost
Expand All @@ -1159,9 +1165,6 @@ Gameplay
Overlay entities
==

Size
==

Show text entities
==

Expand Down Expand Up @@ -1264,6 +1267,12 @@ Learn
https://wiki.ddnet.tw/
==

Tutorial
==

Can't find a Tutorial server
==

Website
==

Expand Down
59 changes: 34 additions & 25 deletions data/languages/russian.txt
Expand Up @@ -152,9 +152,6 @@ Dynamic Camera
Emoticon
== Эмоции

Enter
== Вход

Error
== Ошибка

Expand Down Expand Up @@ -807,18 +804,6 @@ Welcome to DDNet
DDraceNetwork is a cooperative online game where the goal is for you and your group of tees to reach the finish line of the map. As a newcomer you should start on Novice servers, which host the easiest maps. Consider the ping to choose a server close to you.
== DDraceNetwork - кооперативная онлайн-игра, где Вашей главной целью и целью вашей команды является достижение конца карты. Как новенький, Вы должны начать свой путь на Novice, на которых есть лёгкие карты. Также учитывайте пинг и выбирайте ближайший к вам сервер.

The maps contain freeze, which temporarily make a tee unable to move. You have to work together to get through these parts.
== Карта содержит фриз, который временно лишает вас возможности двигаться. Вы должны работать сообща, чтобы пройти такие места.

The mouse wheel changes weapons. Hammer (left mouse) can be used to hit other tees and wake them up from being frozen.
== Колесо мыши меняет оружие. Молотком (ЛКМ) можно ударить по другим и расфризить их.

Hook (right mouse) can be used to swing through the map and to hook other tees to you.
== Крюк (ПКМ) используется для перемещения по карте, а также для притягивания игроков к себе.

Most importantly communication is key: There is no tutorial so you'll have to chat (t key) with other players to learn the basics and tricks of the game.
== Самое главное, общение - ключ к успеху: здесь нет туториалов, поэтому тебе придется общаться (кнопка Т) с остальными игроками, чтобы обучиться базовым вещам и трюкам в игре.

It's recommended that you check the settings to adjust them to your liking before joining a server.
== Перед посещением сервера рекомендуем изменить настройки на Ваш вкус.

Expand Down Expand Up @@ -975,12 +960,6 @@ may cause delay
Screen
== Экран

Preinit VBO (iGPUs only)
== Преинициал-ть VBO (только iGPU)

Multiple texture units (disable for macOS)
== Улучш. блоки текстур (откл. для macOS)

Use high DPI
== Использовать высокую чувств.

Expand Down Expand Up @@ -1114,7 +1093,7 @@ Skip the main menu
== Пропускать главное меню

https://wiki.ddnet.tw/
== https://wiki.ddnet.tw/
== https://wiki.ddnet.tw/wiki/Main_Page/ru

Website
== Сайт
Expand Down Expand Up @@ -1306,9 +1285,6 @@ Windowed borderless
Desktop fullscreen
== Полноэкранный

Use modern OpenGL
== Использовать новый OpenGL

Tee
== Tee

Expand Down Expand Up @@ -1339,14 +1315,47 @@ Hookable
Show local player's key presses
== Показывать нажатия клавиш игрока

The format of texture %s is not RGBA which will cause visual bugs.
==

Join Tutorial Server
==

Skip Tutorial
==

Settings file
==

Config directory
==

Windowed fullscreen
==

Renderer
==

default
==

custom
==

Graphics cards
==

auto
==

Run on join
==

Chat command (e.g. showall 1)
==

Tutorial
==

Can't find a Tutorial server
==
57 changes: 33 additions & 24 deletions data/languages/serbian.txt
Expand Up @@ -145,9 +145,6 @@ Dynamic Camera
Emoticon
== Emotikon

Enter
== Započni

Error
== Greška

Expand Down Expand Up @@ -644,6 +641,9 @@ Saving ddnet-settings.cfg failed
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
==

The format of texture %s is not RGBA which will cause visual bugs.
==

Warning
==

Expand Down Expand Up @@ -686,18 +686,6 @@ Welcome to DDNet
DDraceNetwork is a cooperative online game where the goal is for you and your group of tees to reach the finish line of the map. As a newcomer you should start on Novice servers, which host the easiest maps. Consider the ping to choose a server close to you.
==

The maps contain freeze, which temporarily make a tee unable to move. You have to work together to get through these parts.
==

The mouse wheel changes weapons. Hammer (left mouse) can be used to hit other tees and wake them up from being frozen.
==

Hook (right mouse) can be used to swing through the map and to hook other tees to you.
==

Most importantly communication is key: There is no tutorial so you'll have to chat (t key) with other players to learn the basics and tricks of the game.
==

It's recommended that you check the settings to adjust them to your liking before joining a server.
==

Expand Down Expand Up @@ -725,6 +713,12 @@ Destination file already exist
Speed
==

Join Tutorial Server
==

Skip Tutorial
==

Show DDNet map finishes in server browser
==

Expand Down Expand Up @@ -992,6 +986,9 @@ Windowed
Windowed borderless
==

Windowed fullscreen
==

Desktop fullscreen
==

Expand All @@ -1001,16 +998,22 @@ may cause delay
Screen
==

Use modern OpenGL
Use high DPI
==

Preinit VBO (iGPUs only)
Renderer
==

Multiple texture units (disable for macOS)
default
==

Use high DPI
custom
==

Graphics cards
==

auto
==

Enable game sounds
Expand Down Expand Up @@ -1100,6 +1103,9 @@ Laser Inner Color
Hookline
==

Size
==

No hit
==

Expand Down Expand Up @@ -1139,10 +1145,10 @@ Preview
Save the best demo of each race
==

Default length: %d
Enable replays
==

Enable replays
Default length: %d
==

Show ghost
Expand All @@ -1157,9 +1163,6 @@ Gameplay
Overlay entities
==

Size
==

Show text entities
==

Expand Down Expand Up @@ -1259,6 +1262,12 @@ https://ddnet.tw/discord
https://wiki.ddnet.tw/
==

Tutorial
==

Can't find a Tutorial server
==

Website
==

Expand Down
53 changes: 31 additions & 22 deletions data/languages/serbian_cyrillic.txt
Expand Up @@ -142,9 +142,6 @@ Dynamic Camera
Emoticon
== Осећања

Enter
== Започни

Error
== Грешка

Expand Down Expand Up @@ -687,18 +684,6 @@ Welcome to DDNet
DDraceNetwork is a cooperative online game where the goal is for you and your group of tees to reach the finish line of the map. As a newcomer you should start on Novice servers, which host the easiest maps. Consider the ping to choose a server close to you.
== DDraceNetwork је кооперативна онлајн игра у којој је циљ да ви и ваша група teeova дођете до циља на мапи. Као новајлија требали бисте започети на Novice серверима, на којима се налазе најједноставније мапе. Размислите о пингу да бисте изабрали сервер који вам је близу.

The maps contain freeze, which temporarily make a tee unable to move. You have to work together to get through these parts.
== Мапе садрже замрзавање, што привремено teeu онемогућава кретање. Морате радити заједно да бисте прошли кроз ове делове.

The mouse wheel changes weapons. Hammer (left mouse) can be used to hit other tees and wake them up from being frozen.
== Точак миша мења оружје. Чекићем (леви миш) може се користити за ударање других teeova и њихово буђење из смрзавања.

Hook (right mouse) can be used to swing through the map and to hook other tees to you.
== Кука (десни миш) се може користити за пролазак кроз мапу и за причвршћивање других teeova уз вас.

Most importantly communication is key: There is no tutorial so you'll have to chat (t key) with other players to learn the basics and tricks of the game.
== Најважније је да је комуникација кључна: не постоји водич, па ћете морати да се дописујете (тастер т) са другим играчима да бисте научили основе и трикове игре.

Use k key to kill (restart), q to pause and watch other players. See settings for other key binds.
== Користите тастер к за убијање (поновно покретање), q за паузирање и гледање других играча. Погледајте подешавања за остале пречице тастера.

Expand Down Expand Up @@ -928,12 +913,6 @@ UI mouse s.
may cause delay
== може проузроковати кашњење

Preinit VBO (iGPUs only)
== Preinit VBO (само у iGPUs)

Multiple texture units (disable for macOS)
== Вишеструке текстурне јединице (угашено за macOS)

Use high DPI
== Користи високи DPI

Expand Down Expand Up @@ -1199,6 +1178,9 @@ Saving ddnet-settings.cfg failed
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
==

The format of texture %s is not RGBA which will cause visual bugs.
==

Debug mode enabled. Press Ctrl+Shift+D to disable debug mode.
==

Expand All @@ -1214,6 +1196,12 @@ Checking for existing player with your name
Are you sure that you want to disconnect and switch to a different server?
==

Join Tutorial Server
==

Skip Tutorial
==

AFR
==

Expand Down Expand Up @@ -1265,10 +1253,25 @@ Windowed
Windowed borderless
==

Windowed fullscreen
==

Desktop fullscreen
==

Use modern OpenGL
Renderer
==

default
==

custom
==

Graphics cards
==

auto
==

Game sound volume
Expand Down Expand Up @@ -1342,3 +1345,9 @@ Discord

https://ddnet.tw/discord
==

Tutorial
==

Can't find a Tutorial server
==
239 changes: 127 additions & 112 deletions data/languages/simplified_chinese.txt

Large diffs are not rendered by default.

57 changes: 33 additions & 24 deletions data/languages/slovak.txt
Expand Up @@ -142,9 +142,6 @@ Dynamic Camera
Emoticon
== Smajlíci

Enter
== Vstúpiť

Error
== Chyba

Expand Down Expand Up @@ -622,6 +619,9 @@ Replay feature is disabled!
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
==

The format of texture %s is not RGBA which will cause visual bugs.
==

Warning
==

Expand Down Expand Up @@ -676,18 +676,6 @@ Welcome to DDNet
DDraceNetwork is a cooperative online game where the goal is for you and your group of tees to reach the finish line of the map. As a newcomer you should start on Novice servers, which host the easiest maps. Consider the ping to choose a server close to you.
==

The maps contain freeze, which temporarily make a tee unable to move. You have to work together to get through these parts.
==

The mouse wheel changes weapons. Hammer (left mouse) can be used to hit other tees and wake them up from being frozen.
==

Hook (right mouse) can be used to swing through the map and to hook other tees to you.
==

Most importantly communication is key: There is no tutorial so you'll have to chat (t key) with other players to learn the basics and tricks of the game.
==

Use k key to kill (restart), q to pause and watch other players. See settings for other key binds.
==

Expand Down Expand Up @@ -721,6 +709,12 @@ Speed
Video name:
==

Join Tutorial Server
==

Skip Tutorial
==

Show DDNet map finishes in server browser
==

Expand Down Expand Up @@ -988,6 +982,9 @@ Windowed
Windowed borderless
==

Windowed fullscreen
==

Desktop fullscreen
==

Expand All @@ -997,16 +994,22 @@ may cause delay
Screen
==

Use modern OpenGL
Use high DPI
==

Preinit VBO (iGPUs only)
Renderer
==

Multiple texture units (disable for macOS)
default
==

Use high DPI
custom
==

Graphics cards
==

auto
==

Enable game sounds
Expand Down Expand Up @@ -1096,6 +1099,9 @@ Laser Inner Color
Hookline
==

Size
==

No hit
==

Expand Down Expand Up @@ -1135,10 +1141,10 @@ Preview
Save the best demo of each race
==

Default length: %d
Enable replays
==

Enable replays
Default length: %d
==

Show ghost
Expand All @@ -1153,9 +1159,6 @@ Gameplay
Overlay entities
==

Size
==

Show text entities
==

Expand Down Expand Up @@ -1258,6 +1261,12 @@ Learn
https://wiki.ddnet.tw/
==

Tutorial
==

Can't find a Tutorial server
==

Website
==

Expand Down
67 changes: 39 additions & 28 deletions data/languages/spanish.txt
Expand Up @@ -12,6 +12,8 @@
# Headshot 2020-11-07 12:40:00
# Headshot 2021-05-30 17:00:00
# Deëivid! 2021-10-27 00:49:00
# Deëivid! 2022-02-05 21:53:00
# Deëivid! 2022-03-27 18:40:00
##### /authors #####

##### translated strings #####
Expand Down Expand Up @@ -151,9 +153,6 @@ Dynamic Camera
Emoticon
== Emoticon

Enter
== Entrar

Error
== Error

Expand Down Expand Up @@ -676,18 +675,6 @@ Welcome to DDNet
DDraceNetwork is a cooperative online game where the goal is for you and your group of tees to reach the finish line of the map. As a newcomer you should start on Novice servers, which host the easiest maps. Consider the ping to choose a server close to you.
== DDraceNetwork es un juego cooperativo en línea donde el objetivo es que tú y vuestro grupo de tees lleguen a la meta del mapa. Como recién llegado, deberías comenzar en los servidores Novice, que alojan los mapas más fáciles. Considera el ping para elegir un servidor cercano.

The maps contain freeze, which temporarily make a tee unable to move. You have to work together to get through these parts.
== Los mapas contienen freeze, lo que hace que un tee no pueda moverse temporalmente. Tendrán que trabajar juntos para superar estas partes.

The mouse wheel changes weapons. Hammer (left mouse) can be used to hit other tees and wake them up from being frozen.
== La rueda del ratón cambia las armas. El martillo (ratón izquierdo) se puede usar para golpear otros tees y despertarlos del freeze.

Hook (right mouse) can be used to swing through the map and to hook other tees to you.
== El gancho (mouse derecho) se puede usar para desplazarse por el mapa y enganchar a otros tees hacia ti.

Most importantly communication is key: There is no tutorial so you'll have to chat (t key) with other players to learn the basics and tricks of the game.
== Lo más importante es que la comunicación es clave: no hay un tutorial, por lo que tendrás que chatear (tecla t) con otros jugadores para aprender los conceptos básicos y las técnicas del juego.

It's recommended that you check the settings to adjust them to your liking before joining a server.
== Se recomienda que verifiques la configuración para ajustarla a tu gusto antes de unirte a un servidor.

Expand Down Expand Up @@ -901,12 +888,6 @@ may cause delay
Screen
== Pantalla

Preinit VBO (iGPUs only)
== Preinit VBO (solo iGPU)

Multiple texture units (disable for macOS)
== Múltiples unidades de textura (deshabilitar para macOS)

Use high DPI
== Usar DPI alto

Expand Down Expand Up @@ -1280,9 +1261,6 @@ Windowed borderless
Desktop fullscreen
== Pantalla completa de escritorio

Use modern OpenGL
== Usar OpenGL moderno

Show client IDs
== Mostrar IDs de clientes

Expand Down Expand Up @@ -1341,13 +1319,46 @@ Show local player's key presses
== Mostrar las teclas presionadas por el jugador local

Settings file
==
== Archivo de configuraciones

Config directory
==
== Directorio de configuración

Run on join
==
== Ejec. al entrar

Chat command (e.g. showall 1)
==
== Comando de chat (Ej. showall 1)

The format of texture %s is not RGBA which will cause visual bugs.
== El formato de la textura %s no es RGBA, lo que puede causar errores visuales.

Join Tutorial Server
== Ir a un servidor Tutorial

Skip Tutorial
== Saltar Tutorial

Windowed fullscreen
== Ventana a pantalla completa

Renderer
== Renderizador

default
== por defecto

custom
== personalizado

Graphics cards
== Tarjetas de video

auto
== auto.

Tutorial
== Tutorial

Can't find a Tutorial server
== No se pudo encontrar un servidor Tutorial
196 changes: 102 additions & 94 deletions data/languages/swedish.txt

Large diffs are not rendered by default.

63 changes: 38 additions & 25 deletions data/languages/traditional_chinese.txt
Expand Up @@ -8,6 +8,10 @@
# 2021-06-01 TsFreddie
# 2021-11-19 cheeser0613
# 2021-12-21 cheeser0613
# 2022-02-07 cheeser0613
# 2022-03-19 cheeser0613
# 2022-03-22 cheeser0613
# 2022-03-24 cheeser0613
##### /authors #####

##### translated strings #####
Expand Down Expand Up @@ -147,9 +151,6 @@ Dynamic Camera
Emoticon
== 表情

Enter
== 確定

Error
== 錯誤

Expand Down Expand Up @@ -907,15 +908,9 @@ Deactivate
Welcome to DDNet
== 歡迎來到 DDNet

Preinit VBO (iGPUs only)
== 預初始化頂點緩衝物件 (僅限整合顯示卡)

Activate
== 啟用

Multiple texture units (disable for macOS)
== 多重紋理單元 (macOS不可用)

File already exists, do you want to overwrite it?
== 檔案已存在,是否覆蓋?

Expand Down Expand Up @@ -1051,18 +1046,6 @@ Toggle dyncam
DDraceNetwork is a cooperative online game where the goal is for you and your group of tees to reach the finish line of the map. As a newcomer you should start on Novice servers, which host the easiest maps. Consider the ping to choose a server close to you.
== DDraceNetwork 是以到達地圖終點為目標,單人或組隊的線上合作遊戲。如果你是新手,你可以從有入門級地圖的 Novice 伺服器開 始。記得選擇 Ping 值低的伺服器。

The maps contain freeze, which temporarily make a tee unable to move. You have to work together to get through these parts.
== 地圖中的冰凍可以使 tee 暫時無法移動。你需要合作來透過這些關卡。

The mouse wheel changes weapons. Hammer (left mouse) can be used to hit other tees and wake them up from being frozen.
== 滑鼠滾輪可以切換武器。錘子 (滑鼠左鍵) 擊中其他 tee 時,可以讓他們從冰凍中甦醒。

Hook (right mouse) can be used to swing through the map and to hook other tees to you.
== 鉤索 (滑鼠右鍵) 可以用來悠盪您的角色來透過地圖關卡,也可以用來將其他 tee 拉向自己。

Most importantly communication is key: There is no tutorial so you'll have to chat (t key) with other players to learn the basics and tricks of the game.
== 遊戲內沒有教程,溝通則至關重要。你需要透過聊天 (t鍵) 向其他玩家學習基本技巧。

It's recommended that you check the settings to adjust them to your liking before joining a server.
== 推薦在進入伺服器前,先將設定調整到符合你的習慣。

Expand All @@ -1076,7 +1059,7 @@ Server best:
== 伺服器最佳

Learn
== 教程
== 教程Wiki

Use high DPI
== 使用高 DPI
Expand Down Expand Up @@ -1280,9 +1263,6 @@ Windowed borderless
Desktop fullscreen
== 無邊框全螢幕

Use modern OpenGL
== 使用現代OpenGL

Show client IDs
== 顯示客戶端ID

Expand Down Expand Up @@ -1351,3 +1331,36 @@ Run on join

Chat command (e.g. showall 1)
== 聊天指令 (例如: showall 1)

Windowed fullscreen
== 視窗化全螢幕

The format of texture %s is not RGBA which will cause visual bugs.
== %s 材質文件并非RGBA格式因此可能會導致視覺錯誤

Join Tutorial Server
== 進入教學伺服器

Skip Tutorial
== 跳過教學

Renderer
== 渲染設定

default
== 默認

custom
== 自定義

Graphics cards
== 顯示卡

auto
== 自動

Tutorial
== 進入教學

Can't find a Tutorial server
==
53 changes: 31 additions & 22 deletions data/languages/turkish.txt
Expand Up @@ -147,9 +147,6 @@ Dynamic Camera
Emoticon
== Yüz ifadesi

Enter
== Gir

Error
== Hata

Expand Down Expand Up @@ -666,18 +663,6 @@ Welcome to DDNet
DDraceNetwork is a cooperative online game where the goal is for you and your group of tees to reach the finish line of the map. As a newcomer you should start on Novice servers, which host the easiest maps. Consider the ping to choose a server close to you.
== DDRaceNetwork bitiş çizgisine en kısa sürede ulaşmayı amaçlayan oyunculardan oluşan, çevrimiçi bir takım oyunudur. Çaylak olarak ilk önce kolay haritalardan yani Novice sunuculardan oynamaya başlamanı öneririz. Herhangi bir sunucu seçmeden önce sana yakın olan sunucuyu seçmek için ping'i dikkate al.

The maps contain freeze, which temporarily make a tee unable to move. You have to work together to get through these parts.
== Haritalar, içindeyken haraket edemediğin freeze denilen yapılar içerir. Bu aşamaları geçmen için takım çalışması lazım.

The mouse wheel changes weapons. Hammer (left mouse) can be used to hit other tees and wake them up from being frozen.
== Mouse tekeri silahını değiştirir. Çekiç (sol tık) kullanarak diğer oyunculara vurabilir, onları uyandırıp haraket etmelerini sağlayabilirsin.

Hook (right mouse) can be used to swing through the map and to hook other tees to you.
== Kanca (sağ tık) ile sallanma haraketi yaparak haritada aşamaları geçebilir, diğer oyunculara tutunmak için kullanabilirsin.

Most importantly communication is key: There is no tutorial so you'll have to chat (t key) with other players to learn the basics and tricks of the game.
== Herhangi bir öğretici mekanizma olmadığı için diğer oyuncularla yazışarak (t tuşu) yardım isteyebilir, oyunun genel mantığını ipuçlarıyla öğrenebilirsin.

Use k key to kill (restart), q to pause and watch other players. See settings for other key binds.
== İntihar etmek (yeniden başlamak) için k tuşu, oyunu durdurup diğer oyuncuları izlemek için q tuşunu kullanabilirsin. Diğer kontrollere ayarlardan bakabilirsin.

Expand Down Expand Up @@ -900,12 +885,6 @@ may cause delay
Screen
== Ekran

Preinit VBO (iGPUs only)
== Preinit VBO (sadece iGPUs)

Multiple texture units (disable for macOS)
== Çoklu doku birimleri (macOS'da kullanılmaz)

Use high DPI
== Yüksek DPI kullan

Expand Down Expand Up @@ -1122,6 +1101,9 @@ Saving ddnet-settings.cfg failed
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
==

The format of texture %s is not RGBA which will cause visual bugs.
==

Warning
==

Expand All @@ -1146,6 +1128,12 @@ Country / Region
Speed
==

Join Tutorial Server
==

Skip Tutorial
==

Theme
==

Expand Down Expand Up @@ -1230,10 +1218,25 @@ Windowed
Windowed borderless
==

Windowed fullscreen
==

Desktop fullscreen
==

Use modern OpenGL
Renderer
==

default
==

custom
==

Graphics cards
==

auto
==

Game sound volume
Expand Down Expand Up @@ -1326,6 +1329,12 @@ https://ddnet.tw/discord
https://wiki.ddnet.tw/
==

Tutorial
==

Can't find a Tutorial server
==

Website
==

Expand Down
57 changes: 33 additions & 24 deletions data/languages/ukrainian.txt
Expand Up @@ -88,9 +88,6 @@ Dynamic Camera
Emoticon
== Емоція

Enter
== Вхід

Error
== Помилка

Expand Down Expand Up @@ -511,18 +508,6 @@ Welcome to DDNet
DDraceNetwork is a cooperative online game where the goal is for you and your group of tees to reach the finish line of the map. As a newcomer you should start on Novice servers, which host the easiest maps. Consider the ping to choose a server close to you.
== DDraceNetwork кооперативна онлайн гра, де Вашою головною метою і метою вашої команди є досягненням фінішу карти. Новачкам рекомендовано починати свій шлях на Novice серверах, на яких стоять легкі карти. Також враховуйте пінг щоб вибрати найближчий до вас сервер.

The maps contain freeze, which temporarily make a tee unable to move. You have to work together to get through these parts.
== Карта містить фриз-тайли, які тимчасово позбавляють вас можливості рухатися. Ви повинні працювати спільно, щоб пройти такі рівні.

The mouse wheel changes weapons. Hammer (left mouse) can be used to hit other tees and wake them up from being frozen.
== Колесо миші змінює зброю. Молот (ЛКМ) можна використовувати для удару інших і пробудження їх від замерзання.

Hook (right mouse) can be used to swing through the map and to hook other tees to you.
== Гак (ПКМ) можна використовувати для переміщення по карті та притягання до вас інших граців.

Most importantly communication is key: There is no tutorial so you'll have to chat (t key) with other players to learn the basics and tricks of the game.
== Найголовніше, що спілкування є ключовим: туторіалу немає, тому вам доведеться спілкуватися з іншими гравцями, щоб засвоїти основи та хитрощі гри.

It's recommended that you check the settings to adjust them to your liking before joining a server.
== Рекомендується перевірити налаштування, щоб підлаштувати їх для комфортної гри перед тим, як приєднатися до сервера.

Expand Down Expand Up @@ -883,12 +868,6 @@ may cause delay
Screen
== Екран

Preinit VBO (iGPUs only)
== Preinit VBO (iGPUs only)

Multiple texture units (disable for macOS)
== Декілька текстурних одиниць (вимкнути для macOS)

Use high DPI
== Використовувати високий DPI

Expand Down Expand Up @@ -1222,9 +1201,6 @@ Windowed borderless
Desktop fullscreen
== Повний робочий стіл

Use modern OpenGL
== Використовувати сучасний OpenGL

Game sound volume
== Гучність звуку гри

Expand Down Expand Up @@ -1331,14 +1307,47 @@ Editor
Play
== Грати

The format of texture %s is not RGBA which will cause visual bugs.
==

Join Tutorial Server
==

Skip Tutorial
==

Settings file
==

Config directory
==

Windowed fullscreen
==

Renderer
==

default
==

custom
==

Graphics cards
==

auto
==

Run on join
==

Chat command (e.g. showall 1)
==

Tutorial
==

Can't find a Tutorial server
==
Binary file added data/maps/Tutorial.map
Binary file not shown.
4 changes: 4 additions & 0 deletions data/maps/license.txt
Expand Up @@ -13,3 +13,7 @@ CC-BY-SA license, grass_main is redrawn from original Teeworlds grass_main mapre
Tsunami:
Copyright louis
CC-BY-SA license

Tutorial:
Copyright unique2 & Alisa
CC-BY-SA license
Binary file added data/maps7/Tutorial.map
Binary file not shown.
20 changes: 20 additions & 0 deletions data/shader/vulkan/prim.frag
@@ -0,0 +1,20 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable

#ifdef TW_TEXTURED
layout(binding = 0) uniform sampler2D gTextureSampler;
#endif

layout(location = 0) noperspective in vec2 texCoord;
layout(location = 1) noperspective in vec4 vertColor;

layout(location = 0) out vec4 FragClr;
void main()
{
#ifdef TW_TEXTURED
vec4 tex = texture(gTextureSampler, texCoord);
FragClr = tex * vertColor;
#else
FragClr = vertColor;
#endif
}
20 changes: 20 additions & 0 deletions data/shader/vulkan/prim.vert
@@ -0,0 +1,20 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable

layout (location = 0) in vec2 inVertex;
layout (location = 1) in vec2 inVertexTexCoord;
layout (location = 2) in vec4 inVertexColor;

layout(push_constant) uniform SPosBO {
layout(offset = 0) mat4x2 gPos;
} gPosBO;

layout (location = 0) noperspective out vec2 texCoord;
layout (location = 1) noperspective out vec4 vertColor;

void main()
{
gl_Position = vec4(gPosBO.gPos * vec4(inVertex, 0.0, 1.0), 0.0, 1.0);
texCoord = inVertexTexCoord;
vertColor = vec4(inVertexColor);
}
24 changes: 24 additions & 0 deletions data/shader/vulkan/prim3d.frag
@@ -0,0 +1,24 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable

#ifdef TW_TEXTURED
layout (binding = 0) uniform sampler2DArray gTextureSampler;
#endif

layout (location = 0) noperspective in vec4 oVertColor;
#ifdef TW_TEXTURED
layout (location = 1) noperspective in vec3 oTexCoord;
#endif

layout (location = 0) out vec4 FragClr;

void main()
{
#ifdef TW_TEXTURED
vec4 TexColor = texture(gTextureSampler, oTexCoord.xyz).rgba;
FragClr = TexColor.rgba * oVertColor.rgba;
#else
FragClr = oVertColor.rgba;
#endif
}

24 changes: 24 additions & 0 deletions data/shader/vulkan/prim3d.vert
@@ -0,0 +1,24 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable

layout (location = 0) in vec2 inVertex;
layout (location = 1) in vec4 inVertexColor;
layout (location = 2) in vec3 inVertexTexCoord;

layout(push_constant) uniform SPosBO {
layout(offset = 0) mat4x2 gPos;
} gPosBO;

layout (location = 0) noperspective out vec4 oVertColor;
#ifdef TW_TEXTURED
layout (location = 1) noperspective out vec3 oTexCoord;
#endif

void main()
{
gl_Position = vec4(gPosBO.gPos * vec4(inVertex, 0.0, 1.0), 0.0, 1.0);
#ifdef TW_TEXTURED
oTexCoord = inVertexTexCoord;
#endif
oVertColor = inVertexColor;
}
24 changes: 24 additions & 0 deletions data/shader/vulkan/primex.frag
@@ -0,0 +1,24 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable

#ifdef TW_TEXTURED
layout(binding = 0) uniform sampler2D gTextureSampler;
#endif

layout(push_constant) uniform SVertexColorBO {
layout(offset = 48) vec4 gVerticesColor;
} gColorBO;

layout (location = 0) noperspective in vec2 texCoord;
layout (location = 1) noperspective in vec4 vertColor;

layout (location = 0) out vec4 FragClr;
void main()
{
#ifdef TW_TEXTURED
vec4 tex = texture(gTextureSampler, texCoord);
FragClr = tex * vertColor * gColorBO.gVerticesColor;
#else
FragClr = vertColor * gColorBO.gVerticesColor;
#endif
}
33 changes: 33 additions & 0 deletions data/shader/vulkan/primex.vert
@@ -0,0 +1,33 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable

layout (location = 0) in vec2 inVertex;
layout (location = 1) in vec2 inVertexTexCoord;
layout (location = 2) in vec4 inVertexColor;

layout(push_constant) uniform SPosBO {
layout(offset = 0) mat4x2 gPos;
#ifndef TW_ROTATIONLESS
layout(offset = 32) vec2 gCenter;
layout(offset = 40) float gRotation;
#endif
} gPosBO;

layout (location = 0) noperspective out vec2 texCoord;
layout (location = 1) noperspective out vec4 vertColor;

void main()
{
vec2 FinalPos = vec2(inVertex.xy);
#ifndef TW_ROTATIONLESS
float X = FinalPos.x - gPosBO.gCenter.x;
float Y = FinalPos.y - gPosBO.gCenter.y;

FinalPos.x = X * cos(gPosBO.gRotation) - Y * sin(gPosBO.gRotation) + gPosBO.gCenter.x;
FinalPos.y = X * sin(gPosBO.gRotation) + Y * cos(gPosBO.gRotation) + gPosBO.gCenter.y;
#endif

gl_Position = vec4(gPosBO.gPos * vec4(FinalPos, 0.0, 1.0), 0.0, 1.0);
texCoord = inVertexTexCoord;
vertColor = inVertexColor;
}
62 changes: 62 additions & 0 deletions data/shader/vulkan/quad.frag
@@ -0,0 +1,62 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable

#ifdef TW_QUAD_TEXTURED
layout (set = 0, binding = 0) uniform sampler2D gTextureSampler;
#endif

#ifdef TW_QUAD_TEXTURED
#define UBOSetIndex 1
#else
#define UBOSetIndex 0
#endif

struct SQuadUniformEl {
vec4 gVertColor;
vec2 gOffset;
float gRotation;
};

#ifndef TW_PUSH_CONST
#define TW_MAX_QUADS 256

layout (std140, set = UBOSetIndex, binding = 1) uniform SOffBO {
uniform SQuadUniformEl gUniEls[TW_MAX_QUADS];
} gQuadBO;
#else
#define gQuadBO gPosBO
#define QuadIndex 0
#endif

layout(push_constant) uniform SPosBO {
layout(offset = 0) uniform mat4x2 gPos;
#ifdef TW_PUSH_CONST
layout(offset = 32) uniform SQuadUniformEl gUniEls[1];
layout(offset = 64) uniform int gQuadOffset;
#else
layout(offset = 32) uniform int gQuadOffset;
#endif
} gPosBO;

layout (location = 0) noperspective in vec4 QuadColor;
#ifndef TW_PUSH_CONST
layout (location = 1) flat in int QuadIndex;
#endif
#ifdef TW_QUAD_TEXTURED
#ifndef TW_PUSH_CONST
layout (location = 2) noperspective in vec2 TexCoord;
#else
layout (location = 1) noperspective in vec2 TexCoord;
#endif
#endif

layout (location = 0) out vec4 FragClr;
void main()
{
#ifdef TW_QUAD_TEXTURED
vec4 TexColor = texture(gTextureSampler, TexCoord);
FragClr = TexColor * QuadColor * gQuadBO.gUniEls[QuadIndex].gVertColor;
#else
FragClr = QuadColor * gQuadBO.gUniEls[QuadIndex].gVertColor;
#endif
}
83 changes: 83 additions & 0 deletions data/shader/vulkan/quad.vert
@@ -0,0 +1,83 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable

layout (location = 0) in vec4 inVertex;
layout (location = 1) in vec4 inColor;
#ifdef TW_QUAD_TEXTURED
layout (location = 2) in vec2 inVertexTexCoord;
#endif

#ifdef TW_QUAD_TEXTURED
#define UBOSetIndex 1
#else
#define UBOSetIndex 0
#endif

struct SQuadUniformEl {
vec4 gVertColor;
vec2 gOffset;
float gRotation;
};

#ifndef TW_PUSH_CONST
#define TW_MAX_QUADS 256

layout (std140, set = UBOSetIndex, binding = 1) uniform SOffBO {
uniform SQuadUniformEl gUniEls[TW_MAX_QUADS];
} gQuadBO;
#else
#define gQuadBO gPosBO
#define TmpQuadIndex 0
#endif

layout(push_constant) uniform SPosBO {
layout(offset = 0) uniform mat4x2 gPos;
#ifdef TW_PUSH_CONST
layout(offset = 32) uniform SQuadUniformEl gUniEls[1];
layout(offset = 64) uniform int gQuadOffset;
#else
layout(offset = 32) uniform int gQuadOffset;
#endif
} gPosBO;

layout (location = 0) noperspective out vec4 QuadColor;
#ifndef TW_PUSH_CONST
layout (location = 1) flat out int QuadIndex;
#endif
#ifdef TW_QUAD_TEXTURED
#ifndef TW_PUSH_CONST
layout (location = 2) noperspective out vec2 TexCoord;
#else
layout (location = 1) noperspective out vec2 TexCoord;
#endif
#endif

void main()
{
vec2 FinalPos = vec2(inVertex.xy);

#ifndef TW_PUSH_CONST
int TmpQuadIndex = int(gl_VertexIndex / 4) - gPosBO.gQuadOffset;
#endif

if(gQuadBO.gUniEls[TmpQuadIndex].gRotation != 0.0)
{
float X = FinalPos.x - inVertex.z;
float Y = FinalPos.y - inVertex.w;

FinalPos.x = X * cos(gQuadBO.gUniEls[TmpQuadIndex].gRotation) - Y * sin(gQuadBO.gUniEls[TmpQuadIndex].gRotation) + inVertex.z;
FinalPos.y = X * sin(gQuadBO.gUniEls[TmpQuadIndex].gRotation) + Y * cos(gQuadBO.gUniEls[TmpQuadIndex].gRotation) + inVertex.w;
}

FinalPos.x = FinalPos.x / 1024.0 + gQuadBO.gUniEls[TmpQuadIndex].gOffset.x;
FinalPos.y = FinalPos.y / 1024.0 + gQuadBO.gUniEls[TmpQuadIndex].gOffset.y;

gl_Position = vec4(gPosBO.gPos * vec4(FinalPos, 0.0, 1.0), 0.0, 1.0);
QuadColor = inColor;
#ifndef TW_PUSH_CONST
QuadIndex = TmpQuadIndex;
#endif
#ifdef TW_QUAD_TEXTURED
TexCoord = inVertexTexCoord;
#endif
}
13 changes: 13 additions & 0 deletions data/shader/vulkan/quadbo.vertfrag
@@ -0,0 +1,13 @@

struct SQuadUniformEl {
vec4 gVertColor;
vec2 gOffset;
float gRotation;
};

#define TW_MAX_QUADS 256

layout (std140, set = 2, binding = 2) uniform SOffBO {
uniform SQuadUniformEl gUniEls[TW_MAX_QUADS];
} gQuadBO;

23 changes: 23 additions & 0 deletions data/shader/vulkan/spritemulti.frag
@@ -0,0 +1,23 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable

layout (set = 0, binding = 0) uniform sampler2D gTextureSampler;

layout(push_constant) uniform SVertexColorBO {
#ifdef TW_PUSH_CONST
layout(offset = 64) vec4 gVerticesColor;
#else
layout(offset = 48) vec4 gVerticesColor;
#endif
} gColorBO;

layout (location = 0) noperspective in vec2 texCoord;
layout (location = 1) noperspective in vec4 vertColor;

layout (location = 0) out vec4 FragClr;

void main()
{
vec4 tex = texture(gTextureSampler, texCoord);
FragClr = tex * vertColor * gColorBO.gVerticesColor;
}
50 changes: 50 additions & 0 deletions data/shader/vulkan/spritemulti.vert
@@ -0,0 +1,50 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable

layout (location = 0) in vec2 inVertex;
layout (location = 1) in vec2 inVertexTexCoord;
layout (location = 2) in vec4 inVertexColor;

layout(push_constant) uniform SPosBO {
layout(offset = 0) uniform mat4x2 gPos;
layout(offset = 32) uniform vec2 gCenter;
#ifdef TW_PUSH_CONST
layout(offset = 48) uniform vec4 gRSP[1];
#endif
} gPosBO;

#ifndef TW_PUSH_CONST
layout (std140, set = 1, binding = 1) uniform SRSPBO {
vec4 gRSP[512];
} gRSPBO;
#define RSPIndex gl_InstanceIndex
#else
#define gRSPBO gPosBO
#define RSPIndex 0
#endif

layout (location = 0) noperspective out vec2 texCoord;
layout (location = 1) noperspective out vec4 vertColor;

void main()
{
vec2 FinalPos = vec2(inVertex.xy);
if(gRSPBO.gRSP[RSPIndex].w != 0.0)
{
float X = FinalPos.x - gPosBO.gCenter.x;
float Y = FinalPos.y - gPosBO.gCenter.y;

FinalPos.x = X * cos(gRSPBO.gRSP[RSPIndex].w) - Y * sin(gRSPBO.gRSP[RSPIndex].w) + gPosBO.gCenter.x;
FinalPos.y = X * sin(gRSPBO.gRSP[RSPIndex].w) + Y * cos(gRSPBO.gRSP[RSPIndex].w) + gPosBO.gCenter.y;
}

FinalPos.x *= gRSPBO.gRSP[RSPIndex].z;
FinalPos.y *= gRSPBO.gRSP[RSPIndex].z;

FinalPos.x += gRSPBO.gRSP[RSPIndex].x;
FinalPos.y += gRSPBO.gRSP[RSPIndex].y;

gl_Position = vec4(gPosBO.gPos * vec4(FinalPos, 0.0, 1.0), 0.0, 1.0);
texCoord = inVertexTexCoord;
vertColor = inVertexColor;
}
43 changes: 43 additions & 0 deletions data/shader/vulkan/text.frag
@@ -0,0 +1,43 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable

layout(binding = 0) uniform sampler2D gTextSampler;
layout(binding = 1) uniform sampler2D gTextOutlineSampler;

layout(push_constant) uniform SFragConstBO {
layout(offset = 48) uniform vec4 gVertColor;
layout(offset = 64) uniform vec4 gVertOutlineColor;
} gFragConst;

layout (location = 0) noperspective in vec2 texCoord;
layout (location = 1) noperspective in vec4 outVertColor;

layout(location = 0) out vec4 FragClr;

void main()
{
vec4 textColor = gFragConst.gVertColor * outVertColor * vec4(1.0, 1.0, 1.0, texture(gTextSampler, texCoord).r);
vec4 textOutlineTex = gFragConst.gVertOutlineColor * vec4(1.0, 1.0, 1.0, texture(gTextOutlineSampler, texCoord).r);

// ratio between the two textures
float OutlineBlend = (1.0 - textColor.a);

// since the outline is always black, or even if it has decent colors, it can be just added to the actual color
// without loosing any or too much color

// lerp isn't commutative, so add the color the fragment looses by lerping
// this reduces the chance of false color calculation if the text is transparent

// first get the right color
vec4 textOutlineFrag = vec4(textOutlineTex.rgb * textOutlineTex.a, textOutlineTex.a) * OutlineBlend;
vec3 textFrag = (textColor.rgb * textColor.a);
vec3 finalFragColor = textOutlineFrag.rgb + textFrag;

float RealAlpha = (textOutlineFrag.a + textColor.a);

// simply add the color we will loose through blending
if(RealAlpha > 0.0)
FragClr = vec4(finalFragColor / RealAlpha, RealAlpha);
else
FragClr = vec4(0.0, 0.0, 0.0, 0.0);
}
22 changes: 22 additions & 0 deletions data/shader/vulkan/text.vert
@@ -0,0 +1,22 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable

layout (location = 0) in vec2 inVertex;
layout (location = 1) in vec2 inVertexTexCoord;
layout (location = 2) in vec4 inVertexColor;

layout(push_constant) uniform SPosBO {
layout(offset = 0) mat4x2 gPos;
layout(offset = 32) float gTextureSize;
} gPosBO;

layout (location = 0) noperspective out vec2 texCoord;
layout (location = 1) noperspective out vec4 outVertColor;

void main()
{
gl_Position = vec4(gPosBO.gPos * vec4(inVertex, 0.0, 1.0), 0.0, 1.0);

texCoord = vec2(inVertexTexCoord.x / gPosBO.gTextureSize, inVertexTexCoord.y / gPosBO.gTextureSize);
outVertColor = inVertexColor;
}
25 changes: 25 additions & 0 deletions data/shader/vulkan/tile.frag
@@ -0,0 +1,25 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable

#ifdef TW_TILE_TEXTURED
layout(binding = 0) uniform sampler2DArray gTextureSampler;
#endif

layout(push_constant) uniform SVertexColorBO {
layout(offset = 64) uniform vec4 gVertColor;
} gColorBO;

#ifdef TW_TILE_TEXTURED
layout (location = 0) noperspective in vec3 TexCoord;
#endif

layout (location = 0) out vec4 FragClr;
void main()
{
#ifdef TW_TILE_TEXTURED
vec4 TexColor = texture(gTextureSampler, TexCoord.xyz);
FragClr = TexColor * gColorBO.gVertColor;
#else
FragClr = gColorBO.gVertColor;
#endif
}
49 changes: 49 additions & 0 deletions data/shader/vulkan/tile.vert
@@ -0,0 +1,49 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable

layout (location = 0) in vec2 inVertex;
#ifdef TW_TILE_TEXTURED
layout (location = 1) in vec3 inVertexTexCoord;
#endif

layout(push_constant) uniform SPosBO {
layout(offset = 0) uniform mat4x2 gPos;

#if defined(TW_TILE_BORDER) || defined(TW_TILE_BORDER_LINE)
layout(offset = 32) uniform vec2 gDir;
layout(offset = 40) uniform vec2 gOffset;
#endif

#if defined(TW_TILE_BORDER)
layout(offset = 48) uniform int gJumpIndex;
#endif
} gPosBO;

#ifdef TW_TILE_TEXTURED
layout (location = 0) noperspective out vec3 TexCoord;
#endif

void main()
{
#if defined(TW_TILE_BORDER)
vec4 VertPos = vec4(inVertex, 0.0, 1.0);
int XCount = gl_InstanceIndex - (int(gl_InstanceIndex/gPosBO.gJumpIndex) * gPosBO.gJumpIndex);
int YCount = (int(gl_InstanceIndex/gPosBO.gJumpIndex));
VertPos.x += gPosBO.gOffset.x + gPosBO.gDir.x * float(XCount);
VertPos.y += gPosBO.gOffset.y + gPosBO.gDir.y * float(YCount);

gl_Position = vec4(gPosBO.gPos * VertPos, 0.0, 1.0);
#elif defined(TW_TILE_BORDER_LINE)
vec4 VertPos = vec4(inVertex.x + gPosBO.gOffset.x, inVertex.y + gPosBO.gOffset.y, 0.0, 1.0);
VertPos.x += gPosBO.gDir.x * float(gl_InstanceIndex);
VertPos.y += gPosBO.gDir.y * float(gl_InstanceIndex);

gl_Position = vec4(gPosBO.gPos * VertPos, 0.0, 1.0);
#else
gl_Position = vec4(gPosBO.gPos * vec4(inVertex, 0.0, 1.0), 0.0, 1.0);
#endif

#ifdef TW_TILE_TEXTURED
TexCoord = inVertexTexCoord;
#endif
}
5 changes: 4 additions & 1 deletion datasrc/compile.py
Expand Up @@ -271,7 +271,10 @@ class CNetObjHandler
lines += ['\t}']

for item in network.Objects:
for line in item.emit_validate():
base_item = None
if item.base:
base_item = next(i for i in network.Objects if i.name == item.base)
for line in item.emit_validate(base_item):
lines += ["\t" + line]
lines += ['\t']
lines += ['\t}']
Expand Down
10 changes: 0 additions & 10 deletions datasrc/content.py
Expand Up @@ -228,7 +228,6 @@ def FileList(fmt, num):
image_null = Image("null", "")
image_particles = Image("particles", "particles.png")
image_game = Image("game", "game.png")
image_browseicons = Image("browseicons", "browse_icons.png")
image_emoticons = Image("emoticons", "emoticons.png")
image_speedup_arrow = Image("speedup_arrow", "editor/speed_arrow.png")
image_demobuttons = Image("demobuttons", "demo_buttons.png")
Expand All @@ -246,7 +245,6 @@ def FileList(fmt, num):
container.images.Add(Image("cursor", "gui_cursor.png"))
container.images.Add(Image("banner", "gui_logo.png"))
container.images.Add(image_emoticons)
container.images.Add(image_browseicons)
container.images.Add(Image("console_bg", "console.png"))
container.images.Add(Image("console_bar", "console_bar.png"))
container.images.Add(image_speedup_arrow)
Expand All @@ -267,7 +265,6 @@ def FileList(fmt, num):
set_particles = SpriteSet("particles", image_particles, 8, 8)
set_game = SpriteSet("game", image_game, 32, 16)
set_tee = SpriteSet("tee", image_null, 8, 4)
set_browseicons = SpriteSet("browseicons", image_browseicons, 6, 1)
set_emoticons = SpriteSet("emoticons", image_emoticons, 4, 4)
set_speedup_arrow = SpriteSet("speedup_arrow", image_speedup_arrow, 1, 1)
set_demobuttons = SpriteSet("demobuttons", image_demobuttons, 5, 1)
Expand All @@ -281,7 +278,6 @@ def FileList(fmt, num):
container.spritesets.Add(set_particles)
container.spritesets.Add(set_game)
container.spritesets.Add(set_tee)
container.spritesets.Add(set_browseicons)
container.spritesets.Add(set_emoticons)
container.spritesets.Add(set_speedup_arrow)
container.spritesets.Add(set_demobuttons)
Expand Down Expand Up @@ -398,12 +394,6 @@ def FileList(fmt, num):
container.sprites.Add(Sprite("eyes", set_emoticons, 2, 3, 1, 1))
container.sprites.Add(Sprite("question", set_emoticons, 3, 3, 1, 1))

container.sprites.Add(Sprite("browse_lock", set_browseicons, 0,0,1,1))
container.sprites.Add(Sprite("browse_heart", set_browseicons, 1,0,1,1))
container.sprites.Add(Sprite("browse_unpure", set_browseicons, 3,0,1,1))
container.sprites.Add(Sprite("browse_ddnet", set_browseicons, 4,0,1,1))
container.sprites.Add(Sprite("browse_rank", set_browseicons, 5,0,1,1))

container.sprites.Add(Sprite("speedup_arrow", set_speedup_arrow, 0,0,1,1))

container.sprites.Add(Sprite("demobutton_play", set_demobuttons, 0,0,1,1))
Expand Down
7 changes: 5 additions & 2 deletions datasrc/datatypes.py
Expand Up @@ -222,14 +222,17 @@ def emit_declaration(self):
lines += ["\t"+line for line in v.emit_declaration()]
lines += ["};"]
return lines
def emit_validate(self):
def emit_validate(self, base_item):
lines = ["case %s:" % self.enum_name]
lines += ["{"]
if self.validate_size:
lines += ["\t%s *pObj = (%s *)pData;"%(self.struct_name, self.struct_name)]
lines += ["\tif((int)sizeof(*pObj) > Size) return -1;"]
prev_len = len(lines)
for v in self.variables:
variables = self.variables
if base_item:
variables += base_item.variables
for v in variables:
lines += ["\t"+line for line in v.emit_validate()]
if not self.validate_size and prev_len != len(lines):
raise ValueError("Can't use members that need validation in a struct whose size isn't validated")
Expand Down
4 changes: 2 additions & 2 deletions datasrc/network.py
Expand Up @@ -176,7 +176,7 @@
NetIntRange("m_Direction", -1, 1),

NetIntRange("m_Jumped", 0, 3),
NetIntRange("m_HookedPlayer", 0, 'MAX_CLIENTS-1'),
NetIntRange("m_HookedPlayer", -1, 'MAX_CLIENTS-1'),
NetIntRange("m_HookState", -1, 5),
NetTick("m_HookTick"),

Expand Down Expand Up @@ -238,7 +238,7 @@
NetObjectEx("DDNetCharacter", "character@netobj.ddnet.tw", [
NetIntAny("m_Flags"),
NetTick("m_FreezeEnd"),
NetIntRange("m_Jumps", 0, 255),
NetIntRange("m_Jumps", -1, 255),
NetIntAny("m_TeleCheckpoint"),
NetIntRange("m_StrongWeakID", 0, 'MAX_CLIENTS-1'),
]),
Expand Down
2 changes: 1 addition & 1 deletion ddnet-libs
Submodule ddnet-libs updated 491 files
21 changes: 9 additions & 12 deletions license.txt
@@ -1,6 +1,6 @@
Teeworlds Copyright (C) 2007-2014 Magnus Auvinen
DDRace Copyright (C) 2010-2011 Shereef Marzouk
DDNet Copyright (C) 2013-2021 Dennis Felsing
DDNet Copyright (C) 2013-2022 Dennis Felsing

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
Expand All @@ -23,20 +23,17 @@ freely, subject to the following restrictions:
All content under 'data' except the assets, font, language & skin files,
(which have their own licenses) are released under
CC-BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0/).
Apache 2.0 for the 'Icon.tff' file:
Copyright Google
SIL OFL 1.1 License for the 'Icon.otf' ('Font Awesome 6 Free-Solid-900.otf') file:

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Copyright (c) 2022 Fonticons, Inc. (https://fontawesome.com)
with Reserved Font Name: "Font Awesome".

http://www.apache.org/licenses/LICENSE-2.0
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SIL OPEN FONT LICENSE
Version 1.1 - 26 February 2007

The other fonts are released under CC-BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0/).

Expand Down
3 changes: 2 additions & 1 deletion scripts/android/cmake_android.sh
Expand Up @@ -104,7 +104,8 @@ function build_for_type() {
-DTOOLS=OFF \
-DDEV=TRUE \
-DCMAKE_CROSSCOMPILING=ON \
-DPREFER_BUNDLED_LIBS=ON
-DPREFER_BUNDLED_LIBS=ON \
-DVULKAN=ON
(
cd "build_android/$_ANDROID_SUB_BUILD_DIR/$1" || exit 1
cmake --build . --target DDNet
Expand Down
29 changes: 29 additions & 0 deletions scripts/parse_drmingw.sh
@@ -0,0 +1,29 @@
#!/bin/bash

if [ -z ${1+x} ]; then
printf "\e[31m%s\e[30m\n" "Did not pass executable file (full path)"
printf "\e[31m%s\e[30m\n" "Usage: ./parse_drmingw.sh <executable> <crash_log>"
exit 1
fi

if [ -z ${2+x} ]; then
printf "\e[31m%s\e[30m\n" "Did not pass crash log file (full path)"
printf "\e[31m%s\e[30m\n" "Usage: ./parse_drmingw.sh <executable> <crash_log>"
exit 1
fi

TMP_OFFSET=$(grep -E -o "\(with offset [0-9A-F]*\)" "$2" | grep -E -o "[A-F0-9]*")

ADDR_PC_REGEX='[0-9A-F]+ [0-9A-F]+ [0-9A-F]+ [0-9A-F]+'
while read -r line
do
if [[ $line =~ $ADDR_PC_REGEX ]]
then
TMP_ADDR=$(echo "$line" | grep -E -o -m 1 "[A-F0-9]+ " | head -1)
ADDR_BASE=$(winedump -f "$1" | grep -E -o "image base[ ]*0x[0-9A-Fa-f]*" | grep -E -o "[0-9A-Fa-f]+" | tail -1)
REAL_ADDR=$(printf '%X\n' "$(((0x$TMP_ADDR-0x$TMP_OFFSET)+0x$ADDR_BASE))")
echo "Parsing address: $REAL_ADDR (img base: $ADDR_BASE)"
addr2line -e "$1" "$REAL_ADDR"
fi
done < "$2"

2 changes: 1 addition & 1 deletion src/base/color.h
Expand Up @@ -96,7 +96,7 @@ class color4_base
z = ((col >> 0) & 0xFF) / 255.0f;
}

vec4 v4() const { return vec4(x, y, z, a); };
vec4 v4() const { return vec4(x, y, z, a); }

unsigned Pack(bool Alpha = true)
{
Expand Down
6 changes: 3 additions & 3 deletions src/base/hash_libtomcrypt.cpp
Expand Up @@ -5,9 +5,9 @@

#include "hash_ctxt.h"

#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <cstddef>
#include <cstdint>
#include <cstring>

typedef uint32_t u32;
typedef uint64_t u64;
Expand Down
462 changes: 327 additions & 135 deletions src/base/system.cpp

Large diffs are not rendered by default.

109 changes: 76 additions & 33 deletions src/base/system.h
Expand Up @@ -720,24 +720,21 @@ Current value of the timer in microseconds.
int64_t time_get_microseconds();

/* Group: Network General */
typedef struct
{
int type;
int ipv4sock;
int ipv6sock;
int web_ipv4sock;
} NETSOCKET;
typedef struct NETSOCKET_INTERNAL *NETSOCKET;

enum
{
NETADDR_MAXSTRSIZE = 1 + (8 * 4 + 7) + 1 + 1 + 5 + 1, // [XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX]:XXXXX

NETTYPE_LINK_BROADCAST = 4,

NETTYPE_INVALID = 0,
NETTYPE_IPV4 = 1,
NETTYPE_IPV6 = 2,
NETTYPE_LINK_BROADCAST = 4,
NETTYPE_WEBSOCKET_IPV4 = 8,
NETTYPE_ALL = NETTYPE_IPV4 | NETTYPE_IPV6 | NETTYPE_WEBSOCKET_IPV4

NETTYPE_ALL = NETTYPE_IPV4 | NETTYPE_IPV6 | NETTYPE_WEBSOCKET_IPV4,
NETTYPE_MASK = NETTYPE_ALL | NETTYPE_LINK_BROADCAST,
};

typedef struct
Expand Down Expand Up @@ -835,6 +832,19 @@ int net_addr_from_str(NETADDR *addr, const char *string);

/* Group: Network UDP */

/*
Function: net_socket_type
Determine a socket's type.
Parameters:
sock - Socket whose type should be determined.
Returns:
The socket type, a bitset of `NETTYPE_IPV4`, `NETTYPE_IPV6` and
`NETTYPE_WEBSOCKET_IPV4`.
*/
int net_socket_type(NETSOCKET sock);

/*
Function: net_udp_create
Creates a UDP socket and binds it to a port.
Expand Down Expand Up @@ -864,40 +874,21 @@ NETSOCKET net_udp_create(NETADDR bindaddr);
*/
int net_udp_send(NETSOCKET sock, const NETADDR *addr, const void *data, int size);

#define VLEN 128
#define PACKETSIZE 1400
typedef struct
{
#ifdef CONF_PLATFORM_LINUX
int pos;
int size;
struct mmsghdr msgs[VLEN];
struct iovec iovecs[VLEN];
char bufs[VLEN][PACKETSIZE];
char sockaddrs[VLEN][128];
#else
int dummy;
#endif
} MMSGS;

void net_init_mmsgs(MMSGS *m);

/*
Function: net_udp_recv
Receives a packet over an UDP socket.
Parameters:
sock - Socket to use.
addr - Pointer to an NETADDR that will receive the address.
buffer - Pointer to a buffer that can be used to receive the data.
maxsize - Maximum size to receive.
data - Will get set to the actual data, might be the passed buffer or an internal one
data - Received data. Will be invalidated when this function is
called again.
Returns:
On success it returns the number of bytes received. Returns -1
on error.
*/
int net_udp_recv(NETSOCKET sock, NETADDR *addr, void *buffer, int maxsize, MMSGS *m, unsigned char **data);
int net_udp_recv(NETSOCKET sock, NETADDR *addr, unsigned char **data);

/*
Function: net_udp_close
Expand Down Expand Up @@ -1356,9 +1347,26 @@ int str_comp_num(const char *a, const char *b, int num);
*/
int str_comp_filenames(const char *a, const char *b);

/*
Function: str_startswith_nocase
Checks case insensitive whether the string begins with a certain prefix.
Parameter:
str - String to check.
prefix - Prefix to look for.
Returns:
A pointer to the string str after the string prefix, or 0 if
the string prefix isn't a prefix of the string str.
Remarks:
- The strings are treated as zero-terminated strings.
*/
const char *str_startswith_nocase(const char *str, const char *prefix);

/*
Function: str_startswith
Checks whether the string begins with a certain prefix.
Checks case sensitive whether the string begins with a certain prefix.
Parameter:
str - String to check.
Expand All @@ -1373,9 +1381,26 @@ int str_comp_filenames(const char *a, const char *b);
*/
const char *str_startswith(const char *str, const char *prefix);

/*
Function: str_endswith_nocase
Checks case insensitive whether the string ends with a certain suffix.
Parameter:
str - String to check.
suffix - Suffix to look for.
Returns:
A pointer to the beginning of the suffix in the string str, or
0 if the string suffix isn't a suffix of the string str.
Remarks:
- The strings are treated as zero-terminated strings.
*/
const char *str_endswith_nocase(const char *str, const char *suffix);

/*
Function: str_endswith
Checks whether the string ends with a certain suffix.
Checks case sensitive whether the string ends with a certain suffix.
Parameter:
str - String to check.
Expand Down Expand Up @@ -1858,6 +1883,9 @@ typedef void (*DBG_LOGGER)(const char *line, void *user);
typedef void (*DBG_LOGGER_FINISH)(void *user);
void dbg_logger(DBG_LOGGER logger, DBG_LOGGER_FINISH finish, void *user);

typedef void (*DBG_LOGGER_ASSERTION)(void *user);
void dbg_logger_assertion(DBG_LOGGER logger, DBG_LOGGER_FINISH finish, DBG_LOGGER_ASSERTION on_assert, void *user);

void dbg_logger_stdout();
void dbg_logger_debugger();
void dbg_logger_file(const char *filename);
Expand Down Expand Up @@ -2294,6 +2322,16 @@ void generate_password(char *buffer, unsigned length, unsigned short *random, un
*/
int secure_random_init();

/*
Function: secure_random_uninit
Uninitializes the secure random module.
Returns:
0 - Uninitialization succeeded.
1 - Uninitialization failed.
*/
int secure_random_uninit();

/*
Function: secure_random_password
Fills the buffer with the specified amount of random password
Expand Down Expand Up @@ -2358,6 +2396,11 @@ void set_console_msg_color(const void *rgbvoid);
*/
int os_version_str(char *version, int length);

#if defined(CONF_EXCEPTION_HANDLING)
void init_exception_handler();
void set_exception_handler_log_file(const char *log_file_path);
#endif

#if defined(__cplusplus)
}
#endif
Expand Down
4 changes: 2 additions & 2 deletions src/base/unicode/confusables.cpp
Expand Up @@ -2,7 +2,7 @@

#include "../system.h"

#include <stddef.h>
#include <cstddef>

static int str_utf8_skeleton(int ch, const int **skeleton, int *skeleton_len)
{
Expand Down Expand Up @@ -88,7 +88,7 @@ int str_utf8_comp_confusable(const char *str1, const char *str2)
str_utf8_skeleton_begin(&skel1, str1);
str_utf8_skeleton_begin(&skel2, str2);

while(1)
while(true)
{
int ch1 = str_utf8_skeleton_next(&skel1);
int ch2 = str_utf8_skeleton_next(&skel2);
Expand Down
2 changes: 1 addition & 1 deletion src/base/unicode/tolower.cpp
@@ -1,4 +1,4 @@
#include <stdlib.h>
#include <cstdlib>

#include "tolower_data.h"

Expand Down
4 changes: 4 additions & 0 deletions src/engine/client.h
Expand Up @@ -142,10 +142,13 @@ class IClient : public IInterface
virtual void LoadFont() = 0;
virtual void Notify(const char *pTitle, const char *pMessage) = 0;

virtual void UpdateAndSwap() = 0;

// networking
virtual void EnterGame(int Conn) = 0;

//
virtual const char *ServerAddress() const = 0;
virtual const char *MapDownloadName() const = 0;
virtual int MapDownloadAmount() const = 0;
virtual int MapDownloadTotalsize() const = 0;
Expand Down Expand Up @@ -233,6 +236,7 @@ class IClient : public IInterface

virtual SWarning *GetCurWarning() = 0;
virtual CChecksumData *ChecksumData() = 0;
virtual bool InfoTaskRunning() = 0;
};

class IGameClient : public IInterface
Expand Down
41 changes: 41 additions & 0 deletions src/engine/client/backend/backend_base.cpp
@@ -0,0 +1,41 @@
#include "backend_base.h"
#include "engine/shared/image_manipulation.h"

size_t CCommandProcessorFragment_GLBase::TexFormatToImageColorChannelCount(int TexFormat)
{
if(TexFormat == CCommandBuffer::TEXFORMAT_RGBA)
return 4;
return 4;
}

void *CCommandProcessorFragment_GLBase::Resize(const unsigned char *pData, int Width, int Height, int NewWidth, int NewHeight, int BPP)
{
return ResizeImage((const uint8_t *)pData, Width, Height, NewWidth, NewHeight, BPP);
}

bool CCommandProcessorFragment_GLBase::Texture2DTo3D(void *pImageBuffer, int ImageWidth, int ImageHeight, int ImageColorChannelCount, int SplitCountWidth, int SplitCountHeight, void *pTarget3DImageData, int &Target3DImageWidth, int &Target3DImageHeight)
{
Target3DImageWidth = ImageWidth / SplitCountWidth;
Target3DImageHeight = ImageHeight / SplitCountHeight;

size_t FullImageWidth = (size_t)ImageWidth * ImageColorChannelCount;

for(int Y = 0; Y < SplitCountHeight; ++Y)
{
for(int X = 0; X < SplitCountWidth; ++X)
{
for(int Y3D = 0; Y3D < Target3DImageHeight; ++Y3D)
{
int DepthIndex = X + Y * SplitCountWidth;

size_t TargetImageFullWidth = (size_t)Target3DImageWidth * ImageColorChannelCount;
size_t TargetImageFullSize = (size_t)TargetImageFullWidth * Target3DImageHeight;
ptrdiff_t ImageOffset = (ptrdiff_t)(((size_t)Y * FullImageWidth * (size_t)Target3DImageHeight) + ((size_t)Y3D * FullImageWidth) + ((size_t)X * TargetImageFullWidth));
ptrdiff_t TargetImageOffset = (ptrdiff_t)(TargetImageFullSize * (size_t)DepthIndex + ((size_t)Y3D * TargetImageFullWidth));
mem_copy(((uint8_t *)pTarget3DImageData) + TargetImageOffset, ((uint8_t *)pImageBuffer) + (ptrdiff_t)(ImageOffset), TargetImageFullWidth);
}
}
}

return true;
}
111 changes: 111 additions & 0 deletions src/engine/client/backend/backend_base.h
@@ -0,0 +1,111 @@
#ifndef ENGINE_CLIENT_BACKEND_BACKEND_BASE_H
#define ENGINE_CLIENT_BACKEND_BACKEND_BASE_H

#include "../backend_sdl.h"
#include "engine/graphics.h"

#include <vector>

enum EDebugGFXModes
{
DEBUG_GFX_MODE_NONE = 0,
DEBUG_GFX_MODE_MINIMUM,
DEBUG_GFX_MODE_AFFECTS_PERFORMANCE,
DEBUG_GFX_MODE_VERBOSE,
DEBUG_GFX_MODE_ALL,
};

class CCommandProcessorFragment_GLBase
{
protected:
static size_t TexFormatToImageColorChannelCount(int TexFormat);
static void *Resize(const unsigned char *pData, int Width, int Height, int NewWidth, int NewHeight, int BPP);

static bool Texture2DTo3D(void *pImageBuffer, int ImageWidth, int ImageHeight, int ImageColorChannelCount, int SplitCountWidth, int SplitCountHeight, void *pTarget3DImageData, int &Target3DImageWidth, int &Target3DImageHeight);

virtual bool GetPresentedImageData(uint32_t &Width, uint32_t &Height, uint32_t &Format, std::vector<uint8_t> &DstData) = 0;

public:
virtual ~CCommandProcessorFragment_GLBase() = default;
virtual bool RunCommand(const CCommandBuffer::SCommand *pBaseCommand) = 0;

virtual void StartCommands(size_t CommandCount, size_t EstimatedRenderCallCount) {}
virtual void EndCommands() {}

enum
{
CMD_PRE_INIT = CCommandBuffer::CMDGROUP_PLATFORM_GL,
CMD_INIT,
CMD_SHUTDOWN,
CMD_POST_SHUTDOWN,
};

struct SCommand_PreInit : public CCommandBuffer::SCommand
{
SCommand_PreInit() :
SCommand(CMD_PRE_INIT) {}

SDL_Window *m_pWindow;
uint32_t m_Width;
uint32_t m_Height;

char *m_pVendorString;
char *m_pVersionString;
char *m_pRendererString;

TTWGraphicsGPUList *m_pGPUList;
};

struct SCommand_Init : public CCommandBuffer::SCommand
{
SCommand_Init() :
SCommand(CMD_INIT) {}

SDL_Window *m_pWindow;
uint32_t m_Width;
uint32_t m_Height;

class IStorage *m_pStorage;
std::atomic<uint64_t> *m_pTextureMemoryUsage;
std::atomic<uint64_t> *m_pBufferMemoryUsage;
std::atomic<uint64_t> *m_pStreamMemoryUsage;
std::atomic<uint64_t> *m_pStagingMemoryUsage;

TTWGraphicsGPUList *m_pGPUList;

TGLBackendReadPresentedImageData *m_pReadPresentedImageDataFunc;

SBackendCapabilites *m_pCapabilities;
int *m_pInitError;

const char **m_pErrStringPtr;

char *m_pVendorString;
char *m_pVersionString;
char *m_pRendererString;

int m_RequestedMajor;
int m_RequestedMinor;
int m_RequestedPatch;

EBackendType m_RequestedBackend;

int m_GlewMajor;
int m_GlewMinor;
int m_GlewPatch;
};

struct SCommand_Shutdown : public CCommandBuffer::SCommand
{
SCommand_Shutdown() :
SCommand(CMD_SHUTDOWN) {}
};

struct SCommand_PostShutdown : public CCommandBuffer::SCommand
{
SCommand_PostShutdown() :
SCommand(CMD_POST_SHUTDOWN) {}
};
};

#endif
351 changes: 187 additions & 164 deletions src/engine/client/backend/opengl/backend_opengl.cpp

Large diffs are not rendered by default.

32 changes: 20 additions & 12 deletions src/engine/client/backend/opengl/backend_opengl.h
Expand Up @@ -12,6 +12,7 @@

#include <base/system.h>

#include <engine/client/backend/backend_base.h>
#include <engine/client/backend_sdl.h>

class CGLSLProgram;
Expand All @@ -28,7 +29,7 @@ class CGLSLSpriteMultipleProgram;
#endif

// takes care of opengl related rendering
class CCommandProcessorFragment_OpenGL : public CCommandProcessorFragment_OpenGLBase
class CCommandProcessorFragment_OpenGL : public CCommandProcessorFragment_GLBase
{
protected:
struct CTexture
Expand All @@ -39,9 +40,9 @@ class CCommandProcessorFragment_OpenGL : public CCommandProcessorFragment_OpenGL
}

TWGLuint m_Tex;
TWGLuint m_Tex2DArray; //or 3D texture as fallback
TWGLuint m_Tex2DArray; // or 3D texture as fallback
TWGLuint m_Sampler;
TWGLuint m_Sampler2DArray; //or 3D texture as fallback
TWGLuint m_Sampler2DArray; // or 3D texture as fallback
int m_LastWrapMode;

int m_MemSize;
Expand All @@ -53,7 +54,10 @@ class CCommandProcessorFragment_OpenGL : public CCommandProcessorFragment_OpenGL
float m_ResizeHeight;
};
std::vector<CTexture> m_Textures;
std::atomic<int> *m_pTextureMemoryUsage;
std::atomic<uint64_t> *m_pTextureMemoryUsage;

uint32_t m_CanvasWidth = 0;
uint32_t m_CanvasHeight = 0;

TWGLint m_MaxTexSize;

Expand All @@ -65,35 +69,41 @@ class CCommandProcessorFragment_OpenGL : public CCommandProcessorFragment_OpenGL
bool m_HasNPOTTextures;

bool m_HasShaders;
int m_LastBlendMode; //avoid all possible opengl state changes
int m_LastBlendMode; // avoid all possible opengl state changes
bool m_LastClipEnable;

int m_OpenGLTextureLodBIAS;

bool m_IsOpenGLES;

bool IsTexturedState(const CCommandBuffer::SState &State);
static bool Texture2DTo3D(void *pImageBuffer, int ImageWidth, int ImageHeight, int ImageColorChannelCount, int SplitCountWidth, int SplitCountHeight, void *pTarget3DImageData, int &Target3DImageWidth, int &Target3DImageHeight);

bool InitOpenGL(const SCommand_Init *pCommand);

void SetState(const CCommandBuffer::SState &State, bool Use2DArrayTexture = false);
virtual bool IsNewApi() { return false; }
void DestroyTexture(int Slot);

virtual bool GetPresentedImageData(uint32_t &Width, uint32_t &Height, uint32_t &Format, std::vector<uint8_t> &DstData);

static int TexFormatToOpenGLFormat(int TexFormat);
static int TexFormatToImageColorChannelCount(int TexFormat);
static void *Resize(int Width, int Height, int NewWidth, int NewHeight, int Format, const unsigned char *pData);
static size_t GLFormatToImageColorChannelCount(int GLFormat);

void TextureUpdate(int Slot, int X, int Y, int Width, int Height, int GLFormat, void *pTexData);
void TextureCreate(int Slot, int Width, int Height, int PixelSize, int GLFormat, int GLStoreFormat, int Flags, void *pTexData);

virtual bool Cmd_Init(const SCommand_Init *pCommand);
virtual void Cmd_Shutdown(const SCommand_Shutdown *pCommand) {}
virtual void Cmd_Texture_Update(const CCommandBuffer::SCommand_Texture_Update *pCommand);
virtual void Cmd_Texture_Destroy(const CCommandBuffer::SCommand_Texture_Destroy *pCommand);
virtual void Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand);
virtual void Cmd_TextTexture_Update(const CCommandBuffer::SCommand_TextTexture_Update *pCommand);
virtual void Cmd_TextTextures_Destroy(const CCommandBuffer::SCommand_TextTextures_Destroy *pCommand);
virtual void Cmd_TextTextures_Create(const CCommandBuffer::SCommand_TextTextures_Create *pCommand);
virtual void Cmd_Clear(const CCommandBuffer::SCommand_Clear *pCommand);
virtual void Cmd_Render(const CCommandBuffer::SCommand_Render *pCommand);
virtual void Cmd_RenderTex3D(const CCommandBuffer::SCommand_RenderTex3D *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderTex3D"); }
virtual void Cmd_Screenshot(const CCommandBuffer::SCommand_Screenshot *pCommand);
virtual void Cmd_Screenshot(const CCommandBuffer::SCommand_TrySwapAndScreenshot *pCommand);

virtual void Cmd_Update_Viewport(const CCommandBuffer::SCommand_Update_Viewport *pCommand);
virtual void Cmd_Finish(const CCommandBuffer::SCommand_Finish *pCommand);
Expand All @@ -114,7 +124,6 @@ class CCommandProcessorFragment_OpenGL : public CCommandProcessorFragment_OpenGL
virtual void Cmd_RenderBorderTileLine(const CCommandBuffer::SCommand_RenderBorderTileLine *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderBorderTileLine"); }
virtual void Cmd_RenderQuadLayer(const CCommandBuffer::SCommand_RenderQuadLayer *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderQuadLayer"); }
virtual void Cmd_RenderText(const CCommandBuffer::SCommand_RenderText *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderText"); }
virtual void Cmd_RenderTextStream(const CCommandBuffer::SCommand_RenderTextStream *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderTextStream"); }
virtual void Cmd_RenderQuadContainer(const CCommandBuffer::SCommand_RenderQuadContainer *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderQuadContainer"); }
virtual void Cmd_RenderQuadContainerEx(const CCommandBuffer::SCommand_RenderQuadContainerEx *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderQuadContainerEx"); }
virtual void Cmd_RenderQuadContainerAsSpriteMultiple(const CCommandBuffer::SCommand_RenderQuadContainerAsSpriteMultiple *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderQuadContainerAsSpriteMultiple"); }
Expand All @@ -130,7 +139,6 @@ class CCommandProcessorFragment_OpenGL2 : public CCommandProcessorFragment_OpenG
{
struct SBufferContainer
{
SBufferContainer() {}
SBufferContainerInfo m_ContainerInfo;
};
std::vector<SBufferContainer> m_BufferContainers;
Expand Down Expand Up @@ -202,7 +210,7 @@ class CCommandProcessorFragment_OpenGL2 : public CCommandProcessorFragment_OpenG
int m_TextureSlot;
bool m_Is2DArray;
};
std::vector<STextureBound> m_TextureSlotBoundToUnit; //the texture index generated by loadtextureraw is stored in an index calculated by max texture units
std::vector<STextureBound> m_TextureSlotBoundToUnit; // the texture index generated by loadtextureraw is stored in an index calculated by max texture units

bool IsAndUpdateTextureSlotBound(int IDX, int Slot, bool Is2DArray = false);

Expand Down