[Home]DDD/Pong

ec2-18-223-185-228.us-east-2.compute.amazonaws.com | ToothyWiki | DDD | RecentChanges | Login | Webcomic

;If you have built an 64k computer then it must have this...
;: Is there a .dc command in the assembler to allocate globals?  What about strings?
;: dat is the directive for allocating data. Quoted strings are allowed, and get written out as one word per character. Ooooh, it works! You should post a link here their [forum], they have a section for DCPU16 apps ;) --MoonShadow

;::Ohh - Hardware for clocks and interrupts.  Just like having a real computer!  You know, like the one running the emulator :)


; [Load this page in the emulator]

;
; Trampoline entry point - initialise Hardware
.org 0
	set i, 0xFFFF	; counter
	hwn j			; number of attached devices
	
1:	
    add i, 1	; next device
    ife i, j	; all enumerated?
		set pc, 4f	; bail
   
	hwq i		; load info about this device into a, b, c, x, y
	
    ; http://dcpu.com/highnerd/rc_1/lem1802.txt
    ife b, 0x7349
    ife a, 0xf615
        set pc, 2f

    ; http://dcpu.com/highnerd/rc_1/keyboard.txt
    ife b, 0x30cf
    ife a, 0x7406
        set pc, 3f
    
    b 1b	; nothing we care about; go around

2:
	set [screen], i	; store the device id
	; configure it how it used to be in the old days:
	; vram at 0x8000, character ram at 0x8180 and prepopulated, palette left as default
	
	set a, 0	
	set b, 0x8000
	hwi i
	set a, 4
	set b, 0x8180
	hwi i
	set a, 1
	set b, 0x8180
	hwi i
	
	b 1b	; carry on examining devices	

3:
	set [keyboard], i	; store the device id
	b 1b				; carry on examining devices	
    
4:
	jsr main;
	hcf 0;

screen:		dat 0
keyboard:	dat 0

; main()
;   Set up the game and run the main loop
:main
    ; Speed
    set A, 0x1000;
    jsr Game_initialise;

    ; Draw the screen
    jsr Game_displayTitle;
    jsr Bat_draw;
    jsr Ball_draw;

    ; Wait for the player to start
    jsr Keyboard_getWait;

    ; Play the game
:main_loop:
    jsr Keyboard_get;
    jsr Game_handlePlayerInput;

    ; Check the delay loop
    jsr Game_tick;
    ife A, 0x0;
      set PC, main_loop

    ; Time to move the ball
    jsr Ball_hide;
    jsr Ball_move;
    jsr Ball_draw;

    ; Animate the logo
    jsr Game_displayTitle;
    set PC, main_loop;



; Game_initialise( delayLoop A )
;   Set up the game and clear the screen
:Game_initialise
    set [Game_g_gameOver], 0x0;
    set [Game_g_speed], A;
    set [Game_g_tickTimer], 0x0;
    set [Game_g_animation], 0x0;

    jsr Bat_reset;
    jsr Ball_reset;

    set A,0xf;
    jsr Screen_cls;

    set	A,0x4;
    jsr	Screen_border;
    ret;

; Game_g_gameOver [word]
:Game_g_gameOver
   dat 0;

; Game_g_speed [word]
:Game_g_speed
   dat 0;

; Game_g_tickTimer [word]
:Game_g_tickTimer
   dat 0;

; Game_g_animation [word]
:Game_g_animation
   dat 0;


:Game_displayTitle_pong
   dat " PONG ", 0;

:Game_displayTitle_gameOver
   dat "Game Over", 0;

; Game_displayTitle()
;    Display the "Pong" and "Game Over" messages 
:Game_displayTitle

    ; Print PONG
    add [Game_g_animation], 1;

    set A, [Game_g_animation];
    ifg 0x8000, A;
      set PC, Game_displayTitle_checkRHS;

    ; Moving right to left
    mul A, 0xffff;
    set PC, Game_displayTitle_show;

:Game_displayTitle_checkRHS
    jsr Screen_width;
    sub A, 0x7;
    set B, A;
    set A, [Game_g_animation];
    ifg B, A;
      set PC, Game_displayTitle_show;

    ; Hit RHS
    mul [Game_g_animation], 0xffff;

:Game_displayTitle_show
    set B, 0x0;
    jsr Screen_setCursor;

    set A, Game_displayTitle_pong;
    set B, 0x1f00;
    jsr Screen_print;

    ife [Game_g_gameOver], 0x0;
      ret;

    ; Print GAME OVER
    set A, 0xB;
    set B, 0x4;
    jsr Screen_setCursor;

    set A, Game_displayTitle_gameOver;
    set B, 0x1400;
    jsr Screen_print;
    ret;


