[ create a new paste ] login | about

Link: http://codepad.org/FSy6TjcB    [ raw code | fork ]

hurracane - Plain Text, pasted on Nov 10:
; "First Argument" = the one at the bottom of the stack. Calling a function with 1 and 2 means we pushed 1 first, then 2
.MODEL small
.STACK 1024

video_segment           EQU         0A000h
width_13h               EQU         320        ; Amount of pixels per line in mode 13h
height_13h              EQU         200

colour_black            EQU         0
colour_white            EQU         15
colour_red              EQU         4
.DATA

.CODE

main PROC NEAR
    mov AH, 0               ; Initialize screen to mode 13h
    mov AL, 13h
    int 10h
    
    mov AX, video_segment   ; Store the video segment in the correct register
    mov ES, AX
    
    jmp label_game_loop_start     ; Start the game loop
main ENDP

macro_draw_pixel macro X, Y, colour
; Easy macro to prevent a lot of code duplication
    push AX                 ; Save register we're going to modify
    
    ;Push X, Y, Colour on the stack in this order.
    mov AX, X
    push AX
    mov AX, Y
    push AX
    mov AX, colour
    push AX
    call func_draw_pixel
    
    pop AX                  ; Restore modified register
endm

;; ##########--------------------##########--------------------##########
;; ##########--------------- General functions ----------------##########
;; ##########--------------------##########--------------------##########

func_exit PROC NEAR
    mov AX, 4c00h           ; Exit to DOS
    int 21h
func_exit ENDP

;; ##########--------------------##########--------------------##########
;; ##########------------- Pixel drawing functions ------------##########
;; ##########--------------------##########--------------------##########
func_draw_pixel PROC NEAR
; Func expects 3 16-bit arguments on the stack, pushed in this order:
;        - X-value: width on the screen (in pixels)
;        - Y-value: height on the screen (in pixels)
;        - Colour: Colour of the pixel

    push BP                 ; Save the base pointer
    mov BP, SP
    push AX                 ; Save registers the function modifies
    push BX
    
    ; -- Function code --    
    mov AX, width_13h
    mov BX, [BP+4][2]       ; [BP+4] Because we set BP to be the SP, which contains the BP register we just pushed, followed by the return address of our function.
                            ; Our second parameter on the stack is the Y value, because we assume we push X first, then Y.
    mul BX                  ; First pixel on the second line has offset 320, thus we multiply the Y-value with the width
    
    mov BX, [BP+4][4]       ; Get the X value, which is the last (or "deepest") argument
    add AX, BX              ; After getting the correct offset for the height, we need to add the X-offset
    
    mov DI, AX              ; Set the location of our pixel in DI
    mov AL, [bp+4][0]       ; Set the colour of the pixel, our third argument which was pushed last, thus it is on the top of the stack.
    mov ES:[DI], AL         ; Draw a pixel on location DI in the video segment ES with colour AL.
    ; -- End function code --
    
    pop BX                  ; Restore original values of BX and AX before we restore the original stack pointer (which was saved prior to pushing these values)
    pop AX
    
    mov SP, BP              ; Restore the original stack and base pointer
    pop BP
    ret 6                   ; Remove our arguments from the stack and return
func_draw_pixel ENDP

;; ##########--------------------##########--------------------##########
;; ##########--------- Keyboard interaction functions ---------##########
;; ##########--------------------##########--------------------##########
label_check_keyboard:
    mov AH, 01h             ; Check to see if a character is available in the buffer. 00h Waits for the user to press a key, whereas 01h just reads the current keyboard state
                            ; 01h doesn't automatically flush the buffer, thus we must do this ourselves or it will appear as if the key is being pressed constantly when it actually isn't.
    int 16h                 ; Call keyboard BIOS. Returns keycode in AX with AH being the scan code and AL being the ASCII code for the key.
    jz label_game_loop_after_keyboard      ; No keys pressed (Int 16h returns 0 when no keys pressed and 1 when a key is available).
    
    ; -- Key checks go here --
    cmp AL, 27              ; Escape key
    je func_exit
    cmp AL, 32              ; Space ( ) key
    je label_space_pressed
    cmp AL, 43              ; plus (+) key
    je label_plus_pressed
    ; -- End of key checks --
    ; If we reach this we don't have a function bound to the pressed key, but we should still flush the keyboard buffer
    jmp label_keyboard_flush
    
label_space_pressed:
    macro_draw_pixel 1, 2, colour_red
    jmp label_keyboard_flush
label_plus_pressed:
    macro_draw_pixel 1, 3, colour_white
    jmp label_keyboard_flush
    
label_keyboard_flush:
; Flush the keyboard buffer and jump back to the game loop
    mov AH, 0Ch             ; 0Ch in AH flushes the keyboard buffer, then executes the function specified by AL. If AL isn't 1, 6, 7, 8, or 0Ah, no other action will be taken
    mov AL, 0               ; Unspecified function, so no other action taken.
    int 21h
    jmp label_game_loop_after_keyboard

;; ##########--------------------##########--------------------##########
;; ##########------------ Game logic and game loop ------------##########
;; ##########--------------------##########--------------------##########
label_game_loop_start:
    ; Update game, then check for keys at the very end
label_game_loop_keyboard:
    jmp label_check_keyboard
    
label_game_loop_after_keyboard:
label_game_loop_restart:
    jmp label_game_loop_start
end main



Create a new paste based on this one


Comments: