Merge chat-scaling (= current state of branch "ui-scaling") into default branch
authorsheepluva
Sat, 04 Jul 2020 03:11:41 +0200 (2020-07-04)
changeset 15665 63e2b7b2ec47
parent 15662 41121e2f5c03 (current diff)
parent 15664 0b99e220568a (diff)
child 15666 10bcec19045c
Merge chat-scaling (= current state of branch "ui-scaling") into default branch
ChangeLog.txt
hedgewars/uChat.pas
hedgewars/uConsts.pas
hedgewars/uStore.pas
hedgewars/uTypes.pas
hedgewars/uVariables.pas
--- a/ChangeLog.txt	Tue Jun 30 23:25:52 2020 +0300
+++ b/ChangeLog.txt	Sat Jul 04 03:11:41 2020 +0200
@@ -40,6 +40,10 @@
  + Themes: Make Sudden Death jellyfish in Underwater theme rise
  + Various small HUD tweaks
 
+User Interface:
+ + In-Game chat size can now be adjusted. Hold Ctrl and press -, + or = while in chat input. Hold shift for finer control.
+ + The intial in-game chat size can be configured in the Frontend's "advanced" settings tab.
+
 Frontend:
  + Sort ammos in weapon scheme editor
  * Fix weapon schemes sometimes not being saved properly
--- a/QTfrontend/game.cpp	Tue Jun 30 23:25:52 2020 +0300
+++ b/QTfrontend/game.cpp	Sat Jul 04 03:11:41 2020 +0200
@@ -657,6 +657,8 @@
         arguments << "--translucent-tags";
     if (!config->isHolidaySillinessEnabled())
         arguments << "--no-holiday-silliness";
+    arguments << "--chat-size";
+    arguments << QString::number(config->chatSize());
 
     return arguments;
 }
--- a/QTfrontend/gameuiconfig.cpp	Tue Jun 30 23:25:52 2020 +0300
+++ b/QTfrontend/gameuiconfig.cpp	Sat Jul 04 03:11:41 2020 +0200
@@ -178,6 +178,8 @@
             if (m_binds[i].strbind.isEmpty() || m_binds[i].strbind == "default") m_binds[i].strbind = cbinds[i].strbind;
         }
     }
+
+    Form->ui.pageOptions->sbChatSize->setValue(value("chat/size", 100).toInt());
 }
 
 void GameUIConfig::reloadVideosValues(void)
@@ -332,6 +334,8 @@
             setValue(QString("colors/color%1").arg(i), model->item(i)->data().value<QColor>().name());
     }
 
+    setValue("chat/size", Form->ui.pageOptions->sbChatSize->value());
+
     sync();
 }
 
@@ -647,6 +651,11 @@
     }
 }
 
+int GameUIConfig::chatSize()
+{
+    return Form->ui.pageOptions->sbChatSize->value();
+}
+
 quint8 GameUIConfig::volume()
 {
     return Form->ui.pageOptions->SLVolume->value() * 128 / 100;
--- a/QTfrontend/gameuiconfig.h	Tue Jun 30 23:25:52 2020 +0300
+++ b/QTfrontend/gameuiconfig.h	Sat Jul 04 03:11:41 2020 +0200
@@ -53,6 +53,7 @@
         bool isShowFPSEnabled();
         bool isAltDamageEnabled();
         bool appendDateTimeToRecordName();
+        int chatSize();
         quint8 volume();
         quint8 timerInterval();
         QString netNick();
--- a/QTfrontend/net/recorder.cpp	Tue Jun 30 23:25:52 2020 +0300
+++ b/QTfrontend/net/recorder.cpp	Sat Jul 04 03:11:41 2020 +0200
@@ -156,6 +156,8 @@
         arguments << config->audioCodec();
     else
         arguments << "no";
+    arguments << "--chat-size";
+    arguments << QString::number(config->chatSize());
 
     return arguments;
 }
