;-------= Slopes Level Editor 2 =-------
; Author:       Ian Graf
;               (ian_graf@geocities.com)
; Version:      2.0
; Platform:     ION
; Date:         11/3/99
;---------------------------------------

;---------------= header =--------------

        .nolist
        #define         editor
        #include        "slopes.inc"
        #include        "ion.inc"
        .list
#ifdef  TI83P
        .org    progstart-2
        .db     $BB,$6D
#else
        .org    progstart
#endif
        ret
        jr      nc,start_of_program
        .db     "Slopes Editor 2.0 by Ian Graf",0


;------------= title screen =-----------

start_of_program:
        set     7,(iy+20)               ; write to graph
title_screen:
        ld      hl,menusize             ;
        ld      a,2                     ;
        ld      (hl),a                  ; menusize = 2
        inc     hl                      ;
        ld      a,(itemback)            ; restore menu item
        ld      (hl),a                  ; menuitem = itemback
        inc     hl                      ;
        ld      (hl),0                  ; menutop = 0
        ld      hl,newstr               ; item 1
        ld      (menuitem1),hl          ;
        ld      hl,editstr              ; item 2
        ld      (menuitem2),hl          ;
contt:  call    drawtitle               ; draw title
        call    drawmenu                ; draw menu
        call    ionFastCopy             ;
        ld      a,(menuitem)            ; store menu item
        ld      (itemback),a            ;
titlel: bcall(_getk)                    ;
        dec     a                       ; [(down)]
        jr      nz,titled               ; move highlight
        call    menudown                ;
        jr      contt                   ;
titled: sub     4-1                     ; [(up)]
        jr      nz,titleq               ; move highlight
        call    menuup                  ;
        jr      contt                   ;
titleq: sub     15-4                    ; [CLEAR]
        ret     z                       ; quit
        sub     54-15                   ; [2nd]
        jr      nz,titlel               ; jump to menu item
        ld      a,(menuitem)            ;
        dec     a                       ;
        jr      z,edit_level            ;


;----------= create new level =---------

new_level:
        call    getnew                  ;
        jr      c,nomem                 ;
        push    de                      ;
        push    de                      ;
        pop     hl                      ;
        ld      (hl),0                  ;
        inc     de                      ;
        ld      bc,1501                 ;
        ldir                            ;
        pop     hl                      ;
        jp      doedit                  ;

nomem:  call    drawtitle               ;
        ld      hl,44*256+17            ; write "Not Enough Memory"
        ld      (pencol),hl             ;
        ld      hl,nomemstr             ;
        bcall(_vputs)                   ;
        call    ionFastCopy             ;
        call    wait_for_2nd            ; wait for [2nd]
        jp      title_screen            ;


;-------------= edit level =------------

edit_level:
        xor     a                       ; initalize menu
        ld      (menusize),a            ;
        ld      (menuitem),a            ;
        ld      (menutop),a             ;
        ld      hl,(progptr)            ;
        ld      ix,detectstr            ;
        call    ionDetect               ;
        jp      nz,nolevels             ; no levels
store_item:
        ld      (curvat),de             ;
        push    hl                      ;
        ld      hl,menusize             ; increment menu size
        ld      a,(hl)                  ;
        inc     (hl)                    ;
        call    itemaddr                ; compute address of menu item
        pop     de                      ;
        ld      (hl),e                  ; store pointer to item (level name)
        inc     hl                      ;
        ld      (hl),d                  ;
nextl:  ld      hl,(curvat)             ; look up next level
        ld      ix,detectstr            ;
        call    ionDetect               ;
        jr      z,store_item            ;
lloop:  call    drawtitle               ; draw title
        call    drawmenu                ; draw menu
        call    ionFastCopy             ;
lkloop: bcall(_getk)                    ;
        dec     a                       ; [(down)]
        jr      nz,lup                  ; move highlight
        call    menudown                ;
        jr      lloop                   ;
