From 62e509e9c90d728c9f65145947276f79112ab48c Mon Sep 17 00:00:00 2001 From: "Christian A. Weber" Date: Tue, 2 Nov 1993 18:53:33 +0000 Subject: Initial revision --- ByteMap.S | 591 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 591 insertions(+) create mode 100644 ByteMap.S (limited to 'ByteMap.S') diff --git a/ByteMap.S b/ByteMap.S new file mode 100644 index 0000000..d2a0c04 --- /dev/null +++ b/ByteMap.S @@ -0,0 +1,591 @@ +** +** Bobi - The Ultimate Amiga Bob Manipulator +** +** ByteMap.S - ByteMaps konvertieren, spiegeln, rotieren, zoomen usw. +** +** COPYRIGHT (C) 1989-1993 BY CHRISTIAN A. WEBER, ZUERICH, SWITZERLAND. +** ALL RIGHTS RESERVED. NO PART OF THIS SOFTWARE MAY BE COPIED, REPRODUCED, +** OR TRANSMITTED IN ANY FORM OR BY ANY MEANS, WITHOUT THE PRIOR WRITTEN +** PERMISSION OF THE AUTHOR. NO WARRANTY. USE AT YOUR OWN RISK. +** + + + IDNT ByteMap + SECTION text,CODE + + INCLUDE "exec/types.i" + INCLUDE "graphics/gfx.i" + + XDEF @BitMapToByteMap,@BobToByteMap,@ByteMapToBitMap + XDEF @AutoResizeByteMap + XDEF @FlipXByteMap,@FlipYByteMap + XDEF @RotateByteMap,@ZoomByteMap + + +***************************************************************************** + + STRUCTURE MyBob,0 + STRUCT mb_Planes,8*4 ; Alle Planes sind aneinander!! + APTR mb_Mask ; Zeiger auf Masken-Plane + WORD mb_BytesPerRow ; Aufgerundetes ((Width+15)/8)&~1 + WORD mb_Width + WORD mb_Height + WORD mb_Depth + WORD mb_Flags ; Siehe BOBF_ Definitionen + WORD mb_PlaneSize ; BytesPerRow*Height + + WORD mb_X0 ; Nullpunkt X-Koordinate + WORD mb_Y0 ; Nullpunkt Y-Koordinate + WORD mb_CollX0 ; X0 des Kollisions-Bereiches + WORD mb_CollY0 ; Y0 des Kollisions-Bereiches + WORD mb_CollX1 ; X1 des Kollisions-Bereiches + WORD mb_CollY1 ; Y1 des Kollisions-Bereiches + + BYTE mb_PlanePick ; Für welche Planes existieren Daten + BYTE mb_PlaneOnOff ; wie bei Image Struktur + STRUCT mb_SourceLabel,64 + + LABEL mb_SIZEOF + + +***************************************************************************** + + STRUCTURE ByteMap,0 + + WORD bym_Width ; Breite der ByteMap in Pixel + WORD bym_Height ; Höhe der ByteMap in Pixel + LONG bym_PlaneSize ; Grösse für Alloc/FreeMem der Plane + APTR bym_Plane ; Zeiger auf die aktuelle Datenplane + + LABEL bym_SIZEOF + + +*************************************************************************** +** ** +** BitMapToByteMap - BitMap in ByteMap umwandeln (1Byte=1Pixel) ** +** ** +*************************************************************************** +** ** +** Parameter : A0.L : Zeiger auf struct BitMap (Source) ** +** A1.L : Zeiger auf struct ByteMap (Destination) ** +** ** +** Resultat : nix ** +** ** +*************************************************************************** + +@BitMapToByteMap: + movem.l d0-d7/a0-a6,-(SP) + movem.l bm_Planes(a0),a2-a6 ; IMMER 5 Planes + bra.b ToByteMap ; ---> + + +*************************************************************************** +** ** +** BobToByteMap - struct MyBob in ByteMap umwandeln (1Byte=1Pixel) ** +** ** +*************************************************************************** +** ** +** Parameter : A0.L : Zeiger auf struct MyBob (Source) ** +** A1.L : Zeiger auf struct ByteMap (Destination) ** +** ** +** Resultat : nix ** +** ** +*************************************************************************** + +@BobToByteMap: movem.l d0-d7/a0-a6,-(SP) + movem.l mb_Planes(a0),a2-a6 ; IMMER 5 Planes + ;; bra.b ToByteMap ; ---> + +ToByteMap: bsr ValidatePlanePointers ; Falls weniger als 5 Planes + move.w bym_Height(a1),-(SP) + move.w bym_Width(a1),-(SP) + movea.l bym_Plane(a1),a1 ; Destination-Plane + movea.w #16,a0 ; 16 Bits pro Word + +1$: move.w (SP),d7 ; Breite in Pixel +2$: move.w (a2)+,d2 + move.w (a3)+,d3 + move.w (a4)+,d4 + move.w (a5)+,d5 + move.w (a6)+,d6 + moveq #15,d1 + cmp.w a0,d7 ; Noch mehr als 16 Bit ? + bge.b 3$ ; ja ---> + move.w d7,d1 + bra.b 4$ ; für dbf +3$: ;; moveq #0,d0 + addx.w d6,d6 ; roxl.w #1,d6 + addx.w d0,d0 + addx.w d5,d5 + addx.w d0,d0 + addx.w d4,d4 + addx.w d0,d0 + addx.w d3,d3 + addx.w d0,d0 + addx.w d2,d2 + addx.w d0,d0 + move.b d0,(a1)+ +4$: dbf d1,3$ + sub.w a0,d7 ; D7 -= 16 + bgt.b 2$ + subq.w #1,2(SP) ; DEC Rows + bgt.b 1$ + addq.l #4,SP ; Lokalen Datenraum freigeben + movem.l (SP)+,d0-d7/a0-a6 + rts + + +*************************************************************************** +** ** +** ByteMapToBitMap - ByteMap in BitMap umwandeln (1Byte=1Pixel) ** +** ** +*************************************************************************** +** ** +** Parameter : A0.L : Zeiger auf struct ByteMap (Source) ** +** A1.L : Zeiger auf struct BitMap (Destination) ** +** ** +** Resultat : nix ** +** ** +*************************************************************************** + +@ByteMapToBitMap: + movem.l d0-d7/a0-a6,-(SP) + move.w bym_Height(a0),-(SP) + move.w bym_Width(a0),-(SP) + movea.l bym_Plane(a0),a0 ; Source-ByteMap-Plane + movem.l bm_Planes(a1),a2-a6 ; IMMER 5 Destination-Planes + bsr ValidatePlanePointers ; Falls weniger als 5 Planes + movea.w #16,a1 ; 16 Bits pro Word + +1$: move.w (SP),d7 ; Breite in Pixel +2$: moveq #15,d1 +3$: move.b (a0)+,d0 ; Color-Wert + roxr.w #1,d0 + roxl.w #1,d2 + roxr.w #1,d0 + roxl.w #1,d3 + roxr.w #1,d0 + roxl.w #1,d4 + roxr.w #1,d0 + roxl.w #1,d5 + roxr.w #1,d0 + roxl.w #1,d6 + dbf d1,3$ + move.w d2,(a2)+ + move.w d3,(a3)+ + move.w d4,(a4)+ + move.w d5,(a5)+ + move.w d6,(a6)+ + + sub.w a1,d7 ; D7 -= 16 + bgt.b 2$ + neg.w d7 ; D7 := #zuvielgenommene Pixel + suba.w d7,a0 ; Correct Source + add.w d7,d7 ; Index in WORD-Tabelle + move.w MaskTab(PC,d7.w),d0 + and.w d0,-2(a2) ; Rest-Pixel löschen + and.w d0,-2(a3) + and.w d0,-2(a4) + and.w d0,-2(a5) + and.w d0,-2(a6) + subq.w #1,2(SP) ; DEC Rows + bgt.b 1$ + + addq.l #4,SP ; Lokalen Datenraum freigeben + movem.l (SP)+,d0-d7/a0-a6 + rts + +MaskTab: dc.w %1111111111111111 + dc.w %1111111111111110 + dc.w %1111111111111100 + dc.w %1111111111111000 + dc.w %1111111111110000 + dc.w %1111111111100000 + dc.w %1111111111000000 + dc.w %1111111110000000 + dc.w %1111111100000000 + dc.w %1111111000000000 + dc.w %1111110000000000 + dc.w %1111100000000000 + dc.w %1111000000000000 + dc.w %1110000000000000 + dc.w %1100000000000000 + dc.w %1000000000000000 + + +*************************************************************************** +** ** +** AutoResizeByteMap - ByteMap auf kleinstmögliche Grösse reduzieren ** +** ** +*************************************************************************** +** ** +** Parameter : A0.L : Zeiger auf struct ByteMap ** +** ** +** Resultat : D0.L : 0 falls ByteMap leer, 1 sonst ** +** ** +*************************************************************************** + +@AutoResizeByteMap: + movem.l d1-d6/a0-a3,-(SP) + moveq #0,d0 ; D0 : X0 + moveq #0,d1 ; D1 : Y0 + move.w bym_Width(a0),d2 ; D2 : Breite in Pixel + move.w bym_Height(a0),d3 ; D3 : Höhe in Pixel + move.w d2,d4 ; D4 : Originalbreite const. + movea.l bym_Plane(a0),a1 ; A1 : Plane + + *** Neues Y0 finden + +FindY0: movea.l a1,a2 ; Plane +1$: move.w d2,d5 ; Breite + bra.b 3$ ; für dbf +2$: tst.b (a2)+ ; Pixel == 0 ? + bne.b 4$ ; nein ---> Y0 gefunden +3$: dbf d5,2$ + addq.w #1,d1 ; INC Y0 + subq.w #1,d3 ; DEC Höhe + bgt.b 1$ ; Noch grösse als 0 ---> Loop + bra ByteMapEmpty +4$: + *** Neues Y1 finden + +FindY1: movea.l a1,a2 ; Plane + move.w d2,d5 ; Breite + mulu.w bym_Height(a0),d5 ; mal Original-Höhe + adda.l d5,a2 ; Plane-Ende +1$: move.w d2,d5 ; Breite + bra.b 3$ ; für dbf +2$: tst.b -(a2) ; Pixel == 0 ? + bne.b 4$ ; nein ---> Y1 gefunden +3$: dbf d5,2$ + subq.w #1,d3 ; DEC Höhe + bgt.b 1$ ; > 0 ---> Loop + bra ByteMapEmpty +4$: + *** Neues X0 finden + +FindX0: movea.l a1,a2 ; Plane + move.w d1,d5 ; Y0 + mulu.w d4,d5 ; * Original-Width + adda.l d5,a2 + move.w d4,d5 ; Original-Breite +1$: movea.l a2,a3 ; Plane + move.w d3,d6 ; Höhe + bra.b 3$ +2$: tst.b (a3) ; Pixel == 0 ? + bne.b 4$ ; nein ---> X0 gefunden + adda.w d5,a3 ; Plane += Width +3$: dbf d6,2$ + addq.l #1,a2 ; INC Plane + addq.w #1,d0 ; INC X0 + subq.w #1,d2 ; DEC Width + bgt.b 1$ ; > 0 ---> Loop + bra ByteMapEmpty +4$: + *** Neues X1 finden + +FindX1: movea.l a1,a2 ; Plane + move.w d1,d5 ; Y0 + addq.w #1,d5 ; Ganz rechts + 1 + mulu.w d4,d5 ; * Original-Width + adda.l d5,a2 + move.w d4,d5 ; Original-Breite +1$: subq.l #1,a2 ; DEC Plane + movea.l a2,a3 ; Plane + move.w d3,d6 ; Höhe + bra.b 3$ +2$: tst.b (a3) ; Pixel == 0 ? + bne.b 4$ ; nein ---> X0 gefunden + adda.w d5,a3 ; Plane += Width +3$: dbf d6,2$ + subq.w #1,d2 ; DEC Width + bgt.b 1$ ; > 0 ---> Loop + bra ByteMapEmpty +4$: + *** Neue Parameter in ByteMap eintragen + + subq.w #1,d2 ; Nur so stimmt's weiss auch nicht wieso + move.w d2,bym_Width(a0) + move.w d3,bym_Height(a0) + + *** ByteMap an neues Format anpassen + +ResizeBM: movea.l a1,a2 ; Destination + adda.w d0,a1 ; A1 += X0 + mulu.w d4,d1 ; Y0 *= Old Width + adda.l d1,a1 ; A1 += Y0 + move.w d4,d0 ; Original-Width + sub.w d2,d0 ; D0 := Width-Modulo + move.w d3,d6 ; Height + bra.b 4$ ; Für dbf +1$: move.w d2,d5 ; Neue Breite + bra.b 3$ ; Für dbf +2$: move.b (a1)+,(a2)+ ; Tada! +3$: dbf d5,2$ + adda.w d0,a1 ; A1 += Width-Modulo +4$: dbf d6,1$ ; DEC Höhe, Loop + + moveq.l #1,d0 ; 'Not empty' + bra.b AutoResizeEnd ; ---> + +ByteMapEmpty: moveq.l #0,d0 ; 'Empty' + +AutoResizeEnd: movem.l (SP)+,d1-d6/a0-a3 + rts + + +*************************************************************************** +** ** +** FlipXByteMap - ByteMap in X-Richtung spiegeln ** +** ** +*************************************************************************** +** ** +** Parameter : A0.L : Zeiger auf struct ByteMap ** +** ** +** Resultat : nix ** +** ** +*************************************************************************** + +@FlipXByteMap: movem.l d0-d3/a0-a2,-(SP) + move.w bym_Width(a0),d0 ; Breite in Pixel + move.w bym_Height(a0),d1 ; Höhe in Pixel + movea.l bym_Plane(a0),a0 ; Plane + bra.b 4$ ; für dbf +1$: move.w d0,d2 + asr.w #1,d2 ; X/2 + movea.l a0,a1 ; links + lea 0(a1,d0.w),a2 ; rechts + bra.b 3$ ; für dbf + +2$: move.b (a1),d3 ; Pixel swappen + move.b -(a2),(a1)+ + move.b d3,(a2) + +3$: dbf d2,2$ + adda.w d0,a0 ; Nächste Linie +4$: dbf d1,1$ + movem.l (SP)+,d0-d3/a0-a2 + rts + + +*************************************************************************** +** ** +** FlipYByteMap - ByteMap in Y-Richtung spiegeln ** +** ** +*************************************************************************** +** ** +** Parameter : A0.L : Zeiger auf struct ByteMap ** +** ** +** Resultat : nix ** +** ** +*************************************************************************** + +@FlipYByteMap: movem.l d0-d3/a0-a1,-(SP) + move.w bym_Width(a0),d0 ; Breite in Pixel + move.w bym_Height(a0),d1 ; Höhe in Pixel + movea.l bym_Plane(a0),a0 ; Plane + + move.w d1,d2 + subq.w #1,d2 + mulu.w d0,d2 + movea.l a0,a1 + adda.l d2,a1 ; A1: Letzte Linie + lsr.w #1,d1 ; D1: Höhe/2 + bra.b 4$ ; für dbf + +1$: move.w d0,d2 ; Breite + bra.b 3$ ; für dbf +2$: move.b (a0),d3 + move.b (a1),(a0)+ + move.b d3,(a1)+ +3$: dbf d2,2$ + suba.w d0,a1 + suba.w d0,a1 +4$: dbf d1,1$ + + movem.l (SP)+,d0-d3/a0-a1 + rts + + +*************************************************************************** +** ** +** RotateByteMap - ByteMap um einen bestimmten Punkt/Winkel rotieren ** +** ** +** ** +*************************************************************************** +** ** +** Parameter : A0.L : Zeiger auf struct ByteMap (Source) ** +** A1.L : Zeiger auf struct ByteMap (Destination) ** +** D0.L : Rotationsmittelpunkt X ** +** D1.L : Rotationsmittelpunkt Y ** +** D2.L : Sinus des Rotationswinkels <<10 ** +** D3.L : Cosinus des Rotationswinkels <<10 ** +** ** +** Resultat : nix ** +** ** +*************************************************************************** + +* x2 = (x1-xm)*cos - (y1-ym)*sin +xm +* y2 = (x1-xm)*sin + (y1-ym)*cos +ym + +@RotateByteMap: movem.l d0-d7/a0-a4,-(SP) + + movem.l 13*4+4(SP),d2-d3 + + move.w bym_Width(a0),d4 ; D4 : Breite in Pixel + move.w bym_Height(a0),d5 ; D5 : Höhe in Pixel + movea.l bym_Plane(a0),a0 ; A0 : Source-Plane + movea.l bym_Plane(a1),a1 ; A1 : Destination-Plane + suba.l a3,a3 ; A3 : Y-Zähler +1$: suba.l a2,a2 ; A2 : X-Zähler + +2$: move.w a2,d6 ; X + sub.w d0,d6 ; -Xm + muls.w d3,d6 ; *cos + move.w a3,d7 ; Y + sub.w d1,d7 ; -Ym + muls.w d2,d7 ; *sin + sub.l d7,d6 + asr.l #5,d6 ; Fixkomma to int + asr.l #5,d6 + add.l d0,d6 ; +Xm + bpl.b 4$ +3$: clr.b (a1)+ + bra.b 5$ +4$: cmp.w d4,d6 + bge.b 3$ + move.l d6,a4 ; X2 + + move.w a2,d6 ; X + sub.w d0,d6 ; -Xm + muls.w d2,d6 ; *sin + move.w a3,d7 ; Y + sub.w d1,d7 ; -Ym + muls.w d3,d7 ; *cos + add.l d7,d6 + asr.l #5,d6 ; Fixkomma to int + asr.l #5,d6 + add.w d1,d6 ; +Ym gibt Y2 + bmi.b 3$ + cmp.w d5,d6 + bge.b 3$ + muls.w d4,d6 ; * Breite + add.l a4,d6 ; + X2 gibt Offset + + move.b 0(a0,d6.l),(a1)+ ; Tada! +5$: + addq.w #1,a2 ; INC X + cmp.w d4,a2 ; == width ? + blt.b 2$ ; nope ---> + + addq.w #1,a3 ; INC Y + cmp.w d5,a3 ; == height ? + blt.b 1$ ; nope ---> + + movem.l (SP)+,d0-d7/a0-a4 + rts + + +*************************************************************************** +** ** +** ZoomByteMap - ByteMap um einen bestimmten Faktor zoomen ** +** ** +** ** +*************************************************************************** +** ** +** Parameter : A0.L : Zeiger auf struct ByteMap (Source) ** +** A1.L : Zeiger auf struct ByteMap (Destination) ** +** D0.L : Zoomfaktor in Prozent ** +** ** +** Resultat : nix ** +** ** +*************************************************************************** + +* x2 = (x1-xm)*f + xm +* y2 = (y1-ym)*f + ym + +@ZoomByteMap: movem.l d0-d7/a0-a2,-(SP) + tst.l d0 + beq .ZoomEnd + move.w bym_Width(a1),d4 ; D4 : Breite in Pixel + move.w bym_Height(a1),d5 ; D5 : Höhe in Pixel + movea.l bym_Plane(a0),a0 ; A0 : Source-Plane + movea.l bym_Plane(a1),a1 ; A1 : Destination-Plane + move.w d4,d6 + lsr.w #1,d6 ; D6 : Mittelpunkt X + move.w d5,d7 + lsr.w #1,d7 ; D7 : Mittelpunkt Y + + moveq #0,d2 ; D2 : Y-Zähler +.YLoop: moveq #0,d3 ; D3 : X-Zähler + +.XLoop: move.w d3,d1 ; X1 + sub.w d6,d1 ; -xm + muls.w #100,d1 + divs.w d0,d1 ; * f + add.w d6,d1 ; +xm + bmi.b .Next ; X < 0 ---> unsichtbar + cmp.w d4,d1 + bge.b .Next ; X > xmax ---> unsichtbar + movea.w d1,a2 ; macht auch ext.l + + move.w d2,d1 ; Y1 + sub.w d7,d1 ; -ym + muls.w #100,d1 + divs.w d0,d1 ; * f + add.w d7,d1 ; +ym + bmi.b .Next ; Y < 0 ---> unsichtbar + cmp.w d5,d1 + bge.b .Next ; Y > xmax ---> unsichtbar + mulu.w d4,d1 ; mal Breite + add.l a2,d1 ; +X + + move.b 0(a0,d1.l),(a1) ; Tada! +.Next: addq.l #1,a1 ; INC destination + + addq.w #1,d3 ; INC X + cmp.w d4,d3 ; X == Width ? + blt.b .XLoop ; noch nicht ---> Loop + + addq.w #1,d2 ; INC Y + cmp.w d5,d2 ; Y == Height ? + blt.b .YLoop ; noch nicht ---> Loop + +.ZoomEnd: movem.l (SP)+,d0-d7/a0-a2 + rts + + +*************************************************************************** +** ** +** ValidatePlanePointers - Letzten gültigen Plane-Pointer in alle ** +** ungültigen Plane-Pointers kopieren ** +** ** +*************************************************************************** +** ** +** Parameter : A2-A6: Zeiger auf Bitplanes oder NULL wenn ungültig ** +** ** +** Resultat : A2-A6: Zeiger auf BitPlanes, nirgends mehr NULL ** +** ** +*************************************************************************** + +ValidatePlanePointers: + move.l a3,d0 ; Plane 1 gültig ? + bne.b 1$ ; ja ---> + movea.l a2,a3 ; Sonst Plane 0 übernehmen +1$: + move.l a4,d0 ; Plane 2 gültig ? + bne.b 2$ ; ja ---> + movea.l a3,a4 ; Sonst Plane 0 übernehmen +2$: + move.l a5,d0 ; Plane 3 gültig ? + bne.b 3$ ; ja ---> + movea.l a4,a5 ; Sonst Plane 0 übernehmen +3$: + move.l a6,d0 ; Plane 4 gültig ? + bne.b 4$ ; ja ---> + movea.l a5,a6 ; Sonst Plane 0 übernehmen +4$: + rts + + + END -- cgit v1.2.3