--- a/QTfrontend/ui/page/pageoptions.cpp	Tue Jun 30 23:25:52 2020 +0300
+++ b/QTfrontend/ui/page/pageoptions.cpp	Sat Jul 04 03:11:41 2020 +0200
@@ -713,6 +713,22 @@
             BtnAssociateFiles->setText(QPushButton::tr("Associate file extensions"));
             BtnAssociateFiles->setVisible(!custom_data && !custom_config);
             groupMisc->layout()->addWidget(BtnAssociateFiles, 4, 0, 1, 2);
+
+            // Divider
+
+            groupMisc->addDivider(); // row 5
+
+            QLabel *labelChatSize = new QLabel(groupMisc);
+            labelChatSize->setText(QLabel::tr("Initial in-game chat size (%)"));
+            groupMisc->layout()->addWidget(labelChatSize, 6, 0);
+
+            // Chat size adjustment
+            sbChatSize = new QSpinBox(groupMisc);
+            sbChatSize->setMinimum(80);
+            sbChatSize->setMaximum(2000);
+            sbChatSize->setValue(100);
+            groupMisc->layout()->addWidget(sbChatSize, 6, 1);
+
         }
 
 #ifdef __APPLE__
--- a/QTfrontend/ui/page/pageoptions.h	Tue Jun 30 23:25:52 2020 +0300
+++ b/QTfrontend/ui/page/pageoptions.h	Sat Jul 04 03:11:41 2020 +0200
@@ -106,6 +106,7 @@
 
         FPSEdit *fpsedit;
         QLabel *labelNN;
+        QSpinBox * sbChatSize;
         QSlider *SLVolume;
         QLabel *lblVolumeLevel;
         QLineEdit *editNetNick;
--- a/hedgewars/ArgParsers.pas	Tue Jun 30 23:25:52 2020 +0300
+++ b/hedgewars/ArgParsers.pas	Sat Jul 04 03:11:41 2020 +0200
@@ -106,6 +106,7 @@
     WriteLn(stdout, '  --no-hogtag: Disable hedgehog name tags');
     WriteLn(stdout, '  --no-healthtag: Disable hedgehog health tags');
     WriteLn(stdout, '  --translucent-tags: Enable translucent name and health tags');
+    WriteLn(stdout, '  --chat-size [default chat size in percent]');
     WriteLn(stdout, '  --showfps: Show frames per second');
     WriteLn(stdout, '');
     WriteLn(stdout, 'Miscellaneous:');
@@ -243,13 +244,13 @@
 end;
 
 function parseParameter(cmd:string; arg:string; var paramIndex:LongInt): Boolean;
-const reallyAll: array[0..34] of shortstring = (
+const reallyAll: array[0..35] of shortstring = (
                 '--prefix', '--user-prefix', '--locale', '--fullscreen-width', '--fullscreen-height', '--width',
                 '--height', '--maximized', '--frame-interval', '--volume','--nomusic', '--nosound', '--nodampen',
                 '--fullscreen', '--showfps', '--altdmg', '--low-quality', '--raw-quality', '--stereo', '--nick',
                 '--zoom',
   {internal}    '--internal', '--port', '--recorder', '--landpreview',
-  {misc}        '--stats-only', '--gci', '--help','--protocol', '--no-teamtag','--no-hogtag','--no-healthtag','--translucent-tags','--lua-test','--no-holiday-silliness');
+  {misc}        '--stats-only', '--gci', '--help','--protocol', '--no-teamtag','--no-hogtag','--no-healthtag','--translucent-tags','--lua-test','--no-holiday-silliness','--chat-size');
 var cmdIndex: byte;
 begin
     parseParameter:= false;
@@ -297,6 +298,7 @@
         {--translucent-tags}    32 : cTagsMask := cTagsMask or htTransparent;
         {--lua-test}            33 : begin cTestLua := true; SetSound(false); cScriptName := getstringParameter(arg, paramIndex, parseParameter); WriteLn(stdout, 'Lua test file specified: ' + cScriptName);end;
         {--no-holiday-silliness} 34 : cHolidaySilliness:= false;
+        {--chat-size}           35 : cDefaultChatScale := 1.0 * getLongIntParameter(arg, paramIndex, parseParameter) / 100;
     else
         begin
         //Assume the first "non parameter" is the demo file, anything else is invalid