lup:    sub     4-1                     ; [(up)]
        jr      nz,lquit                ; move highlight
        call    menuup                  ;
        jr      lloop                   ;
lquit:  sub     15-4                    ; [CLEAR]
        jp      z,title_screen          ; quit
        sub     54-15                   ; [2nd]
        jr      nz,lkloop               ;
        ld      a,(menuitem)            ; get pointer to highlighted level
        call    itemaddr                ;
        bcall(_ldhlind)                 ;
        call    getlength               ; skip level name
        add     hl,de                   ;
        inc     hl                      ;
doedit: xor     a                       ; reset high score
        ld      (hl),a                  ;
        inc     hl                      ;
        ld      (hl),a                  ;
        inc     hl                      ;
        ld      (level),hl              ; level data pointer
        ld      (row),a                 ;
        ld      a,5                     ; position skier
        ld      (col),a                 ;
        ld      a,1                     ;
        ld      (itemnum),a             ;
editl:  bcall(_cleargbuf)               ;
        call    drawlevel               ; draw level
        call    ionFastCopy             ;
editkl: bcall(_getk)                    ;
        dec     a                       ; [(down)]
        jr      z,edown                 ; move item down
        dec     a                       ; [(left)]
        jr      z,eleft                 ; move item right
        dec     a                       ; [(right)]
        jr      z,eright                ; move item left
        dec     a                       ; [(up)]
        jr      z,eup                   ; move item up
        sub     15-4                    ; [CLEAR]
        jp      z,title_screen          ; quit
        sub     48-15                   ; [ALPHA]
        jr      z,nexti                 ; toggle item
        cp      54-48                   ; [2nd]
        jr      nz,editkl               ; put item at current position

puti:   ld      a,(col)                 ;
        srl     a                       ;
        push    af                      ;
        call    getoff                  ;
        ld      d,0                     ;
        ld      e,a                     ;
        add     hl,de                   ;
        pop     af                      ;
        ld      a,(itemnum)             ;
        ld      b,a                     ;
        ld      a,(hl)                  ;
        jr      c,odd                   ;
even:   and     %00001111               ;
        sla     b                       ;
        sla     b                       ;
        sla     b                       ;
        sla     b                       ;
        jr      putl                    ;
odd:    and     %11110000               ;
putl:   or      b                       ;
        ld      (hl),a                  ;
        jp      editl                   ;

eup:    ld      a,(row)                 ; top of level
        or      a                       ;
        jr      z,editl                 ;
        dec     a                       ;
        ld      (row),a                 ;
        jr      editl                   ;

edown:  ld      a,(row)                 ; bottom of level
        cp      248                     ;
        jr      z,editl                 ;
        inc     a                       ;
        ld      (row),a                 ;
        jr      editl                   ;

eleft:  ld      a,(col)                 ; left
        or      a                       ;
        jr      z,editl                 ;
        dec     a                       ;
        ld      (col),a                 ;
        jr      editl                   ;

eright: ld      a,(col)                 ; right
        cp      11                      ;
        jr      z,editl                 ;
        inc     a                       ;
        ld      (col),a                 ;
        jr      editl                   ;
                        
nexti:  ld      a,(itemnum)             ; last item
        cp      7                       ;
        jr      nz,next                 ;
        ld      a,$FF                   ;
next:   inc     a                       ;
        ld      (itemnum),a             ;
        jp      editl                   ;


;-------= get data for new level =------

getnew: ld      de,1546                 ; check free memory
        bcall(_memfree)                 ;
        bcall(_cphlde)                  ;
        ret     c                       ;
        ld      de,op1                  ; get program name
        ld      hl,levelname            ;
        ld      bc,6                    ;
        ldir                            ;
        xor     a                       ;
        ld      bc,5*256+0              ;
        ld      hl,op1+5                ;
