313 Gear^.X:= Gear^.X - int2hwFloat(ShiftX); |
313 Gear^.X:= Gear^.X - int2hwFloat(ShiftX); |
314 Gear^.Y:= Gear^.Y - int2hwFloat(ShiftY) |
314 Gear^.Y:= Gear^.Y - int2hwFloat(ShiftY) |
315 end; |
315 end; |
316 |
316 |
317 |
317 |
318 function calcSlopeNormal(Gear: PGear; collisionX, collisionY: LongInt; var deltaX, deltaY: LongInt; TestWord: LongWord): boolean; |
318 function calcSlopeTangent(Gear: PGear; collisionX, collisionY: LongInt; var deltaX, deltaY: LongInt; TestWord: LongWord): boolean; |
319 var sx, sy, ldx, ldy, rdx, rdy: LongInt; |
319 var ldx, ldy, rdx, rdy: LongInt; |
320 i, j, mx, my : ShortInt; |
320 i, j, mx, my, li, ri, jfr, jto, tmpo : ShortInt; |
321 tmpx, tmpy: LongWord; |
321 tmpx, tmpy: LongWord; |
322 dx, dy, rx, ry: hwFloat; |
322 dx, dy: hwFloat; |
323 leftsteps: Array[0..4,0..1] of ShortInt; |
323 offset: Array[0..7,0..1] of ShortInt; |
324 rightsteps: Array[0..4,0..1] of ShortInt; |
|
325 |
324 |
326 begin |
325 begin |
327 dx:= Gear^.dX; |
326 dx:= Gear^.dX; |
328 dy:= Gear^.dY; |
327 dy:= Gear^.dY; |
|
328 |
|
329 // we start searching from the direction the gear center is at |
|
330 mx:= hwRound(Gear^.X-dx) - hwRound(Gear^.X); |
|
331 my:= hwRound(Gear^.Y-dy) - hwRound(Gear^.Y); |
|
332 |
|
333 li:= -1; |
|
334 ri:= -1; |
329 |
335 |
330 if Gear^.AdvBounce > 0 then |
336 // go around collision pixel, checking for first/last collisions |
|
337 // this will determinate what angles will be tried to crawl along |
|
338 for i:= 0 to 7 do |
331 begin |
339 begin |
332 rx:= _0_5 + Int2hwFloat(collisionX) - Gear^.X; |
340 offset[i,0]:= mx; |
333 ry:= _0_5 + Int2hwFloat(collisionY) - Gear^.Y; |
341 offset[i,1]:= my; |
334 end |
342 |
335 else |
343 tmpx:= collisionX + mx; |
336 begin |
344 tmpy:= collisionY + my; |
337 rx:= dx; |
345 |
338 ry:= dy; |
346 if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) then |
339 end; |
347 if (Land[tmpy,tmpx] > TestWord) then |
340 |
348 begin |
341 sx:= hwSign(rx); |
349 // remember the index belonging to the first and last collision (if in 1st half) |
342 sy:= hwSign(ry); |
350 if (i <> 0) then |
343 |
351 begin |
344 if rx.QWordValue > ry.QWordValue then |
352 if (ri = -1) then |
345 begin |
353 ri:= i |
346 if (ry/rx).QWordValue < _0_5.QWordValue then sy:= 0; |
354 else |
347 end |
355 li:= i; |
348 else |
356 end; |
349 begin |
357 end; |
350 if (rx/ry).QWordValue < _0_5.QWordValue then sx:= 0; |
358 |
351 end; |
359 if i = 7 then break; |
352 |
360 |
353 mx:= -sx; |
361 // prepare offset for next check (clockwise) |
354 my:= -sy; |
|
355 |
|
356 for i:= 0 to 4 do |
|
357 begin |
|
358 if (mx = -1) and (my <> 1) then my:= my + 1 |
|
359 else if (my = 1) and (mx <> 1) then mx:= mx + 1 |
|
360 else if (mx = 1) and (my <> -1) then my:= my - 1 |
|
361 else mx:= mx - 1; |
|
362 |
|
363 leftsteps[i,0]:= mx; |
|
364 leftsteps[i,1]:= my; |
|
365 end; |
|
366 |
|
367 mx:= -sx; |
|
368 my:= -sy; |
|
369 |
|
370 for i:= 0 to 4 do |
|
371 begin |
|
372 if (mx = -1) and (my <> -1) then my:= my - 1 |
362 if (mx = -1) and (my <> -1) then my:= my - 1 |
373 else if (my = -1) and (mx <> 1) then mx:= mx + 1 |
363 else if (my = -1) and (mx <> 1) then mx:= mx + 1 |
374 else if (mx = 1) and (my <> 1) then my:= my + 1 |
364 else if (mx = 1) and (my <> 1) then my:= my + 1 |
375 else mx:= mx - 1; |
365 else mx:= mx - 1; |
376 |
366 |
377 rightsteps[i,0]:= mx; |
|
378 rightsteps[i,1]:= my; |
|
379 end; |
367 end; |
380 |
368 |
381 ldx:= collisionX; |
369 ldx:= collisionX; |
382 ldy:= collisionY; |
370 ldy:= collisionY; |
383 rdx:= collisionX; |
371 rdx:= collisionX; |
384 rdy:= collisionY; |
372 rdy:= collisionY; |
385 |
373 |
386 for i:= 0 to 4 do |
374 // edge-crawl |
|
375 for i:= 0 to 8 do |
387 begin |
376 begin |
388 tmpx:= collisionX + leftsteps[i,0]; |
377 // using mx,my as temporary value buffer here |
389 tmpy:= collisionY + leftsteps[i,1]; |
378 |
390 if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) then |
379 jfr:= 8+li+1; |
391 if (Land[tmpy,tmpx] > TestWord) then |
380 jto:= 8+li-1; |
392 begin |
381 |
393 if i <> 0 then |
382 for j:= jfr downto jto do |
394 for j:= 0 to 2 do |
|
395 begin |
|
396 leftsteps[j,0]:= leftsteps[i+j,0]; |
|
397 leftsteps[j,1]:= leftsteps[i+j,1]; |
|
398 end; |
|
399 ldx:= tmpx; |
|
400 ldy:= tmpy; |
|
401 break; |
|
402 end; |
|
403 end; |
|
404 |
|
405 for i:= 0 to 4 do |
|
406 begin |
|
407 tmpx:= collisionX + rightsteps[i,0]; |
|
408 tmpy:= collisionY + rightsteps[i,1]; |
|
409 if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) then |
|
410 if (Land[tmpy,tmpx] > TestWord) then |
|
411 begin |
|
412 if i <> 0 then |
|
413 for j:= 0 to 2 do |
|
414 begin |
|
415 rightsteps[j,0]:= rightsteps[i+j-1,0]; |
|
416 rightsteps[j,1]:= rightsteps[i+j-1,1]; |
|
417 end; |
|
418 rdx:= tmpx; |
|
419 rdy:= tmpy; |
|
420 break; |
|
421 end; |
|
422 end; |
|
423 |
|
424 // TODO: avoid redundant checks |
|
425 for i:= 0 to 4 do |
|
426 begin |
|
427 for j:= 0 to 2 do |
|
428 begin |
383 begin |
429 tmpx:= ldx + leftsteps[j,0]; |
384 tmpo:= j mod 8; |
430 tmpy:= ldy + leftsteps[j,1]; |
385 tmpx:= ldx + offset[tmpo,0]; |
431 if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) then |
386 tmpy:= ldy + offset[tmpo,1]; |
432 if (Land[tmpy,tmpx] > TestWord) then |
387 if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) |
|
388 and (Land[tmpy,tmpx] > TestWord) then |
433 begin |
389 begin |
434 ldx:= tmpx; |
390 ldx:= tmpx; |
435 ldy:= tmpy; |
391 ldy:= tmpy; |
436 break; |
392 break; |
437 end; |
393 end; |
438 end; |
394 end; |
439 end; |
395 |
440 |
396 jfr:= 8+ri-1; |
441 for i:= 0 to 4 do |
397 jto:= 8+ri+1; |
442 begin |
398 |
443 for j:= 0 to 2 do |
399 for j:= jfr to jto do |
444 begin |
400 begin |
445 tmpx:= rdx + rightsteps[j,0]; |
401 tmpo:= j mod 8; |
446 tmpy:= rdy + rightsteps[j,1]; |
402 tmpx:= rdx + offset[tmpo,0]; |
447 if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) then |
403 tmpy:= rdy + offset[tmpo,1]; |
448 if (Land[tmpy,tmpx] > TestWord) then |
404 if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) |
|
405 and (Land[tmpy,tmpx] > TestWord) then |
449 begin |
406 begin |
450 rdx:= tmpx; |
407 rdx:= tmpx; |
451 rdy:= tmpy; |
408 rdy:= tmpy; |
452 break; |
409 break; |
453 end; |
410 end; |