; Game_handlePlayerInput( key A )
;   Handle player inout and show the bat
:Game_handlePlayerInput
    ; Is the player moving left or right?
    set X,0x0;
    ife A, 0x82;
      sub X, 0x1;

    ife A, 0x83;
      add X, 0x1;

    ; Player is stationary
    ife X, 0x0;
      ret;

    ; Move the bat
    set [--SP], X;
    jsr Bat_hide;
    set A,[SP++];
    jsr Bat_move;
    jsr Bat_draw;
    ret;

; Game_tick() : A (non-zero if we have to do something)
;     Returns true when we have exceeded the delay loop
:Game_tick
    set A,0;
    add [Game_g_tickTimer],1;
    ifg [Game_g_speed],[Game_g_tickTimer];
      ret;

    ifn [Game_g_gameOver], 0x0;
      ret;

    set [Game_g_tickTimer],0x0;
    set A,1;
    ret;

; Game_setGameOver()
;     Called when the player has missed the ball
:Game_setGameOver
    set [Game_g_gameOver], 0x1;
    jsr Game_displayTitle;
    ret;



; Bat_reset()
;    Initalise the Bat
:Bat_reset
   set [Bat_width], 0x8;
   set [Bat_x], 0x0;
   ret;

; Bat Size
:Bat_width [word]
   dat 0;

:Bat_x
   dat 0;


; Bat_move( dx A )
;    The user has asked the bat to move left or right
:Bat_move
   set I, [Bat_x];
   add I, A;

   ; Check not off the left
   ifg 0x0, I;
     ret;

   ; Check not off the right
   jsr Screen_width;
   sub A, [Bat_width];
   ifg I,A;
     ret;

   set [Bat_x], I;
   ret;

; Bat_drawWithChar( charToDraw A )
;    Hide or draw the bat
:Bat_drawWithChar
   set [--SP],A;
   jsr Screen_height;
   set B, A;
   sub B, 0x1;
   set A, [Bat_x];
   jsr Screen_setCursor;

   set J, [Bat_width];
   set A,[SP++];
:Bat_draw_loop
   ife J, 0x0;
     ret;
   jsr Screen_putChar;
   sub J, 0x1;
   set PC, Bat_draw_loop;

; Bat_draw()
;    Draw the bat
:Bat_draw
   set A, 0xf120;
   jsr Bat_drawWithChar;
   ret

; Bat_hide()
;    Hide the bat
:Bat_hide
   set A, 0x1f20;
   jsr Bat_drawWithChar;
   ret

; Ball_reset()
;    Initialise the Ball
:Ball_reset
   set [Ball_x],  0x88;
   set [Ball_y],  0x8;
   set [Ball_dx], 0x1;
   set [Ball_dy], 0x1;
   set [Ball_bounceCount], 0x0;
   ret;

; Ball position and speed (*8 of screen resolution)
:Ball_x
   dat 0;

:Ball_y
   dat 0;

:Ball_dx
   dat 0;

:Ball_dy
   dat 0;

:Ball_bounceCount
   dat 0;


; Ball_drawWithChar( character A )
:Ball_drawWithChar
   set [--SP], A;

   set A, [Ball_x];
   set B, [Ball_y];
   shr A, 3;
   shr B, 3;

   jsr Screen_setCursor;

   set A, [SP++];
   jsr Screen_putChar;
   ret;

; Ball_draw()
:Ball_draw
   set A, 0x1f4f;
   jsr Ball_drawWithChar;
   ret;

; Ball_hide()
:Ball_hide
   set A, 0x1f20;
   jsr Ball_drawWithChar;
   ret;

; Ball_move()
:Ball_move
   ; X direction
   set X,[Ball_x];
   add X,[Ball_dx];

   ; Left wall
   ifg 0x8000, X;
     set PC,Ball_move_checkRightWall;

   ; Bounce left
   mul [Ball_dx], 0xffff;
   set Y, X;
   set X, 0;
   sub X, Y;

:Ball_move_checkRightWall
   jsr Screen_width;
   sub A, 1;
   shl A, 3;
   ifg A, X;
     Set PC,Ball_move_xOk;

   ; Bounce right
   mul [Ball_dx], 0xffff;
   set Y, X;
   sub Y, A;
   set X, A;
   sub X, Y;

:Ball_move_xOk
   set [Ball_x], X


   ; Y direction
   set Y,[Ball_y];
   add Y,[Ball_dy];

   ; Top wall
   ifg Y, 0x8
     set PC,Ball_move_checkDead;

   ; Bounce top
   mul [Ball_dy], 0xffff;
   set Z, Y;
   sub Z, 0x8;
   set Y, 0x8;
   sub Y, Z;

