; Copyright 1996 Acorn Computers 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.
;
; > s.StartLoop

; ----------------------------------------------------------------------------------------------------------------------
;      Application title and 'TASK' word store
taskidentifier  DCB     "TASK"
tasktitle       DCB     "TaskID",0
                ALIGN
; ----------------------------------------------------------------------------------------------------------------------
;       Set up error blocks

        MakeErrorBlock Pinboard_NoWimp

ErrorOldWimp
        SWI     XWimp_CloseDown
        SWI     XOS_WriteI+4            ; just in case (old Wimp!)
        ADR     r0,ErrorBlock_Pinboard_NoWimp
        BL      msgtrans_errorlookup

ErrorNoWimp
        SWI     OS_GenerateError        ; can't use Wimp to report error!

CloseWimp

        EntryS  r0
        LDR     r0, mytaskhandle        ; Get task handle
        LDR     r1, taskidentifier
        SWI     XWimp_CloseDown
        MOV     r0, #0
        STR     r0, mytaskhandle
        EXITS

; ----------------------------------------------------------------------------------------------------------------------
template_filename
        DCB     "Pinboard:Templates",0
        ALIGN
;info_name
;        DCB     "Proginfo",0
;        ALIGN
saveas_name
        DCB     "saveas",0
        ALIGN
back_name
        DCB     "Back",0
        ALIGN

bgcol
        DCD &77777700
 [ technicolour_text
fgcol
        DCD &FFFFFF00
 ]

MessagesList
                DCD     Message_DataLoad
                DCD     Message_DataLoadAck
                DCD     Message_DataSaveAck
                DCD     Message_FilerDevicePath
                DCD     Message_ModeChange
              [ :LNOT: ursulawimp
                DCD     Message_PaletteChange
              ]
                DCD     Message_MenusDeleted
                DCD     Message_HelpRequest
                DCD     Message_Iconize
                DCD     Message_IconizeAt
                DCD     Message_TaskNameIs
                DCD     Message_WindowClosed
                DCD     Message_TaskCloseDown
                DCD     Message_WindowInfo
                DCD     Message_FilerSelection
                DCD     Message_FontChanged
                DCD     Message_ToggleBackdrop
                DCD     0

