Changeset 447 for trunk/CmdList.pas
- Timestamp:
- May 19, 2022, 10:39:34 PM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/CmdList.pas
r438 r447 10 10 MaxDataSize = 1024; 11 11 CommandDataElementSize = 4; 12 CommandDataElementCountMask = $ f;12 CommandDataElementCountMask = $F; 13 13 CommandDataMaxSize = CommandDataElementSize * CommandDataElementCountMask; 14 14 … … 27 27 constructor Create; 28 28 destructor Destroy; override; 29 procedure Get(var Command, Player, Subject: integer; var Data: pointer);30 procedure GetDataChanges(Data: pointer; DataSize: integer);31 procedure Put(Command, Player, Subject: integer; Data: pointer);32 procedure PutDataChanges(Command, Player: integer;33 OldData, NewData: pointer; DataSize: integer);34 procedure LoadFromFile(const f: TFileStream);35 procedure SaveToFile(const f: TFileStream);36 procedure AppendToFile(const f: TFileStream; const OldState: TCmdListState);29 procedure Get(var Command, Player, Subject: Integer; var Data: Pointer); 30 procedure GetDataChanges(Data: Pointer; DataSize: Integer); 31 procedure Put(Command, Player, Subject: Integer; Data: Pointer); 32 procedure PutDataChanges(Command, Player: Integer; 33 OldData, NewData: Pointer; DataSize: Integer); 34 procedure LoadFromFile(const F: TFileStream); 35 procedure SaveToFile(const F: TFileStream); 36 procedure AppendToFile(const F: TFileStream; const OldState: TCmdListState); 37 37 procedure Cut; 38 function Progress: integer;38 function Progress: Integer; 39 39 private 40 LogAlloc: integer; { allocated size of LogData in bytes }40 LogAlloc: Integer; { allocated size of LogData in bytes } 41 41 LogData: ^TLogData; 42 42 FState: TCmdListState; 43 procedure PutData(Data: pointer; Length: integer);43 procedure PutData(Data: Pointer; Length: Integer); 44 44 procedure CompleteMoveCode; 45 45 public … … 92 92 end; 93 93 94 procedure TCmdList.Get(var Command, Player, Subject: integer; var Data: pointer);94 procedure TCmdList.Get(var Command, Player, Subject: Integer; var Data: Pointer); 95 95 var 96 96 DirCode: Cardinal; … … 127 127 else 128 128 begin 129 code := Cardinal((@LogData[FState.LoadPos])^);130 if code and 3 = 0 then129 Code := Cardinal((@LogData[FState.LoadPos])^); 130 if Code and 3 = 0 then 131 131 begin // non-clientex command 132 Command := code shr 2 and $3FFF + sExecute;133 Player := code shr 16 and $F;134 Subject := code shr 20 and $FFF;135 inc(FState.LoadPos, 4);136 end 137 else if code and 7 = 2 then132 Command := Code shr 2 and $3FFF + sExecute; 133 Player := Code shr 16 and $F; 134 Subject := Code shr 20 and $FFF; 135 Inc(FState.LoadPos, 4); 136 end 137 else if Code and 7 = 2 then 138 138 begin // clientex command 139 Command := code shr 3 and $FFFF;140 Player := code shr 19 and $F;139 Command := Code shr 3 and $FFFF; 140 Player := Code shr 19 and $F; 141 141 Subject := 0; 142 inc(FState.LoadPos, 3);142 Inc(FState.LoadPos, 3); 143 143 end 144 144 else 145 145 begin // move command shortcut 146 if ( code and 1 = 1) and (code and (7 shl 4) <> 6 shl 4) then146 if (Code and 1 = 1) and (Code and (7 shl 4) <> 6 shl 4) then 147 147 begin 148 FState.LoadMoveCode := code and $FF;149 inc(FState.LoadPos);148 FState.LoadMoveCode := Code and $FF; 149 Inc(FState.LoadPos); 150 150 end 151 151 else 152 152 begin 153 FState.LoadMoveCode := code and $FFFFFF;154 inc(FState.LoadPos, 3);153 FState.LoadMoveCode := Code and $FFFFFF; 154 Inc(FState.LoadPos, 3); 155 155 end; 156 156 Get(Command, Player, Subject, Data); … … 163 163 begin 164 164 Data := @LogData[FState.LoadPos]; 165 inc(FState.LoadPos, Command and CommandDataElementCountMask * CommandDataElementSize);166 end; 167 end; 168 end; 169 170 procedure TCmdList.GetDataChanges(Data: pointer; DataSize: integer);165 Inc(FState.LoadPos, Command and CommandDataElementCountMask * CommandDataElementSize); 166 end; 167 end; 168 end; 169 170 procedure TCmdList.GetDataChanges(Data: Pointer; DataSize: Integer); 171 171 var 172 b0, b1: integer;172 b0, b1: Integer; 173 173 Map0, Map1: Cardinal; 174 174 begin 175 175 Map0 := Cardinal((@LogData[FState.LoadPos])^); 176 inc(FState.LoadPos, 4);176 Inc(FState.LoadPos, 4); 177 177 b0 := 0; 178 178 while Map0 > 0 do begin 179 179 if Map0 and 1 <> 0 then begin 180 180 Map1 := Cardinal((@LogData[FState.LoadPos])^); 181 inc(FState.LoadPos, 4);181 Inc(FState.LoadPos, 4); 182 182 for b1 := 0 to 31 do 183 183 if 1 shl b1 and Map1 <> 0 then begin 184 184 if b0 * 32 + b1 < DataSize then 185 185 PData(Data)[b0 * 32 + b1] := Cardinal((@LogData[FState.LoadPos])^); 186 inc(FState.LoadPos, 4);186 Inc(FState.LoadPos, 4); 187 187 end; 188 188 end; 189 inc(b0);189 Inc(b0); 190 190 Map0 := Map0 shr 1; 191 191 end; 192 192 end; 193 193 194 procedure TCmdList.Put(Command, Player, Subject: integer; Data: pointer);194 procedure TCmdList.Put(Command, Player, Subject: Integer; Data: Pointer); 195 195 var 196 DirCode, code: Cardinal;196 DirCode, Code: Cardinal; 197 197 begin 198 198 if Command and $FC00 = sMoveUnit then … … 209 209 end; 210 210 if Subject = FState.LastMovingUnit then 211 code := 1 + DirCode shl 1212 else 213 code := 6 + DirCode shl 3 + Cardinal(Subject) shl 6;211 Code := 1 + DirCode shl 1 212 else 213 Code := 6 + DirCode shl 3 + Cardinal(Subject) shl 6; 214 214 if FState.MoveCode = 0 then 215 FState.MoveCode := code215 FState.MoveCode := Code 216 216 else if FState.MoveCode and 1 = 1 then 217 217 begin // FM + this 218 FState.MoveCode := FState.MoveCode + code shl 4;219 if code and 1 = 1 then218 FState.MoveCode := FState.MoveCode + Code shl 4; 219 if Code and 1 = 1 then 220 220 PutData(@FState.MoveCode, 1) // FM + FM 221 221 else … … 223 223 FState.MoveCode := 0; 224 224 end 225 else if code and 1 = 1 then225 else if Code and 1 = 1 then 226 226 begin // M + FM 227 FState.MoveCode := FState.MoveCode + code shl 18;227 FState.MoveCode := FState.MoveCode + Code shl 18; 228 228 PutData(@FState.MoveCode, 3); 229 229 FState.MoveCode := 0; … … 232 232 begin 233 233 PutData(@FState.MoveCode, 3); 234 FState.MoveCode := code;234 FState.MoveCode := Code; 235 235 end; 236 236 FState.LastMovingUnit := Subject; … … 241 241 if Command >= cClientEx then 242 242 begin 243 code := 2 + Command shl 3 + Player shl 19;244 PutData(@ code, 3);245 end 246 else 247 begin 248 code := Cardinal(Command - sExecute) shl 2 + Cardinal(Player) shl 16 +243 Code := 2 + Command shl 3 + Player shl 19; 244 PutData(@Code, 3); 245 end 246 else 247 begin 248 Code := Cardinal(Command - sExecute) shl 2 + Cardinal(Player) shl 16 + 249 249 Cardinal(Subject) shl 20; 250 PutData(@ code, 4);250 PutData(@Code, 4); 251 251 end; 252 252 end; … … 255 255 end; 256 256 257 procedure TCmdList.PutDataChanges(Command, Player: integer;258 OldData, NewData: pointer; DataSize: integer);257 procedure TCmdList.PutDataChanges(Command, Player: Integer; 258 OldData, NewData: Pointer; DataSize: Integer); 259 259 var 260 MapPos, LogPos, b0, b1, RowEnd: integer;261 Map0, Map1, code: Cardinal;260 MapPos, LogPos, b0, b1, RowEnd: Integer; 261 Map0, Map1, Code: Cardinal; 262 262 begin 263 263 if DataSize <= 0 then 264 exit;264 Exit; 265 265 if DataSize > MaxDataSize then 266 266 DataSize := MaxDataSize; … … 273 273 if LogPos + 4 * 32 > LogAlloc then 274 274 begin 275 inc(LogAlloc, LogGrow);275 Inc(LogAlloc, LogGrow); 276 276 ReallocMem(LogData, LogAlloc); 277 277 end; … … 287 287 begin 288 288 Cardinal((@LogData[LogPos])^) := PData(NewData)[b1]; 289 inc(LogPos, 4);290 inc(Map1, $80000000);289 Inc(LogPos, 4); 290 Inc(Map1, $80000000); 291 291 end; 292 292 end; … … 296 296 Cardinal((@LogData[MapPos])^) := Map1; 297 297 MapPos := LogPos; 298 inc(LogPos, 4);299 inc(Map0, $80000000);298 Inc(LogPos, 4); 299 Inc(Map0, $80000000); 300 300 end; 301 301 end; 302 302 if Map0 = 0 then 303 exit; // no changes303 Exit; // no changes 304 304 305 305 Map0 := Map0 shr (31 - (DataSize - 1) div 32); 306 306 Cardinal((@LogData[FState.nLog + 4])^) := Map0; 307 code := Cardinal(Command - sExecute) shl 2 + Cardinal(Player) shl 16;308 Cardinal((@LogData[FState.nLog])^) := code;307 Code := Cardinal(Command - sExecute) shl 2 + Cardinal(Player) shl 16; 308 Cardinal((@LogData[FState.nLog])^) := Code; 309 309 FState.nLog := MapPos; 310 310 end; 311 311 312 procedure TCmdList.PutData(Data: pointer; Length: integer);312 procedure TCmdList.PutData(Data: Pointer; Length: Integer); 313 313 begin 314 314 if FState.nLog + Length > LogAlloc then 315 315 begin 316 inc(LogAlloc, LogGrow);316 Inc(LogAlloc, LogGrow); 317 317 ReallocMem(LogData, LogAlloc); 318 318 end; 319 move(Data^, LogData[FState.nLog], Length);320 inc(FState.nLog, Length);319 Move(Data^, LogData[FState.nLog], Length); 320 Inc(FState.nLog, Length); 321 321 end; 322 322 … … 333 333 end; 334 334 335 procedure TCmdList.LoadFromFile(const f: TFileStream);336 begin 337 f.read(FState.nLog, 4);335 procedure TCmdList.LoadFromFile(const F: TFileStream); 336 begin 337 F.read(FState.nLog, 4); 338 338 LogData := nil; 339 339 LogAlloc := ((FState.nLog + 2) div LogGrow + 1) * LogGrow; 340 340 ReallocMem(LogData, LogAlloc); 341 f.read(LogData^, FState.nLog);341 F.read(LogData^, FState.nLog); 342 342 FState.LoadPos := 0; 343 343 end; 344 344 345 procedure TCmdList.SaveToFile(const f: TFileStream);345 procedure TCmdList.SaveToFile(const F: TFileStream); 346 346 begin 347 347 CompleteMoveCode; 348 f.write(FState.nLog, 4);349 f.write(LogData^, FState.nLog);350 end; 351 352 procedure TCmdList.AppendToFile(const f: TFileStream;348 F.write(FState.nLog, 4); 349 F.write(LogData^, FState.nLog); 350 end; 351 352 procedure TCmdList.AppendToFile(const F: TFileStream; 353 353 const OldState: TCmdListState); 354 354 begin 355 355 CompleteMoveCode; 356 f.write(FState.nLog, 4);357 f.Position := f.Position + OldState.nLog;358 f.write(LogData[OldState.nLog], FState.nLog - OldState.nLog);356 F.write(FState.nLog, 4); 357 F.Position := F.Position + OldState.nLog; 358 F.write(LogData[OldState.nLog], FState.nLog - OldState.nLog); 359 359 end; 360 360 … … 364 364 end; 365 365 366 function TCmdList.Progress: integer;366 function TCmdList.Progress: Integer; 367 367 begin 368 368 if (FState.LoadPos = FState.nLog) and (FState.LoadMoveCode = 0) then 369 result := 1000 // loading complete369 Result := 1000 // loading complete 370 370 else if FState.nLog > 1 shl 20 then 371 result := (FState.LoadPos shr 8) * 999 div (FState.nLog shr 8)371 Result := (FState.LoadPos shr 8) * 999 div (FState.nLog shr 8) 372 372 else 373 result := FState.LoadPos * 999 div FState.nLog;373 Result := FState.LoadPos * 999 div FState.nLog; 374 374 end; 375 375 … … 379 379 Byte3 Byte2 Byte1 Byte0 380 380 ssssssss sssspppp cccccccc cccccc00 381 ( c = Command-sExecute, p = Player, s= Subject)381 (C = Command-sExecute, P = Player, S = Subject) 382 382 383 383 ClientEx-Command: 384 384 Byte2 Byte1 Byte0 385 385 0ppppccc cccccccc ccccc010 386 ( c = Command, p= Player)386 (C = Command, P = Player) 387 387 388 388 Single Move: 389 389 Byte2 Byte1 Byte0 390 390 000000ss ssssssss ssaaa110 391 ( a = Direction, s= Subject)391 (A = Direction, S = Subject) 392 392 393 393 Move + Follow Move: 394 394 Byte2 Byte1 Byte0 395 395 00bbb1ss ssssssss ssaaa110 396 ( a = Direction 1, s = Subject 1, b= Direction 2)396 (A = Direction 1, S = Subject 1, B = Direction 2) 397 397 398 398 Follow Move + Move: 399 399 Byte2 Byte1 Byte0 400 400 00ssssss ssssssbb b110aaa1 401 ( a = Direction 1, b = Direction 2, s= Subject 2)401 (A = Direction 1, B = Direction 2, S = Subject 2) 402 402 403 403 Single Follow Move: 404 404 Byte0 405 405 0000aaa1 406 ( a= Direction)406 (A = Direction) 407 407 408 408 Double Follow Move: 409 409 Byte0 410 410 bbb1aaa1 411 ( a = Direction 1, b= Direction 2)411 (A = Direction 1, B = Direction 2) 412 412 } 413 413
Note:
See TracChangeset
for help on using the changeset viewer.