# HG changeset patch # User sheepluva # Date 1593825101 -7200 # Node ID 63e2b7b2ec4725b27032381fb2d15aad53769cb7 # Parent 41121e2f5c038e6ce3dd5b810499115b8e13b5b7# Parent 0b99e220568a4c9d9b2fa585b5e62dc861e98ab9 Merge chat-scaling (= current state of branch "ui-scaling") into default branch diff -r 41121e2f5c03 -r 63e2b7b2ec47 ChangeLog.txt --- 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 diff -r 41121e2f5c03 -r 63e2b7b2ec47 QTfrontend/game.cpp --- 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; } diff -r 41121e2f5c03 -r 63e2b7b2ec47 QTfrontend/gameuiconfig.cpp --- 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().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; diff -r 41121e2f5c03 -r 63e2b7b2ec47 QTfrontend/gameuiconfig.h --- 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(); diff -r 41121e2f5c03 -r 63e2b7b2ec47 QTfrontend/net/recorder.cpp --- 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; } diff -r 41121e2f5c03 -r 63e2b7b2ec47 QTfrontend/ui/page/pageoptions.cpp --- 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__ diff -r 41121e2f5c03 -r 63e2b7b2ec47 QTfrontend/ui/page/pageoptions.h --- 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; diff -r 41121e2f5c03 -r 63e2b7b2ec47 hedgewars/ArgParsers.pas --- 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 diff -r 41121e2f5c03 -r 63e2b7b2ec47 hedgewars/uChat.pas --- 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:= ''; diff -r 41121e2f5c03 -r 63e2b7b2ec47 hedgewars/uConsts.pas --- 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 diff -r 41121e2f5c03 -r 63e2b7b2ec47 hedgewars/uStore.pas --- 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); diff -r 41121e2f5c03 -r 63e2b7b2ec47 hedgewars/uTypes.pas --- 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); diff -r 41121e2f5c03 -r 63e2b7b2ec47 hedgewars/uVariables.pas --- 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; diff -r 41121e2f5c03 -r 63e2b7b2ec47 share/hedgewars/Data/Graphics/slider.png diff -r 41121e2f5c03 -r 63e2b7b2ec47 share/hedgewars/Data/Music/Jungle.ogg diff -r 41121e2f5c03 -r 63e2b7b2ec47 share/hedgewars/Data/Themes/Hoggywood/SkyL.png