home *** CD-ROM | disk | FTP | other *** search
- ; \|/
- ; O O
- ; --------------------------------oOO--U--OOo--------------------------------
- ; | |
- ; | Jelly Bubbles. |
- ; | By Alain BROBECKER. (as Baah) |
- ; | |
- ; ---------------------------------------------------------------------------
- ;
- ; Parameter for this effect.
- ; A variable called bubble_time.
- ; r0=adress of a buffer for xleft-xright tables.
- ;
- ; * This effect, though nice, is not really interesting. This is not real
- ; 3d, and movements are not realistic, so I won' t comment it too much. The
- ; only things you may appreciate are...
- ; 1) Clipping, achieved by putting the good values in the xleft-xright
- ; edges lookup table when x<0 or x>319.
- ; 2) The axial ellipses routine. I' m ashamed to say that it is based
- ; upon precalculations, so it is not all that interesting.
- ; * The background must be filled with 0, and all colors must be black.
- ; NOTATIONS...
- ; r for radius.
- ; b for bubble.
- ; r for reflex.
- ; s for shadow.
- ; x for x coord.
- ; y for y coord.
- ; For example rxr = x coord of reflex radius.
- ; yb = y coord of bubble. (its center, then)
-
-
- #set clip_nb = 192 ; Nb of clipped pixels for filling.
- #set dist_user = 450 ; Distance between user and screen.
- #set dist_user2 = 8 ; The shift for dist_user.
- #set obj_radius = 200 ; Radius of group of bubbles.
- #set rad_b = 70 ; Radius of bubble.
- #set rad_r = 12 ; Radius of reflex.
- #set pos_r = 35 ; Dist betweem bubble and reflex centers.
- #set y_ground = 90
- #set recenter_y = 129
-
- .bubble_part
- stmfd r13!,{r0-r12,r14}
-
- ; Creates tables for converting x values to mask+offset. This tables will
- ; be used for a str hline filling routine in Mode9. You must note that
- ; the clipping is achieved by saving, for x<0 and x>319, masks+offsets which
- ; won' t affect the filling. (ie mask is null, and offset is -4 or 160)
- mov r1,#clip_nb ; Nb of clipped pixels.
- add r2,r0,r1,lsl #4
- add r2,r2,#320*8 ; r2 points on xright table.
- sub r3,r2,r1,lsl #3 ; r3 points on right clipping of xleft.
- add r4,r2,#320*8
- add r4,r4,r1,lsl #3 ; r4 points on right clipping of xright.
- mov r5,#0 ; Null mask.
- mov r6,#-4 ; Offsets for clipped pixels.
- mov r7,#160
- ._make_clipped_pixels_one
- stmia r0!,{r5,r6} ; Save left clipped pixels.
- stmia r2!,{r5,r6}
- stmia r3!,{r5,r7} ; Save right clipped pixels.
- stmia r4!,{r5,r7}
- subS r1,r1,#1
- bNE _make_clipped_pixels_one
- mov r1,r4 ; r1=r4 points after the two tables.
- mov r3,r0 ; Don' t modify r0 and r2, which are
- mov r4,r2 ; pointing on visibles pixels in tables.
- mov r5,#40 ; 40 sets of 8 pixels.
- mov r9,#0 ; r9=offset.
- ._make_eight_pixels
- mov r6,#&ffffffff ; Mask of xleft pixel.
- mov r8,#8 ; 8 pixels per long.
- ._make_one_pixel
- stmia r3!,{r6,r9} ; Save mask_left | offset.
- mov r6,r6,lsl #4 ; Mask for next xleft pixel.
- mvn r7,r6 ; Mask for current xright pixel.
- stmia r4!,{r7,r9} ; Save mask_right | offset.
- subS r8,r8,#1 ; One pixel done.
- bNE _make_one_pixel
- add r9,r9,#4 ; Next offset.
- subS r5,r5,#1 ; One long donr.
- bNE _make_eight_pixels
- str r0,bb_xleft_ad ; Save adresses.
-
- ;---- Now the demo really begins! -------------------------------------------
- adr r2,_bubbles_colors ; Set colors.
- bl set_palette
- bl get_showscreen ; r0=showscreen adress.
- bl bubble_design1 ; Let' s have nice transitions.
- bl get_workscreen
- bl bubble_clear ; Clear screen.
-
- ._one_frame
- bl wait_and_swap ; Wait vsync, swap screens, r0=workscreen.
- bl bubble_clear ; Clear screen.
-
- adr r1,_bubbles_parameters
- adr r2,_new_parameters
- adr r3,bss+sin_cos_ad
- adr r4,bss+inv_ad
- mov r5,#6 ; 6 bubbles.
- ._calc_one_bubble
- ldmia r1,{r6-r7} ; Load gel_pos and angle.
- subS r7,r7,#3 ; Decrement angle.
- movMI r7,#511
- add r6,r6,#1 ; Increment gel_pos.
- cmp r6,#120 ; Flags=gel_pos-120.
- subPL r6,r6,#120
- stmia r1!,{r6-r7} ; Store new parameters.
- ldr r8,[r3,r7,lsl #2] ; r8=65536*sin(angle).
- add r7,r7,#128
- ldr r7,[r3,r7,lsl #2] ; r7=65536*cos(angle).
- mov r9,#obj_radius
- mul r8,r9,r8 ; r8=65536*obj_radius*sin.
- mul r7,r9,r7 ; r7=65536*obj_radius*cos.
- ldr r9,_x_object
- add r7,r9,r7,asr #16 ; r7=new_x.
- ldr r9,_z_object
- add r9,r9,#dist_user
- add r8,r9,r8,asr #16 ; r8=new_z+dist_user.
- str r8,[r2],#4 ; Save z of bubble.
- ldr r8,[r4,r8,lsl #2] ; r8=65536/(z+dist_user).
- mul r7,r8,r7 ; r7=x*65536/(z+dist_user).
- mov r7,r7,asr #dist_user2 ; r7=xb.
- str r7,[r2],#4 ; Save xb of bubble.
- adr r9,_gel_mvts
- add r6,r6,r6,lsl #1 ; r6=gel_pos*3.
- add r6,r9,r6,lsl #2 ; r6 points on good gel pos...
- ldmia r6,{r6,r9,r10} ; Load y,mulx,muly.
- mul r6,r8,r6 ; r6=y*65536/(z+dist_user).
- mov r6,r6,asr #dist_user2 ; r6=yb.
- str r6,[r2],#4 ; Save yb of bubble.
- mov r11,#pos_r
- mul r12,r10,r11 ; r12=65536*muly*pos_r.
- mov r12,r12,asr #16
- mul r11,r9,r11 ; r11=65536*mulx*pos_r.
- mov r11,r11,asr #16
- mul r11,r8,r11 ; r11=mulx*pos_r/(z+dist_user).
- mov r11,r11,asr #dist_user2
- add r11,r11,r7 ; r11=xb+...=xr.
- mul r12,r8,r12 ; r12=muly*pos_r/(z+dist_user).
- mov r12,r12,asr #dist_user2
- sub r12,r6,r12 ; r12=yb-...=yr.
- stmia r2!,{r11,r12} ; Save xr and yr.
- mov r6,#y_ground
- mul r6,r8,r6 ; r6=y_ground*65536/(z+dist_user).
- mov r6,r6,asr #dist_user2
- str r6,[r2],#4 ; Save ys.
- mov r6,#rad_b
- mul r6,r9,r6 ; r6=65536*mulx*rad_b.
- mov r6,r6,asr #16
- mul r7,r8,r6 ; r7=mulx*rad_b/(z+dist).
- mov r7,r7,asr #dist_user2
- str r7,[r2],#4 ; Save rxb.
- mov r7,#rad_b
- mul r7,r10,r7 ; r7=65536*muly*rad_b.
- mov r7,r7,asr #16
- mul r7,r8,r7 ; r7=muly*rad_b/(z+dist).
- mov r7,r7,asr #dist_user2
- str r7,[r2],#4 ; Save ryb.
- mov r7,#rad_r
- mul r7,r9,r7 ; r7=65536*mulx*rad_r.
- mov r7,r7,asr #16
- mul r7,r8,r7 ; r7=mulx*rad_r/(z+dist).
- mov r7,r7,asr #dist_user2
- str r7,[r2],#4 ; Save rxr.
- mov r7,#rad_r
- mul r7,r10,r7 ; r7=65536*muly*rad_r.
- mov r7,r7,asr #16
- mul r7,r8,r7 ; r7=muly*rad_r/(z+dist).
- mov r7,r7,asr #dist_user2
- str r7,[r2],#4 ; Save ryr.
- ldr r7,[r2,#-40] ; Load z+dist_user.
- add r6,r7,r6 ; r6=z+dist_user+rad_b*mulx.
- ldr r6,[r4,r6,lsl #2] ; r6=65536/(...).
- mov r7,#y_ground
- mul r7,r6,r7 ; r7=y_ground/(...).
- mov r7,r7,asr #dist_user2
- ldr r6,[r2,#-20] ; r6=ys.
- sub r7,r6,r7
- str r7,[r2],#4 ; Save rys.
- subS r5,r5,#1
- bNE _calc_one_bubble
-
- ._print_shadows
- adr r10,_new_parameters
- mov r11,#6
- mov r1,#&33333333
- ._one_shadow
- ldr r2,[r10,#4]
- add r2,r2,#159
- ldr r3,[r10,#20]
- add r3,r3,#recenter_y
- ldr r4,[r10,#24]
- ldr r5,[r10,#40]
- bl ellipse
- add r10,r10,#44
- subS r11,r11,#1
- bNE _one_shadow
-
- ._print_bubbles
- adr r11,_bubbles_patterns
- mov r12,#6
- ._search_zmax
- adr r10,_new_parameters
- mov r9,#0 ; r9=zmax.
- mov r8,#0
- ._search_z_one
- ldr r7,[r10],#44
- cmp r9,r7 ; Flags=zmax-z?
- movMI r6,r8 ; Then say which bubble is max.
- movMI r9,r7 ; And new zmax.
- add r8,r8,#1
- cmp r8,#6
- bNE _search_z_one
- ._zmax_found
- adr r10,_new_parameters
- add r9,r11,r6,lsl #3 ; r9 points on bubble colours.
- add r7,r6,r6,lsl #2 ; r7=pos*5.
- add r6,r6,r7,lsl #1 ; r6=pos*11.
- add r10,r10,r6,lsl #2 ; r10 points on bubble.
- mov r6,#0
- str r6,[r10],#4 ; Bubble done.
- ldr r1,[r9],#4 ; Colour.
- ldr r2,[r10],#4 ; xb.
- add r2,r2,#159
- ldr r3,[r10],#4 ; yb.
- add r3,r3,#recenter_y
- ldr r4,[r10,#12] ; rxb.
- ldr r5,[r10,#16] ; ryb.
- bl ellipse
- ldr r1,[r9]
- ldr r2,[r10],#4 ; xr.
- add r2,r2,#159
- ldr r3,[r10],#4 ; yr.
- add r3,r3,#recenter_y
- ldr r4,[r10,#12] ; rxr.
- ldr r5,[r10,#16] ; ryr.
- bl ellipse
- subS r12,r12,#1 ; One bubble drawn.
- bNE _search_zmax
-
- ; Now, we go on with the bubbles lateral movements.
- bl read_time ; r0=time elapsed.
- ldr r1,_x_object ; X movements.
- cmp r1,#0
- addMI r1,r1,#4 ; If x<0 then we add 4 to x so that the
- strMI r1,_x_object ; bubbles enter the screen.
- bMI _one_frame
- cmp r0,#bubble_time ; Time elapsed?
- bLE _one_frame
- add r1,r1,#4 ; If time has passed, we add 4 to x,
- str r1,_x_object ; so that bubles go out of screen.
- cmp r1,#600
- bMI _one_frame
-
- bl get_showscreen ; r0=showscreen adress.
- bl bubble_design2
-
- ldmfd r13!,{r0-r12,pc} ; Bye...
-
- ; ===========================================================================
- ; = =
- ; = MAIN DATAS =
- ; = =
- ; ===========================================================================
-
- ._bubbles_colors
- dcb &00,&00,&00,&50,&50,&50,&40,&40,&40,&30,&30,&30
- dcb &50,&00,&00,&80,&00,&00,&00,&40,&00,&00,&60,&00
- dcb &00,&00,&60,&00,&00,&b0,&50,&50,&00,&70,&70,&00
- dcb &50,&00,&50,&80,&00,&80,&00,&50,&50,&00,&70,&70
-
- ._bubbles_parameters
- dcd 0,0 ; Gel pos and angle...
- dcd 60,85
- dcd 20,171
- dcd 80,256
- dcd 40,341
- dcd 100,427
-
- ._bubbles_patterns
- dcd &44444444,&55555555 ; Colours of bubble and reflex.
- dcd &aaaaaaaa,&bbbbbbbb
- dcd &66666666,&77777777
- dcd &eeeeeeee,&ffffffff
- dcd &88888888,&99999999
- dcd &cccccccc,&dddddddd
-
- ._x_object
- dcd -600
- ._z_object
- dcd 0
-
- ._new_parameters ; Here are saved...
- dbd 66 ; z|xb|yb|xr|yr|ys|rxb|ryb|rxr|ryr|rys.
-
- ._gel_mvts
- incbin Datas.Movements
-
- .bb_xleft_ad ; Will contain adresses of the tables.
- dcd 0
-
- ; ===========================================================================
- ; ===========================================================================
- ; = =
- ; = ROUTINES =
- ; = =
- ; ===========================================================================
- ; ===========================================================================
-
-
- ; ***************************************************************************
- ; ***** *****
- ; ***** Routine which draws a simple ellipse. *****
- ; ***** By Alain BROBECKER. (as Baah) *****
- ; ***** 27-28 september 1994. *****
- ; ***** *****
- ; ***************************************************************************
- ;
- ; >-------------------------------------------------------------------------<
- ; Parameters of this routine...
- ; r0=videoram adress.
- ; r1=fill_pattern.
- ; r2=x of the center.
- ; r3=y of the center.
- ; r4=radius_x.
- ; r5=radius_y.
- ; >-------------------------------------------------------------------------<
- ;
- ; The routine uses symmetry and 8 Kb of precalcs. The precalcs are organised
- ; into two tables. The first table contains, for each circle radius,
- ; the succession of the increments to go from one x to another, when you
- ; change from one hline to another. The second table contains the offset
- ; of the circles tables, since their size are not constant.
- ; Routine is x clipped but not y clipped.
- ; The radius_x of the bubble must not exceed 127.
- ; Routine is made for mode9.
-
- .ellipse
- stmfd r13!,{r0-r12,r14}
- str r13,_old_stack
- addS r6,r2,r4 ; r6=x+radius_x.
- bMI _end_ellipse ; Don' t draw if x+radius_x<0.
- sub r6,r2,r4 ; r6=x-radius_x.
- cmp r6,#320 ; Flags=x-radius_x-320.
- bPL _end_ellipse ; Don' t draw if x-radius_x>319.
- add r3,r3,r3,lsl #2 ; r3=y*5.
- add r0,r0,r3,lsl #5 ; r0 points on y*160.
- mov r3,r0 ; For the symmetry.
- adr r6,_circles
- adr r7,_circles_offsets
- ldr r7,[r7,r4,lsl #2] ; r7=offset for the circle of radius x.
- add r6,r6,r7 ; r6 points on the good circle.
- adr r7,bss+inv_ad
- ldr r5,[r7,r5,lsl #2] ; r5=65536/radius_y.
- mul r5,r4,r5 ; r5=65536*(radius_x/radius_y).
- mov r4,r4,lsl #16 ; r4=65536*radius_x.
- add r4,r4,#&8000 ; Nicer with r4=65536*(radius_x+0.5).
- ldr r7,bb_xleft_ad
- ._two_lines
- ldrB r8,[r6,r4,lsr #16] ; Load x.
- add r9,r2,r8 ; r9=x_center+x=xmax.
- sub r8,r2,r8 ; r8=x_center-x=xmin.
- add r8,r7,r8,lsl #3 ; r8 points on xmin.
- add r9,r7,r9,lsl #3
- add r9,r9,#8*(320+(2*clip_nb)) ; r9 points on xmax.
- ldmia r8,{r8,r10} ; Load masks+offsets.
- ldmia r9,{r9,r11}
- subS r11,r11,r10 ; r11=(nb_longs_2_draw-1)*4.
- add r12,r10,r0 ; r12 points on first word.
- add r10,r10,r3 ; The same for symmetry.
- bEQ _melted
- ._normal_fill
- ldr r13,[r12] ; Load longs.
- ldr r14,[r10]
- bic r13,r13,r8 ; r13=long and not(mask).
- bic r14,r14,r8
- and r8,r8,r1 ; r8=mask and fill_pattern.
- orr r13,r13,r8
- orr r14,r14,r8
- str r13,[r12],#4 ; Store longs.
- str r14,[r10],#4
- rsb r8,r11,#33*4 ; r8=(33-(nb_longs-1))*4.
- add pc,pc,r8,lsl #1 ; Pass 2*... instructions.
- mov r0,r0 ; Paglop.
- #rept 32
- str r1,[r12],#4
- str r1,[r10],#4
- #endr
- ldr r13,[r12] ; Load last longs.
- ldr r14,[r10]
- bic r13,r13,r9 ; r13=long and not(mask).
- bic r14,r14,r9
- and r9,r9,r1 ; r9=mask and fill_pattern.
- orr r13,r13,r9
- orr r14,r14,r9
- str r13,[r12] ; Store longs.
- str r14,[r10]
- add r0,r0,#160 ; Next line.
- sub r3,r3,#160
- subS r4,r4,r5 ; Points on next radius to use.
- bPL _two_lines
- ldr r13,_old_stack
- ldmfd r13!,{r0-r12,pc}
-
- ._melted
- and r8,r8,r9 ; mask=mask_left and mask_right.
- ldr r13,[r12] ; Load longs.
- ldr r14,[r10]
- bic r13,r13,r8 ; r13=long and not(mask).
- bic r14,r14,r8
- and r8,r8,r1 ; r8=mask and fill_pattern.
- orr r13,r13,r8
- orr r14,r14,r8
- str r13,[r12] ; Store longs.
- str r14,[r10]
- add r0,r0,#160 ; Next line.
- sub r3,r3,#160
- subS r4,r4,r5 ; Points on next radius to use.
- bPL _two_lines
- ._end_ellipse
- ldr r13,_old_stack
- ldmfd r13!,{r0-r12,pc}
-
- ._old_stack
- dcd 0
- ._circles
- incbin Datas.Circles
- ._circles_offsets
- incbin Datas.Circle_off
-
- ;****************************************************************************
- ; BUBBLE CLEAR
- ;****************************************************************************
- ; The screen is cleared with 140 lines in color 1, and the rest in color 2.
- ; r0 points on the Mode9 screen.
-
- .bubble_clear
- stmfd r13!,{r1-r12,r14}
- str r13,_old_stack
- mov r1,#&11111111
- mov r2,r1:mov r3,r2:mov r4,r3:mov r5,r4:mov r6,r5:mov r7,r6:mov r8,r7
- mov r9,r8:mov r10,r9:mov r11,r10:mov r12,r11:mov r13,r12
- mov r14,#10
- ._clear_many1
- str r14,_counter
- mov r14,r13 ; Here, r1-r14=fill pattern.
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- ldr r14,_counter
- subS r14,r14,#1
- bNE _clear_many1
- ; Fill second part of the screen.
- mov r1,#&22222222
- mov r2,r1:mov r3,r2:mov r4,r3:mov r5,r4:mov r6,r5:mov r7,r6:mov r8,r7
- mov r9,r8:mov r10,r9:mov r11,r10:mov r12,r11:mov r13,r12
- mov r14,#10
- ._clear_many2
- str r14,_counter
- mov r14,r13 ; Here, r1-r14=fill pattern.
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- ldr r14,_counter
- subS r14,r14,#1
- bNE _clear_many2
- mov r14,r13
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}
- stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r14}:stmia r0!,{r1-r6}
- sub r0,r0,#160*256 ; Restore r0.
- ldr r13,_old_stack
- ldmfd r13!,{r1-r12,pc}
- ._old_stack
- dcd 0
- ._counter
- dcd 0
-
- ;****************************************************************************
- ; Those two routines are made to let the background appear in a nice way.
- ; I don' t comment them, they are dull, boring, tedious, stupid and so on.
- ; r0=videoram adress.
- .bubble_design1
- stmfd r13!,{r0-r12,r14}
- mov r12,r0
- add r11,r0,#(140*160)+156
- mov r3,#&11111111
- mov r4,#&22222222
- mov r5,#40
- ._one_vbl
- mov r0,#&13 ; Wait for Vsync.
- swi OS_Byte
- mov r6,r12
- add r12,r12,#4
- mov r7,r11
- sub r11,r11,#4
- mov r8,#140
- ._fill1
- str r3,[r6],#160
- subS r8,r8,#1
- bNE _fill1
- mov r8,#116
- ._fill2
- str r4,[r7],#160
- subS r8,r8,#1
- bNE _fill2
- subS r5,r5,#1
- bNE _one_vbl
- ldmfd r13!,{r0-r12,pc}
-
- .bubble_design2
- stmfd r13!,{r0-r12,r14}
- mov r12,r0
- add r11,r0,#(140*160)+156
- mov r10,#160*256
- mov r3,#&0
- mov r4,#40
- ._one_vbl
- mov r0,#&13 ; Wait for Vsync.
- swi OS_Byte
- mov r5,r12
- add r12,r12,#4
- mov r6,r11
- sub r11,r11,#4
- mov r7,#140
- ._fill1
- str r3,[r5],#160
- subS r7,r7,#1
- bNE _fill1
- mov r7,#116
- ._fill2
- str r3,[r6],#160
- subS r7,r7,#1
- bNE _fill2
- subS r4,r4,#1
- bNE _one_vbl
- ldmfd r13!,{r0-r12,pc}
-
-