--- a/hedgewars/uChat.pas	Tue Jun 30 23:25:52 2020 +0300
+++ b/hedgewars/uChat.pas	Sat Jul 04 03:11:41 2020 +0200
@@ -35,7 +35,7 @@
 procedure TextInput(var event: TSDL_TextInputEvent);
 
 implementation
-uses uInputHandler, uTypes, uVariables, uCommands, uUtils, uTextures, uRender, uIO, uScript, uRenderUtils, uLocale
+uses uConsts, uInputHandler, uTypes, uVariables, uCommands, uUtils, uTextures, uRender, uIO, uScript, uRenderUtils, uStore, uLocale
      {$IFDEF USE_VIDEO_RECORDING}, uVideoRec{$ENDIF};
 
 const MaxStrIndex = 27;
@@ -94,8 +94,14 @@
             );
 
 
-const Padding  = 2;
-      ClHeight = 2 * Padding + 16; // font height
+const PaddingFactor = 0.125; // relative to font size in pixels
+
+var Padding, ClHeight: integer;
+    LastChatScaleValue, LastUIScaleValue: real;
+    SkipNextInput: boolean;
+
+procedure UpdateInputLinePrefix(); forward;
+procedure UpdateCursorCoords(); forward;
 
 // relevant for UTF-8 handling
 function IsFirstCharByte(c: char): boolean; inline;
@@ -114,26 +120,106 @@
     selectedPos:= -1;
 end;
 
+procedure AdjustToUIScale();
+var fntSize, fntSizePx: integer;
+begin
+    // don't do anything if no change
+    if (ChatScaleValue = LastChatScaleValue) and (UIScaleValue = LastUIScaleValue) then
+        exit;
+
+    LastChatScaleValue:= ChatScaleValue;
+    LastUIScaleValue:= UIScaleValue;
+
+    fntSize:= max(1, round(UIScaleValue * ChatScaleValue * cBaseChatFontHeight));
+
+    if Fontz[fntChat].Height <> fntSize then
+        begin
+        // adjust associated heights
+        Fontz[fntChat].Height:= fntSize;
+        Fontz[CJKfntChat].Height:= fntSize;
+        // reload if initialized already
+        if Fontz[fntChat].Handle <> nil then
+            LoadFont(fntChat);
+        if Fontz[CJKfntChat].Handle <> nil then
+            LoadFont(CJKfntChat);
+        end;
+
+    // adjust line height etc.
+    fntSizePx:= round(cFontPxToPtRatio * fntSize);
+    Padding:= max(1, round(PaddingFactor * fntSizePx));
+
+    ClHeight:= 2 * Padding + fntSizePx;
+
+    // clear cache of already rendered lines
+    ReloadLines();
+    UpdateInputLinePrefix();
+    UpdateCursorCoords();
+end;
+
+procedure ChatSizeInc(pxprecise: boolean);
+var fntSize: integer;
+begin
+if pxprecise then
+    begin
+    fntSize:= Fontz[fntChat].Height;
+    inc(fntSize);
+    ChatScaleValue:= 1.0 * fntSize / cBaseChatFontHeight;
+    end
+else
+    ChatScaleValue:= ChatScaleValue * (1.0 + cChatScaleRelDelta);
+if ChatScaleValue > cMaxChatScaleValue then
+    ChatScaleValue:= cMaxChatScaleValue;
+AdjustToUIScale();
+end;
+
+procedure ChatSizeDec(pxprecise: boolean);
+var fntSize: integer;
+begin
+if pxprecise then
+    begin
+    fntSize:= Fontz[fntChat].Height;
+    dec(fntSize);
+    ChatScaleValue:= 1.0 * fntSize / cBaseChatFontHeight;
+    end
+else
+    ChatScaleValue:= ChatScaleValue / (1.0 + cChatScaleRelDelta);
+if ChatScaleValue < cMinChatScaleValue then
+    ChatScaleValue:= cMinChatScaleValue;
+AdjustToUIScale();
+end;
+
+procedure chatSizeReset();
+begin
+ChatScaleValue:= cDefaultChatScale;
+AdjustToUIScale();
+end;
+
+function GetChatFont(str: shortstring): THWFONT;
+begin
+    GetChatFont:= CheckCJKFont(ansistring(str), fntChat);
+end;
+
 procedure UpdateCursorCoords();
 var font: THWFont;
     str : shortstring;
     coff, soff: LongInt;
 begin
