726 } else { |
721 } else { |
727 GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_NORMAL); |
722 GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_NORMAL); |
728 } |
723 } |
729 } |
724 } |
730 |
725 |
731 struct BlitterParams { |
726 static inline void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode) |
732 int start_x, start_y; |
|
733 const byte *sprite; |
|
734 Pixel *dst; |
|
735 BlitterMode mode; |
|
736 int width, height; |
|
737 int width_org; |
|
738 int pitch; |
|
739 }; |
|
740 |
|
741 static void GfxBlitZoomUncomp(BlitterParams *bp, ZoomLevel zoom) |
|
742 { |
|
743 const byte *src = bp->sprite; |
|
744 Pixel *dst = bp->dst; |
|
745 int height = bp->height; |
|
746 int width = bp->width; |
|
747 int i; |
|
748 |
|
749 assert(height > 0); |
|
750 assert(width > 0); |
|
751 |
|
752 height = UnScaleByZoom(height, zoom); |
|
753 |
|
754 switch (bp->mode) { |
|
755 case BM_COLOUR_REMAP: { |
|
756 const byte *ctab = _color_remap_ptr; |
|
757 |
|
758 for (; height != 0; height--) { |
|
759 for (i = 0; i != UnScaleByZoom(width, zoom); i++) { |
|
760 byte b = ctab[src[ScaleByZoom(i, zoom)]]; |
|
761 |
|
762 if (b != 0) dst[i] = b; |
|
763 } |
|
764 src += ScaleByZoom(bp->width_org, zoom); |
|
765 dst += bp->pitch; |
|
766 } |
|
767 break; |
|
768 } |
|
769 |
|
770 case BM_TRANSPARENT: { |
|
771 const byte *ctab = _color_remap_ptr; |
|
772 |
|
773 for (; height != 0; height--) { |
|
774 for (i = 0; i != UnScaleByZoom(width, zoom); i++) |
|
775 if (src[ScaleByZoom(i, zoom)] != 0) dst[i] = ctab[dst[i]]; |
|
776 src += ScaleByZoom(bp->width_org, zoom); |
|
777 dst += bp->pitch; |
|
778 } |
|
779 break; |
|
780 } |
|
781 |
|
782 default: |
|
783 for (; height != 0; height--) { |
|
784 for (i = 0; i != UnScaleByZoom(width, zoom); i++) |
|
785 if (src[ScaleByZoom(i, zoom)] != 0) dst[i] = src[ScaleByZoom(i, zoom)]; |
|
786 src += ScaleByZoom(bp->width_org, zoom); |
|
787 dst += bp->pitch; |
|
788 } |
|
789 break; |
|
790 } |
|
791 } |
|
792 |
|
793 static void GfxBlitTileZoom(BlitterParams *bp, ZoomLevel zoom) |
|
794 { |
|
795 const byte *src_o = bp->sprite; |
|
796 const byte *src; |
|
797 int num, skip; |
|
798 byte done; |
|
799 Pixel *dst; |
|
800 const byte *ctab; |
|
801 |
|
802 src_o += ReadLE16Aligned(src_o + bp->start_y * 2); |
|
803 |
|
804 for (;;) { |
|
805 do { |
|
806 done = src_o[0]; |
|
807 num = done & 0x7F; |
|
808 skip = src_o[1]; |
|
809 src = src_o + 2; |
|
810 src_o += num + 2; |
|
811 |
|
812 dst = bp->dst; |
|
813 |
|
814 if (zoom >= ZOOM_LVL_OUT_2X && (skip & 1)) { |
|
815 skip += 1; |
|
816 src += 1; |
|
817 num -= 1; |
|
818 if (num <= 0) continue; |
|
819 } |
|
820 |
|
821 if (zoom >= ZOOM_LVL_OUT_4X && (skip & 2)) { |
|
822 skip += 2; |
|
823 src += 2; |
|
824 num -= 2; |
|
825 if (num <= 0) continue; |
|
826 } |
|
827 |
|
828 if (zoom >= ZOOM_LVL_OUT_8X && (skip & 4)) { |
|
829 skip += 4; |
|
830 src += 4; |
|
831 num -= 4; |
|
832 if (num <= 0) continue; |
|
833 } |
|
834 |
|
835 if (zoom >= ZOOM_LVL_OUT_16X && (skip & 8)) { |
|
836 skip += 8; |
|
837 src += 8; |
|
838 num -= 8; |
|
839 if (num <= 0) continue; |
|
840 } |
|
841 |
|
842 if ( (skip -= bp->start_x) > 0) { |
|
843 dst += UnScaleByZoom(skip, zoom); |
|
844 } else { |
|
845 src -= skip; |
|
846 num += skip; |
|
847 if (num <= 0) continue; |
|
848 skip = 0; |
|
849 } |
|
850 |
|
851 skip = skip + num - bp->width; |
|
852 if (skip > 0) { |
|
853 num -= skip; |
|
854 if (num <= 0) continue; |
|
855 } |
|
856 |
|
857 num = UnScaleByZoom(num + ScaleByZoom(1, zoom) - 1, zoom); |
|
858 |
|
859 switch (bp->mode) { |
|
860 case BM_COLOUR_REMAP: |
|
861 ctab = _color_remap_ptr; |
|
862 for (; num != 0; num--) { |
|
863 *dst = ctab[*src]; |
|
864 dst++; |
|
865 src += ScaleByZoom(1, zoom); |
|
866 } |
|
867 break; |
|
868 |
|
869 case BM_TRANSPARENT: |
|
870 ctab = _color_remap_ptr; |
|
871 for (; num != 0; num--) { |
|
872 *dst = ctab[*dst]; |
|
873 dst++; |
|
874 } |
|
875 break; |
|
876 |
|
877 default: |
|
878 for (; num != 0; num--) { |
|
879 *dst = *src; |
|
880 dst++; |
|
881 src += ScaleByZoom(1, zoom); |
|
882 } |
|
883 break; |
|
884 } |
|
885 |
|
886 |
|
887 } while (!(done & 0x80)); |
|
888 |
|
889 bp->dst += bp->pitch; |
|
890 if (--bp->height == 0) return; |
|
891 |
|
892 for (int i = 0; i < ScaleByZoom(1, zoom) - 1; i++) { |
|
893 do { |
|
894 done = src_o[0]; |
|
895 src_o += (done & 0x7F) + 2; |
|
896 } while (!(done & 0x80)); |
|
897 if (--bp->height == 0) return; |
|
898 } |
|
899 } |
|
900 } |
|
901 |
|
902 static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode) |
|
903 { |
727 { |
904 const DrawPixelInfo *dpi = _cur_dpi; |
728 const DrawPixelInfo *dpi = _cur_dpi; |
905 int start_x, start_y; |
729 Blitter::BlitterParams bp; |
906 BlitterParams bp; |
730 |
907 int zoom_mask = ~(ScaleByZoom(1, dpi->zoom) - 1); |
731 /* Move to the correct offset */ |
908 |
|
909 /* decode sprite header */ |
|
910 x += sprite->x_offs; |
732 x += sprite->x_offs; |
911 y += sprite->y_offs; |
733 y += sprite->y_offs; |
912 bp.width_org = bp.width = sprite->width; |
734 |
913 bp.height = sprite->height; |
735 /* Copy the main data directly from the sprite */ |
914 bp.sprite = sprite->data; |
736 bp.sprite = sprite->data; |
|
737 bp.sprite_width = sprite->width; |
|
738 bp.sprite_height = sprite->height; |
|
739 bp.width = UnScaleByZoom(sprite->width, dpi->zoom); |
|
740 bp.height = UnScaleByZoom(sprite->height, dpi->zoom); |
|
741 bp.top = 0; |
|
742 bp.left = 0; |
|
743 bp.skip_left = 0; |
|
744 bp.skip_top = 0; |
915 bp.dst = dpi->dst_ptr; |
745 bp.dst = dpi->dst_ptr; |
916 bp.mode = mode; |
|
917 bp.pitch = dpi->pitch; |
746 bp.pitch = dpi->pitch; |
918 |
747 bp.remap = _color_remap_ptr; |
919 assert(bp.height > 0); |
748 |
920 assert(bp.width > 0); |
749 assert(sprite->width > 0); |
921 |
750 assert(sprite->height > 0); |
922 if (sprite->info & 8) { |
751 |
923 /* tile blit */ |
752 if (bp.width <= 0) return; |
924 start_y = 0; |
753 if (bp.height <= 0) return; |
925 |
754 |
926 if (dpi->zoom > ZOOM_LVL_NORMAL) { |
755 y -= dpi->top; |
927 start_y += bp.height & ~zoom_mask; |
756 /* Check for top overflow */ |
928 bp.height &= zoom_mask; |
757 if (y < 0) { |
929 if (bp.height == 0) return; |
758 bp.height -= -UnScaleByZoom(y, dpi->zoom); |
930 y &= zoom_mask; |
759 if (bp.height <= 0) return; |
931 } |
760 bp.skip_top += -UnScaleByZoom(y, dpi->zoom); |
932 |
761 y = 0; |
933 if ( (y -= dpi->top) < 0) { |
|
934 bp.height += y; |
|
935 if (bp.height <= 0) return; |
|
936 start_y -= y; |
|
937 y = 0; |
|
938 } else { |
|
939 bp.dst += bp.pitch * UnScaleByZoom(y, dpi->zoom); |
|
940 } |
|
941 bp.start_y = start_y; |
|
942 |
|
943 if ( (y = y + bp.height - dpi->height) > 0) { |
|
944 bp.height -= y; |
|
945 if (bp.height <= 0) return; |
|
946 } |
|
947 |
|
948 start_x = 0; |
|
949 x &= zoom_mask; |
|
950 if ( (x -= dpi->left) < 0) { |
|
951 bp.width += x; |
|
952 if (bp.width <= 0) return; |
|
953 start_x -= x; |
|
954 x = 0; |
|
955 } |
|
956 bp.start_x = start_x; |
|
957 bp.dst += UnScaleByZoom(x, dpi->zoom); |
|
958 |
|
959 if ( (x = x + bp.width - dpi->width) > 0) { |
|
960 bp.width -= x; |
|
961 if (bp.width <= 0) return; |
|
962 } |
|
963 |
|
964 GfxBlitTileZoom(&bp, dpi->zoom); |
|
965 } else { |
762 } else { |
966 bp.sprite += bp.width * (bp.height & ~zoom_mask); |
763 bp.top = UnScaleByZoom(y, dpi->zoom); |
967 bp.height &= zoom_mask; |
764 } |
968 if (bp.height == 0) return; |
765 |
969 |
766 /* Check for bottom overflow */ |
970 y &= zoom_mask; |
767 y += ScaleByZoom(bp.height, dpi->zoom) - dpi->height; |
971 |
768 if (y > 0) { |
972 if ( (y -= dpi->top) < 0) { |
769 bp.height -= UnScaleByZoom(y, dpi->zoom); |
973 bp.height += y; |
770 if (bp.height <= 0) return; |
974 if (bp.height <= 0) return; |
771 } |
975 bp.sprite -= bp.width * y; |
772 |
976 y = 0; |
773 x -= dpi->left; |
977 } else { |
774 /* Check for left overflow */ |
978 bp.dst += bp.pitch * UnScaleByZoom(y, dpi->zoom); |
775 if (x < 0) { |
979 } |
776 bp.width -= -UnScaleByZoom(x, dpi->zoom); |
980 |
777 if (bp.width <= 0) return; |
981 if (bp.height > dpi->height - y) { |
778 bp.skip_left += -UnScaleByZoom(x, dpi->zoom); |
982 bp.height = dpi->height - y; |
779 x = 0; |
983 if (bp.height <= 0) return; |
780 } else { |
984 } |
781 bp.left = UnScaleByZoom(x, dpi->zoom); |
985 |
782 } |
986 x &= zoom_mask; |
783 |
987 |
784 /* Check for right overflow */ |
988 if ( (x -= dpi->left) < 0) { |
785 x += ScaleByZoom(bp.width, dpi->zoom) - dpi->width; |
989 bp.width += x; |
786 if (x > 0) { |
990 if (bp.width <= 0) return; |
787 bp.width -= UnScaleByZoom(x, dpi->zoom); |
991 bp.sprite -= x; |
788 if (bp.width <= 0) return; |
992 x = 0; |
789 } |
993 } |
790 |
994 bp.dst += UnScaleByZoom(x, dpi->zoom); |
791 BlitterFactoryBase::GetCurrentBlitter()->Draw(&bp, mode, dpi->zoom); |
995 |
|
996 if (bp.width > dpi->width - x) { |
|
997 bp.width = dpi->width - x; |
|
998 if (bp.width <= 0) return; |
|
999 } |
|
1000 |
|
1001 GfxBlitZoomUncomp(&bp, dpi->zoom); |
|
1002 } |
|
1003 } |
792 } |
1004 |
793 |
1005 void DoPaletteAnimations(); |
794 void DoPaletteAnimations(); |
1006 |
795 |
1007 void GfxInitPalettes() |
796 void GfxInitPalettes() |