named:  dec     hl                      ;
        push    bc                      ;
        push    af                      ;
        push    hl                      ;
        call    drawtitle               ;        
        ld      hl,44*256+5             ;
        ld      (pencol),hl             ;
        ld      hl,namestr              ;
        bcall(_vputs)                   ;
        ld      hl,op1+4                ;
        bcall(_vputs)                   ;
        call    ionFastCopy             ;
        pop     hl                      ;
        pop     af                      ;
        pop     bc                      ;
        call    getc                    ;
        djnz    named                   ;
        xor     a                       ; get level name
        ld      bc,23*256+1             ;
        ld      hl,inputdata            ;
        ld      (hl),'A'                ;
        inc     hl                      ;
        ld      (hl),0                  ;
leveld: dec     hl                      ;
        push    bc                      ;
        push    af                      ;
        push    hl                      ;
        call    drawtitle               ;        
        ld      hl,36*256+28            ;
        ld      (pencol),hl             ;
        ld      hl,levelstr             ;
        bcall(_vputs)                   ;
        ld      hl,44*256+0             ;
        ld      (pencol),hl             ;
        ld      hl,inputdata            ;
        bcall(_vputs)                   ;
        call    ionFastCopy             ;
        pop     hl                      ;
        pop     af                      ;
        pop     bc                      ;
        call    getc                    ;
        djnz    leveld                  ;
        bcall(_chkfindsym)              ;
        jr      c,ndel                  ;
        bcall(_delvar)                  ; delete existing prog
ndel:   ld      hl,inputdata            ;
        call    getlength               ;
        inc     de                      ;
        push    de                      ;
        push    hl                      ;
        ld      hl,1507                 ;
        add     hl,de                   ;
        bcall(_createprog)              ; create level
        ld      (hl),protprogobj        ; protect level
        inc     de                      ;
        inc     de                      ;
        ld      hl,detectstr            ; write level detection string
        ld      bc,5                    ;
        ldir                            ;
        pop     hl                      ; write level name
        pop     bc                      ;
        ldir                            ;
        ret                             ;

nolevels:
        call    drawtitle               ;
        ld      hl,44*256+9             ; write "There are not any levels"
        ld      (pencol),hl             ;
        ld      hl,nolevelstr           ;
        bcall(_vputs)                   ;
        call    ionFastCopy             ;
        call    wait_for_2nd            ; wait for [2nd]
        jp      title_screen            ;


;-----------= wait for [2nd] =----------

wait_for_2nd:
        bcall(_getk)                    ; wait for [2nd]
        cp      54                      ;
        jr      nz,wait_for_2nd         ;
        ret                             ;


;-------------= draw title =------------

drawtitle:
        bcall(_cleargbuf)               ;
        ld      hl,title                ;
        ld      de,grbuf+(12*5)         ;
        ld      bc,12*25                ;
        ldir                            ;
        ret                             ;


;-------------= draw level =------------

drawlevel:
        call    getoff                  ; decompress data
        ld      de,leveldata            ;
        push    de                      ;
        ld      bc,48*256+15            ;
        call    ionDecompress           ;
        ld      a,250                   ; determine number of rows to draw
        ld      hl,row                  ;
        sub     (hl)                    ;
        cp      8                       ;
        jr      c,contd                 ;
        ld      a,8                     ;
contd:  ld      b,a                     ;
        pop     hl                      ;
        ld      de,grbuf                ;
        push    de                      ;
drawl1: push    bc                      ;
        ld      b,12                    ; 12 cols
drawl2: push    bc                      ;
        push    de                      ;
        push    hl                      ;
        ld      a,(hl)                  ; get item
        call    drawi                   ; draw item
        pop     hl                      ;
        pop     de                      ;
        pop     bc                      ;
        inc     hl                      ;
        inc     de                      ;
        djnz    drawl2                  ;
        ld      b,84                    ;
drawl3: inc     de                      ;
        djnz    drawl3                  ;
        pop     bc                      ;
        djnz    drawl1                  ;
        ld      a,(col)                 ;
        ld      d,0                     ;
        ld      e,a                     ;
        pop     hl                      ;
        add     hl,de                   ;
        ex      de,hl                   ;
        ld      a,(itemnum)             ;
