31 #include "water_map.h" |
31 #include "water_map.h" |
32 #include "network.h" |
32 #include "network.h" |
33 #include "yapf/yapf.h" |
33 #include "yapf/yapf.h" |
34 |
34 |
35 #define INVALID_COORD (-0x8000) |
35 #define INVALID_COORD (-0x8000) |
36 #define GEN_HASH(x,y) (((x & 0x1F80)>>7) + ((y & 0xFC0))) |
36 #define GEN_HASH(x, y) ((GB((y), 6, 6) << 6) + GB((x), 7, 6)) |
37 |
37 |
38 /* |
38 /* |
39 * These command macros are used to call vehicle type specific commands with non type specific commands |
39 * These command macros are used to call vehicle type specific commands with non type specific commands |
40 * it should be used like: DoCommandP(x, y, p1, p2, flags, CMD_STARTSTOP_VEH(v->type)) |
40 * it should be used like: DoCommandP(x, y, p1, p2, flags, CMD_STARTSTOP_VEH(v->type)) |
41 * that line will start/stop a vehicle nomatter what type it is |
41 * that line will start/stop a vehicle nomatter what type it is |
359 |
359 |
360 static VehicleID _vehicle_position_hash[0x1000]; |
360 static VehicleID _vehicle_position_hash[0x1000]; |
361 |
361 |
362 void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc) |
362 void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc) |
363 { |
363 { |
364 int x,y,x2,y2; |
|
365 Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, 0); |
364 Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, 0); |
366 |
365 |
367 x2 = ((pt.x + 104) & 0x1F80) >> 7; |
366 // The hash area to scan |
368 x = ((pt.x - 174) & 0x1F80) >> 7; |
367 const int xl = GB(pt.x - 174, 7, 6); |
369 |
368 const int xu = GB(pt.x + 104, 7, 6); |
370 y2 = ((pt.y + 56) & 0xFC0); |
369 const int yl = GB(pt.y - 294, 6, 6) << 6; |
371 y = ((pt.y - 294) & 0xFC0); |
370 const int yu = GB(pt.y + 56, 6, 6) << 6; |
372 |
371 |
373 for (;;) { |
372 int x; |
374 int xb = x; |
373 int y; |
375 for (;;) { |
374 |
|
375 for (y = yl;; y = (y + (1 << 6)) & (0x3F << 6)) { |
|
376 for (x = xl;; x = (x + 1) & 0x3F) { |
376 VehicleID veh = _vehicle_position_hash[(x + y) & 0xFFFF]; |
377 VehicleID veh = _vehicle_position_hash[(x + y) & 0xFFFF]; |
|
378 |
377 while (veh != INVALID_VEHICLE) { |
379 while (veh != INVALID_VEHICLE) { |
378 Vehicle *v = GetVehicle(veh); |
380 Vehicle *v = GetVehicle(veh); |
379 void *a; |
381 void* a = proc(v, data); |
380 |
382 |
381 a = proc(v, data); |
|
382 if (a != NULL) return a; |
383 if (a != NULL) return a; |
383 veh = v->next_hash; |
384 veh = v->next_hash; |
384 } |
385 } |
385 |
386 |
386 if (x == x2) |
387 if (x == xu) break; |
387 break; |
388 } |
388 |
389 |
389 x = (x + 1) & 0x3F; |
390 if (y == yu) break; |
390 } |
|
391 x = xb; |
|
392 |
|
393 if (y == y2) |
|
394 break; |
|
395 |
|
396 y = (y + 0x40) & ((0x3F) << 6); |
|
397 } |
391 } |
398 return NULL; |
392 return NULL; |
399 } |
393 } |
400 |
394 |
401 |
395 |
435 } |
429 } |
436 } |
430 } |
437 |
431 |
438 void InitializeVehicles(void) |
432 void InitializeVehicles(void) |
439 { |
433 { |
440 int i; |
434 uint i; |
441 |
435 |
442 /* Clean the vehicle pool, and reserve enough blocks |
436 /* Clean the vehicle pool, and reserve enough blocks |
443 * for the special vehicles, plus one for all the other |
437 * for the special vehicles, plus one for all the other |
444 * vehicles (which is increased on-the-fly) */ |
438 * vehicles (which is increased on-the-fly) */ |
445 CleanPool(&_vehicle_pool); |
439 CleanPool(&_vehicle_pool); |
446 AddBlockToPool(&_vehicle_pool); |
440 AddBlockToPool(&_vehicle_pool); |
447 for (i = 0; i < BLOCKS_FOR_SPECIAL_VEHICLES; i++) |
441 for (i = 0; i < BLOCKS_FOR_SPECIAL_VEHICLES; i++) |
448 AddBlockToPool(&_vehicle_pool); |
442 AddBlockToPool(&_vehicle_pool); |
449 |
443 |
450 // clear it... |
444 for (i = 0; i < lengthof(_vehicle_position_hash); i++) { |
451 memset(_vehicle_position_hash, -1, sizeof(_vehicle_position_hash)); |
445 _vehicle_position_hash[i] = INVALID_VEHICLE; |
|
446 } |
452 } |
447 } |
453 |
448 |
454 Vehicle *GetLastVehicleInChain(Vehicle *v) |
449 Vehicle *GetLastVehicleInChain(Vehicle *v) |
455 { |
450 { |
456 while (v->next != NULL) v = v->next; |
451 while (v->next != NULL) v = v->next; |
738 v->sprite_width, v->sprite_height, v->z_height, v->z_pos); |
733 v->sprite_width, v->sprite_height, v->z_height, v->z_pos); |
739 } |
734 } |
740 |
735 |
741 void ViewportAddVehicles(DrawPixelInfo *dpi) |
736 void ViewportAddVehicles(DrawPixelInfo *dpi) |
742 { |
737 { |
743 int x,xb, y, x2, y2; |
738 // The bounding rectangle |
744 VehicleID veh; |
739 const int l = dpi->left; |
745 Vehicle *v; |
740 const int r = dpi->left + dpi->width; |
746 |
741 const int t = dpi->top; |
747 x = ((dpi->left - 70) & 0x1F80) >> 7; |
742 const int b = dpi->top + dpi->height; |
748 x2 = ((dpi->left + dpi->width) & 0x1F80) >> 7; |
743 |
749 |
744 // The hash area to scan |
750 y = ((dpi->top - 70) & 0xFC0); |
745 const int xl = GB(l - 70, 7, 6); |
751 y2 = ((dpi->top + dpi->height) & 0xFC0); |
746 const int xu = GB(r, 7, 6); |
752 |
747 const int yl = GB(t - 70, 6, 6) << 6; |
753 for (;;) { |
748 const int yu = GB(b, 6, 6) << 6; |
754 xb = x; |
749 |
755 for (;;) { |
750 int x; |
756 veh = _vehicle_position_hash[(x + y) & 0xFFFF]; |
751 int y; |
|
752 |
|
753 for (y = yl;; y = (y + (1 << 6)) & (0x3F << 6)) { |
|
754 for (x = xl;; x = (x + 1) & 0x3F) { |
|
755 VehicleID veh = _vehicle_position_hash[(x + y) & 0xFFFF]; |
|
756 |
757 while (veh != INVALID_VEHICLE) { |
757 while (veh != INVALID_VEHICLE) { |
758 v = GetVehicle(veh); |
758 const Vehicle* v = GetVehicle(veh); |
759 |
759 |
760 if (!(v->vehstatus & VS_HIDDEN) && |
760 if (!(v->vehstatus & VS_HIDDEN) && |
761 dpi->left <= v->right_coord && |
761 l <= v->right_coord && |
762 dpi->top <= v->bottom_coord && |
762 t <= v->bottom_coord && |
763 dpi->left + dpi->width >= v->left_coord && |
763 r >= v->left_coord && |
764 dpi->top + dpi->height >= v->top_coord) { |
764 b >= v->top_coord) { |
765 DoDrawVehicle(v); |
765 DoDrawVehicle(v); |
766 } |
766 } |
767 veh = v->next_hash; |
767 veh = v->next_hash; |
768 } |
768 } |
769 |
769 |
770 if (x == x2) break; |
770 if (x == xu) break; |
771 x = (x + 1) & 0x3F; |
771 } |
772 } |
772 |
773 x = xb; |
773 if (y == yu) break; |
774 |
|
775 if (y == y2) break; |
|
776 y = (y + 0x40) & ((0x3F) << 6); |
|
777 } |
774 } |
778 } |
775 } |
779 |
776 |
780 static void ChimneySmokeInit(Vehicle *v) |
777 static void ChimneySmokeInit(Vehicle *v) |
781 { |
778 { |