; ---------------------------------------------------------------------------- ; dA JoRMaS: Major Release ; ; (C) 2004 Vesuri/dA JoRMaS (Vesa Halttunen ) ; ---------------------------------------------------------------------------- ; This source code is provided strictly for the purpose of education. ; ; You are NOT allowed to sell or modify this code or ; use any part of it in your own programs (modified or unmodified) ; without a written permission from the author. ; ---------------------------------------------------------------------------- FINALVERSION equ 1 STARTPATTERN equ 1 PATTERNLENGTH equ 64 BZ_PLANEWIDTH equ 32 BZ_PLANEHEIGHT equ 256 BZ_PLANESIZE equ BZ_PLANEWIDTH*BZ_PLANEHEIGHT BZ_PLANES equ 4 CH_PLANEWIDTH equ 24 CH_PLANEHEIGHT equ 85 CH_PLANESIZE equ CH_PLANEWIDTH*CH_PLANEHEIGHT CH_PLANES equ 4 CH_CHUNKY_WIDTH equ CH_PLANEWIDTH/2*8 CH_CHUNKY_HEIGHT equ CH_PLANEHEIGHT CH_CHUNKY_SIZE equ CH_CHUNKY_WIDTH*CH_CHUNKY_HEIGHT CH_SOURCE_WIDTH equ 128 CH_SOURCE_HEIGHT equ 128 CH_SOURCE_SIZE equ CH_SOURCE_WIDTH*CH_SOURCE_HEIGHT CT_MAX_OFFSET equ 16320+2 CT_ANGLE_RANGE equ 128 CS_PLANEWIDTH equ 44 CS_PLANEHEIGHT equ 208 CS_PLANESIZE equ CS_PLANEWIDTH*CS_PLANEHEIGHT CS_PLANES equ 1 CS_BUILDING_SIZE equ 25 CS_CLIP equ -18 CS_SINUS equ -16 CS_COSINUS equ -14 CS_X equ -12 CS_Z equ -10 CS_OCTANTS equ -8 CS_OLDX equ -4 CS_OLDY equ -2 CS_BLITTER_CLEAR equ 112 CLIP_LEFT_EDGE equ (1<<0) CLIP_RIGHT_EDGE equ (1<<1) CLIP_TOP_EDGE equ (1<<2) CLIP_BOTTOM_EDGE equ (1<<3) DP_PLANEWIDTH equ 32 DP_PLANEHEIGHT equ 256 DP_PLANESIZE equ DP_PLANEWIDTH*DP_PLANEHEIGHT DP_PLANES equ 5 FW_PLANEWIDTH equ 40 FW_PLANEHEIGHT equ 256 FW_PLANESIZE equ FW_PLANEWIDTH*FW_PLANEHEIGHT FW_PLANES equ 2 FW_BLITTER_CLEAR equ 128 FW_STARTING_ROW equ 16 FW_ENDING_ROW equ 240 FW_NUMBER_OF_FONTS equ 95 FW_NUMBER_OF_PARTICLES equ 80 FS_PLANEWIDTH equ 32 FS_PLANEHEIGHT equ 256 FS_PLANESIZE equ FS_PLANEWIDTH*FS_PLANEHEIGHT FS_PLANES equ 4 HO_PLANEWIDTH equ 40 HO_PLANEHEIGHT equ 256 HO_PLANESIZE equ HO_PLANEWIDTH*HO_PLANEHEIGHT HO_PLANES equ 5 HO_HORIZON_PLANES equ 4 HO_GRADIENT_HEIGHT equ 16 HO_MINXX equ -10 HO_MINXY equ -8 HO_MAXXX equ -6 HO_MAXXY equ -4 HO_SUBSTRACT equ -2 HO_TABLE_COORDINATES equ 0 HO_TABLE_HEIGHT equ 4 HO_TABLE_Z equ 6 HO_TABLE_ZOOM equ 8 HO_TABLE_SIZE equ 12 IR_PLANEWIDTH equ 44 IR_PLANEHEIGHT equ 320 IR_PLANESIZE equ IR_PLANEWIDTH*IR_PLANEHEIGHT IR_PLANES equ 6 IR_RADIUS equ 23 IR_MAX equ 125 IR_SOURCE_HEIGHT equ 272 IP_PLANEWIDTH equ 40 IP_PLANEHEIGHT equ 232 IP_PLANESIZE equ IP_PLANEWIDTH*IP_PLANEHEIGHT IP_PLANES equ 2 RO_PLANEWIDTH equ 36 RO_PLANEHEIGHT equ 258 RO_PLANESIZE equ RO_PLANEWIDTH*RO_PLANEHEIGHT RO_PLANES equ 2 RO_SIZE equ 16 RO_RESOLUTION equ 16 RO_NUMPOINTS equ 7 SW_PLANEWIDTH equ 32 SW_PLANEHEIGHT equ 256 SW_PLANESIZE equ SW_PLANEWIDTH*SW_PLANEHEIGHT SW_PLANES equ 1 SW_ANGLE equ 4 SW_WIDTH equ 32 SW_HEIGHT equ 512 SW_BITMAP_HEIGHT equ 1620 SW_NUMBER_OF_FONTS equ 95 SV_PLANEWIDTH equ 32 SV_PLANEHEIGHT equ 160 SV_PLANESIZE equ SV_PLANEWIDTH*SV_PLANEHEIGHT SV_PLANES equ 4 SV_STENCIL_WIDTH equ 32 SV_STENCIL_HEIGHT equ 256 SV_STENCIL_SIZE equ SV_STENCIL_WIDTH*SV_STENCIL_HEIGHT SV_OLDX equ -2 SV_OLDY equ -4 SV_XANGLESIN equ 0 SV_XANGLECOS equ 2 SV_YANGLESIN equ 4 SV_YANGLECOS equ 6 SV_ZANGLESIN equ 8 SV_ZANGLECOS equ 10 SV_XX equ 0 SV_XY equ 2 SV_XZ equ 4 SV_YX equ 6 SV_YY equ 8 SV_YZ equ 10 SV_ZX equ 12 SV_ZY equ 14 SV_ZZ equ 16 SV_XXXY equ 18 SV_YXYY equ 22 SV_ZXZY equ 26 SV_X equ 0 SV_Y equ 2 SV_Z equ 4 SV_X_Y equ 6 SV_NORMAL_SHIFT equ 7 SV_DISTANCE_MAX equ 1505 SV_DISTANCE_MIN equ 295 JL_PLANES equ 3 JL_PLANEWIDTH equ 44 JL_PLANEHEIGHT equ 64 JL_PLANESIZE equ JL_PLANEWIDTH*JL_PLANEHEIGHT VV_PLANEWIDTH equ 44 VV_PLANEHEIGHT equ 256 VV_PLANESIZE equ VV_PLANEWIDTH*VV_PLANEHEIGHT VV_PLANES equ 1 incdir "include:" include "JoRMaS.i" section FastCode,Code nop ; Tooltypes and command line arguments only handled in final version ; ------------------------------------------------------------------ ifne FINALVERSION bsr SystemStartUp endc ; Allocate memory and setup copperlists etc. ; ------------------------------------------ bsr StartUp ; Main loop ; --------- main: tst.b quit bne done ; Check whether a new part should be initialized ; ----------------------------------------------- script: lea parts,a0 add.l part,a0 move.l sc_position,d0 move.l (a0)+,d1 bmi noinit cmp.l d0,d1 bhi noinit clr.l part_vbi lea custom,a6 ; Disable the (possible) blitter interrupt during init ; ---------------------------------------------------- move.w #INTF_BLIT,d0 move.w d0,intena(a6) waitb move.w d0,intreq(a6) move.w d0,intreq(a6) ; Use the "no effects" copperlist ; ------------------------------- move.l #ne_cl,cop1lch(a6) move.w #0,copjmp1(a6) addq.l #8,part clr.b render clr.l part_main ; Initialize the effect ; --------------------- move.l (a0),a0 jsr (a0) bra.s script noinit: tst.b render bne main ; Check whether there is a main function to run and if so run it ; -------------------------------------------------------------- move.l part_main,d0 beq main move.l d0,a0 jsr (a0) bra main ; Restore system to normal state ; ------------------------------ done: bsr ShutDown tst.l loop bne main die: rts ; Level 3 Interrupt ; ----------------- interrupt_level3: move.l d0,-(sp) ; Check whether the interrupt is blitter or vertical blank ; -------------------------------------------------------- move.w intreqr+custom,d0 and.w #INTF_VERTB,d0 bne VBI ; Blitter interrupt ; ----------------- movem.l a0-a1/a6,-(sp) ; Clear interrupt request ; ----------------------- lea custom,a6 move.w #INTF_BLIT,d0 move.w d0,intreq(a6) move.w d0,intreq(a6) ; Next pass ; --------- moveq #0,d0 add.b #1,ch_c2p_pass cmp.b #8,ch_c2p_pass beq.w ch_bp8 cmp.b #7,ch_c2p_pass beq.w ch_bp7 cmp.b #6,ch_c2p_pass beq.w ch_bp6 cmp.b #5,ch_c2p_pass beq.w ch_bp5 cmp.b #4,ch_c2p_pass beq.w ch_bp4 cmp.b #3,ch_c2p_pass beq.w ch_bp3 ch_bp2: ; Pass 2: ; First half of the buffer: upper bits (3 & 2) ; 000044449999dddd22226666bbbbffff ; -------------------------------- lea ch_tempbuffer1,a0 lea ch_tempbuffer2,a1 waitb move.w #4,bltamod(a6) move.w #4,bltbmod(a6) move.w d0,bltdmod(a6) move.l a0,bltapth(a6) addq #4,a0 move.l a0,bltbpth(a6) move.l a1,bltdpth(a6) move.w #%1111000011110000,bltcdat(a6) move.w #SRCA|SRCB|DEST|ANBC|ABC|ABNC|NABNC,bltcon0(a6) move.w #(4<dy = okt7 move.b #8|LINEMODE,cs_octants+2 ;y1x2, dxx2, dx>dy = okt4 ; Create ordered table ; -------------------- lea table_order,a0 lea cs_order,a1 moveq #0,d1 moveq #16-1,d7 .ord1: moveq #0,d3 moveq #16-1,d6 .ord2: move.b (a0)+,d1 move.w d7,d2 addq #1,d2 lsl.w #4,d2 sub.w d1,d2 addx.w d3,d3 dbra d6,.ord2 move.w d3,(a1)+ dbra d7,.ord1 ; Create gradient helper bitplane ; ------------------------------- lea cs_planes,a1 add.l #5*CS_PLANESIZE,a1 move.l #CS_PLANEHEIGHT/16-1,d7 .grad1: lea cs_order,a0 moveq #16-1,d6 .grad2: moveq #CS_PLANEWIDTH/2-1,d5 .grad3: move.w (a0),(a1)+ dbra d5,.grad3 addq #2,a0 dbra d6,.grad2 dbra d7,.grad1 ; Create multiply table ; --------------------- rollo: lea cs_mulu_16,a0 moveq #1,d0 moveq #16-1,d7 .mulu1: moveq #0,d1 moveq #16-1,d6 .mulu2: move.w d1,d2 mulu d0,d2 lsr.w #4,d2 move.b d2,(a0)+ addq #1,d1 dbra d6,.mulu2 addq #1,d0 dbra d7,.mulu1 ; Create copperlist ; ----------------- lea cs_mulu_16,a0 lea cs_gradient,a1 lea cs_cl_data,a2 move.l #$3001fffe,a3 move.w cs_citycolor,a4 moveq #(CS_PLANEHEIGHT-1)/16-1,d7 .coplp: cmp.l #$0001fffe,a3 bne.s .nskip move.l #$ffd1fffe,a3 .nskip: move.l a3,(a2)+ move.w (a1)+,a5 move.w (a1),a6 move.w #$180,(a2)+ move.w a5,(a2)+ move.w #$182,(a2)+ move.w a6,(a2)+ move.w a4,d0 moveq #3,d3 bsr multiplycolor move.w d0,d4 move.w d0,d5 move.w a5,d0 moveq #15-3,d3 bsr multiplycolor add.w d0,d4 move.w a6,d0 moveq #15-3,d3 bsr multiplycolor add.w d0,d5 move.w #$188,(a2)+ move.w d4,(a2)+ move.w #$18a,(a2)+ move.w d5,(a2)+ move.w #$190,(a2)+ move.w d4,(a2)+ move.w #$192,(a2)+ move.w d5,(a2)+ move.w #$1a0,(a2)+ move.w d4,(a2)+ move.w #$1a2,(a2)+ move.w d5,(a2)+ move.w a4,d0 moveq #6,d3 bsr multiplycolor move.w d0,d4 move.w d0,d5 move.w a5,d0 moveq #15-6,d3 bsr multiplycolor add.w d0,d4 move.w a6,d0 moveq #15-6,d3 bsr multiplycolor add.w d0,d5 move.w #$198,(a2)+ move.w d4,(a2)+ move.w #$19a,(a2)+ move.w d5,(a2)+ move.w #$1a8,(a2)+ move.w d4,(a2)+ move.w #$1aa,(a2)+ move.w d5,(a2)+ move.w #$1b0,(a2)+ move.w d4,(a2)+ move.w #$1b2,(a2)+ move.w d5,(a2)+ move.w a4,d0 moveq #10,d3 bsr multiplycolor move.w d0,d4 move.w d0,d5 move.w a5,d0 moveq #15-10,d3 bsr multiplycolor add.w d0,d4 move.w a6,d0 moveq #15-10,d3 bsr multiplycolor add.w d0,d5 move.w #$1b8,(a2)+ move.w d4,(a2)+ move.w #$1ba,(a2)+ move.w d5,(a2)+ add.l #$10000000,a3 dbra d7,.coplp sub.l #$01000000,a3 move.l a3,(a2)+ move.w #$180,(a2)+ move.w a4,(a2)+ move.w #bplcon0,(a2)+ move.w #0,(a2)+ move.l #$fffffffe,(a2)+ move.w cs_citycolor,d0 lea cs_cl_palette+2,a0 moveq #16-1,d7 .ccoll: move.w d0,(a0) addq #4,a0 dbra d7,.ccoll move.w cs_gradient,cs_cl_palette+66 move.w #512,cs_cosinus move.w #140,cs_z move.l #-$58000,cs_sinus_add_add rts cityscape_go: move.l #cityscape_main,part_main move.l #cityscape_vbi,part_vbi rts cityscape_main: ; Clear destination bitplane ; -------------------------- lea custom,a6 move.l #cs_planes,d0 add.l cs_planes_add,d0 moveq #0,d1 waitb ; Notice that the following blits use these values as well ; -------------------------------------------------------- move.l #-1,bltafwm(a6) move.w d1,bltcon1(a6) move.w #DEST,bltcon0(a6) move.w d1,bltdmod(a6) move.l d0,bltdpth(a6) move.w #(CS_BLITTER_CLEAR<<6)|(CS_PLANEWIDTH/2),bltsize(a6) ; Clear part of the screen using the CPU ; -------------------------------------- move.l d0,a0 add.w #CS_PLANESIZE,a0 moveq #0,d0 moveq #0,d1 moveq #0,d2 moveq #0,d3 moveq #0,d4 moveq #0,d5 moveq #0,d6 sub.l a1,a1 sub.l a2,a2 sub.l a3,a3 sub.l a4,a4 move.l #((CS_PLANEHEIGHT-CS_BLITTER_CLEAR)/16)-1,d7 .clr: movem.l d0-d6/a1-a4,-(a0) movem.l d0-d6/a1-a4,-(a0) movem.l d0-d6/a1-a4,-(a0) movem.l d0-d6/a1-a4,-(a0) movem.l d0-d6/a1-a4,-(a0) movem.l d0-d6/a1-a4,-(a0) movem.l d0-d6/a1-a4,-(a0) movem.l d0-d6/a1-a4,-(a0) movem.l d0-d6/a1-a4,-(a0) movem.l d0-d6/a1-a4,-(a0) movem.l d0-d6/a1-a4,-(a0) movem.l d0-d6/a1-a4,-(a0) movem.l d0-d6/a1-a4,-(a0) movem.l d0-d6/a1-a4,-(a0) movem.l d0-d6/a1-a4,-(a0) movem.l d0-d6/a1-a4,-(a0) dbra d7,.clr ; Rotate one building first ; ------------------------- lea sinus,a0 move.w cs_sinus,d0 add.w #256,d0 and.w #511,d0 add.w #1024,d0 move.w d0,d1 add.w #512,d1 moveq #4-1,d7 .build: and.w #2046,d0 and.w #2046,d1 ; Convert to rectangular coordinates ; ---------------------------------- move.w (a0,d0.w),d2 move.w (a0,d1.w),d3 muls #CS_BUILDING_SIZE,d2 muls #CS_BUILDING_SIZE,d3 asr.l #8,d2 swap d3 move.w d3,-(sp) move.w d2,-(sp) add.w #512,d0 add.w #512,d1 dbra d7,.build ; Prepare blitter for line drawing ; -------------------------------- lea custom,a6 waitb move.w #$8000,bltadat(a6) move.w #$ffff,bltbdat(a6) move.w #CS_PLANEWIDTH,bltcmod(a6) move.w #CS_PLANEWIDTH,bltdmod(a6) ; Rotate building center coordinates ; ---------------------------------- lea cs_coords,a0 lea sinus,a1 lea cs_mulu_planewidth,a2 lea cs_planes,a3 add.l cs_planes_add,a3 move.w (a1,d0.w),d2 move.w (a1,d1.w),d3 move.w (a0)+,d7 subq #1,d7 .loop: ; Angle and distance (polar) ; -------------------------- move.w (a0)+,d2 move.w (a0)+,d3 ; Rotate (add to angle) ; --------------------- move.w d2,d4 add.w CS_SINUS(a2),d2 add.w CS_COSINUS(a2),d4 and.w #2046,d2 and.w #2046,d4 ; Convert to rectangular coordinates ; ---------------------------------- move.w (a1,d2.w),d2 move.w (a1,d4.w),d4 muls d3,d2 muls d3,d4 asr.l #8,d2 swap d4 ; Get height (y) ; -------------- move.w (a0)+,d3 lsl.w #7,d3 ; Translation: x=x+cx, z=z+cz ; --------------------------- add.w CS_X(a2),d2 sub.w CS_Z(a2),d4 cmp.w #CS_BUILDING_SIZE,d4 ;-CS_BUILDING_SIZE*2,d4 bge .skip swap d3 move.w d2,d3 move.l d3,a4 move.w d4,a5 move.w #$8000,CS_OLDX(a2) move.w #-1,CS_CLIP(a2) ; Plot building around the center coordinate ; ------------------------------------------ moveq #4-1,d6 .bldng: move.l a4,d2 move.l d2,d3 swap d3 move.l a5,d4 add.w (sp)+,d2 add.w (sp)+,d4 bmi .zok move.w #$8000,CS_OLDX(a2) bra .next .zok: ext.l d2 ext.l d3 ext.l d4 ; Projection: x'=x/z, y'=y/z ; -------------------------- divs d4,d2 divs d4,d3 ; Centering ; --------- .projd: add.w #CS_PLANEWIDTH*8/2,d2 add.w #CS_PLANEHEIGHT*3/4,d3 ; Get line coordinates ; -------------------- move.w CS_OLDX(a2),d0 move.w CS_OLDY(a2),d1 move.w d2,CS_OLDX(a2) move.w d3,CS_OLDY(a2) cmp.w #$8000,d0 beq .next ; Clipping test ; ------------- lea cs_clipstorage+16,a6 movem.l d6-d7,-(a6) movem.l a2-a3,-(a6) moveq #0,d7 sub.l a2,a2 sub.l a3,a3 .cloop: moveq #0,d4 ; code1 moveq #0,d5 ; code2 tst.w d0 bpl.s .x1lok or.w #CLIP_LEFT_EDGE,d4 .x1lok: cmp.w #CS_PLANEWIDTH*8,d0 blt.s .x1rok or.w #CLIP_RIGHT_EDGE,d4 .x1rok: tst.w d1 bpl.s .y1lok or.w #CLIP_TOP_EDGE,d4 .y1lok: cmp.w #CS_PLANEHEIGHT,d1 blt.s .y1rok or.w #CLIP_BOTTOM_EDGE,d4 .y1rok: tst.w d2 bpl.s .x2lok or.w #CLIP_LEFT_EDGE,d5 .x2lok: cmp.w #CS_PLANEWIDTH*8,d2 blt.s .x2rok or.w #CLIP_RIGHT_EDGE,d5 .x2rok: tst.w d3 bpl.s .y2lok or.w #CLIP_TOP_EDGE,d5 .y2lok: cmp.w #CS_PLANEHEIGHT,d3 blt.s .y2rok or.w #CLIP_BOTTOM_EDGE,d5 .y2rok: move.w d4,d6 or.w d5,d6 beq.w .line move.w d4,d6 and.w d5,d6 beq.s .ok btst #0,d4 beq.s .nl1 moveq #0,d0 .nl1: btst #1,d4 beq.s .nr1 move.l #CS_PLANEWIDTH*8-1,d0 .nr1: btst #2,d4 beq.s .nt1 moveq #0,d1 .nt1: btst #3,d4 beq.s .nb1 move.l #CS_PLANEHEIGHT-1,d1 .nb1: btst #0,d5 beq.s .nl2 moveq #0,d2 .nl2: btst #1,d5 beq.s .nr2 move.l #CS_PLANEWIDTH*8-1,d2 .nr2: btst #2,d5 beq.s .nt2 moveq #0,d3 .nt2: btst #3,d5 beq.s .nb2 move.l #CS_PLANEHEIGHT-1,d3 .nb2: bra .line .ok: cmp.l #0,a2 bne.s .m2 move.w d3,d6 ; m1=(y2-y1)/(x2-x1) sub.w d1,d6 ext.l d6 asl.l #5,d6 move.w d2,d7 sub.w d0,d7 beq.s .m1 add.l #$3f,d6 divs d7,d6 ext.l d6 move.l d6,a2 .m1: move.w d2,d6 ; m2=(x2-x1)/(y2-y1) sub.w d0,d6 ext.l d6 asl.l #5,d6 move.w d3,d7 sub.w d1,d7 beq.s .m2 add.l #$3f,d6 divs d7,d6 ext.l d6 move.l d6,a3 .m2: tst.w d4 bne.s .clip exg d0,d2 exg d1,d3 exg d4,d5 .clip: btst #0,d4 beq.s .nleft move.l a2,d6 muls d6,d0 asr.l #6,d0 sub.l d0,d1 moveq #0,d0 bra.w .cloop .nleft: btst #1,d4 beq.s .nrite sub.w #CS_PLANEWIDTH*8-1,d0 move.l a2,d6 muls d6,d0 asr.l #6,d0 sub.l d0,d1 move.l #CS_PLANEWIDTH*8-1,d0 bra.w .cloop .nrite: btst #2,d4 beq.s .ntop cmp.w d0,d2 beq.s .y1 move.l a3,d6 muls d6,d1 asr.l #6,d1 sub.l d1,d0 .y1: moveq #0,d1 bra.w .cloop .ntop: btst #3,d4 beq.w .cloop cmp.w d0,d2 beq.s .y2 sub.w #CS_PLANEHEIGHT-1,d1 move.l a3,d6 muls d6,d1 asr.l #6,d1 sub.l d1,d0 .y2: move.l #CS_PLANEHEIGHT-1,d1 bra.w .cloop .line: lea custom,a6 .wait: btst #14,dmaconr(a6) bne.s .wait lea cs_clipstorage,a6 movem.l (a6)+,a2-a3 ; If the top y of the previous line was 0 check out if this one's is too ; ---------------------------------------------------------------------- cmp.w #-1,CS_CLIP(a2) beq .chtop tst.w d1 beq.s .d1tp1 tst.w d3 bne.s .chtop .d3tp1: move.w d2,d4 bra.s .width .d1tp1: move.w d0,d4 .width: move.w CS_CLIP(a2),d5 cmp.w d5,d4 bcs.s .d4ok exg d4,d5 .d4ok: moveq #-1,d7 move.w d5,d6 not.w d6 and.w #15,d6 lsl.w d6,d7 swap d7 move.w d4,d6 and.w #15,d6 lsr.w d6,d7 lsr.w #3,d4 lsr.w #3,d5 and.w #$fffe,d4 and.w #$fffe,d5 sub.w d4,d5 beq.s .nloop lsr.w d5 or.w d7,(a3,d4.w) addq #2,d4 subq #2,d5 bmi .sloop .filll: move.w #-1,(a3,d4.w) addq #2,d4 dbra d5,.filll .sloop: swap d7 or.w d7,(a3,d4.w) bra.s .chtop .nloop: move.w d7,d6 swap d7 and.w d7,d6 or.w d6,(a3,d4.w) ; Check if the top y of this line is at 0 ; --------------------------------------- .chtop: move.w #-1,CS_CLIP(a2) tst.w d1 beq.s .d1tp2 tst.w d3 bne.s .swap .d3tp2: move.w d2,CS_CLIP(a2) bra.s .swap .d1tp2: move.w d0,CS_CLIP(a2) .swap: movem.l (a6)+,d6-d7 lea custom,a6 ; Make sure the line is drawn from top to bottom ; ---------------------------------------------- cmp.w d1,d3 bhi.s .yok bne.s .exg cmp.w d0,d2 bne .yok bra .next .exg: exg d0,d2 exg d1,d3 .yok: moveq #0,d5 move.w d3,d4 sub.w d1,d4 add.w d4,d4 sub.w d0,d2 bge.s .x2gx1 neg.w d2 addq #2,d5 .x2gx1: cmp.w d4,d2 blo.s .allok subq #1,d3 .allok: sub.w d1,d3 add.w d1,d1 move.w (a2,d1.w),d1 ext.l d1 move.w d0,d4 asr.w #3,d4 add.w d4,d1 add.l a3,d1 move.w d3,d4 sub.w d2,d4 bge.s .dygdx exg d2,d3 addq #1,d5 .dygdx: move.b CS_OCTANTS(a2,d5.w),d5 and.w #$00ff,d5 add.w d2,d2 and.w #$000f,d0 ror.w #4,d0 or.w #SRCA|SRCC|DEST|NANBC|NABC|ANBC|ABC|ABNC,d0 .waitb: btst #14,dmaconr(a6) bne.s .waitb move.w d2,bltbmod(a6) sub.w d3,d2 bge.s .signl or.w #SIGNFLAG,d5 .signl: move.w d2,bltaptl(a6) sub.w d3,d2 move.w d2,bltamod(a6) move.w d0,bltcon0(a6) move.w d5,bltcon1(a6) move.l d1,bltcpth(a6) move.l d1,bltdpth(a6) lsl.w #6,d3 addq #2,d3 move.w d3,bltsize(a6) .next: dbra d6,.bldng sub.w #16,sp .skip: dbra d7,.loop add.w #16,sp ; Prepare blitter for vertical filling ; ------------------------------------ lea custom,a6 move.l #cs_planes+4,d0 add.l cs_planes_add,d0 move.l d0,d1 add.l #CS_PLANEWIDTH,d1 waitb move.w #SRCA|SRCB|DEST|ABC|ABNC|ANBC|ANBNC|NABC|NABNC,bltcon0(a6) move.l #$00040004,bltamod(a6) move.l #$00040004,bltcmod(a6) move.l #-1,bltafwm(a6) move.w #0,bltcon1(a6) move.l d1,bltapth(a6) move.l d0,bltbpth(a6) move.l d1,bltdpth(a6) move.w #((CS_PLANEHEIGHT-1)<<6)|((CS_PLANEWIDTH-4)/2),bltsize(a6) ; Fill the first 4 bytes of each row using the CPU ; ------------------------------------------------ lea cs_planes,a0 add.l cs_planes_add,a0 moveq #0,d0 move.l #CS_PLANEWIDTH,d6 move.l #CS_PLANEHEIGHT/8-1,d7 .vfill: or.l d0,(a0) move.l (a0),d0 add.w d6,a0 or.l d0,(a0) move.l (a0),d0 add.w d6,a0 or.l d0,(a0) move.l (a0),d0 add.w d6,a0 or.l d0,(a0) move.l (a0),d0 add.w d6,a0 or.l d0,(a0) move.l (a0),d0 add.w d6,a0 or.l d0,(a0) move.l (a0),d0 add.w d6,a0 or.l d0,(a0) move.l (a0),d0 add.w d6,a0 or.l d0,(a0) move.l (a0),d0 add.w d6,a0 dbra d7,.vfill waitb move.b #1,render rts cityscape_vbi: movem.l d1/d7,-(sp) move.l sc_position,d0 subq #1,d0 and.w #127,d0 cmp.w #103,d0 bhi.s .noadd add.l #$200,cs_sinus_add_add move.l cs_sinus_add_add,d1 add.l d1,cs_sinus_add move.w cs_sinus_add,d1 beq.s .noadd clr.w cs_sinus_add add.w d1,d1 add.w d1,cs_sinus add.w d1,cs_cosinus and.w #2046,cs_sinus and.w #2046,cs_cosinus .noadd: cmp.w #64,d0 bcs.s .moved cmp.w #96,d0 bcs.s .out .in: sub.w #2,cs_z bra.s .moved .out: add.w #1,cs_z .moved: tst.b render beq.s .vbiok move.l #cs_cl,cop1lch+custom move.l #cs_planes,d0 move.l d0,d1 add.l cs_planes_add,d0 lea cs_cl_bpl2pth,a0 moveq #4-1,d7 .setplanesloop: move.w d0,4(a0) swap d0 move.w d0,(a0) swap d0 addq #8,a0 sub.l #CS_PLANESIZE,d0 cmp.l d1,d0 bge .plnok add.l #5*CS_PLANESIZE,d0 .plnok: dbra d7,.setplanesloop add.l #CS_PLANESIZE,cs_planes_add cmp.l #5*CS_PLANESIZE,cs_planes_add bcs .pladd clr.l cs_planes_add .pladd: clr.b render move.w cs_citycolor,ne_cl_palette+2 .vbiok: movem.l (sp)+,d1/d7 rts multiplycolor: move.w d0,d1 move.w d0,d2 lsr.w #8,d0 lsr.w #4,d1 and.w #$f,d1 and.w #$f,d2 lsl.w #4,d3 add.w d3,a0 move.b (a0,d0.w),d0 move.b (a0,d1.w),d1 move.b (a0,d2.w),d2 sub.w d3,a0 lsl.w #8,d0 lsl.b #4,d1 or.b d1,d0 or.b d2,d0 rts discopallo: ; Clear memory ; ------------ lea dp_cl,a0 move.l #dp_requirements_chipmem,d7 bsr clearmemory lea dp_planes_add,a0 move.l #dp_requirements_fastmem,d7 bsr clearmemory ; Copy copperlist ; --------------- lea dp_ct,a0 lea dp_cl,a1 move.w #(dp_ct_data-dp_ct)/4-1,d7 .cplst: move.l (a0)+,(a1)+ dbra d7,.cplst move.l #$fffffffe,(a1)+ ; Screen setup ; ------------ move.l #dp_planes,d0 lea dp_cl_bpl1pth,a0 moveq #DP_PLANES-1,d7 .setplanesloop: move.w d0,4(a0) swap d0 move.w d0,(a0) swap d0 addq #8,a0 add.l #DP_PLANEWIDTH,d0 dbra d7,.setplanesloop ; Create multiply table ; --------------------- moveq #0,d0 lea dp_mulu_planewidth,a0 move.l #DP_PLANEHEIGHT-1,d7 .mulu: move.w d0,-(a0) add.w #DP_PLANEWIDTH,d0 dbra d7,.mulu moveq #0,d0 lea dp_mulu_256,a0 .mulu2: moveq #1,d1 .mulu3: move.w d0,d2 mulu d1,d2 lsr.w #8,d2 move.b d2,(a0)+ addq #1,d1 cmp.w #256,d1 ble.s .mulu3 addq #1,d0 cmp.w #128,d0 bcs.s .mulu2 lea dp_mulu_256-128*256,a0 .mulu4: moveq #1,d1 .mulu5: move.w d0,d2 mulu d1,d2 lsr.w #8,d2 move.b d2,(a0)+ addq #1,d1 cmp.w #256,d1 ble.s .mulu5 addq #1,d0 cmp.w #256,d0 bcs.s .mulu4 ; Create discopallo ball width table (x=sqrt(r^2-y^2)) ; ---------------------------------------------------- lea dp_table,a0 move.l #-256,d7 .dpbw: move.l d7,d0 bpl.s .dpbp neg.l d0 .dpbp: mulu d0,d0 move.l #256*256-1,d1 sub.w d0,d1 ; Calculate square root ; --------------------- moveq #-1,d2 clr.w d2 cmp.l d2,d1 bls.s .sqrt0 move.l #$00010000,d2 bra.s .sqrt3 .sqrt0: moveq #31,d0 .sqrt1: bclr d0,d2 lsr.l d2 cmp.l d2,d1 bls.s .sqrt2 sub.l d2,d1 bset d0,d2 .sqrt2: subq #2,d0 bcc.s .sqrt1 lsr.l d2 .sqrt3: cmp.w #$100,d2 bcs.s .dpbok subq #1,d2 .dpbok: move.b d2,(a0)+ addq #1,d7 cmp.w #256,d7 bne.s .dpbw ; Copy the ordered table to the discopallo table ; ---------------------------------------------- lea table_order,a0 lea dp_xoffsets,a1 move.l #16-1,d7 .dptf: move.l (a0)+,(a1)+ move.l (a0)+,60(a1) move.l (a0)+,124(a1) move.l (a0)+,188(a1) dbra d7,.dptf ; Remove pixels from the discopallo table ; --------------------------------------- lea dp_xoffsets,a0 move.l #255-1,d7 .dpt: move.b (a0)+,d0 move.l a0,a1 move.l d7,d6 cmp.b #128,d0 bcs.s .dptl .dptr: .dptrl: move.b (a1)+,d1 cmp.b d0,d1 bcs.s .dptrn subq #1,d1 move.b d1,-1(a1) .dptrn: dbra d6,.dptrl bra.s .dptnx .dptl: .dptll: move.b (a1)+,d1 cmp.b d0,d1 bhi.s .dptln addq #1,d1 move.b d1,-1(a1) .dptln: dbra d6,.dptll .dptnx: dbra d7,.dpt ; Create discopallo Y offsets ; --------------------------- moveq #-2,d0 moveq #-1,d1 lea sinus,a0 lea dp_yoffsets,a1 moveq #32-1,d7 .dpyol: addq #2,d0 cmp.w #512,d0 bne.s .dpyon move.b #128,(a1)+ bra.s .dpyol .dpyon: move.w (a0,d0.w),d2 lsr.w #8,d2 lsr.w #3,d2 cmp.w d1,d2 beq .dpyol move.w d2,d1 move.w d0,d3 lsr.w #2,d3 addq #1,d3 move.b d3,(a1)+ dbra d7,.dpyol move.b #$ff,(a1)+ clr.b (a1)+ ; Create jelly table ; ------------------ lea dp_jelly,a0 move.w #64-16,d6 .jell1: moveq #0,d7 .jell2: move.w d7,d0 mulu d6,d0 lsr.w #6,d0 cmp.w #256,d0 bcs.s .jelok move.w #255,d0 .jelok: move.b d0,(a0)+ addq #1,d7 cmp.w #256,d7 bcs.s .jell2 addq #1,d6 cmp.w #64+16,d6 bcs.s .jell1 ; Decrunch data ; ------------- lea dp_texture,a0 lea dp_texture_stc,a1 bsr decrunch ; Add some of the texture below the texture (bubble gum fix...) ; ------------------------------------------------------------- lea dp_texture,a0 lea dp_texture_hotfix,a1 move.w #128*2/4-1,d7 .hotfx: move.l (a0)+,(a1)+ dbra d7,.hotfx ; Create discopallo ; ----------------- lea sinus,a0 lea dp_planes+DP_PLANES*DP_PLANESIZE-DP_PLANES*DP_PLANEWIDTH,a1 lea DP_PLANEWIDTH(a1),a2 lea DP_PLANEWIDTH(a2),a3 lea DP_PLANEWIDTH(a3),a4 lea DP_PLANEWIDTH+16(a4),a5 move.l #$80,d0 moveq #128-1,d7 .dp1: move.w (a0)+,d1 addq #2,a0 lsr.w #8,d1 lsr.w #4,d1 bcc .dp1n1 or.b d0,(a1) .dp1n1: lsr.w d1 bcc .dp1n2 or.b d0,(a2) .dp1n2: lsr.w d1 bcc .dp1n3 or.b d0,(a3) .dp1n3: lsr.w d1 bcc .dp1n4 or.b d0,(a4) .dp1n4: ror.b d0 bpl.s .dp1ok addq #1,a1 addq #1,a2 addq #1,a3 addq #1,a4 .dp1ok: dbra d7,.dp1 moveq #128-1,d7 .dp2: move.w #$7fff,d1 sub.w (a0)+,d1 addq #2,a0 lsr.w #8,d1 lsr.w #4,d1 bcc .dp2n1 or.b d0,(a1) .dp2n1: lsr.w d1 bcc .dp2n2 or.b d0,(a2) .dp2n2: lsr.w d1 bcc .dp2n3 or.b d0,(a3) .dp2n3: lsr.w d1 bcc .dp2n4 or.b d0,(a4) .dp2n4: ror.b d0 bpl.s .dp2ok addq #1,a1 addq #1,a2 addq #1,a3 addq #1,a4 move.b #-1,(a5)+ .dp2ok: dbra d7,.dp2 lea dp_xoffsets,a1 lea dp_planes+DP_PLANES*DP_PLANESIZE-2*DP_PLANES*DP_PLANEWIDTH,a3 lea DP_PLANES*DP_PLANEWIDTH(a3),a2 lea custom,a6 moveq #0,d7 dp_lp: ; Copy row below as is ; -------------------- moveq #0,d0 waitb move.w #SRCA|DEST|ABC|ABNC|ANBC|ANBNC,bltcon0(a6) move.w d0,bltcon1(a6) move.l #$fffffffe,bltafwm(a6) move.l d0,bltamod(a6) move.l a2,bltapth(a6) move.l a3,bltdpth(a6) move.w #(DP_PLANES<<6)|(32/2),bltsize(a6) ; Get destination pixel to remove ; ------------------------------- move.b (a1,d7.w),d0 ; Check whether the pixel is on the left or on the right half ; ----------------------------------------------------------- cmp.b #128,d0 bcs.s dp_ol ; Blit width in words ; ------------------- move.w #255,d1 sub.b d0,d1 lsr.w #4,d1 addq #1,d1 ; Modulo in bytes ; --------------- move.w #DP_PLANEWIDTH,d2 sub.w d1,d2 sub.w d1,d2 ; How many pixels of the original are preserved ; --------------------------------------------- and.w #15,d0 ; Calculate blitter mask ; -------------------- move.l #$fffeffff,d3 lsr.w d0,d3 lea DP_PLANES*DP_PLANEWIDTH-2(a3),a4 or.w #(DP_PLANES<<6),d1 waitb move.w #SRCB|SRCC|DEST|ABC|ABNC|NABC|NANBC,bltcon0(a6) move.w #(1< 0, next byte, 7 -> 0 ...) ; --------------------------------------------------------- moveq #7,d5 move.l fs_data,a5 move.l fs_pointers,a6 ; Skip the width (in the first word) ; ---------------------------------- addq #2,a6 ; Uppermost Y position ; -------------------- move.w fs_yorigin,d1 ; Draw the pixel pairs from X = 0 to X = PLANEWIDTH * 8 - 1 ; --------------------------------------------------------- move.l #FS_PLANEWIDTH*8-1,d7 .xloop: ; Get wobble sinus and advance in it ; ---------------------------------- move.w (a1)+,d4 ; If the source X pointer is outside the source data area do nothing ; ------------------------------------------------------------------ move.l d2,d0 bmi .next ; If the source X pointer is outside the source data area do nothing ; ------------------------------------------------------------------ swap d0 cmp.w -2(a6),d0 bge fs_fillsinus ; Add Y origin to sinus wobble ; ---------------------------- add.w d1,d4 ; Get pixel pair data ; ------------------- add.w d0,d0 move.w (a6,d0.w),d0 lea (a5,d0.w),a0 ; Get number of coordinate pairs - 1 in this column (-1 if none) ; -------------------------------------------------------------- move.b (a0)+,d6 bmi.s .next ext.w d6 .yloop: ; Y coordinate of the first pixel in the pair ; ------------------------------------------- moveq #0,d0 move.b (a0)+,d0 ; Multiply by zoom ; ---------------- move.b (a2,d0.w),d0 ; Add Y origin and sinus wobble ; ----------------------------- add.w d4,d0 ; Get PLANEWIDTH multiplied offset to plane data ; ---------------------------------------------- add.w d0,d0 move.w (a3,d0.w),d0 bchg.b d5,(a4,d0.w) ; Second pixel of pair as above ; ----------------------------- moveq #0,d0 move.b (a0)+,d0 move.b (a2,d0.w),d0 add.w d4,d0 add.w d0,d0 move.w (a3,d0.w),d0 bchg.b d5,(a4,d0.w) dbra d6,.yloop ; Move on to the next pixel on screen ; ----------------------------------- .next: ; Advance in source data ; ---------------------- add.l d3,d2 ; Next bit ; -------- subq #1,d5 bpl.s .nbyte addq #1,a4 moveq #7,d5 .nbyte: dbra d7,.xloop fs_fillsinus: ; Prepare blitter for vertical filling ; ------------------------------------ move.l #fs_planes+3*FS_PLANESIZE+4,d1 add.l fs_planes_add,d1 move.l d1,d2 add.l #FS_PLANEWIDTH,d2 lea custom,a6 waitb move.w #SRCA|SRCB|DEST|ANBC|ANBNC|NABC|NABNC,bltcon0(a6) move.l d2,bltapth(a6) move.l d1,bltbpth(a6) move.l d2,bltdpth(a6) move.l #$00040004,bltamod(a6) move.w #4,bltbmod(a6) move.w #((FS_PLANEHEIGHT-1)<<6)|((FS_PLANEWIDTH-4)/2),bltsize(a6) ; Fill the first 4 bytes of each row using the CPU ; ------------------------------------------------ lea fs_planes+3*FS_PLANESIZE,a0 add.l fs_planes_add,a0 moveq #0,d0 move.l #FS_PLANEWIDTH-4,d6 move.l #FS_PLANEHEIGHT/8-1,d7 .vfill: eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 dbra d7,.vfill fsoks: move.b #1,render rts fullscreenscrollersinus_vbi: movem.l d1-d4/d7/a1-a2,-(sp) move.l sc_position,d0 subq #1,d0 and.w #127,d0 cmp.w #3,d0 bcs.s .fade cmp.w #110,d0 bcs .npal .fade: mulu #6,d0 addq #6,d0 sub.w tp_wait,d0 cmp.w #16,d0 bhi.s .fdout lsl.w #4,d0 ; Fade palette in ; --------------- lea fs_palette_1,a0 lea table_fade,a1 add.w d0,a1 lea fs_cl_palette+2,a2 moveq #16-1,d7 .fdpl1: move.w #$fff,d0 sub.w (a0)+,d0 move.w d0,d1 move.w d0,d2 lsr.w #8,d0 lsr.w #4,d1 and.w #$f,d1 and.w #$f,d2 move.b (a1,d0.w),d0 move.b (a1,d1.w),d1 move.b (a1,d2.w),d2 lsl.w #8,d0 lsl.w #4,d1 or.w d1,d0 or.w d2,d0 move.w #$fff,d1 sub.w d0,d1 move.w d1,(a2) addq #4,a2 dbra d7,.fdpl1 bra.s .npal .fdout: move.w #113*6-1,d1 sub.w d0,d1 bmi.s .npal cmp.w #16,d1 bhi.s .npal lsl.w #4,d1 ; Fade palette out ; ---------------- lea fs_palette_1,a0 lea table_fade,a1 add.w d1,a1 lea fs_cl_palette+2,a2 moveq #16-1,d7 .fdpl2: move.w (a0)+,d0 move.w d0,d1 move.w d0,d2 lsr.w #8,d0 lsr.w #4,d1 and.w #$f,d1 and.w #$f,d2 move.b (a1,d0.w),d0 move.b (a1,d1.w),d1 move.b (a1,d2.w),d2 lsl.w #8,d0 lsl.w #4,d1 or.w d1,d0 or.w d2,d0 move.w d0,(a2) addq #4,a2 dbra d7,.fdpl2 .npal: ; Synchronize scale the beat ; -------------------------- add.w #42,fs_scalesinus move.l sc_position,d0 and.w #7,d0 bne.s .nsync tst.b fs_synced bne.s .nores move.b #1,fs_synced move.w #768,fs_scalesinus bra.s .nores .nsync: clr.b fs_synced .nores: add.w #2,fs_xsinus add.w #12,fs_sinusadd and.w #2046,fs_scalesinus and.w #2046,fs_xsinus and.w #511,fs_sinusadd lea sinus,a0 move.w fs_scalesinus,d0 move.w (a0,d0.w),d2 add.w #$8000,d2 lsr.w #8,d2 lsr.w #2,d2 move.w d2,d3 lsr.w d3 add.w d3,d2 add.w #32,d2 cmp.w #1,d2 bhi.s .fsok moveq #2,d2 .fsok: move.w d2,fs_scalefactor move.w fs_xsinus,d1 move.w (a0,d1.w),d2 ext.l d2 move.l fs_pointers,a1 moveq #0,d3 move.w (a1),d3 move.l #$8000,d4 divu d3,d4 divs d4,d2 add.w d3,d2 lsr.w d2 move.w d2,fs_xposition tst.b render beq.s .vbiok ; Set the bitplanes ; ----------------- move.l #fs_planes+3*FS_PLANESIZE,d0 add.l fs_planes_add,d0 move.w d0,fs_cl_bpl4ptl swap d0 move.w d0,fs_cl_bpl4pth ; Double buffering ; ---------------- eor.l #FS_PLANES*FS_PLANESIZE,fs_planes_add clr.b render .vbiok: movem.l (sp)+,d1-d4/d7/a1-a2 rts fullscreenscrollerrotate: ; Clear memory ; ------------ lea fs_cl,a0 move.l #fs_requirements_chipmem,d7 bsr clearmemory lea fs_planes_add,a0 move.l #fs_requirements_fastmem,d7 bsr clearmemory ; Copy copperlist ; --------------- lea fs_ct,a0 lea fs_cl,a1 move.w #(fs_ct_data-fs_ct)/4-1,d7 .cplst: move.l (a0)+,(a1)+ dbra d7,.cplst ; Decrunch bitmap ; --------------- lea fs_planes,a0 lea fs_background_2_stc,a1 bsr decrunch ; Screen setup ; ------------ move.l #fs_planes,d0 lea fs_cl_bpl1pth,a0 moveq #FS_PLANES-1,d7 .setplanesloop: move.w d0,4(a0) swap d0 move.w d0,(a0) swap d0 addq #8,a0 add.l #FS_PLANESIZE,d0 dbra d7,.setplanesloop ; Create multiply table ; --------------------- moveq #0,d0 lea fs_mulu_planewidth,a0 move.l #FS_PLANEHEIGHT-1,d7 .mulu1: move.w d0,(a0)+ add.w #FS_PLANEWIDTH,d0 dbra d7,.mulu1 ; Create scaling table ; -------------------- moveq #0,d0 lea fs_mulu_256,a0 .mulu2: move.w #-255,d1 .mulu3: move.w d0,d2 muls d1,d2 asr.w #7,d2 add.w #128,d2 move.b d2,(a0)+ addq #2,d1 cmp.w #256,d1 blt.s .mulu3 addq #1,d0 cmp.w #128,d0 bcs.s .mulu2 moveq #-128,d0 lea fs_mulu_256-128*256,a0 .mulu4: move.w #-255,d1 .mulu5: move.w d0,d2 muls d1,d2 asr.w #7,d2 add.w #128,d2 move.b d2,(a0)+ addq #2,d1 cmp.w #256,d1 blt.s .mulu5 addq #1,d0 bmi.s .mulu4 ; Create sinus table ; ------------------ lea sinus,a0 lea fs_sinus,a1 move.l #1024/4-1,d7 .fssin: move.w (a0),d0 asr.w #8,d0 asr.w d0 move.w d0,1536(a1) move.w d0,1024(a1) move.w d0,512(a1) move.w d0,(a1)+ addq #8,a0 dbra d7,.fssin ; Decrunch data ; ------------- ; lea fs_data_1,a0 ; lea fs_data_1_stc,a1 ; bsr decrunch lea fs_data_2,a0 lea fs_data_2_stc,a1 bsr decrunch ; Set object ; ---------- move.l #fs_pointers_2,fs_pointers move.l #fs_data_2,fs_data move.w #512,fs_xsinus rts fullscreenscrollerrotate_go: move.l #fs_cl,cop1lch+custom move.l #fullscreenscrollerrotate_main,part_main move.l #fullscreenscrollerrotate_vbi,part_vbi rts fullscreenscrollerrotate_main: lea fs_planes+3*FS_PLANESIZE,a4 add.l fs_planes_add,a4 ; Clear the first 144 rows of the bitplane ; ---------------------------------------- lea custom,a6 moveq #0,d0 waitb move.w #DEST,bltcon0(a6) move.l #-1,bltafwm(a6) move.w d0,bltdmod(a6) move.w d0,bltcon1(a6) move.l a4,bltdpth(a6) move.w #(144<<6)|(FS_PLANEWIDTH/2),bltsize(a6) ; Simultaneously clear the rest of the bitplane using the CPU ; ----------------------------------------------------------- moveq #0,d1 moveq #0,d2 moveq #0,d3 moveq #0,d4 moveq #0,d5 moveq #0,d6 sub.l a0,a0 move.l a4,a1 lea FS_PLANESIZE(a1),a1 moveq #7-1,d7 .clr: movem.l d0-d6/a0,-(a1) movem.l d0-d6/a0,-(a1) movem.l d0-d6/a0,-(a1) movem.l d0-d6/a0,-(a1) movem.l d0-d6/a0,-(a1) movem.l d0-d6/a0,-(a1) movem.l d0-d6/a0,-(a1) movem.l d0-d6/a0,-(a1) movem.l d0-d6/a0,-(a1) movem.l d0-d6/a0,-(a1) movem.l d0-d6/a0,-(a1) movem.l d0-d6/a0,-(a1) movem.l d0-d6/a0,-(a1) movem.l d0-d6/a0,-(a1) movem.l d0-d6/a0,-(a1) movem.l d0-d6/a0,-(a1) dbra d7,.clr waitb ; Draw the pixel pairs ; -------------------- lea sinus,a1 lea fs_mulu_256,a2 lea fs_mulu_planewidth,a3 ; Current planar bit to set (7 -> 0, next byte, 7 -> 0 ...) ; --------------------------------------------------------- moveq #7,d5 move.l fs_data,a5 move.l fs_pointers,a6 ; Draw the pixel pairs from X = 0 to X = PLANEWIDTH * 8 - 1 ; --------------------------------------------------------- move.l #FS_PLANEWIDTH*8,d7 move.w (a6)+,d2 sub.w d7,d2 move.w fs_xposition,d0 ; Check bounds ; ------------ bpl.s .xpok1 add.w d0,d7 bra.s .xpok2 .xpok1: move.w d0,d3 sub.w d2,d3 bmi.s .xpok2 sub.w d3,d7 .xpok2: add.w d0,d0 add.w d0,a6 move.w fs_rotatesinus,d2 move.w #$ff,d3 subq #1,d7 bmi fs_fillrotate .xloop: ; Get sinus and advance in it ; --------------------------- move.w (a1,d2.w),d4 asr.w d4 ; Get pixel pair data ; ------------------- move.w (a6)+,d0 lea (a5,d0.w),a0 ; Get number of coordinate pairs - 1 in this column (-1 if none) ; -------------------------------------------------------------- move.b (a0)+,d6 bmi.s .next ext.w d6 .yloop: ; Y coordinate of the first pixel in the pair ; ------------------------------------------- move.w d4,d0 move.b (a0)+,d0 ; Multiply by zoom ; ---------------- move.b (a2,d0.w),d0 and.w d3,d0 ; Get PLANEWIDTH multiplied offset to plane data ; ---------------------------------------------- add.w d0,d0 move.w (a3,d0.w),d0 bchg.b d5,(a4,d0.w) ; Second pixel of pair as above ; ----------------------------- move.w d4,d0 move.b (a0)+,d0 move.b (a2,d0.w),d0 and.w d3,d0 add.w d0,d0 move.w (a3,d0.w),d0 bchg.b d5,(a4,d0.w) dbra d6,.yloop ; Move on to the next pixel on screen ; ----------------------------------- .next: ; Next bit ; -------- subq #1,d5 bpl.s .nbyte addq #1,a4 moveq #7,d5 .nbyte: addq #2,d2 and.w #2046,d2 dbra d7,.xloop fs_fillrotate: ; Prepare blitter for vertical filling ; ------------------------------------ move.l #fs_planes+3*FS_PLANESIZE+4,d1 add.l fs_planes_add,d1 move.l d1,d2 add.l #FS_PLANEWIDTH,d2 lea custom,a6 waitb move.w #SRCA|SRCB|DEST|ANBC|ANBNC|NABC|NABNC,bltcon0(a6) move.l d2,bltapth(a6) move.l d1,bltbpth(a6) move.l d2,bltdpth(a6) move.l #$00040004,bltamod(a6) move.w #4,bltbmod(a6) move.w #((FS_PLANEHEIGHT-1)<<6)|((FS_PLANEWIDTH-4)/2),bltsize(a6) ; Fill the first 4 bytes of each row using the CPU ; ------------------------------------------------ lea fs_planes+3*FS_PLANESIZE,a0 add.l fs_planes_add,a0 moveq #0,d0 move.l #FS_PLANEWIDTH-4,d6 move.l #FS_PLANEHEIGHT/8-1,d7 .vfill: eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 eor.l d0,(a0) move.l (a0)+,d0 add.w d6,a0 dbra d7,.vfill fsokr: move.b #1,render rts fullscreenscrollerrotate_vbi: movem.l d1-d4/d7/a1-a2,-(sp) move.l sc_position,d0 subq #1,d0 and.w #127,d0 cmp.w #3,d0 bcs.s .fade cmp.w #123,d0 bcs .npal .fade: mulu #6,d0 addq #6,d0 sub.w tp_wait,d0 cmp.w #16,d0 bhi.s .fdout lsl.w #4,d0 ; Fade palette in ; --------------- lea fs_palette_2,a0 lea table_fade,a1 add.w d0,a1 lea fs_cl_palette+2,a2 moveq #16-1,d7 .fdpl1: move.w #$fff,d0 sub.w (a0)+,d0 move.w d0,d1 move.w d0,d2 lsr.w #8,d0 lsr.w #4,d1 and.w #$f,d1 and.w #$f,d2 move.b (a1,d0.w),d0 move.b (a1,d1.w),d1 move.b (a1,d2.w),d2 lsl.w #8,d0 lsl.w #4,d1 or.w d1,d0 or.w d2,d0 move.w #$fff,d1 sub.w d0,d1 move.w d1,(a2) addq #4,a2 dbra d7,.fdpl1 bra.s .npal .fdout: move.w #126*6-1,d1 sub.w d0,d1 bmi.s .npal cmp.w #16,d1 bhi.s .npal lsl.w #4,d1 ; Fade palette out ; ---------------- lea fs_palette_2,a0 lea table_fade,a1 add.w d1,a1 lea fs_cl_palette+2,a2 moveq #16-1,d7 .fdpl2: move.w (a0)+,d0 move.w d0,d1 move.w d0,d2 lsr.w #8,d0 lsr.w #4,d1 and.w #$f,d1 and.w #$f,d2 move.b (a1,d0.w),d0 move.b (a1,d1.w),d1 move.b (a1,d2.w),d2 lsl.w #8,d0 lsl.w #4,d1 or.w d1,d0 or.w d2,d0 move.w d0,(a2) addq #4,a2 dbra d7,.fdpl2 .npal: add.w #26,fs_rotatesinus add.w #2,fs_xsinus add.w #12,fs_sinusadd and.w #2046,fs_rotatesinus and.w #2046,fs_xsinus and.w #511,fs_sinusadd lea sinus,a0 move.w fs_xsinus,d1 move.w (a0,d1.w),d2 ext.l d2 move.l fs_pointers,a1 moveq #0,d3 move.w (a1),d3 sub.w #FS_PLANEWIDTH*16,d3 move.l #$8000,d4 divu d3,d4 divs d4,d2 add.w d3,d2 add.w #FS_PLANEWIDTH*16,d2 lsr.w d2 move.w d2,fs_xposition move.w fs_rotatesinus,d0 move.w (a0,d0.w),d2 add.w #$8000,d2 lsr.w #8,d2 move.w d2,fs_rotate tst.b render beq.s .vbiok ; Set the bitplanes ; ----------------- move.l #fs_planes+3*FS_PLANESIZE,d0 add.l fs_planes_add,d0 move.w d0,fs_cl_bpl4ptl swap d0 move.w d0,fs_cl_bpl4pth ; Double buffering ; ---------------- eor.l #FS_PLANES*FS_PLANESIZE,fs_planes_add clr.b render .vbiok: movem.l (sp)+,d1-d4/d7/a1-a2 rts ; Horizon ; ------- horizon: ; Clear memory ; ------------ lea ho_cl,a0 move.l #ho_requirements_chipmem,d7 bsr clearmemory lea ho_planes_add,a0 move.l #ho_requirements_fastmem,d7 bsr clearmemory ; Copy copperlist ; --------------- lea ho_ct,a0 lea ho_cl,a1 move.w #(ho_ct_data2-ho_ct)/4-1,d7 .cplst: move.l (a0)+,(a1)+ dbra d7,.cplst move.w #(64+56)/2-1,d7 .cp1: clr.l (a1)+ dbra d7,.cp1 move.w #(ho_ct_data-ho_ct_data2)/4-1,d7 .cp2: move.l (a0)+,(a1)+ dbra d7,.cp2 move.w #(64+56)/2-1,d7 .cp3: clr.l (a1)+ dbra d7,.cp3 ; Screen setup ; ------------ move.l #ho_plane_empty,d0 lea ho_cl_bpl1pth,a0 moveq #HO_HORIZON_PLANES-1,d7 .setplanesloop: move.w d0,4(a0) swap d0 move.w d0,(a0) swap d0 addq #8,a0 dbra d7,.setplanesloop move.l #ho_planes+(HO_PLANES-1)*HO_PLANESIZE,d0 move.w d0,4(a0) swap d0 move.w d0,(a0) ; Create multiply table ; --------------------- moveq #0,d0 lea ho_mulu_planewidth,a0 move.l #HO_PLANES*HO_PLANEHEIGHT-1,d7 .mulu: move.w d0,(a0)+ add.w #HO_PLANEWIDTH,d0 dbra d7,.mulu ; Create ordered table ; -------------------- lea table_order,a0 lea ho_order,a1 moveq #0,d1 moveq #16-1,d7 .ord1: moveq #0,d3 moveq #16-1,d6 .ord2: move.b (a0)+,d1 move.w d7,d2 addq #1,d2 lsl.w #4,d2 sub.w d1,d2 addx.w d3,d3 dbra d6,.ord2 move.w d3,(a1)+ dbra d7,.ord1 ; Initialize horizon Z positions ; ------------------------------ lea horizon_table,a0 move.w #256,6(a0) move.w #200,18(a0) move.w #144,30(a0) move.w #88,42(a0) ; Find maximum Y value of each horizon ; ------------------------------------ lea horizon_table,a0 .ho_find_maxy_loop: move.l (a0)+,a2 moveq #0,d0 .ho_find_maxy: cmp.w 2(a2),d0 bhi.s .ho_not_max move.w 2(a2),d0 .ho_not_max: addq #4,a2 cmp.l #-1,(a2) bne.s .ho_find_maxy ; Write to horizon table (as the height value) ; -------------------------------------------- move.w d0,(a0)+ addq #6,a0 cmp.l #horizon_end,a0 bcs.s .ho_find_maxy_loop ; Set up copperlist jump addresses ; -------------------------------- move.l #ho_cl_data1,d0 move.w d0,ho_cl_cop2lcl swap d0 move.w d0,ho_cl_cop2lch ; Create fully filled bitplane ; ---------------------------- lea ho_plane_full,a0 move.l #HO_PLANEHEIGHT-1,d7 .full: move.l #-1,(a0)+ move.l #-1,(a0)+ move.l #-1,(a0)+ move.l #-1,(a0)+ move.l #-1,(a0)+ move.l #-1,(a0)+ move.l #-1,(a0)+ move.l #-1,(a0)+ move.l #-1,(a0)+ move.l #-1,(a0)+ dbra d7,.full ; Create gradient helper bitplane ; ------------------------------- lea ho_planes+(HO_PLANES-1)*HO_PLANESIZE,a0 move.l #HO_PLANEHEIGHT/16-1,d7 .grad1: lea ho_order,a1 moveq #16-1,d6 .grad2: moveq #HO_PLANEWIDTH/2-1,d5 .grad3: move.w (a1),(a0)+ dbra d5,.grad3 addq #2,a1 dbra d6,.grad2 dbra d7,.grad1 move.l #$6000,ho_speed move.w ho_gradient,ho_cl_palette+2 move.l #horizon_table,ho_table rts horizon_go: move.l #horizon_main,part_main move.l #horizon_vbi,part_vbi rts horizon_main: ; Clear bitplanes ; --------------- lea custom,a6 move.l #ho_planes,d0 add.l ho_planes_add,d0 ; Clear (ho_clear/2) & $fff0 rows using the CPU and the rest using blt ; -------------------------------------------------------------------- move.w ho_clear+2,d1 move.w d1,d6 move.w d1,d7 lsr.w d7 and.w #$fff0,d7 sub.w d7,d1 lsl.w #6,d1 or.w #HO_PLANEWIDTH/2,d1 moveq #0,d2 waitb move.w #DEST,bltcon0(a6) move.l #-1,bltafwm(a6) move.w d2,bltdmod(a6) move.w d2,bltcon1(a6) move.l d0,bltdpth(a6) move.w d1,bltsize(a6) ; Clear rest of the bitplanes using the CPU ; ----------------------------------------- move.l d0,a0 mulu #HO_PLANEWIDTH,d6 add.l d6,a0 moveq #0,d0 moveq #0,d1 moveq #0,d2 moveq #0,d3 moveq #0,d4 moveq #0,d5 moveq #0,d6 sub.l a1,a1 sub.l a2,a2 sub.l a3,a3 lsr.w #4,d7 subq #1,d7 bmi .noclr .clr: movem.l d0-d6/a1-a3,-(a0) movem.l d0-d6/a1-a3,-(a0) movem.l d0-d6/a1-a3,-(a0) movem.l d0-d6/a1-a3,-(a0) movem.l d0-d6/a1-a3,-(a0) movem.l d0-d6/a1-a3,-(a0) movem.l d0-d6/a1-a3,-(a0) movem.l d0-d6/a1-a3,-(a0) movem.l d0-d6/a1-a3,-(a0) movem.l d0-d6/a1-a3,-(a0) movem.l d0-d6/a1-a3,-(a0) movem.l d0-d6/a1-a3,-(a0) movem.l d0-d6/a1-a3,-(a0) movem.l d0-d6/a1-a3,-(a0) movem.l d0-d6/a1-a3,-(a0) movem.l d0-d6/a1-a3,-(a0) dbra d7,.clr .noclr: ; Calculate zoom values ; --------------------- move.w ho_frames,d1 clr.w ho_frames lea horizon_table,a0 .zoom_loop: sub.w d1,HO_TABLE_Z(a0) cmp.w #31,HO_TABLE_Z(a0) bhi.s .zoom_ok move.l a0,ho_table move.w #256,HO_TABLE_Z(a0) .zoom_ok: move.l #256*HO_PLANEWIDTH*8,d0 divu HO_TABLE_Z(a0),d0 move.w d0,HO_TABLE_ZOOM(a0) add.l #HO_TABLE_SIZE,a0 cmp.l #horizon_end,a0 bcs.s .zoom_loop ; Fade horizon colors ; ------------------- move.l ho_table,a0 lea ho_colors,a1 lea ho_cl_data1+2,a2 add.l ho_cl_data_add,a2 cmp.w #228,HO_TABLE_Z(a0) bcc.s .setc addq #2,a1 .setc: move.w (a1),d0 move.w 4(a1),d1 move.w 8(a1),d2 move.w 12(a1),d3 move.w d0,(a2) move.w d0,60(a2) move.w d1,4(a2) move.w d1,8(a2) move.w d1,64(a2) move.w d1,68(a2) move.w d2,12(a2) move.w d2,16(a2) move.w d2,20(a2) move.w d2,24(a2) move.w d2,72(a2) move.w d2,76(a2) move.w d2,80(a2) move.w d2,84(a2) move.w d3,28(a2) move.w d3,32(a2) move.w d3,36(a2) move.w d3,40(a2) move.w d3,44(a2) move.w d3,48(a2) move.w d3,52(a2) move.w d3,56(a2) move.w d3,88(a2) move.w d3,92(a2) move.w d3,96(a2) move.w d3,100(a2) move.w d3,104(a2) move.w d3,108(a2) move.w d3,112(a2) move.w d3,116(a2) ; Prepare blitter for vertical filling ; ------------------------------------ lea custom,a6 moveq #0,d0 waitb move.w #SRCA|SRCB|DEST|ABC|ABNC|ANBC|ANBNC|NABC|NABNC,bltcon0(a6) move.l d0,bltamod(a6) move.l d0,bltcmod(a6) move.w d0,bltcon1(a6) ; Render each horizon ; ------------------- clr.w ho_pass lea ho_mulu_planewidth,a1 move.l ho_table,a4 lea ho_height,a5 clr.l 8(a5) clr.l 12(a5) .horiz: clr.w (a5) move.l (a4)+,a6 ; Calculate Y coordinate substract (maxy-PLANEHEIGHT)/2 ; ----------------------------------------------------- move.w (a4),d2 mulu 4(a4),d2 lsr.l #8,d2 sub.w #HO_PLANEHEIGHT,d2 bpl.s .subd2 moveq #0,d2 bra.s .subok .subd2: lsr.w d2 .subok: move.w d2,HO_SUBSTRACT(a1) ; Calculate first coordinate pair into the stack ; ---------------------------------------------- move.w (a6)+,d0 move.w (a6)+,d1 move.w 4(a4),d4 muls d4,d0 muls d4,d1 asr.l #8,d0 asr.l #8,d1 add.w #HO_PLANEWIDTH*8/2,d0 sub.w d2,d1 ; Reset minx and maxx values for this horizon ; ------------------------------------------- move.w #HO_PLANEWIDTH*8-1,HO_MINXX(a1) clr.w HO_MAXXX(a1) move.w d1,-(sp) move.w d0,-(sp) .loop: lea ho_planes,a0 add.l ho_planes_add,a0 moveq #0,d0 move.w 8(a5),d0 add.l d0,a0 ; Use previous coordinate pair values from the stack ; -------------------------------------------------- move.w (sp)+,d0 move.w (sp)+,d1 move.w (a6)+,d2 move.w (a6)+,d3 move.w 4(a4),d4 muls d4,d2 muls d4,d3 asr.l #8,d2 asr.l #8,d3 add.w #HO_PLANEWIDTH*8/2,d2 sub.w HO_SUBSTRACT(a1),d3 move.w d3,-(sp) move.w d2,-(sp) bsr VerticalFillLine ; Check if current height (after clipping) has changed ; ---------------------------------------------------- cmp.w (a5),a3 blt.s .nmaxy move.w a3,(a5) .nmaxy: cmp.l #-1,(a6) bne.s .loop ; If the leftmost X coordinate was not 0 draw line from it to 0 ; ------------------------------------------------------------- move.w HO_MINXX(a1),d2 beq.s .nminl ; If no lines were drawn don't draw any lines now either ; ------------------------------------------------------ cmp.w #HO_PLANEWIDTH*8-1,d2 beq.s .nminl move.w HO_MINXY(a1),d3 ; Only draw the line if it's missing from the top of the screen ; ------------------------------------------------------------- bne.s .nminl moveq #0,d0 move.w d3,d1 bsr VerticalFillLineNoClip .nminl: ; If the rightmost X coordinate was not 351 draw line from it to 351 ; ------------------------------------------------------------------ move.w HO_MAXXX(a1),d0 ; If no lines were drawn don't draw any lines now either ; ------------------------------------------------------ beq.s .nmaxl cmp.w #HO_PLANEWIDTH*8-1,d0 beq.s .nmaxl move.w HO_MAXXY(a1),d1 ; Only draw the line if it's missing from the top of the screen ; ------------------------------------------------------------- bne.s .nmaxl move.w #HO_PLANEWIDTH*8-1,d2 move.w d1,d3 bsr VerticalFillLineNoClip .nmaxl: ; Restore stack ; ------------- addq #4,sp ; Calculate plane offsets ; ----------------------- add.w #1,(a5) moveq #0,d0 move.w (a5)+,d0 add.w d0,d0 move.w (a1,d0.w),d0 add.w 6(a5),d0 move.w d0,8(a5) move.w 6(a5),d0 ; Fill the current horizon ; ------------------------ add.l #ho_planes,d0 add.l ho_planes_add,d0 move.l d0,d1 add.l #HO_PLANEWIDTH,d1 .waitb: btst #14,dmaconr+custom bne.s .waitb move.l #-1,bltafwm+custom move.l d1,bltapth+custom move.l d0,bltbpth+custom move.l d1,bltdpth+custom move.w -2(a5),d0 subq #1,d0 beq.s .nblit lsl.w #6,d0 or.w #HO_PLANEWIDTH/2,d0 move.w d0,bltsize+custom .nblit: ; Render all horizons ; ------------------- add.w #1,ho_pass cmp.w #HO_HORIZON_PLANES,ho_pass beq.s .passd addq #8,a4 cmp.l #horizon_end,a4 bcs.w .horiz lea horizon_table,a4 bra.w .horiz .passd: ; Calculate total height to be cleared ; ------------------------------------ move.w ho_clear,ho_clear+2 clr.w ho_clear lea ho_height,a0 moveq #HO_HORIZON_PLANES-1,d7 .cumul: move.w (a0)+,d0 add.w d0,ho_clear dbra d7,.cumul ; Calculate bitplane y positions ; ------------------------------ move.l ho_table,a0 lea ho_height,a1 lea ho_copper,a2 moveq #0,d2 moveq #4,d3 moveq #HO_HORIZON_PLANES-1,d7 .calcy: move.w 4(a0),d0 mulu 8(a0),d0 lsr.l #8,d0 lsr.w d0 move.w #HO_PLANEHEIGHT/2,d1 sub.w d0,d1 bpl.s .pyok moveq #0,d1 .pyok: ; If the height of the horizon is 0 only sky is to be drawn ; --------------------------------------------------------- move.w (a1)+,d0 subq #1,d0 bne.s .heiok move.w #HO_PLANEHEIGHT-1,d1 .heiok: move.w d1,(a2)+ move.w d2,(a2)+ add.w d0,d1 move.w d1,(a2)+ move.w d3,(a2)+ addq #1,d2 addq #1,d3 add.l #12,a0 cmp.l #horizon_end,a0 bcs.s .hotok lea horizon_table,a0 .hotok: dbra d7,.calcy ; Sort Y positions ; ---------------- lea ho_copper,a0 moveq #8,d0 move.l #HO_PLANEHEIGHT,d1 bsr StraightRadixSort ; Check for duplicates ; -------------------- lea ho_copper,a1 moveq #7-1,d7 .dupe1: move.l a1,a0 move.w (a0),d0 .dupe2: addq #4,a0 cmp.l #ho_copper+32,a0 beq.s .dupe3 cmp.w (a0),d0 bne.s .dupe2 add.w #1,(a0) bra.s .dupe2 .dupe3: addq #4,a1 dbra d7,.dupe1 ; Create copperlist ; ----------------- lea ho_cl_data1+120,a0 add.l ho_cl_data_add,a0 lea ho_mulu_planewidth,a1 lea ho_copper,a2 lea ho_height+8,a3 move.l #ho_planes,a4 add.l ho_planes_add,a4 lea ho_gradient,a5 moveq #0,d3 move.w (a5)+,d4 moveq #0,d6 sub.l a6,a6 moveq #HO_HORIZON_PLANES*2-1,d7 .cop: move.w (a2)+,d1 move.w (a2)+,d2 ; Draw gradient if it has not been drawn yet ; ------------------------------------------ .bg: cmp.w #9*HO_GRADIENT_HEIGHT,d3 bhi.s .nobg ; Set bitplane values if they should be set ; ----------------------------------------- cmp.w d3,d1 ble.s .nobg move.w d3,d5 ; Add first Y position (this should match cl_diwstrt) ; --------------------------------------------------- add.w #$28,d5 lsl.w #8,d5 or.w #1,d5 ; If the line has already been waited for don't wait again ; -------------------------------------------------------- cmp.l d5,a6 beq.s .nwait move.w d5,(a0)+ move.w #$fffe,(a0)+ .nwait: move.w #$180,(a0)+ move.w d4,(a0)+ add.w #HO_GRADIENT_HEIGHT,d3 move.w (a5)+,d4 move.w #$1a0,(a0)+ move.w d4,(a0)+ bra.s .bg .nobg: ; Add first Y position (this should match cl_diwstrt) ; --------------------------------------------------- add.w #$28,d1 ; End copperlist if bottom reached ; -------------------------------- cmp.w #$12f,d1 bhi.s .copdn cmp.w #$100,d1 bcs.s .copyo sub.w #$100,d1 tst.w d6 bne.s .copyo move.l #$ffe1fffe,(a0)+ moveq #1,d6 .copyo: lsl.w #8,d1 or.w #1,d1 move.w d1,(a0)+ move.w #$fffe,(a0)+ move.l d1,a6 cmp.w #3,d2 bhi.s .full moveq #0,d0 add.w d2,d2 move.w (a3,d2.w),d0 add.l a4,d0 add.w d2,d2 add.w #bpl1ptl,d2 move.w d2,(a0)+ move.w d0,(a0)+ swap d0 subq #2,d2 move.w d2,(a0)+ move.w d0,(a0)+ dbra d7,.cop bra.s .copdn .full: sub.w #4,d2 add.w d2,d2 add.w d2,d2 add.w #bpl1ptl,d2 move.l #ho_plane_full,d0 move.w d2,(a0)+ move.w d0,(a0)+ swap d0 subq #2,d2 move.w d2,(a0)+ move.w d0,(a0)+ dbra d7,.cop .copdn: move.l #$fffffffe,(a0)+ move.b #1,render rts ; a0: array to sort ; d0: array size in long words ; d1: maximum value in array StraightRadixSort: move.l a0,a4 move.l d0,d6 move.l d1,d5 move.l d0,d4 add.l d4,d4 add.l d4,d4 subq #1,d5 subq #1,d6 lea ho_rs_tempbuffer,a5 lea ho_rs_distcount,a6 ; Clear distribution count ; ------------------------ move.l a6,a0 move.w d5,d7 .clear: clr.b (a0)+ dbra d7,.clear ; Calculate distribution ; ---------------------- moveq #0,d0 move.l a6,a0 move.l a4,a1 move.w d6,d7 .dist: move.w (a1),d0 add.b #1,(a0,d0.w) addq #4,a1 dbra d7,.dist ; Calculate cumulative distribution ; --------------------------------- move.l a6,a0 move.w d5,d7 subq #1,d7 .cumul: move.b (a0)+,d0 add.b d0,(a0) dbra d7,.cumul moveq #0,d0 move.l a6,a0 move.l a4,a1 add.l d4,a1 move.l a5,a2 move.l a1,a3 moveq #0,d1 move.w d6,d7 .spred: subq #4,a3 move.w (a3),d0 move.b (a0,d0.w),d1 subq #1,d1 move.b d1,(a0,d0.w) add.w d1,d1 add.w d1,d1 move.l -(a1),(a2,d1.w) dbra d7,.spred move.l a5,a0 move.l a4,a1 move.w d6,d7 .copy: move.l (a0)+,(a1)+ dbra d7,.copy rts ; Draws a line, one pixel per x position ; -------------------------------------- ; a0: bitplanes ; d0: x1 ; d1: y1 ; d2: x2 ; d3: y2 ; uses d0-d7/a0-a3 VerticalFillLine: ; Clipping test ; ------------- sub.l a2,a2 sub.l a3,a3 .loop: moveq #0,d4 ; code1 moveq #0,d5 ; code2 tst.w d0 bpl.s .x1lok or.w #CLIP_LEFT_EDGE,d4 .x1lok: cmp.w #HO_PLANEWIDTH*8,d0 blt.s .x1rok or.w #CLIP_RIGHT_EDGE,d4 .x1rok: tst.w d1 bpl.s .y1lok or.w #CLIP_TOP_EDGE,d4 .y1lok: cmp.w #HO_PLANEHEIGHT,d1 blt.s .y1rok or.w #CLIP_BOTTOM_EDGE,d4 .y1rok: tst.w d2 bpl.s .x2lok or.w #CLIP_LEFT_EDGE,d5 .x2lok: cmp.w #HO_PLANEWIDTH*8,d2 blt.s .x2rok or.w #CLIP_RIGHT_EDGE,d5 .x2rok: tst.w d3 bpl.s .y2lok or.w #CLIP_TOP_EDGE,d5 .y2lok: cmp.w #HO_PLANEHEIGHT,d3 blt.s .y2rok or.w #CLIP_BOTTOM_EDGE,d5 .y2rok: move.w d4,d6 or.w d5,d6 beq.w .line move.w d4,d6 and.w d5,d6 beq.s .ok sub.l a3,a3 rts .ok: cmp.l #0,a2 bne.s .m2 move.w d3,d6 ; m1=(y2-y1)/(x2-x1) sub.w d1,d6 ext.l d6 asl.l #5,d6 move.w d2,d7 sub.w d0,d7 beq.s .m1 add.l #$3f,d6 divs d7,d6 ext.l d6 move.l d6,a2 .m1: move.w d2,d6 ; m2=(x2-x1)/(y2-y1) sub.w d0,d6 ext.l d6 asl.l #5,d6 move.w d3,d7 sub.w d1,d7 beq.s .m2 add.l #$3f,d6 divs d7,d6 ext.l d6 move.l d6,a3 .m2: tst.w d4 bne.s .clip exg d0,d2 exg d1,d3 exg d4,d5 .clip: btst #0,d4 beq.s .nleft move.l a2,d6 muls d6,d0 asr.l #6,d0 sub.l d0,d1 moveq #0,d0 bra.w .loop .nleft: btst #1,d4 beq.s .nrite sub.l #HO_PLANEWIDTH*8-1,d0 move.l a2,d6 muls d6,d0 asr.l #6,d0 sub.l d0,d1 move.l #HO_PLANEWIDTH*8-1,d0 bra.w .loop .nrite: btst #2,d4 beq.s .ntop cmp.w d0,d2 beq.s .y1 move.l a3,d6 muls d6,d1 asr.l #6,d1 sub.l d1,d0 .y1: moveq #0,d1 bra.w .loop .ntop: btst #3,d4 beq.w .loop cmp.w d0,d2 beq.s .y2 sub.l #HO_PLANEHEIGHT-1,d1 move.l a3,d6 muls d6,d1 asr.l #6,d1 sub.l d1,d0 .y2: move.l #HO_PLANEHEIGHT-1,d1 bra.w .loop .line: ; Check if the coordinates are the leftmost or rightmost ; ------------------------------------------------------ cmp.w HO_MINXX(a1),d0 bcc.s .nmix1 move.w d0,HO_MINXX(a1) move.w d1,HO_MINXY(a1) .nmix1: cmp.w HO_MINXX(a1),d2 bcc.s .nmix2 move.w d2,HO_MINXX(a1) move.w d3,HO_MINXY(a1) .nmix2: cmp.w HO_MAXXX(a1),d0 bls.s .nmax1 move.w d0,HO_MAXXX(a1) move.w d1,HO_MAXXY(a1) .nmax1: cmp.w HO_MAXXX(a1),d2 bls.s .nmax2 move.w d2,HO_MAXXX(a1) move.w d3,HO_MAXXY(a1) .nmax2: ; Return clipped maximum y in a3 ; ------------------------------ move.l d1,a3 cmp.w d1,d3 blt.s .draw move.l d3,a3 .draw: VerticalFillLineNoClip: ; Draw the line ; ------------- move.l #1,a2 cmp.w d0,d2 bge.s .noexg exg d0,d2 exg d1,d3 .noexg: move.w d2,d4 ; dx sub.w d0,d4 move.w d3,d5 ; dy sub.w d1,d5 bpl.s .dyok neg.w d5 move.l #-1,a2 .dyok: cmp.w d4,d5 bgt.s .yline ; dx>=dy ; ------ add.w d5,d5 ; 2dy move.w d5,d6 ; p sub.w d4,d6 add.w d4,d4 ; 2dx neg.w d4 ; 2dy-2dx add.w d5,d4 move.w d0,d3 move.w d0,d7 not.w d7 and.w #7,d7 lsr.w #3,d3 add.w d3,a0 move.w d1,d3 add.w d3,d3 move.w (a1,d3.w),d3 bset.b d7,(a0,d3.w) ; If x1==x2 and y1==y2 don't go to loop ; ------------------------------------- cmp.w d0,d2 bne.s .xloop tst.w d5 beq.s .done .xloop: addq #1,d0 subq #1,d7 bpl.s .nxadd and.l #7,d7 addq #1,a0 .nxadd: tst.w d6 bpl.s .xpos add.w d5,d6 bra.s .xplot .xpos: add.w a2,d1 add.w d4,d6 .xplot: move.w d1,d3 add.w d3,d3 move.w (a1,d3.w),d3 bset.b d7,(a0,d3.w) cmp.w d2,d0 bne.s .xloop .done: rts .yline: ; dy>dx ; ----- exg d4,d5 add.w d5,d5 ; 2dx move.w d5,d6 ; p sub.w d4,d6 add.w d4,d4 ; 2dy neg.w d4 ; 2dx-2dy add.w d5,d4 move.w d0,d2 move.w d0,d7 not.w d7 and.w #7,d7 lsr.w #3,d2 add.w d2,a0 .yloop: tst.w d6 bpl.s .ypos add.w a2,d1 add.w d5,d6 cmp.w d3,d1 bne.s .yloop rts .ypos: move.w d1,d2 add.w d2,d2 move.w (a1,d2.w),d2 bset.b d7,(a0,d2.w) add.w a2,d1 addq #1,d0 subq #1,d7 bpl.s .nyadd and.l #7,d7 addq #1,a0 .nyadd: add.w d4,d6 cmp.w d3,d1 bne.s .yloop rts horizon_vbi: sub.l a0,a0 move.l sc_position,d0 subq #1,d0 and.w #127,d0 cmp.w #32,d0 bcs.s .up cmp.w #56,d0 bcs.s .spdok cmp.w #88,d0 bcs.s .down move.l #$880,a0 bra.s .spdok .up: move.l #$660,a0 bra.s .spdok .down: move.l #-$330,a0 .spdok: move.l ho_speed,d0 add.l d0,ho_frames add.l a0,d0 move.l d0,ho_speed tst.b render beq.s .vbiok ; Use the correct copperlist ; -------------------------- move.l #ho_cl,cop1lch+custom move.w #%0000000000000001+$1000*HO_PLANES,ho_cl_bplcon0+2 move.l #ho_cl_data1,d0 add.l ho_cl_data_add,d0 move.w d0,ho_cl_cop2lcl swap d0 move.w d0,ho_cl_cop2lch ; Double buffering ; ---------------- eor.l #HO_PLANES*HO_PLANESIZE,ho_planes_add eor.l #ho_cl_data2-ho_cl_data1,ho_cl_data_add clr.b render move.w #$ff0,ne_cl_palette+2 .vbiok: rts imageroll: ; Clear memory ; ------------ lea ir_cl,a0 move.l #ir_requirements_chipmem,d7 bsr clearmemory lea ir_copperlist_add,a0 move.l #ir_requirements_fastmem,d7 bsr clearmemory ; Copy copperlist ; --------------- lea ir_ct,a0 lea ir_cl,a1 move.w #(ir_ct_data-ir_ct)/4-1,d7 .cplst: move.l (a0)+,(a1)+ dbra d7,.cplst ; Screen setup ; ------------ move.l #ir_planes,d0 lea ir_cl_bpl1pth,a0 moveq #IR_PLANES-1,d7 .setplanesloop: move.w d0,4(a0) swap d0 move.w d0,(a0) swap d0 addq #8,a0 add.l #IR_PLANEWIDTH,d0 dbra d7,.setplanesloop move.l #ir_cl_data,d0 move.w d0,ir_cl_cop2lcl swap d0 move.w d0,ir_cl_cop2lch ; Decrunch bitmap ; --------------- lea ir_planes+((IR_PLANEHEIGHT-32-IR_SOURCE_HEIGHT)/2+32)*IR_PLANES*IR_PLANEWIDTH,a0 lea ir_picture_stc,a1 bsr decrunch lea ir_planes+((IR_PLANEHEIGHT-32-IR_SOURCE_HEIGHT)/2+32)*IR_PLANES*IR_PLANEWIDTH+IR_SOURCE_HEIGHT*IR_PLANES*IR_PLANEWIDTH,a0 lea ir_cl_palette+2,a1 moveq #16-1,d7 .pallp: move.w (a0),(a1) clr.w (a0)+ addq #4,a1 dbra d7,.pallp move.l #$fffffffe,ir_cl_data move.l #$fffffffe,ir_cl_data+(IR_RADIUS*2*6+2+4+2)*2 ; Use $1a as the starting position because the first 25 lines are for VBI ; ----------------------------------------------------------------------- move.w #$1a+1,ir_y rts imageroll_go: move.l #ir_cl,cop1lch+custom move.l #imageroll_main,part_main move.l #imageroll_vbi,part_vbi rts imageroll_main: lea ir_low,a0 lea ir_high,a1 lea ir_cl_data,a2 add.l ir_copperlist_add,a2 move.w ir_y,d0 move.w d0,d2 ; Current copper wait ; ------------------- lsl.w #8,d0 add.w #$0001,d0 ; Current y position relative to the beginning of the roll ; -------------------------------------------------------- moveq #-1,d1 ; How many pixels are rolled ; -------------------------- move.w #IR_PLANEHEIGHT-IR_MAX+2*IR_RADIUS,d7 sub.w d2,d7 bmi ir_dn ; Only 2*IR_RADIUS pixels can be rolled ; ---------------------------------- cmp.w #2*IR_RADIUS,d7 ble.s .hiok move.w #2*IR_RADIUS,d7 .hiok: ; How many pixels are shown from the "bottom" layer ; ------------------------------------------------- move.w #2*IR_RADIUS,d6 sub.w d7,d6 beq .high add.w d6,a1 subq #1,d6 bmi .high .lowl: moveq #0,d2 move.b (a0)+,d2 move.w d2,d3 ; Delta between current and previous ; ---------------------------------- sub.w d1,d3 ; Store previous ; -------------- move.w d2,d1 ; Calculate modulo ; ---------------- muls #IR_PLANES*IR_PLANEWIDTH,d3 sub.w #IR_PLANEWIDTH,d3 cmp.w #$0001,d0 bne.s .nolw move.l #$ffd1fffe,(a2)+ .nolw: move.w d0,(a2)+ move.w #$fffe,(a2)+ move.w #bpl1mod,(a2)+ move.w d3,(a2)+ move.w #bpl2mod,(a2)+ move.w d3,(a2)+ add.w #$100,d0 dbra d6,.lowl .high: subq #1,d7 bmi .hdone .highl: moveq #0,d2 move.b (a1)+,d2 move.w d2,d3 ; Delta between current and previous ; ---------------------------------- sub.w d1,d3 ; Store previous ; -------------- move.w d2,d1 ; Calculate modulo ; ---------------- muls #IR_PLANES*IR_PLANEWIDTH,d3 sub.w #IR_PLANEWIDTH,d3 cmp.w #$0001,d0 bne.s .nohw move.l #$ffd1fffe,(a2)+ .nohw: move.w d0,(a2)+ move.w #$fffe,(a2)+ move.w #bpl1mod,(a2)+ move.w d3,(a2)+ move.w #bpl2mod,(a2)+ move.w d3,(a2)+ add.w #$100,d0 dbra d7,.highl .hdone: cmp.w #$0001,d0 bne.s .nolw2 move.l #$ffd1fffe,(a2)+ .nolw2: move.w d0,(a2)+ move.w #$fffe,(a2)+ move.w #bplcon0,(a2)+ clr.w (a2)+ move.l #$fffffffe,(a2)+ tst.b ir_direction beq .down cmp.w #$1b,ir_y beq.s ir_dn sub.w #2,ir_y bra.s ir_dn .down: cmp.w #IR_PLANEHEIGHT-IR_MAX+2*IR_RADIUS-1,ir_y bhs.s .wait add.w #2,ir_y bra.s ir_dn .wait: tst.w ir_wait bne.s ir_dn move.w #1,ir_wait ir_dn: move.b #1,render rts imageroll_vbi: tst.w ir_wait beq.s .nwait add.w #1,ir_wait cmp.w #560,ir_wait bcs.s .nwait move.b #1,ir_direction .nwait: tst.b render beq.s .vbiok move.l #ir_cl_data,d0 add.l ir_copperlist_add,d0 move.w d0,ir_cl_cop2lcl swap d0 move.w d0,ir_cl_cop2lch eor.l #(IR_RADIUS*2*6+2+4+2)*2,ir_copperlist_add clr.b render move.w #$fff,ne_cl_palette+2 .vbiok: rts insaneplasma: ; Clear memory ; ------------ lea ip_cl,a0 move.l #ip_requirements_chipmem,d7 bsr clearmemory lea ip_copperadd,a0 move.l #ip_requirements_fastmem,d7 bsr clearmemory ; Copy copperlist ; --------------- lea ip_ct,a0 lea ip_cl,a1 move.w #(ip_ct_data1-ip_ct)/4-1,d7 .cpl1: move.l (a0)+,(a1)+ dbra d7,.cpl1 move.w #(ip_cl_2-ip_cl_data1)/4-1,d7 .cpl2: clr.l (a1)+ dbra d7,.cpl2 move.w #(ip_ct_data2-ip_ct_2)/4-1,d7 .cpl3: move.l (a0)+,(a1)+ dbra d7,.cpl3 move.w #(ip_planes-ip_cl_data2)/4-1,d7 .cpl4: clr.l (a1)+ dbra d7,.cpl4 ; Screen setup ; ------------ move.l #ip_planedata,d0 move.l d0,d1 add.l #4*IP_PLANEWIDTH,d1 lea ip_cl_bpl1pth1,a0 lea ip_cl_bpl1pth2,a1 moveq #4-1,d7 .setplanesloop1: move.w d0,4(a0) move.w d1,4(a1) swap d0 swap d1 move.w d0,(a0) move.w d1,(a1) swap d0 swap d1 addq #8,a0 addq #8,a1 add.l #IP_PLANEWIDTH,d0 add.l #IP_PLANEWIDTH,d1 dbra d7,.setplanesloop1 move.l #ip_planes,d0 lea ip_cl_bpl2pth,a0 moveq #2-1,d7 .setplanesloop2: move.w d0,4(a0) swap d0 move.w d0,(a0) swap d0 addq #8,a0 add.l #IP_PLANESIZE,d0 dbra d7,.setplanesloop2 ; Create copperlist ; ----------------- lea ip_cl_data1,a0 lea ip_cl_data2,a1 move.l #$3401,d0 move.l #ip_planedata+3*IP_PLANEWIDTH,d1 move.l d1,d2 add.l #4*IP_PLANEWIDTH,d2 move.l #ip_copperdata,d3 move.l #ip_cl,d4 move.l #IP_PLANEHEIGHT-1,d7 .loop: ; Extra copper wait at $ffc1 ; -------------------------- cmp.w #$0001,d0 bne.s .d0ok move.l #$ffd1fffe,(a0)+ move.l #$ffd1fffe,(a1)+ .d0ok: ; Copper wait ; ----------- move.w d0,(a0)+ move.w d0,(a1)+ move.w #$fffe,(a0)+ move.w #$fffe,(a1)+ ; Reset bitplane 6 address ; ------------------------ move.w #bpl6ptl,(a0)+ move.w #bpl6ptl,(a1)+ move.w d1,(a0)+ move.w d2,(a1)+ move.w #bpl6pth,(a0)+ move.w #bpl6pth,(a1)+ swap d1 swap d2 move.w d1,(a0)+ move.w d2,(a1)+ swap d1 swap d2 ; Set copper jump address ; ----------------------- move.w #cop2lcl,(a0)+ move.w #cop2lcl,(a1)+ move.w d3,(a0)+ move.w d3,(a1)+ move.w #cop2lch,(a0)+ move.w #cop2lch,(a1)+ swap d3 move.w d3,(a0)+ move.w d3,(a1)+ swap d3 ; Set copper return address ; ------------------------- move.l a0,d5 move.l a1,d6 add.l #12,d5 add.l #12,d6 move.w #cop1lcl,(a0)+ move.w #cop1lcl,(a1)+ move.w d5,(a0)+ move.w d6,(a1)+ move.w #cop1lch,(a0)+ move.w #cop1lch,(a1)+ swap d5 swap d6 move.w d5,(a0)+ move.w d6,(a1)+ move.w #copjmp2,(a0)+ move.w #copjmp2,(a1)+ clr.w (a0)+ clr.w (a1)+ add.w #$100,d0 dbra d7,.loop move.w #bplcon0,(a0)+ move.w #bplcon0,(a1)+ move.w #1,(a0)+ move.w #1,(a1)+ move.w #cop1lcl,(a0)+ move.w #cop1lcl,(a1)+ move.w d4,(a0)+ move.w d4,(a1)+ move.w #cop1lch,(a0)+ move.w #cop1lch,(a1)+ swap d4 move.w d4,(a0)+ move.w d4,(a1)+ swap d4 move.l #$fffffffe,(a0)+ move.l #$fffffffe,(a1)+ lea table_fade+16,a0 lea ip_copperdata,a3 moveq #16-1,d6 .cpdt2: sub.l a4,a4 moveq #16-1,d7 .cpdt1: lea ip_palette1,a1 lea ip_palette2,a2 move.w a4,d4 mulu d6,d4 lsr.w #4,d4 move.w d4,a5 move.w #15,d5 sub.w d6,d5 move.w a4,d4 mulu d5,d4 lsr.w #4,d4 move.w d4,a6 ; Colors for bitplanes 1,3,5 while 2==1, 4==0 ; ------------------------------------------- move.w #$184,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$186,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$18c,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$18e,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$1a4,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$1a6,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$1ac,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$1ae,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ ; Colors for bitplanes 1,3,5 while 2==0, 4==1 ; ------------------------------------------- move.w #$190,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$192,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$198,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$19a,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$1b0,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$1b2,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$1b8,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$1ba,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ ; Colors for bitplanes 1,3,5 while 2==1, 4==1 ; ------------------------------------------- move.w #$194,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$196,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$19c,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$19e,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$1b4,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$1b6,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$1bc,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ move.w #$1be,(a3)+ move.w a5,d3 move.w (a1)+,d0 bsr multiplycolor move.w d0,d4 move.w a6,d3 move.w (a2)+,d0 bsr multiplycolor add.w d4,d0 move.w d0,(a3)+ ; Jump back to the original copperlist ; ------------------------------------ move.w #copjmp1,(a3)+ clr.w (a3)+ addq #1,a4 dbra d7,.cpdt1 dbra d6,.cpdt2 ; Create copperlist pointers ; -------------------------- lea ip_copperdata,a0 lea ip_copperptr,a1 move.l #16*16-1,d7 .cpptr: move.l a0,(a1)+ lea 25*2*2(a0),a0 dbra d7,.cpptr ; Decrunch bitmap ; --------------- lea ip_planes,a0 lea ip_image_stc,a1 bsr decrunch ; Set copperlist ; -------------- move.l #ip_cl_1,d0 move.w d0,ip_cl_cop1lcl swap d0 move.w d0,ip_cl_cop1lch lea sinus,a0 lea ip_sinus,a1 move.w #1024-1,d7 .sinus: move.w (a0)+,d0 add.w #$8000,d0 lsr.w #8,d0 lsr.w #3,d0 move.w d0,(a1)+ dbra d7,.sinus move.w #$0544,ip_xsinus11 move.w #$018c,ip_xsinus12 move.w #$04dc,ip_xsinus21 move.w #$06e2,ip_xsinus22 move.w #$0624,ip_ysinus11 move.w #$0676,ip_ysinus12 move.w #$0170,ip_ysinus21 move.w #$039e,ip_ysinus22 move.b #1,ip_set rts insaneplasma_go: move.l #ip_cl,cop1lch+custom move.l #insaneplasma_main,part_main move.l #insaneplasma_vbi,part_vbi rts insaneplasma_main: ; X loop: create a row of funky chunky ; ------------------------------------ lea ip_sinus,a0 lea ip_chunky,a1 moveq #2,d0 add.w ip_zoom,d0 move.w d0,a2 mulu #IP_PLANEWIDTH*8/2,d0 move.w d0,a3 move.w ip_xsinus11,d0 move.w ip_xsinus21,d1 move.w (a0,d0.w),d0 move.w (a0,d1.w),d1 lsl.w #4,d0 lsl.w #4,d1 add.w ip_xsinus12,d0 add.w ip_xsinus22,d1 sub.w a3,d0 sub.w a3,d1 move.w #2046,d2 move.w #IP_PLANEWIDTH-1,d7 .xloop: rept 8 and.w d2,d0 and.w d2,d1 move.w (a0,d0.w),d6 add.w (a0,d1.w),d6 lsr.w #2,d6 move.b d6,(a1)+ add.w a2,d0 add.w a2,d1 endr dbra d7,.xloop ; Y loop: set copper jump addresses ; --------------------------------- moveq #2,d0 add.w ip_zoom,d0 move.w d0,a3 mulu #IP_PLANEHEIGHT/2,d0 move.w d0,a4 lea ip_cl_data1,a1 add.l ip_copperadd,a1 lea ip_copperptr,a2 move.w ip_ysinus11,d0 move.w ip_ysinus21,d1 move.w (a0,d0.w),d0 move.w (a0,d1.w),d1 lsl.w #4,d0 lsl.w #4,d1 add.w ip_ysinus12,d0 add.w ip_ysinus22,d1 sub.w a4,d0 sub.w a4,d1 move.w #2046,d2 move.w #$3c,d3 move.l #IP_PLANEHEIGHT/16-1,d7 .yloop: moveq #16-1,d6 .iloop: and.w d2,d0 and.w d2,d1 cmp.w #$ffd1,(a1) bne.w .nskip addq #4,a1 .nskip: move.w (a0,d0.w),d5 add.w (a0,d1.w),d5 and.w d3,d5 move.l (a2,d5.w),d5 move.w d5,14(a1) swap d5 move.w d5,18(a1) add.w a3,d0 add.w a3,d1 lea 32(a1),a1 dbra d6,.iloop lea 64(a2),a2 dbra d7,.yloop moveq #8-1,d6 .rloop: and.w d2,d0 and.w d2,d1 move.w (a0,d0.w),d5 add.w (a0,d1.w),d5 and.w d3,d5 move.l (a2,d5.w),d5 move.w d5,14(a1) swap d5 move.w d5,18(a1) add