+    AdjustToUIScale();
+
     if cursorPos = selectedPos then
         ResetSelection();
 
     // calculate cursor offset
 
     str:= InputStr.s;
-    font:= CheckCJKFont(ansistring(str), fnt16);
+    font:= GetChatFont(str);
 
     // get only substring before cursor to determine length
     // SetLength(str, cursorPos); // makes pas2c unhappy
     str[0]:= char(cursorPos);
     // get render size of text
     TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(str), @coff, nil);
-
-    cursorX:= 2 + coff;
+    cursorX:= Padding + coff;
 
     // calculate selection width on screen
     if selectedPos >= 0 then
@@ -171,7 +257,7 @@
 
 FreeAndNilTexture(cl.Tex);
 
-font:= CheckCJKFont(ansistring(str), fnt16);
+font:= GetChatFont(str);
 
 // get render size of text
 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(str), @cl.Width, nil);
@@ -245,8 +331,9 @@
 procedure ReloadLines;
 var i: LongWord;
 begin
-    if InputStr.s <> '' then
-        SetLine(InputStr, InputStr.s, true);
+    // also reload empty input line (as chat size/scaling might have changed)
+    //if InputStr.s <> '' then
+    SetLine(InputStr, InputStr.s, true);
     for i:= 0 to MaxStrIndex do
         if Strs[i].s <> '' then
             begin
@@ -294,6 +381,8 @@
     selRect: TSDL_Rect;
     c: char;
 begin
+AdjustToUIScale();
+
 ChatReady:= true; // maybe move to somewhere else?
 
 if ChatHidden and (not showAll) then
@@ -329,12 +418,12 @@
         begin
         // draw cursor
         if ((RealTicks - LastKeyPressTick) and 512) < 256 then
-            DrawLineOnScreen(left + cursorX, top + 2, left + cursorX, top + ClHeight - 2, 2.0, $00, $FF, $FF, $FF);
+            DrawLineOnScreen(left + cursorX, top + Padding, left + cursorX, top + ClHeight - Padding, max(2, round(UIScaleValue * ChatScaleValue * 2.0)), $00, $FF, $FF, $FF);
         end
     else // draw selection
         begin
-        selRect.y:= top + 2;
-        selRect.h:= clHeight - 4;
+        selRect.y:= top + Padding;
+        selRect.h:= clHeight - 2 * Padding;
         if selectionDx < 0 then
             begin
             selRect.x:= left + cursorX + selectionDx;
@@ -1068,7 +1157,7 @@
             // ignore me!!!
             end;
         // TODO: figure out how to determine those keys better
-        SDL_SCANCODE_a:
+        SDL_SCANCODE_b:
             begin
             // select all
             if ctrlonly then
@@ -1104,6 +1193,33 @@
                 DeleteSelected();
                 end
             end;
+            // make chat bigger
+        SDL_SCANCODE_KP_PLUS, SDL_SCANCODE_EQUALS:
+            begin
+            if ctrl then
+                begin
+                ChatSizeInc(selMode);
+                SkipNextInput:= true;
+                end;
+            end;
+            // make chat smaller
+        SDL_SCANCODE_KP_MINUS, SDL_SCANCODE_MINUS:
+            begin
+            if ctrl then
+                begin
+                ChatSizeDec(selMode);
+                SkipNextInput:= true;
+                end;
+            end;
+            // revert chat size to default
+        SDL_SCANCODE_KP_0, SDL_SCANCODE_0:
+            begin
+            if ctrl then
+                begin
+                ChatSizeReset();
+                SkipNextInput:= true;
+                end;
+            end;
         end;
 end;
 
@@ -1112,16 +1228,25 @@
     l: byte;
     isl: integer;
 begin
+    if SkipNextInput then
+        begin
+        SkipNextInput:= false;
+        exit;
+        end;
+
     DeleteSelected();
 