drawi:  push    de                      ;
        sla     a                       ;
        sla     a                       ;
        sla     a                       ;
        ld      hl,sprites              ;
        ld      d,0                     ;
        ld      e,a                     ;
        add     hl,de                   ;
        pop     de                      ;
        ld      b,8                     ;
drawl:  ld      a,(hl)                  ;
        ld      (de),a                  ;
        push    hl                      ;
        ld      hl,12                   ;
        add     hl,de                   ;
        ex      de,hl                   ;
        pop     hl                      ;
        inc     hl                      ;
        djnz    drawl                   ;
        ret                             ;


;-------------= draw menu =-------------

drawmenu:
        ld      a,36                    ; reset row
        ld      (penrow),a              ;
        ld      a,(menutop)             ;
        ld      b,a                     ; top of menu
drawml: push    bc                      ;
        ld      a,b                     ; get address to item
        call    itemaddr                ;
        bcall(_ldhlind)                 ; get address to name
        ld      a,5                     ; reset col
        ld      (pencol),a              ;
        push    hl                      ; draw name centered
        call    getlength               ; get length of string
        ld      b,e                     ;
        xor     a                       ;
countl: push    bc                      ;
        push    hl                      ;
        push    af                      ;
        ld      a,(hl)                  ; get character
        ld      h,0                     ;
        ld      l,a                     ;
        add     hl,hl                   ; hl = hl*8
        add     hl,hl                   ;
        add     hl,hl                   ;
        bcall(_sfontlen)                ; get char width
        pop     af                      ;
        cp      93                      ; clip?
        jr      nc,contc                ;
        add     a,b                     ;
contc:  pop     hl                      ;
        inc     hl                      ;
        pop     bc                      ;
        djnz    countl                  ;
        ld      b,a                     ; center string
        ld      a,96                    ;
        sub     b                       ;
        srl     a                       ;
        ld      (pencol),a              ;
        pop     hl                      ;
        bcall(_vputs)                   ; draw string
        ld      a,(penrow)              ; next col
        add     a,7                     ;
        ld      (penrow),a              ;
        pop     bc                      ;
        inc     b                       ;
        ld      a,(menutop)             ; check 3 items drawn
        add     a,3                     ;
        cp      b                       ;
        jr      z,dmdone                ;
        ld      a,(menusize)            ; check end of menu
        cp      b                       ;
        jr      nz,drawml               ;
dmdone: ld      a,(menutop)             ; get offset of highlighted item
        ld      b,a                     ;
        ld      a,(menuitem)            ;
        sub     b                       ;
        ld      h,84                    ;
        ld      l,a                     ;
        bcall(_htimesl)                 ;
        ld      de,grbuf+(12*36)        ;
        add     hl,de                   ;
        ld      b,12*7                  ;
dminvl: ld      a,(hl)                  ; invert item
        cpl                             ;
        ld      (hl),a                  ;
        inc     hl                      ;
        djnz    dminvl                  ;
        ret                             ;


;---------= move highlight up =---------

menuup: ld      a,(menuitem)            ;
        or      a                       ;
        jr      nz,up                   ;
        ld      a,(menusize)            ;
        ld      b,a                     ;
        dec     a                       ;
        cp      3                       ;
        jr      nc,uptop                ;
        ld      a,2                     ;
uptop:  dec     a                       ;
        dec     a                       ;
        ld      (menutop),a             ;
        jr      updone                  ;
up:     ld      b,a                     ;
        ld      a,(menutop)             ;
        cp      b                       ;
        jr      nz,updone               ;
        dec     a                       ;
        ld      (menutop),a             ;
updone: ld      a,b                     ;
        dec     a                       ;
        ld      (menuitem),a            ;
        ret                             ;


;--------= move highlight down =--------

