/*

 ****************************************
   ZAR384 - C64 - 384 Bytes
 ****************************************

    GALAGA & CO ON C64SIZECODED
    IN ASSEMBLY

    LA1N.CH

    SHOOTEMUP

    "DONT LET THE ALIENS GET
     TO THE GROUND!""

    - ONE MOVABLE SHIP
    - ONE FAST SHOOT
    - 6 ENEMIES
    - COLLISON DECTECTION
     (HARDWARE++)
    - SCORE
    - TITLE
    - BACKGROUND GRAPHICS
      (PETSCII)
    - REPLAY (WAIT FOR FIRE)


    VERSION: HARWARE COLLISION

 ****************************************
 BACKGROUND - RESEARCH
 ****************************************

     PART OF CHLUDENS-RESEARCH-PROJECT
     CHLUDENS.CH

     RESEARCH TARGET: 
     WHAT SHOOTEMUP CAN YOU 
     DO WITH 384 BYTES.
     DIFFERENCE VS 256 BYTES 

     WHY THIS IS NOT ANYMORE
     POSSIBLE WITH THE AMIGA/ATARI ST?

 ****************************************
 // COMMENTS: THE OPEN SPACE
 ****************************************

 ****************************************
 // KNOWHOW
 ****************************************

                         sprites: 
                         0 avatar
                         1avatar shoot up
                         2-8 enemies incl. shootemup
                         
                         384 bytes would be perfect
                         256 bytes is not enough


                         Example used with KickAssembler (Java)

                         PETSCII
                         https:sta.c64.org/cbm64pet.html


                         commands:
                         https:www.pagetable.com/c64ref/6502/?tab=2

                         direct:
                         https:www.cs.otago.ac.nz/cosc243/resources/6502js-master/namedconsts.html
                         https://itema-as.github.io/6502js/

                          lda #%00001
                          // = 1
                          lda #%00011
                          // = 3



                         [a][x][y]

                         load into register

                         lda
                         ldx
                         ldy

                         transfer

                         txa
                         tax
                         tya
                         tay 

                         store register

                         sta
                         stx
                         sty

                         x,y
                         inx
                         iny

                         pha > on stack
                         pla < from stack

                         accumulator

                         sbc - add -
                            clc
                            sbc #10
                         adc - sub

                         cmp
                         cpx
                         cpy

                         beq sam
                         bcc less
                         bcs same or more


                         ror /2
                         rol *2

                         lsr /2  - ohne rest
                         asl *2   

                        # screen-size multicolor
                          160 x 200

                        # character-playfield/tiles
                        # 40*20 (4*8)

                           set cursor pos
                             ldx #10
                             ldy #10
                             clc
                          setpos = $fff0
                             jsr setpos

                         lda 
                          print = $ffd2    
                            jsr print


                        ## sprites
                        # screens-size-sprites
                          
                          x: 0-24 + 320 px
                          y: 0-51 + 200 px


                        # kernel routines for print

                        # scores/numbers 
                          // score 0-255
                          ldx score
                        //  txa
                        //  lda #0
                        //  jsr $bdcd // print a number 


                        # score print > 255
                         // print points
                         inc score
                         lda score
                         cmp #255
                         bne nts
                            inc scorehigh
                            lda #0
                            sta score
                         nts:
                         inc $0286 // blinking score



                          // score 0-255
                          ldx score
                          txa
                          lda scorehigh // high bytes
                          jsr $bdcd // print a number 


                        # print string (kernel)

                          LDA #<STRING  ; Load lo-byte of string adress
                          LDY #>STRING  ; Load hi-byte of string adress
                          JSR $AB1E   ; Print string
                          RTS            ; End.
                          
                          STRING     .text "HELLO WORLD!!!"
                                     .byte $00  


                        # optimizing
                          - one loop for all (with states)
                          - jmp > branches
                          - is there another usage of the same values > push it there
                          - xt:  > direct acces > .var xt = $4e01 > lda xt / so xt


 ****************************************
 THE CODE
 ****************************************

*/


// -----------------------
// VARS
// -----------------------

.var setpos = $fff0
.var print = $ffd2

.var shipy = 235

.var shoot_start = shipy-22
.var shoot_speed = 7

.var spritesmax = 8 // max 8 - 6 normal 2024

.var JOY_LEFT            = %00000100     // Joystick left
.var JOY_RIGHT           = %00001000     // Joystick right
.var JOY_UP              = %00000001     // Joystick up
.var JOY_DOWN            = %00000010     // Joystick down
.var JOY_FIRE            = %00010000     // Joystick fire

