Hola a todos. Como os adelanté en otros temas, he invertido algo de tiempo en hacer un juego compacto, y el resultado os lo dejo aquí mismo, para que lo disfrutéis. Se trata del juego de la serpiente de toda la vida, en una implementación muy sencilla, pero funcional, con gráficos e incluso sonido en sólo 256 bytes de código.
Si alguien se anima, que compile las versiones BIN y ROM y que las suba al foro mismo como descarga, que desde donde estoy no puedo hacerlo yo mismo. Gracias por vuestra ayuda.
Espero que lo disfrutéis. Eso sí, el código está bastante ofuscado. Más que analizarlo, deberíais jugarlo.
;-----------------------------------------------------------------------
; TINY SNAKE v.0.10
;-----------------------------------------------------------------------
; The classic snake game coded for MSX in only 256 bytes!
;-----------------------------------------------------------------------
; (C) 2006, Karoshi Corporation
; Coded by Eduardo Robsy Petrus
;-----------------------------------------------------------------------
; Started on 24th May 2006
; Finished on 26th May 2006
;-----------------------------------------------------------------------
; asMSX directives
;-----------------------------------------------------------------------
; Headers to create a ROM
;-----------------------------------------------------------------------
; .bios
; .page 2
; .rom
; .start INIT
; .db "[KO03] SNAKE CLASSIC v.0.10",1Ah
; VARIABLES equ 0C000h
;-----------------------------------------------------------------------
; Headers to create a Basic binary
;-----------------------------------------------------------------------
.bios
.page 3
.basic
.start INIT
VARIABLES equ 0C100h
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
; VRAM position constants
;-----------------------------------------------------------------------
NAMTBL equ 1800h
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
; Program code
;-----------------------------------------------------------------------
INIT:
; Init SCREEN 1
call INIT32
; Clear RAM space
ld hl,LENGTH
@@CLEAR:
ld [hl],0
inc hl
ld a,0C8h
cp h
jr nz,@@CLEAR
; Draw vertical lines
ld hl,SCREEN+32
ld de,SCREEN+32*23
ld b,32
ld a,219
@@BOUNDS:
ld [hl],a
ld [de],a
inc hl
inc de
djnz @@BOUNDS
; Draw horizontal lines
ld de,SCREEN+95
ld [de],a
ld [hl],a
inc de
ld bc,32*20
ldir
; Init snake position
ld hl,SCREEN+32*12+15
ld [SNAKE],hl
; Init food position
inc h
ld [hl],4
; Init snake length
ld hl,LENGTH
inc [hl]
; Main program
MAIN_LOOP:
; Copy positions
ld hl,SNAKE+511
ld de,SNAKE+513
ld bc,512
lddr
; Read cursor/joystick
xor a
call GTSTCK
; Convert to direction code
ld c,a
ld b,0
ld hl,CONVERSION
add hl,bc
ld a,[hl]
; Store direction code
ld hl,DIRECTION
or a
jr z,@@MOVE
; Not opposite direction
ld c,a
ld a,[hl]
add c
cp 5
jr z,@@MOVE
; Store new direction
ld [hl],c
; Convert direction to movement
@@MOVE:
ld a,[hl]
add a
ld c,a
ld hl,MOVEMENTS
add hl,bc
ld e,[hl]
inc hl
ld d,[hl]
; Update position
ld hl,[SNAKE]
add hl,de
ld [SNAKE],hl
; Check if element present
ld a,[hl]
or a
jr z,@@EMPTY
; Check if it is food or block
rlca
jr nc,@@FOOD
; Collision: wait space to restart
@@WAIT:
xor a
call GTTRIG
jr z,@@WAIT
jp INIT
; Relocate food
@@FOOD:
ld a,r
add a
ld c,a
ld hl,SCREEN+65
add hl,bc
add hl,bc
ld a,[hl]
or a
; If destination is not empty, relocate
jr nz,@@FOOD
; Put it on the buffer
ld [hl],4
; Increase length
ld hl,LENGTH
inc [hl]
; Check if maximum size (255)
jr nz,@@BIGGER
dec [hl]
@@BIGGER:
; Increase score
; -First byte
ld hl,SCORE
ld a,01h
add [hl]
daa
ld [hl],a
; -Second byte
inc hl
ld a,[hl]
adc b
daa
ld [hl],a
; Dump to screen buffer
ex de,hl
ld hl,SCREEN
ld b,2
; BCD byte to ASCII codes
@@NUMBER:
ld a,[de]
ld c,a
rra
rra
rra
rra
and 0Fh
add 30h
ld [hl],a
inc hl
ld a,c
and 0Fh
add 30h
ld [hl],a
inc hl
dec de
djnz @@NUMBER
; Eating sound
call BEEP
@@EMPTY:
; Render snake
ld a,[LENGTH]
ld b,a
ld hl,SNAKE
push hl
@@RENDER:
ld e,[hl]
inc hl
ld d,[hl]
inc hl
ld a,219
ld [de],a
djnz @@RENDER
; Update screen
halt
halt
halt
ld hl,SCREEN
ld de,NAMTBL
ld b,3
call LDIRVM
; Erase trail
ld a,[LENGTH]
dec a
ld c,a
pop hl
add hl,bc
add hl,bc
ld e,[hl]
inc hl
ld d,[hl]
ex de,hl
ld [hl],b
; Loop
jp MAIN_LOOP
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
; Tables
;-----------------------------------------------------------------------
; Stick results to directions
CONVERSION:
db 0,1,0,3,0,4,0,2,0
; Directions to screen offsets
MOVEMENTS:
dw 0,-32,-1,1,32
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
; Print code size
;-----------------------------------------------------------------------
FINISH:
.print FINISH-INIT
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
; Variables
;-----------------------------------------------------------------------
.org VARIABLES
; Length of the snake
LENGTH:
ds 1
; Snake direction
DIRECTION:
ds 1
; Score (2 bytes packed BCD)
SCORE:
ds 2
; Screen buffer
SCREEN:
ds 0400h
; Snake positions
SNAKE:
ds 0200h
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
; And that's all, folks! Enjoy it.
;-----------------------------------------------------------------------