:Ball_move_checkDead
   jsr Screen_height;
   shl A, 3;
   ifg A, Y;
      set PC,Ball_move_checkBat;
   
   ;Game Over
   jsr Game_setGameOver;
   ret;

:Ball_move_checkBat
   jsr Screen_height;
   sub A, 2;
   shl A, 3;
   ifg A, Y;
      set PC,Ball_move_yOk;

   ; Is the bat here?
   set X,[Bat_x];
   shl X, 3;
   ifg X, [Ball_x];
      set PC,Ball_move_yOk;

   set X,[Bat_x];
   add X,[Bat_width];
   shl X, 3;
   ifg [Ball_x], X
      set PC,Ball_move_yOk;

   ; Bounce off bat
   mul [Ball_dy], 0xffff;
   set Z, Y;
   sub Z, A;
   set Y, A;
   sub Y, Z;

   ; Make it exciting
   add [Ball_bounceCount],1;
   ifg 5, [Ball_bounceCount];
     set PC, Ball_move_passthrough; 

   ; make the bat smaller
   jsr Bat_hide;
   sub [Bat_width], 0x1;
   jsr Bat_draw;

   add [Ball_dy], 3;
   set [Ball_bounceCount],0;

Ball_move_passthrough:
   ifg [Ball_dy], 0xfffc;
     sub [Ball_dy], 1;

   set X,[Bat_width];
   shr X, 1;
   add X,[Bat_x];
   shl X, 3;
   sub X, [Ball_x];

   sub [Ball_dx], 2;
   ifg 0x8000,X;
     set PC,Ball_move_yOk;
   add [Ball_dx], 4;
   
:Ball_move_yOk
   set [Ball_y], Y
   ret;



; Screen_cursorPosition [word]
:Screen_g_cursorPosition
   dat 0;

; Screen_width() : Width A
:Screen_width
   set A, 0x20;
   ret;

; Screen_height() : Height A
:Screen_height
   set A, 0xc;
   ret;

; Screen_setCursor( xposition A, y position B )
;    Set the write position of the cursor
:Screen_setCursor
   set I, A;
   jsr Screen_width;
   mul B, A;
   add I, B;
   set [Screen_g_cursorPosition], I;
   ret;

; Screen_putChar( character A )
;    Write a character
:Screen_putChar
   set I, [Screen_g_cursorPosition];
   set [0x8000+I],A
   add [Screen_g_cursorPosition], 0x1;
   ret;

; Screen_print( character[] A, colourToBor B )
;    Write a string
:Screen_print
   set J, A;
:Screen_print_loop
   set A, [0x0+J];

   ife 0x0, A;
     ret;

   bor A,B;
   jsr Screen_putChar;
   add J, 0x1;
   set PC, Screen_print_loop;

; Screen_cr()
;   New line
:Screen_cr
   jsr Screen_width;

   set B, [Screen_g_cursorPosition];
   div B,A;
   add B,0x1;
   
   set A, 0x0;
   jsr Screen_setCursor;
   ret;


; Screen_cls( backgroundColour A )
;  Clear the screen
:Screen_cls
    and A, 0xf;
    set X, A;
    shl X, 8;
    bor X, 0x20;

    jsr Screen_width;
    set Y, A;
    jsr Screen_height;
    mul Y, A;
    sub Y, 0x1;

:Screen_cls_loop
   set [0x8000+Y], X
   sub Y, 0x1;
   ifn Y, 0xffff;
     set PC, Screen_cls_loop;

   ; Set cursor top left
   set A, 0x0;
   set B, 0x0;
   jsr Screen_setCursor;
   ret;

; Screen_border( borderColour A )
;    Set the border colour
:Screen_border
   and A,0xf; 
   and [0x8280], 0xfff0;
   bor [0x8280],A;
   
   set push, a
   set push, b
   set a, 3
   set b, [0x8280]
   hwi [screen]
   set b, pop
   set a, pop
   
   ret;

; Keyboard_get() : A next character (or 0)
;   Dequeue the next character and return it (0 if none available)
:Keyboard_get
   set push, c
   set a, 1
   hwi [keyboard]
   set a, c
   set c, pop
   ret;
   
; Keyboard_getWait() : A next character
;   Wait for the user to press a key 
:Keyboard_getWait
   jsr Keyboard_get;
   ife A,0x0;
     set PC, Keyboard_getWait;
   ret;


;
;


ec2-18-223-185-228.us-east-2.compute.amazonaws.com | ToothyWiki | DDD | RecentChanges | Login | Webcomic
This page is read-only | View other revisions | Recently used referrers
Last edited April 27, 2012 10:33 pm (viewing revision 15, which is the newest) (diff)
Search: