pouët.net

Pacman256 by Red Sector Inc. [web]

;
;                 /\______          /\______          /\________
;             __\\\___    \_    __\\\___    \_    __\\\______   \
;            |      /      /   |      /      /   |     _____/    \_
;            |     /      /____|     /      /____|     \           |
;            |     \____       :      _____/     :      \          |
;            |        /                \                 \         |
;            |       /         .        \        .        \        |
;      __   _|_     /                    \                 \      _|_   __
;   \ \\_\ \\__\  _/           :          \_     :          \_   /__// /_// /
;            |____/_ _         :______ _         :______ _         |
;               \\\____________|  \\\____________|  \\\____________|
;
;    _______      _______      _______      _______      _______      _______
; _\\\__    \___\\\__    \___\\\__    \___\\\_____ \___\\\_____ \___\\\__    \_
;|    /______/|    /      /|    /      /|       /    |       /    |    /      /
;\            |   /      /_|   /      /_|      /     |      /     |   /      /_
;|\_______    :    _____/  :   \_____/  :     /      :     /      :   \____    |
;|      /     .     \      .     \      .    /       .    /       .     /      |
;|     /             \            \         /                          /       |
;|___         :___         :___         :___\        :___         :___/    sns |
;  \\_________: \\_________: \\_________: \\_________: \\_________: \\_________|
;
;                          R E D   S E C T O R   I N C
;
g equ p+6      ; Pacman256 by Baudsurfer/rsi 2015 aka olivier.poudade.free.fr
w equ word     ; A 256 bytes intro tested for XPSP3 and VMWare (set x=1) only
b equ byte     ; Presented at QB Multi-platform Party 2015 in Sülysáp/Hungary
x equ 0        ; greet Blabla Bon^2 DESiRE Live! MNDRN Onslaught RZR1911 TRBL 
org 100h       ; UkkO Ggn Fra Den g0blinish Sensenstahl & all assembly coders
  mov al,13h         ; psp+256, if pb or VMWare then set x equ 1 set video fx
  int 10h            ; bios video api
  mov bp,450h        ; DECOMPRESS AND DISPLAY MAZE
  cwd                ; dx=0
  mov cl,16h         ; board 22 non-symetric rows
a:mov ch,11h         ; board 16 cols+ 1 overlay (col17=col1)
u:inc dx             ; col++ inc byte [fs:450h]
  mov al,0dbh        ; al=dbh=219=wall
  rol w[m+si-100h],1 ; get next col bitmask in maze map array
  jc c               ; if not wall then obligatory dot
  mov al,0f9h        ; al=f9h=249=dot
c:mov w[fs:bp],dx    ; empty - update curs row/col pos
  int 29h            ; putchar short dos call
  dec ch             ; *this row's col total--
  jnz u              ; all cols of *this row processed ?
  lodsw              ; maze idx+=siz(w)
  mov dl,ch          ; crlf=xor dl,dl
  inc dh             ; row++ add dh,cl;inc dh;inc byte [fs:451h]
  loop a             ; INIT/DIPLAY PACMAN AND GHOSTS struct siz=6       
  mov edx,10100202h  ; disp extra col off. enable row|col dx symetry
  mov di,g           ; ghost status base idx
  mov cl,4           ; 4 ghost structs to init
e:mov al,1eh         ; al=glyph ascii val ah=putback tile glyph
  stosw              ; store ghost glyph+color
  ror edx,8          ; (col=16 row=2)/(col=2 row=16) symetry
  int 29h            ; display char /w dx=curs pos
  mov al,48h         ; default starting direction for ghost is up
  stosw              ; ghost direction (false kbd scancode) - w padded
  mov ax,dx          ; dw ghost position
  stosw              ; save ghost row/col pos di+=2
  loop e             ; all ghost structs init done ?
f:mov di,p           ; run - GAME LOOP rst to glyph struct base
h:in al,60h          ; delay - messy but shortest working code
  test al,al         ; is it make scancode ?
  js i               ; else skip break scancode 
  mov b [di+2],al    ; glyph direction
i:loop h             ; break - cx=65535 rollover from below loop
  mov cl,5           ; pacman+4 ghosts start /w pacman (should be cx)
j:mov dx,w[di+4]     ; switch - store rollback position
  mov w[fs:bp],dx    ; glyph col+row positions
  mov si,k           ; dir mov array for keys
  mov bl,4           ; test 4 arrow keyb keys
t:lodsb              ; direction - out: car ah=scancode al=ascii
  cmp al,b[di+2]     ; scancode=arrow ?
  lodsw              ; NULL last mov deltaX deltaY assumed in seg
  jz l               ; found asked deltas=>check collision
  dec bl             ; test all 4 NSWE directions 
  jnz t              ; test next direction     
