# HG changeset patch # User Medo # Date 1338640029 -7200 # Node ID 8d1d6adf5f821489ffdc3db2dfc2cbc6f07ea410 # Parent fe76d24a25d7b7bf1ca8720151987d7bad0121cb# Parent fad64b97947ee19a1e738476d03184302b96bb39 Merge diff -r fe76d24a25d7 -r 8d1d6adf5f82 QTfrontend/gameuiconfig.cpp --- a/QTfrontend/gameuiconfig.cpp Sat Jun 02 14:26:52 2012 +0200 +++ b/QTfrontend/gameuiconfig.cpp Sat Jun 02 14:27:09 2012 +0200 @@ -67,7 +67,7 @@ Form->ui.pageOptions->CBFrontendEffects->setChecked(frontendEffects); Form->ui.pageOptions->CBEnableSound->setChecked(value("audio/sound", true).toBool()); Form->ui.pageOptions->CBEnableFrontendSound->setChecked(value("frontend/sound", true).toBool()); - Form->ui.pageOptions->CBEnableMusic->setChecked(value(" audio/music", true).toBool()); + Form->ui.pageOptions->CBEnableMusic->setChecked(value("audio/music", true).toBool()); Form->ui.pageOptions->CBEnableFrontendMusic->setChecked(value("frontend/music", true).toBool()); Form->ui.pageOptions->volumeBox->setValue(value("audio/volume", 100).toUInt()); diff -r fe76d24a25d7 -r 8d1d6adf5f82 QTfrontend/ui/page/pageoptions.cpp --- a/QTfrontend/ui/page/pageoptions.cpp Sat Jun 02 14:26:52 2012 +0200 +++ b/QTfrontend/ui/page/pageoptions.cpp Sat Jun 02 14:27:09 2012 +0200 @@ -181,7 +181,7 @@ { IconedGroupBox* groupMisc = new IconedGroupBox(this); //groupMisc->setContentTopPadding(0); - groupMisc->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + groupMisc->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding); groupMisc->setIcon(QIcon(":/res/miscicon.png")); //groupMisc->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); groupMisc->setTitle(QGroupBox::tr("Misc")); @@ -229,30 +229,22 @@ editNetNick->setText(QLineEdit::tr("anonymous")); MiscLayout->addWidget(editNetNick, 1, 1); - // Label and field for password - labelNetPassword = new QLabel(groupMisc); - labelNetPassword->setText(QLabel::tr("Password")); - MiscLayout->addWidget(labelNetPassword, 2, 0); + // checkbox and field for password + CBSavePassword = new QCheckBox(groupMisc); + CBSavePassword->setText(QCheckBox::tr("Save password")); + MiscLayout->addWidget(CBSavePassword, 2, 0); editNetPassword = new QLineEdit(groupMisc); editNetPassword->setEchoMode(QLineEdit::Password); MiscLayout->addWidget(editNetPassword, 2, 1); - CBSavePassword = new QCheckBox(groupMisc); - CBSavePassword->setText(QCheckBox::tr("Save password")); - MiscLayout->addWidget(CBSavePassword, 3, 0, 1, 2); - - CBAltDamage = new QCheckBox(groupMisc); - CBAltDamage->setText(QCheckBox::tr("Alternative damage show")); - MiscLayout->addWidget(CBAltDamage, 4, 0, 1, 2); - CBNameWithDate = new QCheckBox(groupMisc); CBNameWithDate->setText(QCheckBox::tr("Append date and time to record file name")); MiscLayout->addWidget(CBNameWithDate, 5, 0, 1, 2); BtnAssociateFiles = new QPushButton(groupMisc); BtnAssociateFiles->setText(QPushButton::tr("Associate file extensions")); - BtnAssociateFiles->setEnabled(!custom_data && !custom_config); + BtnAssociateFiles->setVisible(!custom_data && !custom_config); MiscLayout->addWidget(BtnAssociateFiles, 6, 0, 1, 2); #ifdef __APPLE__ @@ -309,7 +301,7 @@ CBFullscreen = new QCheckBox(AGGroupBox); CBFullscreen->setText(QCheckBox::tr("Fullscreen")); - GBAlayout->addWidget(CBFullscreen); + GBAreslayout->addWidget(CBFullscreen); QLabel * quality = new QLabel(AGGroupBox); quality->setText(QLabel::tr("Quality")); @@ -349,36 +341,6 @@ GBAstereolayout->addWidget(CBStereoMode); GBAlayout->addLayout(GBAstereolayout); - hr = new QFrame(AGGroupBox); - hr->setFrameStyle(QFrame::HLine); - hr->setLineWidth(3); - hr->setFixedHeight(10); - GBAlayout->addWidget(hr); - - QHBoxLayout * GBAvollayout = new QHBoxLayout(0); - QLabel * vol = new QLabel(AGGroupBox); - vol->setText(QLabel::tr("Initial sound volume")); - GBAvollayout->addWidget(vol); - GBAlayout->addLayout(GBAvollayout); - volumeBox = new QSpinBox(AGGroupBox); - volumeBox->setRange(0, 100); - volumeBox->setSingleStep(5); - GBAvollayout->addWidget(volumeBox); - - CBEnableSound = new QCheckBox(AGGroupBox); - CBEnableSound->setText(QCheckBox::tr("Enable sound")); - GBAlayout->addWidget(CBEnableSound); - - CBEnableMusic = new QCheckBox(AGGroupBox); - CBEnableMusic->setText(QCheckBox::tr("Enable music")); - GBAlayout->addWidget(CBEnableMusic); - - hr = new QFrame(AGGroupBox); - hr->setFrameStyle(QFrame::HLine); - hr->setLineWidth(3); - hr->setFixedHeight(10); - GBAlayout->addWidget(hr); - QHBoxLayout * GBAfpslayout = new QHBoxLayout(0); QLabel * maxfps = new QLabel(AGGroupBox); maxfps->setText(QLabel::tr("FPS limit")); @@ -389,7 +351,43 @@ CBShowFPS = new QCheckBox(AGGroupBox); CBShowFPS->setText(QCheckBox::tr("Show FPS")); - GBAlayout->addWidget(CBShowFPS); + GBAfpslayout->addWidget(CBShowFPS); + + hr = new QFrame(AGGroupBox); + hr->setFrameStyle(QFrame::HLine); + hr->setLineWidth(3); + hr->setFixedHeight(10); + GBAlayout->addWidget(hr); + + QGridLayout * GBAvollayout = new QGridLayout(); + QLabel * vol = new QLabel(AGGroupBox); + vol->setText(QLabel::tr("Initial sound volume")); + GBAvollayout->addWidget(vol, 0, 0, 1, 2); + GBAlayout->addLayout(GBAvollayout); + volumeBox = new QSpinBox(AGGroupBox); + volumeBox->setRange(0, 100); + volumeBox->setSingleStep(5); + GBAvollayout->addWidget(volumeBox, 0, 2); + + CBEnableSound = new QCheckBox(AGGroupBox); + CBEnableSound->setText(QCheckBox::tr("Enable sound")); + GBAvollayout->addWidget(CBEnableSound, 1, 0, 1, 1); + + CBEnableMusic = new QCheckBox(AGGroupBox); + CBEnableMusic->setText(QCheckBox::tr("Enable music")); + GBAvollayout->addWidget(CBEnableMusic, 1, 1, 1, 2); + + GBAvollayout->setSizeConstraint(QLayout::SetMinimumSize); + + hr = new QFrame(AGGroupBox); + hr->setFrameStyle(QFrame::HLine); + hr->setLineWidth(3); + hr->setFixedHeight(10); + GBAlayout->addWidget(hr); + + CBAltDamage = new QCheckBox(AGGroupBox); + CBAltDamage->setText(QCheckBox::tr("Alternative damage show")); + GBAlayout->addWidget(CBAltDamage); gbTBLayout->addWidget(AGGroupBox, 0, 1, 3, 1); } diff -r fe76d24a25d7 -r 8d1d6adf5f82 QTfrontend/ui/page/pageoptions.h --- a/QTfrontend/ui/page/pageoptions.h Sat Jun 02 14:26:52 2012 +0200 +++ b/QTfrontend/ui/page/pageoptions.h Sat Jun 02 14:27:09 2012 +0200 @@ -65,7 +65,6 @@ FPSEdit *fpsedit; QLabel *labelNN; - QLabel *labelNetPassword; QSpinBox * volumeBox; QLineEdit *editNetNick; QLineEdit *editNetPassword; diff -r fe76d24a25d7 -r 8d1d6adf5f82 QTfrontend/ui/widget/igbox.cpp --- a/QTfrontend/ui/widget/igbox.cpp Sat Jun 02 14:26:52 2012 +0200 +++ b/QTfrontend/ui/widget/igbox.cpp Sat Jun 02 14:27:09 2012 +0200 @@ -29,7 +29,7 @@ // Has issues with border-radius on children // setAttribute(Qt::WA_PaintOnScreen, true); titleLeftPadding = 49; - contentTopPadding = 15; + contentTopPadding = 5; } void IconedGroupBox::setIcon(const QIcon & icon) @@ -45,7 +45,7 @@ "subcontrol-origin: margin;" "subcontrol-position: top left;" "padding-left: %2px;" - "padding-top: %1px;" + "padding-top: 15px;" "text-align: left;" "}" ).arg(contentTopPadding).arg(titleLeftPadding) diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/ArgParsers.inc --- a/hedgewars/ArgParsers.inc Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/ArgParsers.inc Sat Jun 02 14:27:09 2012 +0200 @@ -24,7 +24,7 @@ playReplayFileWithParameters() else begin - val(ParamStr(2), ipcPort); + ipcPort:= StrToInt(ParamStr(2)); GameType:= gmtLandPreview; if ParamStr(3) <> 'landpreview' then GameType:= gmtSyntax @@ -35,22 +35,21 @@ var tmp: LongInt; begin UserPathPrefix:= ParamStr(1); - val(ParamStr(2), cScreenWidth); - val(ParamStr(3), cScreenHeight); - val(ParamStr(4), cBits); - val(ParamStr(5), ipcPort); + cScreenWidth:= StrToInt(ParamStr(2)); + cScreenHeight:= StrToInt(ParamStr(3)); + cBits:= StrToInt(ParamStr(4)); + ipcPort:= StrToInt(ParamStr(5)); cFullScreen:= ParamStr(6) = '1'; SetSound(ParamStr(7) = '1'); SetMusic(ParamStr(8) = '1'); - val(ParamStr(9), tmp); - SetVolume(tmp); - val(ParamStr(10), cTimerInterval); + SetVolume(StrToInt(ParamStr(9))); + cTimerInterval:= StrToInt(ParamStr(10)); PathPrefix:= ParamStr(11); cShowFPS:= ParamStr(12) = '1'; cAltDamage:= ParamStr(13) = '1'; UserNick:= DecodeBase64(ParamStr(14)); - val(ParamStr(15), cReducedQuality); - val(ParamStr(16), tmp); + cReducedQuality:= StrToInt(ParamStr(15)); + tmp:= StrToInt(ParamStr(16)); GrayScale:= false; if (tmp > 9) and (tmp < 16) then begin @@ -72,11 +71,11 @@ end; procedure setVideoWithParameters(screenWidthParam: string; screenHeightParam: string; bitsParam: string); -var screenWidthAsInt, screenHeightAsInt, bitsStrAsInt: LongInt; +var screenWidthAsInt, screenHeightAsInt, bitsStrAsInt, c: LongInt; begin - val(screenWidthParam, screenWidthAsInt); - val(screenHeightParam, screenHeightAsInt); - val(bitsParam, bitsStrAsInt); + val(screenWidthParam, screenWidthAsInt, c); + val(screenHeightParam, screenHeightAsInt, c); + val(bitsParam, bitsStrAsInt, c); setVideo(screenWidthAsInt,screenHeightAsInt,bitsStrAsInt) end; @@ -108,10 +107,10 @@ end; procedure setAudioWithParameters(initialVolumeParam: string; musicEnabledParam: string; soundEnabledParam: string); -var initialVolumeAsInt: LongInt; +var initialVolumeAsInt, c: LongInt; musicEnabled, soundEnabled: boolean; begin - val(initialVolumeParam, initialVolumeAsInt); + val(initialVolumeParam, initialVolumeAsInt, c); musicEnabled:= musicEnabledParam = '1'; soundEnabled:= soundEnabledParam = '1'; setAudio(initialVolumeAsInt,musicEnabled, soundEnabled) @@ -139,7 +138,7 @@ languageFileParam:string; fullScreenParam:string; showFPSParam:string; altDamageParam:string; timeItervalParam:string; reducedQualityParam: string); var showFPS, altDamage, reducedQuality: boolean; - timeIterval: LongInt; + timeIterval, c: LongInt; begin setMultimediaOptionsWithParameters(screenWidthParam,screenHeightParam, bitsParam, initialVolumeParam,musicEnabledParam,soundEnabledParam, @@ -148,7 +147,7 @@ setShowFPS(showFPS); altDamage:= altDamageParam = '1'; - val(timeItervalParam, timeIterval); + val(timeItervalParam, timeIterval, c); reducedQuality:= reducedQualityParam = '1'; setAltDamageTimerValueAndQuality(altDamage,timeIterval,reducedQuality); end; diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/LuaPas.pas --- a/hedgewars/LuaPas.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/LuaPas.pas Sat Jun 02 14:27:09 2012 +0200 @@ -1,4 +1,5 @@ {$HINTS OFF} +{$INCLUDE "options.inc"} unit LuaPas; @@ -23,8 +24,7 @@ lua_State = record end; Plua_State = ^lua_State; -const - LuaLibName = cLuaLibrary; +{$DEFINE LuaLibName:= cLuaLibrary} (*****************************************************************************) @@ -81,8 +81,8 @@ ** CHANGE them if you want to improve this functionality (e.g., by using ** GNU readline and history facilities). *) -function lua_readline(L : Plua_State; -var b : PChar; p : PChar): Boolean; +{function lua_readline(L : Plua_State; +var b : PChar; p : PChar): Boolean;} procedure lua_saveline(L : Plua_State; idx : LongInt); @@ -119,7 +119,7 @@ LUA_AUTHORS = 'R. Ierusalimschy, L. H. de Figueiredo & W. Celes'; (* mark for precompiled code (`Lua') *) - LUA_SIGNATURE = #27 + 'Lua'; + //LUA_SIGNATURE = #27'Lua'; (* option for multiple returns in `lua_pcall' and `lua_call' *) LUA_MULTRET = -1; @@ -799,7 +799,7 @@ (*****************************************************************************) (* luaconfig.h *) (*****************************************************************************) - +{ function lua_readline(L : Plua_State; var b : PChar; p : PChar): Boolean; @@ -811,7 +811,7 @@ b := PChar(s); // and return it lua_readline := (b[0] <> #4); // test for ctrl-D end; - +} procedure lua_saveline(L : Plua_State; idx : LongInt); begin end; @@ -1041,7 +1041,7 @@ lua_ref := luaL_ref(L, LUA_REGISTRYINDEX) else begin - lua_pushstring(L, 'unlocked references are obsolete'); + lua_pushstring(L, _P'unlocked references are obsolete'); lua_error(L); lua_ref := 0; end; diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/hwengine.pas Sat Jun 02 14:27:09 2012 +0200 @@ -104,7 +104,11 @@ if flagMakeCapture then begin flagMakeCapture:= false; + {$IFDEF PAS2C} + s:= 'hw'; + {$ELSE} s:= 'hw_' + FormatDateTime('YYYY-MM-DD_HH-mm-ss', Now()) + inttostr(GameTicks); + {$ENDIF} playSound(sndShutter); @@ -267,10 +271,10 @@ cBits:= 32; cTimerInterval:= 8; cShowFPS:= {$IFDEF DEBUGFILE}true{$ELSE}false{$ENDIF}; - val(gameArgs[0], ipcPort); - val(gameArgs[1], cScreenWidth); - val(gameArgs[2], cScreenHeight); - val(gameArgs[3], cReducedQuality); + ipcPort:= StrToInt(gameArgs[0]); + cScreenWidth:= StrToInt(gameArgs[1]); + cScreenHeight:= StrToInt(gameArgs[2]); + cReducedQuality:= StrToInt(gameArgs[3]); cLocaleFName:= gameArgs[4]; // cFullScreen functionality is platform dependent, ifdef it if you need to modify it cFullScreen:= false; @@ -493,26 +497,26 @@ procedure DisplayUsage; var i: LongInt; begin - WriteLn('Wrong argument format: correct configurations is'); - WriteLn(); - WriteLn(' hwengine [options]'); - WriteLn(); - WriteLn('where [options] must be specified either as:'); - WriteLn(' --set-video [screen width] [screen height] [color dept]'); - WriteLn(' --set-audio [volume] [enable music] [enable sounds]'); - WriteLn(' --set-other [language file] [full screen] [show FPS]'); - WriteLn(' --set-multimedia [screen width] [screen height] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen]'); - WriteLn(' --set-everything [screen width] [screen height] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen] [show FPS] [alternate damage] [timer value] [reduced quality]'); - WriteLn(' --stats-only'); - WriteLn(); - WriteLn('Read documentation online at http://code.google.com/p/hedgewars/wiki/CommandLineOptions for more information'); - WriteLn(); - Write('PARSED COMMAND: '); + WriteLn(stdout, 'Wrong argument format: correct configurations is'); + WriteLn(stdout, ''); + WriteLn(stdout, ' hwengine [options]'); + WriteLn(stdout, ''); + WriteLn(stdout, 'where [options] must be specified either as:'); + WriteLn(stdout, ' --set-video [screen width] [screen height] [color dept]'); + WriteLn(stdout, ' --set-audio [volume] [enable music] [enable sounds]'); + WriteLn(stdout, ' --set-other [language file] [full screen] [show FPS]'); + WriteLn(stdout, ' --set-multimedia [screen width] [screen height] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen]'); + WriteLn(stdout, ' --set-everything [screen width] [screen height] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen] [show FPS] [alternate damage] [timer value] [reduced quality]'); + WriteLn(stdout, ' --stats-only'); + WriteLn(stdout, ''); + WriteLn(stdout, 'Read documentation online at http://code.google.com/p/hedgewars/wiki/CommandLineOptions for more information'); + WriteLn(stdout, ''); + Write(stdout, 'PARSED COMMAND: '); for i:=0 to ParamCount do - Write(ParamStr(i) + ' '); + Write(stdout, ParamStr(i) + ' '); - WriteLn(); + WriteLn(stdout, ''); end; //////////////////// @@ -549,6 +553,6 @@ else Game(); // return 1 when engine is not called correctly - ExitCode:= LongInt(GameType = gmtSyntax); + halt(LongInt(GameType = gmtSyntax)); {$ENDIF} end. diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/pas2c.h --- a/hedgewars/pas2c.h Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/pas2c.h Sat Jun 02 14:27:09 2012 +0200 @@ -29,6 +29,7 @@ } string15; typedef string255 shortstring; +typedef string255 ansistring; typedef uint8_t Byte; typedef int8_t ShortInt; @@ -71,6 +72,7 @@ string255 _strconcat(string255 a, string255 b); string255 _strappend(string255 s, char c); string255 _strprepend(char c, string255 s); +string255 _chrconcat(char a, char b); bool _strcompare(string255 a, string255 b); bool _strcomparec(string255 a, char b); bool _strncompare(string255 a, string255 b); @@ -91,6 +93,7 @@ typedef int TextFile; extern int FileMode; extern int IOResult; +extern int stdout; extern int stderr; #define assign(a, b) assign_(&(a), b) @@ -103,8 +106,8 @@ void BlockWrite_(int f, void * p, int size); void close(int f); -void write(string255 s); -void writeLn(string255 s); +void write(int f, string255 s); +void writeLn(int f, string255 s); bool DirectoryExists(string255 dir); bool FileExists(string255 filename); @@ -132,8 +135,8 @@ string255 ParamStr(int n); int ParamCount(); -#define val(a, b) _val(a, (LongInt*)&(b)) -void _val(string255 str, LongInt * a); +#define val(a, b, c) _val(a, (LongInt*)&(b), (LongInt*)&(c)) +void _val(string255 str, LongInt * a, LongInt * c); extern double pi; diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/pas2cSystem.pas --- a/hedgewars/pas2cSystem.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/pas2cSystem.pas Sat Jun 02 14:27:09 2012 +0200 @@ -43,7 +43,6 @@ PInteger = ^Integer; Handle = integer; - stderr = Handle; png_structp = pointer; png_size_t = integer; @@ -79,6 +78,7 @@ FileExists, DirectoryExists, eof : function : boolean; ExtractFileName : function : string; exitcode : integer; + stdout, stderr : Handle; ParamCount : function : integer; ParamStr : function : string; @@ -134,7 +134,7 @@ Assigned : function : boolean; - _strconcat, _strappend, _strprepend : function : string; + _strconcat, _strappend, _strprepend, _chrconcat : function : string; _strcompare, _strncompare, _strcomparec : function : boolean; png_structp, png_set_write_fn, png_get_io_ptr, diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uAI.pas --- a/hedgewars/uAI.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uAI.pas Sat Jun 02 14:27:09 2012 +0200 @@ -266,9 +266,11 @@ with Stack.States[Pred(Stack.Count)] do AddAction(MadeActions, aia_LJump, 0, 305 + random(50), 0, 0); + // 'not CanGO' means we can't go straight, possible jumps are checked above if not CanGo then break; - inc(steps); + + inc(steps); Actions.actions[Pred(Actions.Count)].Param:= hwRound(Me^.X); Rate:= RatePlace(Me); if Rate > BestRate then @@ -284,11 +286,11 @@ TestAmmos(Actions, Me, true); if GoInfo.FallPix >= FallPixForBranching then Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right - end; + end {while}; if BestRate > BaseRate then exit - end + end {while} end; function Think(Me: Pointer): ptrint; diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uAIAmmoTests.pas --- a/hedgewars/uAIAmmoTests.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uAIAmmoTests.pas Sat Jun 02 14:27:09 2012 +0200 @@ -163,7 +163,7 @@ EX:= trunc(x); EY:= trunc(y); if Me^.Hedgehog^.BotLevel = 1 then - value:= RateExplosion(Me, EX, EY, 101, 3) + value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand) else value:= RateExplosion(Me, EX, EY, 101); if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64; @@ -220,7 +220,7 @@ EX:= trunc(x); EY:= trunc(y); - value:= RateShove(Me, trunc(x), trunc(y), 5, 1, trunc((abs(dX)+abs(dY))*20), -dX, -dY, 1); + value:= RateShove(Me, trunc(x), trunc(y), 5, 1, trunc((abs(dX)+abs(dY))*20), -dX, -dY, afTrackFall); if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64; @@ -323,7 +323,7 @@ EY:= trunc(y); if t < 50 then if Me^.Hedgehog^.BotLevel = 1 then - Score:= RateExplosion(Me, EX, EY, 101, 3) + Score:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand) else Score:= RateExplosion(Me, EX, EY, 101) else Score:= BadTurn; @@ -650,7 +650,7 @@ else ap.Angle:= - cMaxAngle div 4; -valueResult:= RateShove(Me, trunc(x) + LongWord(10*hwSignf(Targ.X - x)), trunc(y), 15, 30, 115, hwSign(Me^.dX)*0.353, -0.353, 1); +valueResult:= RateShove(Me, trunc(x) + LongWord(10*hwSignf(Targ.X - x)), trunc(y), 15, 30, 115, hwSign(Me^.dX)*0.353, -0.353, afTrackFall); if valueResult <= 0 then valueResult:= BadTurn else @@ -659,7 +659,7 @@ end; function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; -var val1: LongInt; +var val1, val2, i, t: LongInt; x, y: real; begin Level:= Level; // avoid compiler hint @@ -670,24 +670,25 @@ ap.Angle:= hwSign(Me^.dX); x:= hwFloat2Float(Me^.X); y:= hwFloat2Float(Me^.Y); -if (Abs(trunc(x) - Targ.X) < 25) - and (Abs(trunc(y) - 50 - Targ.Y) < 50) then +{ +// this block is for digging with firepunch when blocked close to walls (notice TestColl check) +if (Abs(trunc(x) - Targ.X) > 25) + or (Abs(trunc(y) + 50 - Targ.Y) > 50) then begin -// TODO - find out WTH this works. if TestColl(trunc(x), trunc(y) - 16, 6) and (RateShove(Me, trunc(x) + LongWord(10 * hwSign(Me^.dX)), - trunc(y) - 40, 30, 30, 40, hwSign(Me^.dX)*0.45, -0.9, 1) = 0) then + trunc(y) - 40, 30, 30, 40, hwSign(Me^.dX)*0.45, -0.9, 1) >= 0) then val1:= Succ(BadTurn) else val1:= BadTurn; exit(val1); end; -(* -For some silly reason, having this enabled w/ the AI + } +// and this is actual try to attack val1:= 0; for i:= 0 to 4 do begin - t:= RateShove(Me, trunc(x) + 10 * hwSign(Targ.X - x), trunc(y) - 20 * i - 5, 10, 30, 40, hwSign(Me^.dX)*0.45, -0.9, 1); + t:= RateShove(Me, trunc(x) + 10 * hwSignf(Targ.X - x), trunc(y) - 20 * i - 5, 10, 30, 40, hwSign(Me^.dX)*0.45, -0.9, afTrackFall); if (val1 < 0) or (t < 0) then val1:= BadTurn else if t > 0 then val1:= t; end; @@ -695,7 +696,7 @@ val2:= 0; for i:= 0 to 4 do begin - t:= RateShove(Me, trunc(x) + 10 * hwSign(Targ.X - x), trunc(y) - 20 * i - 5, 10, 30, 40, -hwSign(Me^.dX)*0.45, -0.9, 1); + t:= RateShove(Me, trunc(x) + 10 * hwSignf(Targ.X - x), trunc(y) - 20 * i - 5, 10, 30, 40, -hwSign(Me^.dX)*0.45, -0.9, afTrackFall); if (val2 < 0) or (t < 0) then val2:= BadTurn else if t > 0 then val2:= t; end; @@ -706,35 +707,57 @@ ap.Angle:= -hwSign(Me^.dX); TestFirePunch:= val2 end -else TestFirePunch:= BadTurn;*) +else TestFirePunch:= BadTurn; end; +// TODO: TestWhip, TestFirepunch and TestBaseballBat could be called only once at each position +// (now they're called for each possible target in each position) function TestWhip(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; -var i, valueResult: LongInt; +var valueResult, v1, v2: LongInt; x, y: real; begin Level:= Level; // avoid compiler hint ap.ExplR:= 0; ap.Time:= 0; ap.Power:= 1; -ap.Angle:= 0; x:= hwFloat2Float(Me^.X); y:= hwFloat2Float(Me^.Y); -if (Abs(trunc(x) - Targ.X) > 25) -or (Abs(trunc(y) - 50 - Targ.Y) > 50) then + +if(abs(Targ.X - x) > 50) or (abs(Targ.Y - y) > 30) then // we're way too far from our target + exit(BadTurn); + +// check left direction +{first RateShove checks fartherest of two whip's AmmoShove attacks +to encourage distant attacks (damaged hog is excluded from view of second +RateShove call)} +v1:= RateShove(Me, trunc(x) - 15, trunc(y) + , 30, 30, 40 + , -1, -0.8, afTrackFall or afSetSkip); +v1:= v1 + + RateShove(Me, trunc(x), trunc(y) + , 30, 30, 40 + , -1, -0.8, afTrackFall); +// now try opposite direction +v2:= RateShove(Me, trunc(x) + 15, trunc(y) + , 30, 30, 40 + , 1, -0.8, afTrackFall or afSetSkip); +v2:= v2 + + RateShove(Me, trunc(x), trunc(y) + , 30, 30, 40 + , 1, -0.8, afTrackFall); + +if (v2 > v1) + or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then begin - if TestColl(trunc(x), trunc(y) - 16, 6) - and (RateShove(Me, trunc(x) + LongWord(10 * hwSign(Me^.dX)), trunc(y) - 40, 30, 30, 40, hwSign(Me^.dX), -0.8, 1) = 0) then - valueResult:= Succ(BadTurn) - else - valueResult:= BadTurn; - exit(valueResult); + ap.Angle:= 1; + valueResult:= v2 + end +else + begin + ap.Angle:= -1; + valueResult:= v1 end; - -valueResult:= 0; -for i:= 0 to 4 do - valueResult:= valueResult + RateShove(Me, trunc(x) + LongWord(10 * hwSignf(Targ.X - x)), - trunc(y) - LongWord(20 * i) - 5, 10, 30, 40, hwSign(Me^.dX), -0.8, 1); + if valueResult <= 0 then valueResult:= BadTurn else diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uAIMisc.pas --- a/hedgewars/uAIMisc.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uAIMisc.pas Sat Jun 02 14:27:09 2012 +0200 @@ -24,9 +24,15 @@ const MAXBONUS = 1024; + afTrackFall = $00000001; + afErasesLand = $00000002; + afSetSkip = $00000004; + + type TTarget = record Point: TPoint; Score: LongInt; + skip: boolean; end; TTargets = record Count: Longword; @@ -100,6 +106,7 @@ begin with Targets.ar[Targets.Count], Hedgehogs[i] do begin + skip:= false; Point.X:= hwRound(Gear^.X); Point.Y:= hwRound(Gear^.Y); if Clan <> CurrentTeam^.Clan then @@ -122,12 +129,14 @@ procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt); inline; begin -bonuses.ar[bonuses.Count].x:= x; -bonuses.ar[bonuses.Count].y:= y; -bonuses.ar[bonuses.Count].Radius:= r; -bonuses.ar[bonuses.Count].Score:= s; -inc(bonuses.Count); -TryDo(bonuses.Count <= MAXBONUS, 'Bonuses overflow', true) +if(bonuses.Count < MAXBONUS) then + begin + bonuses.ar[bonuses.Count].x:= x; + bonuses.ar[bonuses.Count].y:= y; + bonuses.ar[bonuses.Count].Radius:= r; + bonuses.ar[bonuses.Count].Score:= s; + inc(bonuses.Count); + end; end; procedure FillBonuses(isAfterAttack: boolean); @@ -155,7 +164,7 @@ gtExplosives: if isAfterAttack then - AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 75, -60+Gear^.Health); + AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 75, -60 + Gear^.Health); gtSMine: AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 50, -30); @@ -203,7 +212,7 @@ r:= Radius; if abs(gX-X)+abs(gY-Y) < Radius then r:= trunc(sqrt(sqr(gX - X)+sqr(gY - Y))); - if r < 15 then + if r < 20 then inc(rate, Score * Radius) else if r < Radius then inc(rate, Score * (Radius - r)) @@ -327,7 +336,6 @@ end; end; -// Flags are not defined yet but 1 for checking drowning and 2 for assuming land erasure. function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; begin RateExplosion:= RateExplosion(Me, x, y, r, 0); @@ -349,7 +357,7 @@ end; // rate explosion dmgBase:= r + cHHRadius div 2; -if (Flags and 2 <> 0) and (GameFlags and gfSolidLand = 0) then erasure:= r +if (Flags and afErasesLand <> 0) and (GameFlags and gfSolidLand = 0) then erasure:= r else erasure:= 0; for i:= 0 to Targets.Count do with Targets.ar[i] do @@ -360,7 +368,7 @@ if dmg > 0 then begin - if Flags and 1 <> 0 then + if Flags and afTrackFall <> 0 then begin dX:= 0.005 * dmg + 0.01; dY:= dX; @@ -396,6 +404,9 @@ rate:= 0; for i:= 0 to Pred(Targets.Count) do with Targets.ar[i] do + if skip then + if (Flags and afSetSkip = 0) then skip:= false else {still skip} + else begin dmg:= 0; if abs(Point.x - x) + abs(Point.y - y) < r then @@ -405,8 +416,9 @@ end; if dmg > 0 then begin - if (Flags and 1 <> 0) then - fallDmg:= trunc(TraceShoveFall(Me, Point.x, Point.y-2, dX, dY) * dmgMod); + if (Flags and afSetSkip <> 0) then skip:= true; + if (Flags and afTrackFall <> 0) then + fallDmg:= trunc(TraceShoveFall(Me, Point.x, Point.y - 2, dX, dY) * dmgMod); if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI if Score > 0 then inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings @@ -602,114 +614,124 @@ GoInfo.Ticks:= 0; GoInfo.FallPix:= 0; GoInfo.JumpType:= jmpNone; + repeat -pX:= hwRound(Gear^.X); -pY:= hwRound(Gear^.Y); -if pY + cHHRadius >= cWaterLine then - exit(false); -if (Gear^.State and gstMoving) <> 0 then - begin - inc(GoInfo.Ticks); - Gear^.dY:= Gear^.dY + cGravity; - if Gear^.dY > _0_4 then + pX:= hwRound(Gear^.X); + pY:= hwRound(Gear^.Y); + if pY + cHHRadius >= cWaterLine then + exit(false); + + // hog is falling + if (Gear^.State and gstMoving) <> 0 then begin - Goinfo.FallPix:= 0; - HHJump(AltGear, jmpLJump, GoInfo); // try ljump instead of fall with damage - exit(false) - end; - Gear^.Y:= Gear^.Y + Gear^.dY; - if hwRound(Gear^.Y) > pY then - inc(GoInfo.FallPix); - if TestCollisionYwithGear(Gear, 1) <> 0 then - begin - inc(GoInfo.Ticks, 410); - Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); - Gear^.dY:= _0; - HHJump(AltGear, jmpLJump, GoInfo); // try ljump instead of fall - HHGo:= true; - exit(false) + inc(GoInfo.Ticks); + Gear^.dY:= Gear^.dY + cGravity; + if Gear^.dY > _0_4 then + begin + Goinfo.FallPix:= 0; + // try ljump instead of fall with damage + HHJump(AltGear, jmpLJump, GoInfo); + exit(false) + end; + Gear^.Y:= Gear^.Y + Gear^.dY; + if hwRound(Gear^.Y) > pY then + inc(GoInfo.FallPix); + if TestCollisionYwithGear(Gear, 1) <> 0 then + begin + inc(GoInfo.Ticks, 410); + Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); + Gear^.dY:= _0; + // try ljump instead of fall + HHJump(AltGear, jmpLJump, GoInfo); + exit(true) + end; + continue end; - continue - end; - if (Gear^.Message and gmLeft )<>0 then - Gear^.dX:= -cLittle - else - if (Gear^.Message and gmRight )<>0 then - Gear^.dX:= cLittle + + // usual walk + if (Gear^.Message and gmLeft) <> 0 then + Gear^.dX:= -cLittle else - exit(false); - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then - begin - if not (TestCollisionXwithXYShift(Gear, _0, -6, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then + if (Gear^.Message and gmRight) <> 0 then + Gear^.dX:= cLittle + else + exit(false); + + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin Gear^.Y:= Gear^.Y - _1; - - if not (TestCollisionXwithXYShift(Gear, _0, -5, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin Gear^.Y:= Gear^.Y - _1; - - if not (TestCollisionXwithXYShift(Gear, _0, -4, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin Gear^.Y:= Gear^.Y - _1; - - if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; - - if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then + Gear^.Y:= Gear^.Y + _6 + end else Gear^.Y:= Gear^.Y + _5 else + end else Gear^.Y:= Gear^.Y + _4 else + end else Gear^.Y:= Gear^.Y + _3 else + end else Gear^.Y:= Gear^.Y + _2 else + end else Gear^.Y:= Gear^.Y + _1 + end; + + if not TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then + begin + Gear^.X:= Gear^.X + int2hwFloat(hwSign(Gear^.dX)); + inc(GoInfo.Ticks, cHHStepTicks) end; - if not TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then - begin - Gear^.X:= Gear^.X + int2hwFloat(hwSign(Gear^.dX)); - inc(GoInfo.Ticks, cHHStepTicks) - end; + // too scared to reformat this part + if TestCollisionYwithGear(Gear, 1) = 0 then + begin + Gear^.Y:= Gear^.Y + _1; + + if TestCollisionYwithGear(Gear, 1) = 0 then + begin + Gear^.Y:= Gear^.Y + _1; + + if TestCollisionYwithGear(Gear, 1) = 0 then + begin + Gear^.Y:= Gear^.Y + _1; - // too scared to reformat this part - if TestCollisionYwithGear(Gear, 1) = 0 then - begin - Gear^.Y:= Gear^.Y + _1; - - if TestCollisionYwithGear(Gear, 1) = 0 then - begin - Gear^.Y:= Gear^.Y + _1; - - if TestCollisionYwithGear(Gear, 1) = 0 then - begin - Gear^.Y:= Gear^.Y + _1; + if TestCollisionYwithGear(Gear, 1) = 0 then + begin + Gear^.Y:= Gear^.Y + _1; - if TestCollisionYwithGear(Gear, 1) = 0 then - begin - Gear^.Y:= Gear^.Y + _1; + if TestCollisionYwithGear(Gear, 1) = 0 then + begin + Gear^.Y:= Gear^.Y + _1; - if TestCollisionYwithGear(Gear, 1) = 0 then - begin - Gear^.Y:= Gear^.Y + _1; - - if TestCollisionYwithGear(Gear, 1) = 0 then - begin - Gear^.Y:= Gear^.Y + _1; + if TestCollisionYwithGear(Gear, 1) = 0 then + begin + Gear^.Y:= Gear^.Y + _1; - if TestCollisionYwithGear(Gear, 1) = 0 then - begin - Gear^.Y:= Gear^.Y - _6; - Gear^.dY:= _0; - Gear^.State:= Gear^.State or gstMoving + if TestCollisionYwithGear(Gear, 1) = 0 then + begin + Gear^.Y:= Gear^.Y - _6; + Gear^.dY:= _0; + Gear^.State:= Gear^.State or gstMoving + end + end + end end - end - end - end - end - end - end; -if (pX <> hwRound(Gear^.X)) and ((Gear^.State and gstMoving) = 0) then - exit(true) + end + end + end; + // we have moved for 1 px + if (pX <> hwRound(Gear^.X)) and ((Gear^.State and gstMoving) = 0) then + exit(true) until (pX = hwRound(Gear^.X)) and (pY = hwRound(Gear^.Y)) and ((Gear^.State and gstMoving) = 0); + HHJump(AltGear, jmpHJump, GoInfo); end; diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uCommandHandlers.pas --- a/hedgewars/uCommandHandlers.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uCommandHandlers.pas Sat Jun 02 14:27:09 2012 +0200 @@ -86,11 +86,11 @@ end; procedure chCheckProto(var s: shortstring); -var i: LongInt; +var i, c: LongInt; begin if isDeveloperMode then begin - val(s, i); + val(s, i, c); TryDo(i <= cNetProtoVersion, 'Protocol version mismatch: engine is too old (got '+intToStr(i)+', expecting '+intToStr(cNetProtoVersion)+')', true); TryDo(i >= cNetProtoVersion, 'Protocol version mismatch: engine is too new (got '+intToStr(i)+', expecting '+intToStr(cNetProtoVersion)+')', true); end @@ -683,104 +683,102 @@ procedure chMapGen(var s: shortstring); begin -val(s, cMapGen) +cMapGen:= StrToInt(s) end; procedure chTemplateFilter(var s: shortstring); begin -val(s, cTemplateFilter) +cTemplateFilter:= StrToInt(s) end; procedure chInactDelay(var s: shortstring); begin -val(s, cInactDelay) +cInactDelay:= StrToInt(s) end; procedure chReadyDelay(var s: shortstring); begin -val(s, cReadyDelay) +cReadyDelay:= StrToInt(s) end; procedure chCaseFactor(var s: shortstring); begin -val(s, cCaseFactor) +cCaseFactor:= StrToInt(s) end; procedure chHealthCaseProb(var s: shortstring); begin -val(s, cHealthCaseProb) +cHealthCaseProb:= StrToInt(s) end; procedure chHealthCaseAmount(var s: shortstring); begin -val(s, cHealthCaseAmount) +cHealthCaseAmount:= StrToInt(s) end; procedure chSuddenDTurns(var s: shortstring); begin -val(s, cSuddenDTurns) +cSuddenDTurns:= StrToInt(s) end; procedure chWaterRise(var s: shortstring); begin -val(s, cWaterRise) +cWaterRise:= StrToInt(s) end; procedure chHealthDecrease(var s: shortstring); begin -val(s, cHealthDecrease) +cHealthDecrease:= StrToInt(s) end; procedure chDamagePercent(var s: shortstring); begin -val(s, cDamagePercent) +cDamagePercent:= StrToInt(s) end; procedure chRopePercent(var s: shortstring); begin -val(s, cRopePercent) +cRopePercent:= StrToInt(s) end; procedure chGetAwayTime(var s: shortstring); begin -val(s, cGetAwayTime) +cGetAwayTime:= StrToInt(s) end; procedure chMineDudPercent(var s: shortstring); begin -val(s, cMineDudPercent) +cMineDudPercent:= StrToInt(s) end; procedure chLandMines(var s: shortstring); begin -val(s, cLandMines) +cLandMines:= StrToInt(s) end; procedure chExplosives(var s: shortstring); begin -val(s, cExplosives) +cExplosives:= StrToInt(s) end; procedure chGameFlags(var s: shortstring); begin -val(s, GameFlags) +GameFlags:= StrToInt(s) end; procedure chHedgehogTurnTime(var s: shortstring); begin -val(s, cHedgehogTurnTime) +cHedgehogTurnTime:= StrToInt(s) end; procedure chMinesTime(var s: shortstring); begin -val(s, cMinesTime) +cMinesTime:= StrToInt(s) end; procedure chFastUntilLag(var s: shortstring); -var i: LongInt; begin -val(s, i); -fastUntilLag:= i <> 0 +fastUntilLag:= StrToInt(s) <> 0 end; procedure initModule; diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uConsole.pas --- a/hedgewars/uConsole.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uConsole.pas Sat Jun 02 14:27:09 2012 +0200 @@ -85,7 +85,7 @@ {$IFNDEF NOCONSOLE} WriteToConsole(s); {$IFNDEF ANDROID} -WriteLn(stderr); +WriteLn(stderr, ''); inc(CurrLine); if CurrLine = cLinesCount then CurrLine:= 0; diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uGears.pas --- a/hedgewars/uGears.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uGears.pas Sat Jun 02 14:27:09 2012 +0200 @@ -779,6 +779,7 @@ Gear^.Active:= true; Gear^.State:= Gear^.State or gstMoving; + // move the gear upwards a bit to throw it over tiny obstacles at start if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then begin if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX)) diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uGearsHedgehog.pas --- a/hedgewars/uGearsHedgehog.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uGearsHedgehog.pas Sat Jun 02 14:27:09 2012 +0200 @@ -723,26 +723,32 @@ DeleteCI(Gear); // must be after exit!! (see previous line) Gear^.Hedgehog^.visStepPos:= (Gear^.Hedgehog^.visStepPos + 1) and 7; - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then + + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then begin - if not (TestCollisionXwithXYShift(Gear, _0, -6, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithXYShift(Gear, _0, -5, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithXYShift(Gear, _0, -4, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then + Gear^.Y:= Gear^.Y + _6 + end else Gear^.Y:= Gear^.Y + _5 else + end else Gear^.Y:= Gear^.Y + _4 else + end else Gear^.Y:= Gear^.Y + _3 else + end else Gear^.Y:= Gear^.Y + _2 else + end else Gear^.Y:= Gear^.Y + _1 end; if (not cArtillery) and ((Gear^.Message and gmPrecise) = 0) and (not TestCollisionXwithGear(Gear, hwSign(Gear^.dX))) then diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uInputHandler.pas --- a/hedgewars/uInputHandler.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uInputHandler.pas Sat Jun 02 14:27:09 2012 +0200 @@ -283,7 +283,7 @@ begin for j:= 0 to pred(ControllerNumControllers) do begin - WriteLnToConsole('Using game controller: ' + SDL_JoystickName(j)); + WriteLnToConsole('Using game controller: ' + shortstring(SDL_JoystickName(j))); Controller[j]:= SDL_JoystickOpen(j); if Controller[j] = nil then WriteLnToConsole('* Failed to open game controller!') diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uLand.pas --- a/hedgewars/uLand.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uLand.pas Sat Jun 02 14:27:09 2012 +0200 @@ -750,9 +750,9 @@ procedure freeModule; begin - Land:= nil; - LandPixels:= nil; - LandDirty:= nil; + SetLength(Land, 0, 0); + SetLength(LandPixels, 0, 0); + SetLength(LandDirty, 0, 0); end; end. diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uLandGraphics.pas --- a/hedgewars/uLandGraphics.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uLandGraphics.pas Sat Jun 02 14:27:09 2012 +0200 @@ -39,6 +39,7 @@ procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet: boolean); function LandBackPixel(x, y: LongInt): LongWord; procedure DrawLine(X1, Y1, X2, Y2: LongInt; Color: Longword); +procedure DrawThickLine(X1, Y1, X2, Y2, radius: LongInt; color: Longword); function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; indestructible: boolean): boolean; @@ -1056,4 +1057,104 @@ end end; +procedure DrawDots(x, y, xx, yy: Longint; Color: Longword); inline; +begin + if (((x + xx) and LAND_WIDTH_MASK) = 0) and (((y + yy) and LAND_HEIGHT_MASK) = 0) then Land[y + yy, x + xx]:= Color; + if (((x + xx) and LAND_WIDTH_MASK) = 0) and (((y - yy) and LAND_HEIGHT_MASK) = 0) then Land[y - yy, x + xx]:= Color; + if (((x - xx) and LAND_WIDTH_MASK) = 0) and (((y + yy) and LAND_HEIGHT_MASK) = 0) then Land[y + yy, x - xx]:= Color; + if (((x - xx) and LAND_WIDTH_MASK) = 0) and (((y - yy) and LAND_HEIGHT_MASK) = 0) then Land[y - yy, x - xx]:= Color; + if (((x + yy) and LAND_WIDTH_MASK) = 0) and (((y + xx) and LAND_HEIGHT_MASK) = 0) then Land[y + xx, x + yy]:= Color; + if (((x + yy) and LAND_WIDTH_MASK) = 0) and (((y - xx) and LAND_HEIGHT_MASK) = 0) then Land[y - xx, x + yy]:= Color; + if (((x - yy) and LAND_WIDTH_MASK) = 0) and (((y + xx) and LAND_HEIGHT_MASK) = 0) then Land[y + xx, x - yy]:= Color; + if (((x - yy) and LAND_WIDTH_MASK) = 0) and (((y - xx) and LAND_HEIGHT_MASK) = 0) then Land[y - xx, x - yy]:= Color; +end; + +procedure DrawLines(X1, Y1, X2, Y2, XX, YY: LongInt; color: Longword); +var + eX, eY, dX, dY: LongInt; + i, sX, sY, x, y, d: LongInt; + f: boolean; +begin + eX:= 0; + eY:= 0; + dX:= X2 - X1; + dY:= Y2 - Y1; + + if (dX > 0) then + sX:= 1 + else + if (dX < 0) then + begin + sX:= -1; + dX:= -dX + end + else + sX:= dX; + + if (dY > 0) then + sY:= 1 + else + if (dY < 0) then + begin + sY:= -1; + dY:= -dY + end + else + sY:= dY; + + if (dX > dY) then + d:= dX + else + d:= dY; + + x:= X1; + y:= Y1; + + for i:= 0 to d do + begin + inc(eX, dX); + inc(eY, dY); + + f:= eX > d; + if f then + begin + dec(eX, d); + inc(x, sX); + DrawDots(x, y, xx, yy, color) + end; + if (eY > d) then + begin + dec(eY, d); + inc(y, sY); + f:= true; + DrawDots(x, y, xx, yy, color) + end; + + if not f then + DrawDots(x, y, xx, yy, color) + end +end; + +procedure DrawThickLine(X1, Y1, X2, Y2, radius: LongInt; color: Longword); +var dx, dy, d: LongInt; +begin + dx:= 0; + dy:= Radius; + d:= 3 - 2 * Radius; + while (dx < dy) do + begin + DrawLines(x1, y1, x2, y2, dx, dy, color); + if (d < 0) then + d:= d + 4 * dx + 6 + else + begin + d:= d + 4 * (dx - dy) + 10; + dec(dy) + end; + inc(dx) + end; + if (dx = dy) then + DrawLines(x1, y1, x2, y2, dx, dy, color); +end; + end. diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uLandPainted.pas --- a/hedgewars/uLandPainted.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uLandPainted.pas Sat Jun 02 14:27:09 2012 +0200 @@ -43,78 +43,6 @@ var pointsListHead, pointsListLast: PPointEntry; -procedure DrawLineOnLand(X1, Y1, X2, Y2, radius: LongInt; color: Longword); -var eX, eY, dX, dY: LongInt; - i, sX, sY, x, y, d: LongInt; - b: boolean; - len: LongWord; -begin - len:= 0; - if (X1 = X2) and (Y1 = Y2) then - begin - exit - end; - eX:= 0; - eY:= 0; - dX:= X2 - X1; - dY:= Y2 - Y1; - - if (dX > 0) then - sX:= 1 - else - if (dX < 0) then - begin - sX:= -1; - dX:= -dX - end - else - sX:= dX; - - if (dY > 0) then - sY:= 1 - else - if (dY < 0) then - begin - sY:= -1; - dY:= -dY - end - else - sY:= dY; - - if (dX > dY) then - d:= dX - else - d:= dY; - - x:= X1; - y:= Y1; - - for i:= 0 to d do - begin - inc(eX, dX); - inc(eY, dY); - b:= false; - if (eX > d) then - begin - dec(eX, d); - inc(x, sX); - b:= true - end; - if (eY > d) then - begin - dec(eY, d); - inc(y, sY); - b:= true - end; - if b then - begin - inc(len); - if (len mod 4) = 0 then - FillRoundInLand(X, Y, radius, color) - end - end -end; - procedure chDraw(var s: shortstring); var rec: PointRec; prec: ^PointRec; @@ -173,7 +101,8 @@ else begin AddFileLog('[DRAW] Line to: ('+inttostr(pe^.point.X)+','+inttostr(pe^.point.Y)+'), radius = '+inttostr(radius)); - DrawLineOnLand(prevPoint.X, prevPoint.Y, pe^.point.X, pe^.point.Y, radius, color); + DrawThickLine(prevPoint.X, prevPoint.Y, pe^.point.X, pe^.point.Y, radius, color); + FillRoundInLand(pe^.point.X, pe^.point.Y, radius, color) end; prevPoint:= pe^.point; diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uLandTexture.pas --- a/hedgewars/uLandTexture.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uLandTexture.pas Sat Jun 02 14:27:09 2012 +0200 @@ -155,6 +155,6 @@ if LandBackSurface <> nil then SDL_FreeSurface(LandBackSurface); LandBackSurface:= nil; - LandTextures:= nil; + SetLength(LandTextures, 0, 0); end; end. diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uScript.pas --- a/hedgewars/uScript.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uScript.pas Sat Jun 02 14:27:09 2012 +0200 @@ -1162,6 +1162,25 @@ lc_getstate:= 1 end; +function lc_gettag(L : Plua_State) : LongInt; Cdecl; +var gear : PGear; +begin + if lua_gettop(L) <> 1 then + begin + LuaError('Lua: Wrong number of parameters passed to GetX!'); + lua_pushnil(L); // return value on stack (nil) + end + else + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if gear <> nil then + lua_pushinteger(L, gear^.Tag) + else + lua_pushnil(L); + end; + lc_gettag:= 1 +end; + function lc_settag(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin @@ -2207,6 +2226,7 @@ lua_register(luaState, _P'GetFollowGear', @lc_getfollowgear); lua_register(luaState, _P'SetState', @lc_setstate); lua_register(luaState, _P'GetState', @lc_getstate); +lua_register(luaState, _P'GetTag', @lc_gettag); lua_register(luaState, _P'SetTag', @lc_settag); lua_register(luaState, _P'SetTimer', @lc_settimer); lua_register(luaState, _P'GetTimer', @lc_gettimer); diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uSound.pas --- a/hedgewars/uSound.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uSound.pas Sat Jun 02 14:27:09 2012 +0200 @@ -263,7 +263,7 @@ if not FileExists(s) then s:= Pathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName; WriteToConsole(msgLoading + s + ' '); - voicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1); + voicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), _P'rb'), 1); if voicepack^.chunks[snd] = nil then WriteLnToConsole(msgFailed) else @@ -279,7 +279,7 @@ if not FileExists(s) then s:= Pathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName; WriteToConsole(msgLoading + s + ' '); - defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1); + defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), _P'rb'), 1); SDLTry(defVoicepack^.chunks[snd] <> nil, true); WriteLnToConsole(msgOK); end; @@ -363,7 +363,7 @@ if not FileExists(s) then s:= Pathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName; WriteToConsole(msgLoading + s + ' '); - voicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1); + voicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), _P'rb'), 1); if voicepack^.chunks[snd] = nil then WriteLnToConsole(msgFailed) else @@ -379,7 +379,7 @@ if not FileExists(s) then s:= Pathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName; WriteToConsole(msgLoading + s + ' '); - defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1); + defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), _P'rb'), 1); SDLTry(defVoicepack^.chunks[snd] <> nil, true); WriteLnToConsole(msgOK); end; diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uStats.pas --- a/hedgewars/uStats.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uStats.pas Sat Jun 02 14:27:09 2012 +0200 @@ -185,10 +185,10 @@ begin if time > 4000 then begin - writeln('FLIGHT'); - writeln(Gear^.Hedgehog^.Team^.TeamName); - writeln(time); - writeln; + writeln(stdout, 'FLIGHT'); + writeln(stdout, Gear^.Hedgehog^.Team^.TeamName); + writeln(stdout, inttostr(time)); + writeln(stdout, ''); end end; @@ -293,14 +293,14 @@ // now to console if winnersClan <> nil then begin - writeln('WINNERS'); + writeln(stdout, 'WINNERS'); for t:= 0 to winnersClan^.TeamsNumber - 1 do - writeln(winnersClan^.Teams[t]^.TeamName); + writeln(stdout, winnersClan^.Teams[t]^.TeamName); end else - writeln('DRAW'); + writeln(stdout, 'DRAW'); -writeln; +writeln(stdout, ''); end; procedure initModule; diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uStore.pas --- a/hedgewars/uStore.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uStore.pas Sat Jun 02 14:27:09 2012 +0200 @@ -1010,7 +1010,7 @@ {$ENDIF} begin // set window title - {$IFNDEF SDL13}SDL_WM_SetCaption('Hedgewars', nil);{$ENDIF} + {$IFNDEF SDL13}SDL_WM_SetCaption(_P'Hedgewars', nil);{$ENDIF} WriteToConsole('Init SDL_image... '); SDLTry(IMG_Init(IMG_INIT_PNG) <> 0, true); WriteLnToConsole(msgOK); diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uTeams.pas --- a/hedgewars/uTeams.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uTeams.pas Sat Jun 02 14:27:09 2012 +0200 @@ -482,6 +482,7 @@ procedure chAddHH(var id: shortstring); var s: shortstring; Gear: PGear; + c: LongInt; begin s:= ''; if (not isDeveloperMode) or (CurrentTeam = nil) then @@ -490,10 +491,10 @@ begin SplitBySpace(id, s); CurrentHedgehog:= @Hedgehogs[HedgehogsNumber]; - val(id, CurrentHedgehog^.BotLevel); + val(id, CurrentHedgehog^.BotLevel, c); Gear:= AddGear(0, 0, gtHedgehog, 0, _0, _0, 0); SplitBySpace(s, id); - val(s, Gear^.Health); + val(s, Gear^.Health, c); TryDo(Gear^.Health > 0, 'Invalid hedgehog health', true); Gear^.Hedgehog^.Team:= CurrentTeam; if (GameFlags and gfSharedAmmo) <> 0 then @@ -514,6 +515,7 @@ procedure chAddTeam(var s: shortstring); var Color: Longword; + c: LongInt; ts, cs: shortstring; begin cs:= ''; @@ -522,7 +524,7 @@ begin SplitBySpace(s, cs); SplitBySpace(cs, ts); - val(cs, Color); + val(cs, Color, c); TryDo(Color <> 0, 'Error: black team color', true); // color is always little endian so the mask must be constant also in big endian archs @@ -539,15 +541,15 @@ procedure chSetHHCoords(var x: shortstring); var y: shortstring; - t: Longint; + t, c: Longint; begin y:= ''; if (not isDeveloperMode) or (CurrentHedgehog = nil) or (CurrentHedgehog^.Gear = nil) then exit; SplitBySpace(x, y); -val(x, t); +val(x, t, c); CurrentHedgehog^.Gear^.X:= int2hwFloat(t); -val(y, t); +val(y, t, c); CurrentHedgehog^.Gear^.Y:= int2hwFloat(t) end; diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uTextures.pas --- a/hedgewars/uTextures.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uTextures.pas Sat Jun 02 14:27:09 2012 +0200 @@ -167,7 +167,7 @@ Surface2Tex^.rx:= Surf^.w / tw; Surface2Tex^.ry:= Surf^.h / th; - GetMem(tmpp, tw * th * surf^.format^.BytesPerPixel); + tmpp:= GetMem(tw * th * surf^.format^.BytesPerPixel); fromP4:= Surf^.pixels; toP4:= tmpp; diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uUtils.pas --- a/hedgewars/uUtils.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uUtils.pas Sat Jun 02 14:27:09 2012 +0200 @@ -39,6 +39,7 @@ function Max(a, b: LongInt): LongInt; inline; function IntToStr(n: LongInt): shortstring; +function StrToInt(s: shortstring): LongInt; function FloatToStr(n: hwFloat): shortstring; function DxDy2Angle(const _dY, _dX: hwFloat): GLfloat; @@ -65,6 +66,11 @@ function GetLaunchX(at: TAmmoType; dir: LongInt; angle: LongInt): LongInt; function GetLaunchY(at: TAmmoType; angle: LongInt): LongInt; +{$IFNDEF PAS2C} +procedure Write(var f: textfile; s: shortstring); +procedure WriteLn(var f: textfile; s: shortstring); +{$ENDIF} + procedure initModule(isGame: boolean); procedure freeModule; @@ -158,6 +164,12 @@ str(n, IntToStr) end; +function StrToInt(s: shortstring): LongInt; +var c: LongInt; +begin +val(s, StrToInt, c) +end; + function FloatToStr(n: hwFloat): shortstring; begin FloatToStr:= cstr(n) + '_' + inttostr(Lo(n.QWordValue)) @@ -285,7 +297,7 @@ begin s:= s; {$IFDEF DEBUGFILE} -writeln(f, GameTicks, ': ', s); +writeln(f, inttostr(GameTicks) + ': ' + s); flush(f) {$ENDIF} end; @@ -359,6 +371,18 @@ CheckNoTeamOrHH:= (CurrentTeam = nil) or (CurrentHedgehog^.Gear = nil); end; +{$IFNDEF PAS2C} +procedure Write(var f: textfile; s: shortstring); +begin +system.write(f, s) +end; + +procedure WriteLn(var f: textfile; s: shortstring); +begin +system.writeln(f, s) +end; +{$ENDIF} + procedure initModule(isGame: boolean); {$IFDEF DEBUGFILE} var logfileBase: shortstring; @@ -403,7 +427,7 @@ recordFileName:= ''; {$IFDEF DEBUGFILE} - writeln(f, 'halt at ', GameTicks, ' ticks. TurnTimeLeft = ', TurnTimeLeft); + writeln(f, 'halt at ' + inttostr(GameTicks) + ' ticks. TurnTimeLeft = ' + inttostr(TurnTimeLeft)); flush(f); close(f); {$ENDIF} diff -r fe76d24a25d7 -r 8d1d6adf5f82 hedgewars/uVisualGears.pas --- a/hedgewars/uVisualGears.pas Sat Jun 02 14:26:52 2012 +0200 +++ b/hedgewars/uVisualGears.pas Sat Jun 02 14:27:09 2012 +0200 @@ -184,15 +184,15 @@ FrameTicks:= random(vobFrameTicks); Frame:= random(vobFramesCount); end; - Angle:= random * 360; + Angle:= random(360); dx:= 0.0000038654705 * random(10000); dy:= 0.000003506096 * random(7000); if random(2) = 0 then dx := -dx; if SuddenDeathDmg then - dAngle:= (random(2) * 2 - 1) * (1 + random) * vobSDVelocity / 1000 + dAngle:= (random(2) * 2 - 1) * (vobSDVelocity + random(vobSDVelocity)) / 1000 else - dAngle:= (random(2) * 2 - 1) * (1 + random) * vobVelocity / 1000 + dAngle:= (random(2) * 2 - 1) * (vobVelocity + random(vobVelocity)) / 1000 end; vgtCloud: begin diff -r fe76d24a25d7 -r 8d1d6adf5f82 tools/pas2c.hs --- a/tools/pas2c.hs Sat Jun 02 14:26:52 2012 +0200 +++ b/tools/pas2c.hs Sat Jun 02 14:27:09 2012 +0200 @@ -335,7 +335,7 @@ resolveType (DeriveType (InitFloat _)) = return BTFloat resolveType (DeriveType (InitString _)) = return BTString resolveType (DeriveType (InitBinOp {})) = return BTInt -resolveType (DeriveType (InitPrefixOp {})) = return BTInt +resolveType (DeriveType (InitPrefixOp _ e)) = initExpr2C e >> gets lastType resolveType (DeriveType (BuiltInFunction{})) = return BTInt resolveType (DeriveType (InitReference (Identifier{}))) = return BTBool -- TODO: derive from actual type resolveType (DeriveType _) = return BTUnknown @@ -634,7 +634,7 @@ e <- expr2C expr return $ r <+> text "=" <+> e <> semi _ -> error $ "Assignment to string from " ++ show lt - (BTArray (Range _) _ _, _) -> phrase2C $ + (BTArray _ _ _, _) -> phrase2C $ ProcCall (FunCall [ Reference $ Address ref @@ -719,6 +719,7 @@ ("+", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strconcat" (BTFunction 2 BTString)) ("+", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strappend" (BTFunction 2 BTString)) ("+", BTChar, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strprepend" (BTFunction 2 BTString)) + ("+", BTChar, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_chrconcat" (BTFunction 2 BTString)) ("==", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcomparec" (BTFunction 2 BTBool)) ("==", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcompare" (BTFunction 2 BTBool)) ("!=", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strncompare" (BTFunction 2 BTBool)) @@ -902,9 +903,11 @@ r <- ref2C ref return $ text "&" <> parens r ref2C (TypeCast t'@(Identifier i _) expr) = do - case map toLower i of - "pchar" -> ref2C $ FunCall [expr] (SimpleReference (Identifier "_pchar" $ BTPointerTo BTChar)) - a -> do + lt <- expr2C expr >> gets lastType + case (map toLower i, lt) of + ("pchar", BTString) -> ref2C $ FunCall [expr] (SimpleReference (Identifier "_pchar" $ BTPointerTo BTChar)) + ("shortstring", BTPointerTo _) -> ref2C $ FunCall [expr] (SimpleReference (Identifier "pchar2str" $ BTString)) + (a, _) -> do e <- expr2C expr t <- id2C IOLookup t' return . parens $ parens t <> e