+    s:= '';
     l:= 0;
     // fetch all bytes of character/input
     while event.text[l] <> #0 do
         begin
-        s[l + 1]:= event.text[l];
-        inc(l)
+        if Length(s) < 255 then
+            begin
+            s[l + 1]:= event.text[l];
+            inc(l)
+            end
         end;
-
     if l > 0 then
         begin
         isl:= Length(InputStr.s);
@@ -1237,6 +1362,10 @@
     ChatHidden:= false;
     firstDraw:= true;
 
+    LastChatScaleValue:= 0;
+    LastUIScaleValue:= 0;
+    SkipNextInput:= false;
+
     InputLinePrefix.Tex:= nil;
     UpdateInputLinePrefix();
     inputStr.s:= '';
--- a/hedgewars/uConsts.pas	Tue Jun 30 23:25:52 2020 +0300
+++ b/hedgewars/uConsts.pas	Sat Jul 04 03:11:41 2020 +0200
@@ -240,6 +240,14 @@
     cCamLimitBorderX = 1920; // X (left/right) camera limit, with border
     cCamLimitBorderY = 2048; // Top Y camera limit, with border
 
+    cFontPxToPtRatio   = 1.3281472327365;
+    cBaseChatFontHeight = 12;
+    cChatScaleRelDelta = 0.1;
+    cMinChatScaleValue = 0.8;
+    cMaxChatScaleValue = 10.0;
+
+    cDefaultUIScaleLevel = 1.0;
+
     // game flags
     gfAny                = $FFFFFFFF; // mask for all possible gameflags
     gfOneClanMode        = $00000001; // Game does not end if there's only one clan in play. For missions
--- a/hedgewars/uStore.pas	Tue Jun 30 23:25:52 2020 +0300
+++ b/hedgewars/uStore.pas	Sat Jul 04 03:11:41 2020 +0200
@@ -33,6 +33,7 @@
 function makeHealthBarTexture(w, h, Color: Longword): PTexture;
 procedure AddProgress;
 procedure FinishProgress;
+procedure LoadFont(font: THWFont);
 function  LoadImage(const filename: shortstring; imageFlags: LongInt): PSDL_Surface;
 
 // loads an image from the games data files
@@ -362,23 +363,35 @@
             end
 end;
 
-procedure LoadFonts();
+procedure LoadFont(font: THWFont);
 var s: shortstring;
-    fi: THWFont;
+begin
+    with Fontz[font] do
+        begin
+        if Handle <> nil then
+            begin
+            TTF_CloseFont(Handle);
+            Handle:= nil;
+            end;
+        s:= cPathz[ptFonts] + '/' + Name;
+        WriteToConsole(msgLoading + s + ' (' + inttostr(Height) + 'pt)... ');
+        Handle:= TTF_OpenFontRW(rwopsOpenRead(s), true, Height);
+        if SDLCheck(Handle <> nil, 'TTF_OpenFontRW', true) then exit;
+        TTF_SetFontStyle(Handle, style);
+        WriteLnToConsole(msgOK)
+        end;
+end;
+
+procedure LoadFonts();
+var fi: THWFont;
 begin
 AddFileLog('LoadFonts();');
 
 if (not cOnlyStats) then
     for fi:= Low(THWFont) to High(THWFont) do
-        with Fontz[fi] do
-            begin
-            s:= cPathz[ptFonts] + '/' + Name;
-            WriteToConsole(msgLoading + s + ' (' + inttostr(Height) + 'pt)... ');
-            Handle:= TTF_OpenFontRW(rwopsOpenRead(s), true, Height);
-            if SDLCheck(Handle <> nil, 'TTF_OpenFontRW', true) then exit;
-            TTF_SetFontStyle(Handle, style);
-            WriteLnToConsole(msgOK)
-            end;
+        begin
+        LoadFont(fi);
+        end;
 end;
 
 procedure StoreLoad(reload: boolean);