menudown:
        ld      hl,menutop              ;
        ld      a,(menusize)            ;
        ld      b,a                     ;
        ld      a,(menuitem)            ;
        inc     a                       ;
        cp      b                       ;
        jr      nz,down                 ;
        xor     a                       ;
        ld      (hl),a                  ;
down:   ld      (menuitem),a            ;
        ld      b,a                     ;
        ld      a,(hl)                  ;
        add     a,3                     ;
        cp      b                       ;
        ret     nz                      ;
        inc     (hl)                    ;
        ret                             ;


;------= get address of menu item =-----

itemaddr:
        sla     a                       ; a = item number
        ld      d,0                     ;
        ld      e,a                     ;
        ld      hl,menustart            ;
        add     hl,de                   ; hl = address
        ret                             ;

 
;--------= get length of string =-------

getlength:
        ld      bc,30                   ; get length of string in hl
        xor     a                       ; max length 24 chars
        push    hl                      ;
        cpir                            ;
        ld      hl,29                   ;
        sbc     hl,bc                   ;
        ex      de,hl                   ;
        pop     hl                      ;
        ret                             ; de = length


;-------------= get offset =------------

getoff: push    af                      ;
        ld      a,(row)                 ;
        ld      hl,0                    ;
        ld      d,0                     ;
        ld      e,a                     ;
        add     hl,de                   ;
        add     hl,de                   ;
        add     hl,de                   ;
        add     hl,hl                   ;
        ld      de,(level)              ;
        add     hl,de                   ;
        pop     af                      ;
        ret                             ;


;----------= input character =----------

getc:   inc     b                       ;
        push    af                      ;
getcl:  push    hl                      ;
        push    bc                      ;
        bcall(_getk)                    ;
        pop     bc                      ;
        pop     hl                      ;
        dec     a                       ;
        jr      z,getcd                 ; [(down)]
        sub     3-1                     ;
        jr      z,getcr                 ; [(right)]
        dec     a                       ;
        jr      z,getcu                 ; [(up)]
        sub     9-4                     ;
        jr      z,gcdone                ; [ENTER]
        sub     54-9                    ;
        jr      nz,getcl                ; [2nd]
stoc:   pop     af                      ;
        inc     hl                      ;
        dec     b                       ;
stoc2:  push    hl                      ;
        ld      hl,letters              ;
        ld      d,0                     ;
        ld      e,a                     ;
        add     hl,de                   ;
        ld      d,(hl)                  ;
        pop     hl                      ;
        ld      (hl),d                  ;
        inc     hl                      ;
        ld      (hl),0                  ;
        ret                             ;

getcu:  pop     af                      ;
        inc     a                       ;
        cp      62                      ;
        jr      nz,stoc2                ;
        xor     a                       ;
        jr      stoc2                   ;

getcd:  pop     af                      ;
        dec     a                       ;
        cp      0-1                     ;
        jr      nz,stoc2                ;
        ld      a,61                    ;
        jr      stoc2                   ;

getcr:  ld      a,c                     ;
        or      a                       ;
        jr      z,getcl                 ;
        ld      (hl),' '                ;
        jr      stoc                    ;

gcdone: pop     af                      ;
        ld      b,1                     ;
        ret                             ;


;---------------= dialog =--------------

newstr:
        .db     "New Level",0
editstr:
        .db     "Edit Level",0
namestr:
        .db     "Program Name: ",0
levelstr:
        .db     "Level Name: ",0
nomemstr:
        .db     "Not Enough Memory",0
nolevelstr:
        .db     "There are not any levels",0


;-------= level detection string =------

detectstr:
        .db     "ZSLPS",0
levelname:
        .db     progobj,"ZSLA",0


;------------= input table =------------

letters:
        .db     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        .db     "abcdefghijklmnopqrstuvwxyz"
        .db     "0123456789"


;---------= selected menu item =--------

itemback:
        .db     0


        #include        "slopes.grx"


        .end