// VARS (direct in memory)

.var tmpx = $3000
//tmpx: .byte 0 // x position of avatar
.var tmpy = tmpx +1 
//tmpy: .byte 0 // x position of avatar

.var tmp = tmpx +2
// tmp: .byte 0

.var col = tmpx +3
// col: .byte 0 

.var ind = tmpx +4
// ind: .byte 0

.var counter = tmpx +5 
// counter: .byte 0

.var score = tmpx+ 6
// score: .byte 0
// .var scorehigh = tmpx+ 7
// scorehigh: .byte 0


// --------------------------
// Startup takes bytes 
// --------------------------
BasicUpstart2(start)    

// --------------------------
// Start here
// --------------------------
start:  


    // --------------------
    // _background colors
    // --------------------

        lda #0 // color black
        sta $D020 // screen border register
        sta $D021 // screen border register

        dec $0286 // faster than load / save .-)
     

restart:

        // --------------------------
        // clear screen
        // --------------------------
        jsr $E544 


    
    // --------------------------
    // title (print)
    // --------------------------
    lda #1
    sta $0286
    lda #<title  
    ldy #>title  
    jsr $ab1e   

    // --------------------------
    // define sprite 'look'
    // --------------------------

    // set sprite pointer index
    // this, multiplied by $40, is the address
    // in this case, the address is $2000
    // $80 * $40 = $2000
    // hmmm

    // --------------------
    // _sprites init
    // _show stars
    // --------------------
       ldy #0 // counter   
        // use also for 
        sty score
        // sty scorehigh
    sprites:
       cpy #16
       bcs psoall
            lda #100
            sta $d000,y                
        psoall:    

        // sprite data
        cpy #31
        bcs nstartings
            lda #$80 // sprite data here
            sta $07f8,y // store +1 memory block 
            lda #112
            sta $2000+3*0,y // 3+*      
            lda #255-15    
            sta $2000+3*4,y  //3*4     
            lda #19 
            sta $2000+3*11,y      
        nstartings:

            // --------------------
            // stars
            // --------------------
            // inc $0286
            sty $0286
            lda #32
            jsr print                    
            jsr print     
            lda #46
            jsr print     
            jsr print


         // ship only - do always otherwise the ship is not 
         // at its place always!       
         lda #shipy
         sta $d001 

        iny        
        cpy #255-7-30-45
        bne sprites
    

    // --------------------
    // _buildings (petscii)
    // _define next colors
    // --------------------
        // surface
        ldy #0
surface:
            lda #205
            sta $0286
            jsr print
            inc $0286
            lda #184
            jsr print                    
            jsr print              
            jsr print   
            jsr print   

        iny
        cpy #6*4+12 
        bne surface

        // $0286 // use the char also for the text color .-)

    // --------------------
    // _the yard
    // --------------------
        ldy #0
railway:
    //        inc $0286
            lda #110
            jsr print
        iny
        cpy #87
        bne railway


    // --------------------
    // _enable sprites
    // --------------------
    lda #%11111111
    sta $d015 // all eight sprites on (all bits set)


    //------------------------
    // setup objects
    //------------------------
 
//    //  not necaissre
//        ldy #0
//    spry:
//             lda #50
//             sta $d000,y
//             lda #120
//             sta $d001,y
//        iny
//        iny
//        cpy #16
//       bne spry             



//------------------------
loop:
//------------------------




        // ----------------------
        // vysnc
        // ----------------------

        vsync:
          lda #$FF    // load 255 into A
        cmp $D012    //look if current rasterline equals 255
        bne vsync     // if no, goto wait


        // ----------------
        // collision
        // ----------------
        // 01 000100
        lda $d01e // collision read and clear at the same time ...            
        sta col

        // ----------------------
        // avatar collision?
        // ----------------------
        // direct collision? 
        //        lsr  // sprite 1+  >         
        // gameover_avatar:  
        //         bcs gameover_avatar   // avatar kill


        // ----------------
        // _manage sprites
        //  _set sprites
        // _collision
        // ----------------

        // ----------------
        // forall sprites
        // ----------------

        ldx #0
        
        // 010001 < 
        lda #1
        sta ind

