; Copyright 2002 Tematic Ltd ; ; Licensed under the Apache License, Version 2.0 (the "License"); ; you may not use this file except in compliance with the License. ; You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an "AS IS" BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; ; ; MB 23/3/98 ; Complete reimplementation of tiling code based on 3DPatch sources ; ;------------------------------------------------------------------------------- ; Window background drawing code ;------------------------------------------------------------------------------- DCB "MIB",0 ; this is a 'signed' division macro MACRO $lab DivRemS $ra,$rb,$rc,$tmp $lab CMP $rb,#0 BLT %FT2 DivRem $ra,$rb,$rc,$tmp B %FT4 2 RSB $rb,$rb,#0 DivRem $ra,$rb,$rc,$tmp RSB $rb,$rb,#0 ; modulus should be -ve if divisor is -ve 4 MEND ; plotspritebackground ; ; plot the textured background in a window ; ; on entry : r0 = window background colour ; r6-r9 = window visible area coords ; r10 = internal window block pointer ; ; on exit: all regs preserved ; ROUT plotspritebackground Push "r0-r5,lr" Debug tiling,"Enterring plotspritebackground",r0,r6,r7,r8,r9,r10 cmp r0,#15 bhi %FT02 [ TrueIcon3 ldrb r14,[handle,#w_flags2] ; if using true colours for window backgrounds and this window has a custom tst r14,#wf2_truecolour ; background colour then don't plot a tile, just clear the background bne %FT02 ] mov r5,r0 ; r5 = window bg colour ldr r0,[handle,#w_taskhandle] cmp r0,#-1 ; if the current window is a menu bne %FT01 ldr r1,ThreeDFlags tst r1,#ThreeDFlags_TexturedMenus ; check if menu textures are enabled beq %FT02 tst r1,#ThreeDFlags_UseAlternateMenuTexture ; then check which texture to use movne r5,#16 moveq r5,#1 01 Debug tiling,"Calling TileWindowBackground" bl TileWindowBackground ; Debug tiling,"Calling PlotWindowBorders" ; bl PlotWindowBorders Pull "r0-r5,PC" 02 swi OS_WriteI + 16 Pull "r0-r5,PC" ploticonbackgroundsprite Push "r0-y1,lr" ldr x0,thisCBptr ldr y0,spritename ldr x1,lengthflags Push "x0-x1" adr r14,clipx0 ldmia r14,{x0-y1} Push "x0-y1" ; save the current clipping rectangle CMP x0,cx0 MOVLT x0,cx0 CMP y0,cy0 MOVLT y0,cy0 CMP x1,cx1 MOVGT x1,cx1 CMP y1,cy1 MOVGT y1,cy1 CMP x0,x1 CMPLT y0,y1 ADDGE sp,sp,#7*4 Pull "r0-y1,pc",GE Debug tiling,"In ploticonbackgroundsprite, about to set graphics window to : ",x0,y0,x1,y1 BL graphicswindow LDRB r0,[handle,#w_wbcol] ADD r14,handle,#w_wax0 LDMIA r14,{x0-y1} SWI OS_WriteI + 16 BL plotspritebackground Pull "x0-y1" BL graphicswindow Pull "x0-x1" str x0,thisCBptr str y0,spritename str x1,lengthflags Pull "r0-y1,pc" tile_1 DCB "tile_1",0 ALIGN TileWindowBackground ROUT Push "r6-r11,lr" ldr r1,[handle,#w_areaCBptr] cmp r1,#2 blo %FT00 teq r5,#sc_verylightgrey bne %FT00 adr r2,tile_1 mov r0,#SpriteReason_SelectSprite :OR: 256 swi XOS_SpriteOp bvs %FT00 adrl r8,temp_tile_sprite bl get_tile_sprite_info bvs %FT00 Debug tiling,"Calling tile_sprite_fill_area" bl tile_sprite_fill_area ldr r2,[r8,#TileInfo_TranslationTablePtr] cmp r2,#0 movne r0,#ModHandReason_Free blne XROS_Module mov r2,#0 str r2,[r8,#TileInfo_TranslationTablePtr] CLRV Pull "r6-r11,PC" 00 adrl r8,tile_sprites ASSERT TileInfo = 36 add r0,r5,r5,LSL #3 mov r0,r0,LSL #2 ; r0 = r5 * sizeof(TileInfo) add r8,r8,r0 ; r8 = ptr to correct sprite info block bl get_tile_sprite ; r8 = ptr to filled in sprite info block blvc tile_sprite_fill_area Pull "r6-r11,PC",VC 01 swi XOS_WriteI + 16 ; clear the screen CLRV Pull "r6-r11,PC" PlotWindowBorders ROUT ; on entry: r6-r9 = window visible area ; r10 = internal window block pointer ROUT Push "r3-r5,x0-y1,lr" ldr r14,ThreeDFlags tst r14,#ThreeDFlags_Use3DBorders Pull "r3-r5,x0-y1,pc",EQ ldrb r5,[handle,#w_wbcol] ldr r3,truefacecolour ldr r4,trueoppcolour Push "r3,r4" ldr r3,iconbarhandle Abs r3,r3 ; convert to internal block pointer teq r3,handle beq %FT01 ldr r3,[handle,#w_taskhandle] ; check for menu cmp r3,#-1 bne %FT04 tst r14,#ThreeDFlags_UseAlternateMenuTexture ; see if we need to use the window border colours or the menu colours beq %FT03 ldr r3,truemenuborderfacecolour ; set up the menu border colours ldr r4,truemenuborderoppcolour str r3,truefacecolour str r4,trueoppcolour b %FT00 04 teq r5,#1 ; check if this window needs a border bne %FT02 ldrb r14,[handle,#w_flags2] and r14,r14,#wf2_no3Dborder :OR: wf2_force3Dborder teq r14,#wf2_no3Dborder beq %FT02 teq r14,#wf2_force3Dborder beq %FT03 ldr r14,[handle,#w_flags] tst r14,#&70000000 tsteq r14,#&00000020 [ No3DChildWindows ldreq r14,[handle,#w_parent] cmpeq r14,#-1 ; check if it's a top level window ] bne %FT02 03 ldr r3,truewindowborderfacecolour ; set up the window borders colours ldr r4,truewindowborderoppcolour str r3,truefacecolour str r4,trueoppcolour 00 bl plot_slabout ldr r0,truefgcolour cmp r0,#-1 beq %FT02 ldr r3,ditheringflag mov r4,#0 swi XColourTrans_SetGCOL ; put the forground colour back the way it was before we plotted the border 02 Pull "r3,r4" str r3,truefacecolour str r5,trueoppcolour Pull "r3-r5,x0-y1,pc" 01 tst r14,#ThreeDFlags_Fully3DIconBar subeq x0,x0,#16 ; move the ends off the screen addeq x1,x1,#16 ; not the best way to do it, but the smallest... b %BT03 write_tile_sprite_name_bpp ; on entry: r5 = bpp to add to the end of the sprite name ; r7 = ptr to end of base sprite name ; on exit: string updated to add bpp to end ROUT Push "r0-r2,lr" mov r1,r7 mov r0,#'-' strb r0,[r1],#1 mov r0,r5 cmp r0,#16 movhi r2,#'3' movhi r0,#2 moveq r2,#'1' moveq r0,#6 strhsb r2,[r1],#1 add r0,r0,#'0' strb r0,[r1],#1 mov r0,#0 strb r0,[r1,#0] Pull "r0-r2,pc" tile DCB "tile" get_base_tile_sprite_name ROUT ; on entry: r5 = window bg colour ; r6 = ptr to memory block to put sprite name in ; on exit: memory at sp updated to contain the sprite name ; r7 = ptr to terminating NUL Push "r0,lr" mov r7,r6 ; r7 = ptr to memory to hold name ldr r0,tile str r0,[r7],#4 mov r0,#'_' strb r0,[r7],#1 ; now contains 'tile_ teq r5,#16 moveq r0,#'m' streqb r0,[r7],#1 beq %F00 ; it's a menu, so now 'tile_m' cmp r5,#10 movhs r0,#'1' strhsb r0,[r7],#1 ; >= to 10 so put in the 1 'tile_1' addhs r0,r5,#'0'-10 ; and set r0 to the second character of the number addlo r0,r5,#'0' ; else r0 = the single digit number strb r0,[r7],#1 00 mov r0,#0 ; finished, so terminate the name strb r0,[r7,#0] Pull "r0,pc" get_tile_sprite_info ; on entry: r1 = sprite area pointer ; r2 = sprite pointer ; r8 = ptr to tile info block ; one exit: block at r8 filled in ; or V set for error Push "r0-r4,lr" str r1,[r8,#TileInfo_SpriteAreaPtr] str r2,[r8,#TileInfo_SpritePtr] str r1,thisCBptr str r2,spritename mov r0,#0 str r0,lengthflags bl cachespritedata movvs r0,#-1 strvs r0,[r8,#TileInfo_SpritePtr] Pull "r0-r4,pc",VS ldr r0,sprite_log2px mov r3,r3,LSL r0 str r3,[r8,#TileInfo_Width] ldr r0,sprite_log2py mov r4,r4,LSL r0 str r4,[r8,#TileInfo_Height] ldrb r0,sprite_needsfactors teq r0,#0 moveq r0,#-1 ; if the scale factors are not needed then the first one is -1 adrne r14,sprite_factors ldmneia r14,{r0-r3} add r14,r8,#TileInfo_ScaleFactors stmia r14,{r0-r3} ldr r0,pixtable_at str r0,[r8,#TileInfo_TranslationTablePtr] mov r0,#0 str r0,pixtable_at Pull "r0-r4,pc" find_tile_sprite ; on entry: r6 = ptr to sprite name ; r8 = ptr to info block to fill in ; on exit: block at r8 updated ; or V set if sprite could not be found ROUT Push "r0-r3,lr" DebugS tiling,"Looking for sprite : ",r6 b %FT02 ldr r0,list_at teq r0,#0 ; if the cached sprite list does not exist beq %FT02 ; do the lookup the slow way str r6,spritename bl getspriteaddr ldrvc r1,baseofsprites 00 movvs r2,#-1 strvs r2,[r8,#TileInfo_SpritePtr] Pull "r0-r3,pc",VS 01 Debug tiling,"Sprite found at :",r1,r2 bl get_tile_sprite_info Pull "r0-r3,pc" 02 mov r0,#SpriteReason_SelectSprite :OR: 256 [ SpritePriority ldr r1,baseofhisprites | ldr r1,baseofsprites ] mov r2,r6 mov r3,sp swi XOS_SpriteOp mov r3,sp bvc %BT01 mov r0,#SpriteReason_SelectSprite :OR: 256 [ SpritePriority ldr r1,baseoflosprites | ldr r1,baseofromsprites ] mov r2,r6 mov r3,sp swi XOS_SpriteOp mov r3,sp bvc %BT01 b %BT00 find_tile_sprite_all_depths ; on entry: r5 = window bg colour ; r6 = ptr to memory block rto put sprite name in ; r7 = ptr to end of tile_## string ; r8 = ptr to tile info block to fill in ; stack contains base sprite name ; on exit: block at r8 updated ; or V set if no sprite could be found ROUT Push "r5,lr" ldr r5,log2bpp mov r14,#1 mov r5,r14,LSL r5 ; r6 = bpp of current screen mode 00 bl write_tile_sprite_name_bpp bl find_tile_sprite Pull "r5,pc",VC mov r5,r5,LSR #1 cmp r5,#8 bhs %BT00 mov r5,#0 strb r5,[r7,#0] ; failed to find any variant of the sprite so try the default bl find_tile_sprite Pull "r5,pc" get_tile_sprite ROUT ; on entry: r5 = window bg colour ; r8 = ptr to sprite info block to fill in ; on exit: block at r8 updated ; V set if sprite not found Push "r0-r7,lr" 00 ldr r0,[r8,#TileInfo_SpritePtr] cmp r0,#0 beq %FT01 ; if sprite pointer is != 0 then the sprite has already been cmp r0,#-1 Pull "r0-r7,pc",NE ; if not 0 or -1 then return now with V clear cmn r0,#1:SHL:31 Pull "r0-r7,pc" ; if it is -1 then return with V set to cause the screen to just ; be cleared 01 mov r0,#161 ; check if tiling is disabled in CMOS mov r1,#&8C swi XOS_Byte tst r2,#128 SETV NE movvs r0,#-1 strvs r0,[r8,#TileInfo_SpritePtr] Pull "r0-r7,pc",VS sub sp,sp,#16 mov r6,sp bl get_base_tile_sprite_name DebugS tiling,"Base sprite name : ",r6 bl find_tile_sprite_all_depths add sp,sp,#16 Pull "r0-r7,pc" tile_sprite_fill_area ROUT ; on entry: r8 = ptr to sprite info block Push "r0-r11,lr" mov r11,r8 ldr x0,[handle,#w_wax0] ldr r0,[handle,#w_scx] ldr r3,[r11,#TileInfo_Width] DivRemS x1,r0,r3,r5 sub x0,x0,r0 ; x0 = x tiling start point ldr y1,[handle,#w_way1] ldr r0,[handle,#w_scy] ldr r4,[r11,#TileInfo_Height] DivRemS x1,r0,r4,r5 sub y1,y1,r0 ; y1 = y tiling start point adr r14,clipx0 ldmia r14,{r0,y0,x1,r14} sub y0,y0,#1 sub y0,y0,r4 ; move min y down one whole tile sub r0,r0,#1 add x1,x1,#1 add r14,r14,#1 00 cmp y1,r14 ; get y1 inside clipping rectangle subgt y1,y1,r4 bgt %BT00 01 cmp x0,r0 ; get x0 inside clipping rectangle addlt x0,x0,r3 blt %BT01 sub x0,x0,r3 ; move it back over the left edge of the window mov r0,#SpriteReason_PutSpriteScaled+512 ldr r1,[r11,#TileInfo_SpriteAreaPtr] ldr r2,[r11,#TileInfo_SpritePtr] mov r5,#0 mov r10,r4 ; r10 = tile height mov r4,y1 mov r9,r3 ; r9 (y1) = tile width 02 mov r3,x0 ; r3 = start x pos 03 bl plot_tile add r3,r3,r9 ; move right one tile cmp r3,x1 ; if more tiles on right blt %BT03 ; keep going sub r4,r4,r10 ; move down one tile cmp r4,y0 ; if more tiles below bgt %BT02 ; keep going Pull "r0-r11,pc" plot_tile ROUT ; on entry: r0,r1,r2 - as for OS_SpriteOp 52 ; r3 = x coord ; r4 = y coord ; r5 = plot action ; on exit: r0-r4 preserved Push "r6,r7,lr" ldr r6,[r11,#TileInfo_ScaleFactors + 0] cmp r6,#-1 moveq r6,#0 addne r6,r11,#TileInfo_ScaleFactors ldr r7,[r11,#TileInfo_TranslationTablePtr] swi XOS_SpriteOp Pull "r6,r7,pc" reset_all_tiling_sprites ROUT ; on entry R0 = the value to write to all tile sprite pointers ; all tile sprite pointers are updated and all translation tables freed Push "r0-r4,lr" mov r1,r0 Debug tiling, "Reset tiling to", r1 adrl r3,tile_sprites add r4,r3,#TileInfo * 18 ; 16 background tiles + menu tile + temp tile 00 str r1,[r3,#TileInfo_SpritePtr] ; set the sprite pointer ldr r2,[r3,#TileInfo_TranslationTablePtr] teq r2,#0 ; if the table is non zero then free it movne r0,#ModHandReason_Free blne XROS_Module mov r2,#0 str r2,[r3,#TileInfo_TranslationTablePtr] ; the table no longer exists so set the pointer to 0 add r3,r3,#TileInfo ; move on to the next one cmp r3,r4 bcc %BT00 Pull "r0-r4,pc" ; exit with V clear END