--- a/hedgewars/uTypes.pas	Tue Jun 30 23:25:52 2020 +0300
+++ b/hedgewars/uTypes.pas	Sat Jul 04 03:11:41 2020 +0200
@@ -178,7 +178,7 @@
     // Different kind of crates that e.g. hedgehogs can pick up
     TCrateType = (HealthCrate, AmmoCrate, UtilityCrate);
 
-    THWFont = (fnt16, fntBig, fntSmall {$IFNDEF MOBILE}, CJKfnt16, CJKfntBig, CJKfntSmall{$ENDIF});
+    THWFont = (fnt16, fntBig, fntSmall, fntChat {$IFNDEF MOBILE}, CJKfnt16, CJKfntBig, CJKfntSmall, CJKfntChat{$ENDIF});
 
     TCapGroup = (capgrpGameState, capgrpAmmoinfo, capgrpVolume,
             capgrpMessage, capgrpMessage2, capgrpAmmostate);
--- a/hedgewars/uVariables.pas	Tue Jun 30 23:25:52 2020 +0300
+++ b/hedgewars/uVariables.pas	Sat Jul 04 03:11:41 2020 +0200
@@ -141,6 +141,9 @@
     zoom             : GLfloat; // current zoom
     ZoomValue        : GLfloat; // aimed zoom
     UserZoom         : GLfloat; // user-chosen initial and default zoom
+    ChatScaleValue   : real;
+    cDefaultChatScale: real;
+    UIScaleValue     : real;
 
     cWaterLine       : LongInt;
     cGearScrEdgesDist: LongInt;
@@ -264,6 +267,8 @@
 
     // for tracking the limits of the visible grid based on cScaleFactor
     ViewLeftX, ViewRightX, ViewBottomY, ViewTopY, ViewWidth, ViewHeight: LongInt;
+    // for tracking the limits of the visible UI space based on cUIScaleFactor
+    UIWidth, UIHeight: LongInt;
 
     // for debugging the view limits visually
     cViewLimitsDebug: boolean;
@@ -360,6 +365,10 @@
             (Handle: nil;
             Height: 10*HDPIScaleFactor;
             style: TTF_STYLE_NORMAL;
+            Name: 'DejaVuSans-Bold.ttf'),
+            (Handle: nil; // fntChat
+            Height: 12*HDPIScaleFactor;
+            style: TTF_STYLE_NORMAL;
             Name: 'DejaVuSans-Bold.ttf')
             {$IFNDEF MOBILE}, // remove chinese fonts for now
             (Handle: nil;
@@ -373,6 +382,10 @@
             (Handle: nil;
             Height: 10*HDPIScaleFactor;
             style: TTF_STYLE_NORMAL;
+            Name: 'wqy-zenhei.ttc'),
+            (Handle: nil; // CJKfntChat
+            Height: 12*HDPIScaleFactor;
+            style: TTF_STYLE_NORMAL;
             Name: 'wqy-zenhei.ttc')
             {$ENDIF}
             );
@@ -2631,6 +2644,7 @@
     SyncTexture,
     ConfirmTexture: PTexture;
     cScaleFactor: GLfloat;
+    cUIScaleFactor: float;
     cStereoDepth: GLfloat;
     SupportNPOTT: Boolean;
     Step: LongInt;
@@ -2756,6 +2770,8 @@
     cAudioCodec        := '';
 {$ENDIF}
 
+    cDefaultChatScale:= 1.0;
+
     cTagsMask:= htTeamName or htName or htHealth;
     cPrevTagsMask:= cTagsMask;
 end;
@@ -2964,6 +2980,16 @@
     cExplosives     := 2;
 
     GameState       := Low(TGameState);
+    zoom            := cDefaultZoomLevel;
+    ZoomValue       := cDefaultZoomLevel;
+
+    if cDefaultChatScale < cMinChatScaleValue then
+        cDefaultChatScale := cMinChatScaleValue
+    else if cDefaultChatScale > cMaxChatScaleValue then
+        cDefaultChatScale := cMaxChatScaleValue;
+    ChatScaleValue  := cDefaultChatScale;
+    UIScaleValue    := cDefaultUIScaleLevel;
+
     WeaponTooltipTex:= nil;
     cLaserSighting  := false;
     cLaserSightingSniper := false;