behaviors:

                // --------------
                // load
                // --------------

                lda $d000,x
                sta tmpx
                lda $d001,x
                sta tmpy
                
                // -----------------
                // shoot & enemies                
                // -----------------

                cpx #2
                bcc behavior_enemies_end
  

                    // -----------------
                    // enemies down
                    // -----------------
                    // +
                    adc #1
                    
                    // -----------------
                    // flying up
                    // -----------------
                    // 4+
                    cpx #4
                    bcs third
                        // -
                        sbc #shoot_speed+1
                        // -
                        cmp #50+60
                        bcs third
                            lda $d000
                            sta tmpx
                            lda #shoot_start
                    third:
                    sta tmpy 

                    // -----------------
                    // game over
                    // -----------------
                   cmp #230
                   bcc gameoverit

/*
                  lda #<newgame  
                  ldy #>newgame  
                  jsr $ab1e   
*/


gameover:
                    lda #JOY_FIRE             // mask left movement (8 == bit 4 == %0000 1000)
                    bit $DC01               // bitwise "and" with joystick port 1
                    bne gameover   // if not active (==1), go to .input_up_check

                    jmp restart

gameoverit:           


  
                    // enemy? > bullets
                    // flying down ... 
                    cmp #50+25
                    bcs nnn 
                        lda counter
                        sta tmpx                                            
                    nnn:



                    // ---------------------------------
                    // collision object - shot
                    // ---------------------------------
                    // counter > 50

                        // collision
                        // https://codebase64.org/doku.php?id=base:simple_hardware_sprite_to_sprite_collision

                    /*
                        00000000 < 

                        0 weiss
                        1 braun

                        2 blue light
                        3 violet light

                        4 green
                        5 violet dark

                        6 yellow 
                        7 gray
                        

                    */                    

                    // version 1.0
                    lda ind
                    ora #%00000010 // compose    x0000010 - combination with 111..
                    sta tmp
                    lda col
                    and tmp
                    cmp tmp // invers!
                    bne hit

  /*

                    // version 2 - not working - why?
                    lda ind
                    ora #%00000010 // compose with shoot //   x0000010 - combination with 111..
                    bit col
                    bne hit // beq hit
*/


                    
                         // check if actual ..
                         lda $d003
                         cmp tmpy
                         bcs hit

                             lda #0 // take print value!
                             sta tmpy 

                             // print points
                             inc score
                             /*
                             lda score
                             cmp #255
                             bne nts
                                inc scorehigh
                                lda #0
                                sta score
                             nts:
                             */

                         // ----------------
                         // reset shot
                         // ----------------
                         lda $d000
                         sta $d002 // shot                         
                         lda #shoot_start
                         sta $d003 // shot
                      
                       hit:
 
                        nocollision:

                behavior_enemies_end:
             
               
                // --------------
                // store
                // --------------
                lda tmpx
                sta $d000,x
                lda tmpy
                sta $d001,x


        // ----------------
        // next
        // ----------------
            // x=x+2 
            inx 
            inx 
            // 00010000 < shifting
            asl ind

        cpx #spritesmax*2
        beq behaviors_e
            jmp behaviors
        behaviors_e:
        // ----------------
        // endfor
        // ----------------

        endbehavior:


        // ----------------------
        // counter for all 
        // and border
        // ----------------------
        // <----spread----->
        lda counter
        adc #7
        cmp #255-4-40  // more than 250 ... 
        bcc ttt
          lda #50+40
            // > 251
        ttt:       
        sta counter        


        // ----------------------
        // SCORE
        // -----------------------        
        // print score here


        // PRINT
        // https://www.lemon64.com/forum/viewtopic.php?t=79506

            // classic: -10 || rest>9

            ldx #0
            ldy #40-3
            clc
            jsr setpos 

              // score 0-255
              ldx score
              // lda scorehigh // high bytes
              lda #0
              jsr $bdcd // print a number 
              inc $0286 // blinking score

        // ----------------------
        // JOYSTICK
        // -----------------------        
        // LEFT&RIGHT
        lda #JOY_RIGHT                // mask left movement (8 == bit 4 == %0000 1000)
        bit $DC01               // bitwise "and" with joystick port 1
        bne joystick_notright   // if not active (==1), go to .input_up_check
            lda $d000
            adc #4
            sta $d000
joystick_notright:
        lda #JOY_LEFT             // mask left movement (8 == bit 4 == %0000 1000)
        bit $DC01               // bitwise "and" with joystick port 1
        bne joystick_notleft   // if not active (==1), go to .input_up_check
            lda $d000
            sbc #4
            sta $d000
joystick_notleft:


//------------------------
        jmp loop
//------------------------


title: 
        .text "ZA"
        .byte 118 
        .text "384 "      
//        .byte 119
        .byte $00 

/*
newgame: 
        .text "  FIRE!"       
        .byte $00 
*/      

// ****************************************
// THE END MY FRIEND
// ****************************************
