433 byte x, y; |
433 byte x, y; |
434 }; |
434 }; |
435 |
435 |
436 static void DrawTile_Trees(TileInfo *ti) |
436 static void DrawTile_Trees(TileInfo *ti) |
437 { |
437 { |
438 const PalSpriteID *s; |
|
439 const TreePos* d; |
|
440 byte z; |
|
441 |
|
442 switch (GetTreeGround(ti->tile)) { |
438 switch (GetTreeGround(ti->tile)) { |
443 case TREE_GROUND_SHORE: DrawShoreTile(ti->tileh); break; |
439 case TREE_GROUND_SHORE: DrawShoreTile(ti->tileh); break; |
444 case TREE_GROUND_GRASS: DrawClearLandTile(ti, GetTreeDensity(ti->tile)); break; |
440 case TREE_GROUND_GRASS: DrawClearLandTile(ti, GetTreeDensity(ti->tile)); break; |
445 case TREE_GROUND_ROUGH: DrawHillyLandTile(ti); break; |
441 case TREE_GROUND_ROUGH: DrawHillyLandTile(ti); break; |
446 default: DrawGroundSprite(_tree_sprites_1[GetTreeDensity(ti->tile)] + _tileh_to_sprite[ti->tileh], PAL_NONE); break; |
442 default: DrawGroundSprite(_tree_sprites_1[GetTreeDensity(ti->tile)] + _tileh_to_sprite[ti->tileh], PAL_NONE); break; |
447 } |
443 } |
448 |
444 |
449 DrawClearLandFence(ti); |
445 DrawClearLandFence(ti); |
450 |
446 |
451 z = ti->z; |
447 /* Do not draw trees when the invisible trees patch and transparency tree are set */ |
452 if (ti->tileh != SLOPE_FLAT) { |
448 if (IsTransparencySet(TO_TREES) && _patches.invisible_trees) return; |
453 z += 4; |
449 |
454 if (IsSteepSlope(ti->tileh)) z += 4; |
450 uint16 tmp = ti->x; |
455 } |
451 |
456 |
452 tmp = ROR(tmp, 2); |
457 { |
453 tmp -= ti->y; |
458 uint16 tmp = ti->x; |
454 tmp = ROR(tmp, 3); |
459 uint index; |
455 tmp -= ti->x; |
460 |
456 tmp = ROR(tmp, 1); |
461 tmp = ROR(tmp, 2); |
457 tmp += ti->y; |
462 tmp -= ti->y; |
458 |
463 tmp = ROR(tmp, 3); |
459 uint index = GB(tmp, 6, 2) + (GetTreeType(ti->tile) << 2); |
464 tmp -= ti->x; |
460 |
465 tmp = ROR(tmp, 1); |
461 /* different tree styles above one of the grounds */ |
466 tmp += ti->y; |
462 if (GetTreeGround(ti->tile) == TREE_GROUND_SNOW_DESERT && |
467 |
463 GetTreeDensity(ti->tile) >= 2 && |
468 d = _tree_layout_xy[GB(tmp, 4, 2)]; |
464 IsInsideMM(index, TREE_SUB_ARCTIC << 2, TREE_RAINFOREST << 2)) { |
469 |
465 index += 164 - (TREE_SUB_ARCTIC << 2); |
470 index = GB(tmp, 6, 2) + (GetTreeType(ti->tile) << 2); |
466 } |
471 |
467 |
472 /* different tree styles above one of the grounds */ |
468 assert(index < lengthof(_tree_layout_sprite)); |
473 if (GetTreeGround(ti->tile) == TREE_GROUND_SNOW_DESERT && |
469 |
474 GetTreeDensity(ti->tile) >= 2 && |
470 const PalSpriteID *s = _tree_layout_sprite[index]; |
475 IsInsideMM(index, TREE_SUB_ARCTIC << 2, TREE_RAINFOREST << 2)) { |
471 const TreePos *d = _tree_layout_xy[GB(tmp, 4, 2)]; |
476 index += 164 - (TREE_SUB_ARCTIC << 2); |
472 |
477 } |
473 /* combine trees into one sprite object */ |
478 |
|
479 assert(index < lengthof(_tree_layout_sprite)); |
|
480 s = _tree_layout_sprite[index]; |
|
481 } |
|
482 |
|
483 StartSpriteCombine(); |
474 StartSpriteCombine(); |
484 |
475 |
485 /* Do not draw trees when the invisible trees patch and transparency tree are set */ |
476 TreeListEnt te[4]; |
486 if (!(IsTransparencySet(TO_TREES) && _patches.invisible_trees)) { |
477 |
487 TreeListEnt te[4]; |
478 /* put the trees to draw in a list */ |
488 uint i; |
479 uint trees = GetTreeCount(ti->tile) + 1; |
489 |
480 |
490 /* put the trees to draw in a list */ |
481 for (uint i = 0; i < trees; i++) { |
491 i = GetTreeCount(ti->tile) + 1; |
482 SpriteID image = s[0].sprite + (i == trees - 1 ? GetTreeGrowth(ti->tile) : 3); |
492 do { |
483 SpriteID pal = s[0].pal; |
493 SpriteID image = s[0].sprite + (--i == 0 ? GetTreeGrowth(ti->tile) : 3); |
484 |
494 SpriteID pal = s[0].pal; |
485 te[i].image = image; |
495 |
486 te[i].pal = pal; |
496 te[i].image = image; |
487 te[i].x = d->x; |
497 te[i].pal = pal; |
488 te[i].y = d->y; |
498 te[i].x = d->x; |
489 s++; |
499 te[i].y = d->y; |
490 d++; |
500 s++; |
491 } |
501 d++; |
492 |
502 } while (i); |
493 /* draw them in a sorted way */ |
503 |
494 byte z = ti->z + GetSlopeMaxZ(ti->tileh) / 2; |
504 /* draw them in a sorted way */ |
495 |
505 for (;;) { |
496 for (; trees > 0; trees--) { |
506 byte min = 0xFF; |
497 uint min = te[0].x + te[0].y; |
507 TreeListEnt *tep = NULL; |
498 uint mi = 0; |
508 |
499 |
509 i = GetTreeCount(ti->tile) + 1; |
500 for (uint i = 1; i < trees; i++) { |
510 do { |
501 if ((uint)(te[i].x + te[i].y) < min) { |
511 if (te[--i].image != 0 && te[i].x + te[i].y < min) { |
502 min = te[i].x + te[i].y; |
512 min = te[i].x + te[i].y; |
503 mi = i; |
513 tep = &te[i]; |
504 } |
514 } |
505 } |
515 } while (i); |
506 |
516 |
507 AddSortableSpriteToDraw(te[mi].image, te[mi].pal, ti->x + te[mi].x, ti->y + te[mi].y, 16 - te[mi].x, 16 - te[mi].y, 0x30, z, IsTransparencySet(TO_TREES), -te[mi].x, -te[mi].y); |
517 if (tep == NULL) break; |
508 |
518 |
509 /* replace the removed one with the last one */ |
519 AddSortableSpriteToDraw(tep->image, tep->pal, ti->x + tep->x, ti->y + tep->y, 16 - tep->x, 16 - tep->y, 0x30, z, IsTransparencySet(TO_TREES), -tep->x, -tep->y); |
510 te[mi] = te[trees - 1]; |
520 tep->image = 0; |
|
521 } |
|
522 } |
511 } |
523 |
512 |
524 EndSpriteCombine(); |
513 EndSpriteCombine(); |
525 } |
514 } |
526 |
515 |