; ----------------------------------------------------------------------------------------------------------------------
;       Start up the wimp task for Pinboard
Start
        MOV     r11, r12
        LDR     r12, [r12]              ; get workspace pointer

        addr    r0, ErrorBlock_CantStartPinboard
        MOV     r1,#0                   ; Relies on global error message
        MOV     r2,#0
        ADRL    r4,Title
        SWI     XMessageTrans_ErrorLookup
        CMP     r12, #0
        SWIEQ   OS_GenerateError        ; abort if module not initialised

        LDR     r14, mytaskhandle       ; abort if already a task
        CMP     r14, #-1
        SWINE   OS_GenerateError

        ADRL    sp, stacktop            ; STACK IS NOW VALID!

        BL      msgtrans_openfile
        SWIVS   OS_GenerateError

        ADR     r0,message_file_block+4
        ADR     r1,tasktitle
        ADR     r2,dataarea
        MOV     r3,#&100
        SWI     XMessageTrans_Lookup
        ADRVSL  r2,Title

        LDR     r0, bgcol
        STR     r0, background_colour

 [ technicolour_text
        LDR     r0, fgcol
        STR     r0,foreground_colour
 ]

        MOV     r0,#0
        STR     r0,poll_word
        STR     r0,slot_size                    ; We don't have a slot.
        STR     r0,GotToClearBackdrop
        STR     r0,MonotonicID
        STR     r0,backdrop_options

        ORR     r0, r0, #PinboardOption_UseWinToCorner
        ORR     r0, r0, #PinboardOption_WinToCornerLR
        ORR     r0, r0, #PinboardOption_WinToCornerHV
        STR     r0, Pinboard_options

        MOV     r0, #-1
        STR     r0, IconizeAtX
        STR     r0, IconizeAtY

        MOV     r0, #Default_IconizeAtFlags
        STR     r0, IconizeAtFlags
        MOV     r0, #0
        STR     r0,Pinboard_Icons
        STR     r0,Window_Icons
        STR     r0,All_PB_Icons
        STR     r0,TinyDirs_Icons
        STR     r0,Pinboard_Selected
        STR     r0,TinyDirs_Selected
        STR     r0,Windows_Selected
        STR     r0,Iconbar_Icons
        STR     r0,soft_selection_window
        STR     r0,CachedBackdrop_x1
        STR     r0,CachedBackdrop_y1

        SUB     r0,r0,#1
        STR     r0,CachedBackdropMode
        STR     r0,TinyDirs_Handle

        MOV     r0, #300                ; We know about wimp 3.00 and have a messages list.
        LDR     r1, taskidentifier
        ADR     r3, MessagesList
        SWI     XWimp_Initialise
        LDR     r3, =269                ; Wimp version required
        CMP     r0, #256                ; needs Wimp with Wimp_PollWord, draggable iconbar icons
                                        ; and Iconize and close window messages.
        BCC     ErrorOldWimp

        STR     r1, mytaskhandle        ; Store task handle

        ADR     r1, template_filename   ; Load in the templates
        SWI     XWimp_OpenTemplate
        BLVS    CloseWimp
        SWIVS   OS_GenerateError

        ADR     r1, dataarea                ; Get template for back window.
        LDR     r2, =indirected_data_offset
        ADD     r2,r2,r12
        ADD     r3, r2, #indirected_space
        MOV     r4, #-1                     ; No font array
        ADR     r5, back_name               ; Name of window.
        MOV     r6, #0                      ; Search from first template.
        SWI     XWimp_LoadTemplate
        BLVS    CloseWimp
        SWIVS   OS_GenerateError

        BL      read_mode_variables         ; Read screen bounding box.
        [ truncate_filenames
        BL      read_font_widths
        ]

        ADR     r1, bounding_box            ; Set correct extent
        LDMIA   r1, {r2,r3,r4,r5}
        ADD     r4,r4,#100
        ADD     r5,r5,#100
        ADRL    r1, dataarea+40
        STMIA   r1, {r2,r3,r4,r5}

        ADR     r1, dataarea                ; Create the backdrop window
        SWI     XWimp_CreateWindow
        STRVC   r0, backdrop_handle
        BLVS    CloseWimp
        SWIVS   OS_GenerateError

        ADR     r1, dataarea                ; Get template for saveas box.
        LDR     r2, =save_filename_offset
        ADD     r2,r2,r12
        ADD     r3, r2, #&180
        MOV     r4, #-1
        ADR     r5, saveas_name
        MOV     r6, #0
        SWI     XWimp_LoadTemplate
        BLVS    CloseWimp
        SWIVS   OS_GenerateError
        ADR     r1, dataarea            ; Create the info window
        LDR     r14,[r1,#88+2*32+20]
        DebugS  sa,"Default name is ",R14
        STR     r14,save_filename_address
        SWI     XWimp_CreateWindow
        STRVC   r0, saveas_handle

        SWI     XWimp_CloseTemplate

        BL      set_icon_bar_height

        ADR     r1, dataarea            ; Open the backdrop window
        MOV     r0, r1
        LDR     r2, backdrop_handle
        STR     r2, [r0],#4

        ADR     r3, bounding_box        ; Screen bounding box.
        LDMIA   r3, {r4,r5,r6,r7}
        LDR     r5, icon_bar_height     ; Don't cover iconbar.
        ADD     r6,r6,#100
        ADD     r7,r7,#100
        STMIA   r0!, {r4,r5,r6,r7}

        MOV     r8, #-2                 ; bottom of stack
        STMIA   r0, {r6,r7,r8}          ; Scroll x / Scroll y & open behind.

        Debug   bd,"Open Window"

        SWI     XWimp_OpenWindow        ; Go open the window.
        BLVS    CloseWimp
        SWIVS   OS_GenerateError

        BL      FreeAll                 ; Free icon list, backdrop path etc. if used

      [ defaultbackdrop
        BL      CheckLCD
      ]

        BL      Int_ModeChange

      [ useECFforLCD
        BL      setupECF
      ]

; ----------------------------------------------------------------------------------------------------------------------
;       Wimp polling routine
repollwimp
        Debug   sa,"Repoll wimp"
        BLVS    ReportError

; See if we need to add tinydirs icon.

        LDR     r0,Pinboard_options
        TST     r0,#PinboardOption_TinyDirs
        BEQ     %FT01

        LDR     r0,TinyDirs_Icons
        CMP     r0,#0
        BNE     %FT01

        Debug   sa,"Calling add tiny dirs"
        Push    "PC"
        B       Int_AddTinyDirs
        MOV     r0,r0
01
; Call Wimp_Poll

        Debug   sa,"Calling Wimp_Poll"
        MOV     R0, #null_bit :OR: pointerchange_bits
        ORR     R0, R0, #pollword_enable
        ADR     R1,dataarea
        ADR     r3, poll_word
        SWI     XWimp_Poll              ; can't call non-X form
        Debug   sa,"Wimp_poll returned ",r0
        BVS     repollwimp
        Debug   sa,"No error in wimp_poll"
; Call the appropriate routine using a fast jump table
        ADR     LR,repollwimp
        CMP     R0,#(endjptable-jptable)/4
        ADDCC   PC,PC,R0,ASL #2
        MOV     PC,LR

jptable
        MOV     PC,LR                   ;  0  null reason
        B       Redraw                  ;  1  redraw window
        B       open_window             ;  2  open window
        MOV     PC,LR                   ;  3  close window
        MOV     PC,LR                   ;  4  pointer leaving window
        MOV     PC,LR                   ;  5  pointer entering window
        B       mouse_click             ;  6  mouse click
        B       drag_end                ;  7  drag box complete
        B       Key_Press_Event         ;  8  key pressed.
        B       menu_selection          ;  9  menu selection
        MOV     PC,LR                   ; 10
        MOV     PC,LR                   ; 11
        MOV     PC,LR                   ; 12
        B       poll_word_set           ; 13  poll word non-zero
        MOV     PC,LR                   ; 14
        MOV     PC,LR                   ; 15
        MOV     PC,LR                   ; 16
        B       message_received        ; 17  message_received
        B       message_received        ; 18  message_received_ack
        B       message_bounced         ; 19  message_bounced
endjptable


;----------------------------------------------------------------------------------------------------------------------
; Key_Pressed
;     Check to see which window has the keypress event. The backdrop window gets
;     input focus at the start of a drag operation so that the Escape key can then
;     cancel the drag.
;
Key_Press_Event ROUT
        Push    "R0, R10, LR"
        LDR     R10, [R1]       ; Make a note of the keypress window handle
        LDR     R0, [R1, #24]   ; Check the key is escape
        TEQ     R0, #&1B
        BNE     %FT01
        ; Check there is a drag in progress
        LDR     R0, DragType
        TEQ     R0, #DragType_NoDrag
        BEQ     %FT01
        ; Abort the drag and restore input focus
        MOV     R0, #DragType_NoDrag
        STR     R0, DragType
        BL      Restore_Focus
        SWI     XDragASprite_Stop
        Pull    "R0, R10, PC"
01      ; Skip the drag cancel stuff
        LDR     R0, backdrop_handle
        TEQ     R0, R10
        Pull    "R0, R10, LR"
        BNE     Save_KeyPressed
        LDR     R0, [R1, #24]   ; Pass-on any non-escape keys
        SWI     XWimp_ProcessKey
        MOV     PC, LR


;----------------------------------------------------------------------------------------------------------------------
; open_window
;     Open window unless it's the backdrop window which is opened only on a mode change.
;
open_window

        Push    "LR"

        Debug   pi,"open_window"
        LDR     r0,backdrop_handle
        LDR     r14,[r1]
        CMP     r0,r14
        SWINE   XWimp_OpenWindow        ;  2  open window

        Pull    "PC"

; ----------------------------------------------------------------------------------------------------------------------

poll_word_set

        Push    "LR"

        LDR     R0,poll_word
        TST     R0,#PollWordReason_Buffered
        BICNE   R0,R0,#PollWordReason_Buffered
        STRNE   R0,poll_word
        BLNE    ReadBufferedList
        Pull    "PC",VS
        LDR     R0,poll_word
        TST     R0,#PollWordReason_Recache
 [ technicolour_text
        BLNE    change_icon_colours     ; trashes flags
        TST     R0,#PollWordReason_Recache
 ]
        BICNE   R0,R0,#PollWordReason_Recache
        STRNE   R0,poll_word
        BLNE    CacheBackdropSprite

        LDR     lr,poll_word
        TST     lr,#PollWordReason_Remove
        BICNE   lr,lr,#PollWordReason_Remove
        STRNE   lr,poll_word
        BLNE    ClearBackdrop
        Pull    "PC"

; ----------------------------------------------------------------------------------------------------------------------
Redraw  ROUT

        Push    "LR"

      [ useECFforLCD
        MOV     r0,#1
        SWI     XOS_ReadSysInfo
        Pull    "PC",VS
        MOV     r11,r1                  ; save monitor type
      ]

        ADR     r1,dataarea
        LDR     r9,backdrop_handle
        Debug   td,"Window handle = ",r9
        STR     r9,[r1]

        LDR     r9,backdrop_options
        Debug   td,"Redraw: options are ",r9

        SWI     XWimp_RedrawWindow
        Pull    "PC",VS

01      CMP     r0,#0
        Pull    "PC",EQ

        TST     r9,#bd_OptionActive
        TSTNE   r9,#bd_OptionScaled :OR: bd_OptionTiled
        BNE     %FT10

      [ useECFforLCD
        CMP     r11,#5
        BEQ     %FT08
        LDR     r0,=128+4
        SWI     XWimp_SetColour
        MOVS    r1,PC
08
        MOVEQ   r0,#&30
        ADREQ   r1,backdropECF
        SWIEQ   XOS_SetColour
      |
        Push    "r3,r4"
        LDR     r0, background_colour
        MOV     r3, #128+256
        MOV     r4, #0
        SWI     XColourTrans_SetGCOL
        Pull    "r3,r4"
      ]
        Pull    "PC",VS
        SWI     XOS_WriteI+16           ; Clear background to colour 4
        Pull    "PC",VS

10      TST     r9,#bd_OptionActive     ; do we have a backdrop image?
        BEQ     %FT02                   ; if not, skip plotting of image

        TST     r9,#bd_OptionTiled      ; should the image be tiled?
        BLNE    PlotImageTiled          ; if so, plot the tiled image
        TST     r9, #bd_OptionScaled    ; should the image be scaled?
        TSTEQ   r9, #bd_OptionCentred   ; or centred on screen?
        BLNE    PlotImageScaled         ; if so, plot the image scaled/centred

        ; We've dealt with this redraw rectangle see if there's another one

02      ADR     r1,dataarea             ;
        SWI     XWimp_GetRectangle      ; get next redraw rectangle
        Pull    "PC",VS                 ; exit if something went wrong
        B       %BT01                   ; deal with next rectangle


;-------------------------------------------------------------------------------
; In: Nothing
;
; Out: All registers preserved
;-------------------------------------------------------------------------------
PlotImageScaled
        Entry   "r0-r12"

        LDR     r14,backdrop_options    ; get options for backdrop image
        TST     r14,#bd_OptionJPEG      ; is it a jpeg image?
        BEQ     %FT10                   ; if not, plot a sprite

        ; Scaled/centred backdrop jpeg
        MOV     r0, #&8000              ; -> jpeg image data
        LDR     r1, Sprite_x            ; x co-ordinate at which to plot
        LDR     r2, Sprite_y            ; y co-ordinate at which to plot
        ADR     r3, ScaleFactors        ; -> scale factors to use
        LDR     r4, slot_size           ; size of image
        MOV     r5, #1                  ; 1 => dither output
        SWI     XJPEG_PlotScaled        ; plot jpeg (ignore any errors)
        B       %FT20                   ; jump to exit

        ; Scaled/centred backdrop sprite
10      LDR     r0,=&200 + SpriteReason_PutSpriteUserCoords
        MOV     r1,#&8000               ; -> sprite area
        ADD     r2,r1,#&10              ; -> sprite to plot
        LDR     r3,Sprite_x             ; x co-ordinate at which to plot
        LDR     r4,Sprite_y             ; y co-ordinate at which to plot
        MOV     r5,#0                   ; 0 => plot action is overwrite
        SWI     XOS_SpriteOp            ; plot sprite (ignore any errors)

20
        EXIT


;-------------------------------------------------------------------------------
; In: Nothing
;
; Out: All registers preserved
;-------------------------------------------------------------------------------
PlotImageTiled
        Entry   "r0-r12"

        LDR     r14,backdrop_options
        TST     r14,#bd_OptionJPEG
        BNE     %FT05
        ; Tiled sprite, use the new tiled OS_SpriteOp
        LDR     r0,Screen_y1
        MOV     r9,#1
        LDR     r10,YEig
        ADD     r4,r0,r9,LSL r10
        LDR     r0,=SpriteReason_TileSpriteScaled+512
        MOV     r1,#&8000
        ADD     r2,r1,#16
        MOV     r3,#0
        MOV     r5,#0
        MOV     r6,#0
        MOV     r7,#0
        SWI     XOS_SpriteOp
      [ standalonemessages
        ; Try plotting manually if it looks like the call isn't supported
        EXIT    VC
        LDR     r0,[r0]
        LDR     r1,=ErrorNumber_Sprite_BadReasonCode
        TEQ     r0,r1
        EXIT    NE
      |
        EXIT
      ]

05
        ADR     r1,dataarea             ; Get the redraw rectangle

        ; Work out MinX of first tile to plot

        LDR     r14,[r1,#28]            ; X0 of current rectangle.
        LDR     r0,scale_x1             ; width of image in OS units
        DivRem  r3,r14,r0,r2,norem      ;
        MUL     r6,r0,r3                ; MinX of leftmost tile to plot
        Debug   bd,"First x ",r6

        ; Work out MinY of first tile to plot

        LDR     r0,Screen_y1            ;
        LDR     r14,scale_y1            ;
        MOV     r9,#1                   ;
        LDR     r10,YEig                ;
        MOV     r9,r9,ASL r10           ;
        ADD     r0,r0,r9                ;
        SUB     r3,r14,#0               ;
        LDR     r4,[r1,#32]             ; Y0 of current rectangle.
        SUB     r2,r0,r4                ; r2 = ScrY1 - Y0
        ADD     r2,r2,r3                ; r2 = (ScrY1-Y0)+YSize-1
        DivRem  r3,r2,r14,r5,norem      ; r3 = (ScrY1-Y0+YSize-1)  / YSize
        LDR     r14,scale_y1            ;
        MUL     r5,r3,r14               ; r5 = INT ( (ScrY1-Y0+YSize-1)  / YSize ) * YSize
        SUB     r8,r0,r5                ; r3 = ScrY1 - r5 (Base Y)
        Debug   bd,"First y ",r8

        MOV     R7,R6                   ;
        LDR     r9, [r1,#36]            ; r9  = redraw MaxX
        LDR     r10,[r1,#40]            ; r10 = redraw MaxY

10      MOV     r0,r7                   ; MinX of next tile
        MOV     r1,r8                   ; MinY of next tile

        LDR     r14,backdrop_options    ; get options for backdrop image
        TST     r14,#bd_OptionJPEG      ; is it a jpeg image?

        ADR     r14,%FT20               ; set up a return address
        BNE     PlotJpegTiled           ; if so, plot jpeg
        BEQ     PlotSpriteTiled         ; if not, plot sprite

20      LDR     r2, scale_x1            ; width of image in OS units
        ADD     r7, r7, r2              ; hence MinX of next tile
        CMP     r7, r9                  ; have we gone past redraw MaxX?
        BLT     %BT10                   ; if not, plot this tile

        ; We've gone past the redraw MaxX, move to next row

        MOV     r7, r6                  ; reset MinX to leftmost tile
        LDR     r2, scale_y1            ; height of image in OS units
        ADD     r8, r8, r2              ; hence MinY of next row of tiles
        CMP     r8, r10                 ; have we gone past redraw MaxY?
        BLT     %BT10                   ; if not, plot this tile

        EXIT


;-------------------------------------------------------------------------------
; In:   R0 = x co-ordinate at which to plot
;       R1 = y co-ordinate at which to plot
;
; Out:  All registers preserved
;-------------------------------------------------------------------------------
PlotJpegTiled
        Entry   "r0-r5"

        MOV     r5, #1                  ; 1 => dither output
        LDR     r4, slot_size           ; size of image
        MOV     r3, #0                  ; 0 => no scale factors (1:1)
        MOV     r2, r1                  ; x co-ordinate at which to plot
        MOV     r1, r0                  ; y co-ordinate at which to plot
        MOV     r0, #&8000              ; -> jpeg image data
        SWI     XJPEG_PlotScaled        ; plot jpeg (ignore any errors)

        EXIT


;-------------------------------------------------------------------------------
; In:   R0 = x co-ordinate at which to plot
;       R1 = y co-ordinate at which to plot
;
; Out:  All registers preserved
;-------------------------------------------------------------------------------
PlotSpriteTiled
        Entry   "r0-r5"

        MOV     r5,#0                   ; 0 => plot action is overwrite
        MOV     r4,r1                   ; x co-ordinate at which to plot
        MOV     r3,r0                   ; y co-ordinate at which to plot
        LDR     r0,=&200 + SpriteReason_PutSpriteUserCoords
        MOV     r1,#&8000               ; -> sprite area
        ADD     r2,r1,#&10              ; -> sprite to plot
        SWI     XOS_SpriteOp            ; plot sprite (ignore any errors)

        EXIT


        LNK     Messages.s