l:add w[fs:bp],ax    ; collision - assumed NULL w at key+12
  mov ah,8           ; ah=read car and attrib @curs pos vga api
  IF x               ; BEG for some non-fully compatible bios clones
  push si            ; "Because of the IBM BIOS specifications may exist
  push di            ; some clone BIOSes which do not preserve SI or DI"
  push bp            ; "Some IBM PC ROM BIOSes destroy BP when in gfx modes"
  push bx            ; should not be necessary in gfx mode as all
  mov bh,0           ; other family calls have implict bh=dontcare
  END IF             ; END for some non-fully compatible bios clones
  int 10h            ; out: ah=car color al=car val bh=page number n/A
  IF x               ; BEG for some non-fully compatible bios clones
  pop bx             ; see Ralf Brown's interrupt list warnings
  pop bp             ; cf. http://www.ctyme.com/intr/rb-0098.htm
  pop di             ; cf. http://www.ctyme.com/intr/rb-0098.htm
  pop si             ; cf. http://www.ctyme.com/intr/rb-0098.htm
  END IF             ; END for some non-fully compatible bios clones
  test al,10b        ; if !(wall 11011011b or ghost 11110b) discrimination
  jz o               ; then move is legal and carry on
  xchg w[fs:bp],dx   ; rollback - is wall =>rollback move
  cmp cl,5           ; test if pacman or ghosts
  jz n               ; if pacman keep prev dir and skip frame
  inc b[di+2]        ; else try all 4 directions 
  jmp j              ; switch break happens above so loop
n:mov al,b[di+3]     ; put rollback
  mov b[di+2],al     ; in active position 
  inc bh             ; see alt direction below in "key" (k) 
  jnp j              ; cf. alt key below - tricky wrap-around 
  jmp s              ; and skip event since move faulty 
o:mov bl,b[di+2]     ; event - preserve al=glyph putback tile
  mov b[di+3],bl     ; and keep prev move dir
  cmp al,9           ; case new tile=pacman ? 
  jnz q              ; if not continue
  ret                ; death - else die and exit game to shell 
q:mov b[di+1],al     ; live - save putback tile
  cmp cl,5           ; test if pacman glyph
  jnz r              ; if not skip hardcoded replacement char 
  mov al,20h         ; space char replaces * exclusively for pacman
r:xchg w[fs:bp],dx   ; samescore - score display was stripped 
  int 29h            ; glyph putback tile=al=[di+1]  
  xchg w[fs:bp],dx   ; switch actual /w requested curs pos
  mov w dx,[fs:bp]   ; and restore it in dx
  mov w[di+4],dx     ; save previous curs pos
  mov al,[di+0]      ; glyph char
  int 29h            ; display glyph new position
s:add di,6           ; nokey - advance to next glyph struct
  loop j             ; next glyph movement
  jmp f              ; next game loop frame 
m dw 0ffffh          ; 11111111111111111b maze data 
  dw 8080h           ; 10000000100000001b little endian 17x22 playfield map
  dw 0b6b6h          ; 10110110101101101b shadow 17th column=1st column
  dw 0b6b6h          ; 10110110101101101b total=44 bytes
  dw 8000h           ; 10000000000000001b
  dw 0b5d6h          ; 10110101110101101b
  dw 8490h           ; 10000100100100001b
  dw 0f6b7h          ; 11110110101101111b
  dw 0f417h          ; 11110100000101111b
  dw 0f557h          ; 11110101010101111b
  dw 8140h           ; 00000001010000000b
  dw 0f5d7h          ; 11110101110101111b
  dw 0f417h          ; 11110100000101111b
  dw 0f5d7h          ; 11110101110101111b
  dw 8080h           ; 10000000100000001b
  dw 0b6b6h          ; 10110110101101101b
  dw 9004h           ; 10010000000001001b
  dw 0d5d5h          ; 11010101110101011b
  dw 8490h           ; 10010000100001001b
  dw 0bebeh          ; 10111110101111101b
  dw 8000h           ; 10000000000000001b
  dw 0ffffh          ; 11111111111111111b 
k db 48h,0,-1        ; up (alt=left) arrow - make scanc lsb,deltaX,deltaY
  db 50h,0,1         ; down (alt=up) arrow - cursor update compensated
  db 4bh,-1,-1       ; left (alt=right) arrow+ compensate sign extend 
  db 4dh,1,0         ; right (alt=down) arrow assumed null b
p dw 3209h,4dh,1008h ; glyp+putback/direction+rollback/col+row