|
|
A continuación
podrás encontrar algunas rutinas básicas para la programación
gráfica en modo 13h optimizadas en ensamblador.
Cambia a un nuevo modo de video
void SetMode(char mode)
{
asm
xor ah, ah
asm
mov al, mode
asm
int 10h
} |
Borra una pantalla virtual de un color
determinado
void Cls(BYTE color,
BYTE *where)
{
asm
les di, [where]
asm
xor di, di
asm
mov al, [color]
asm
mov ah, al
asm
mov dx, ax
asm
db 0x66
asm
shl ax, 16
asm
mov cx, 16000
asm
mov ax, dx
asm
db 0xF3, 0x66, 0xAB
} |
Coloca un pixel en una pantalla virtual
void PutPixel(int x,
int y, BYTE color, BYTE *where)
{
asm
les di, [where]
asm
mov ax, y
asm
mov di, ax
asm
shl ax, 8
asm
shl di, 6
asm
add di, ax
asm
add di, x
asm
mov al, color
asm
mov es:[di], al
} |
Devuelve el color de un pixel de
una posición determinada de la pantalla
BYTE GetPixel(int x,
int y, BYTE *where)
{
asm
les di, [where]
asm
mov ax, y
asm
mov di, ax
asm
shl ax, 8
asm
shl di, 6
asm
add di, ax
asm
add di, x
asm
mov al, es:[di]
return
_AL;
} |
Mueve el contenido de una pantalla virtual
(64 Kb) a la VGA
void Flip(BYTE *source)
{
asm
push ds
asm
mov ax, 0xA000
asm
mov es, ax
asm
lds si, [source]
asm
xor di, di
asm
mov cx, 16000
asm
db 0xF3, 0x66, 0xA5 // rep movsd
asm
pop ds
} |
Mueve el contenido de una pantalla virtual
a otra
void FlipTo(BYTE *source,
BYTE *where)
{
asm
push ds
asm
les di, [where]
asm
lds si, [source]
asm
xor di, di
asm
mov cx, 16000
asm
db 0xF3, 0x66, 0xA5 // rep movsd
asm
pop ds
} |
Cambia las intensidades RGB de un
color determinado
void SetColor(BYTE color,
char red, char green, char blue)
{
asm
mov dx, 3C8h
asm
mov al, color
asm
out dx, al
asm
inc dx
// dx=3C9h
asm
mov al, red
asm
out dx, al
asm
mov al, green
asm
out dx, al
asm
mov al, blue
asm
out dx, al
} |
Obtiene las intensidades RGB de un color
determinado
void GetColor(BYTE color,
char *red, char *green, char *blue)
{
char
r, g, b;
asm
mov dx, 3C7h
asm
mov al, color
asm
out dx, al
asm
inc dx
asm
inc dx
// dx=3C9h
asm
in al, dx
asm
mov r, al
asm
in al, dx
asm
mov g, al
asm
in al, dx
asm
mov b, al
*red=r;
*green=g;
*blue=b;
} |
Cambia la paleta actual por una
pasada por parámetro
void SetPal(t_paleta
paleta)
{
asm
push ds
asm
lds si, paleta
asm
mov dx, 3C8h
asm
xor al, al
asm
out dx, al
asm
inc dx
asm
mov cx, 768
asm
rep outsb
asm
pop ds
} |
Obtiene la paleta actual
void GetPal(t_paleta
paleta)
{
asm
les di, paleta
asm
mov dx, 3C7h
asm
xor al, al
asm
out dx, al
asm
add dx, 2
asm
mov cx, 768
asm
rep insb
} |
Coloca un sprite en una pantalla virtual.
El tamaño máximo es de 255x255
En las dos primeras posiciones debe estar
el ancho y alto del sprite respectivamente.
void PutSprite(int x,
int y, BYTE *sprite, BYTE *where)
{
asm
push ds
// Salva los registros de segmento
asm
push es
asm
les di, [where] // es:di dirección de pantalla
virtual
asm
lds si, [sprite] // ds:si dirección del
sprite
asm
mov di, y
// Calcula el offset lo cual corresponde
asm
mov ax, di // al numero
de bytes para llegar al sprite
asm
shl di, 8
// desde el comienzo de la pantalla
asm
shl ax, 6
asm
add di, ax
asm
add di, x
asm
xor dx, dx // dx = 0
asm
xor bx, bx // bx = 0
asm
cld
// Incrementa los desplazamientos
asm
lodsw
// Recupera el primer word de DS:SI y lo guarda en AX
asm
mov dl, al // dl = ancho
asm
mov bl, ah // bl = alto
asm
mov cx, bx // Al registro de cuenta la altura
bucle1:
asm
mov bx, cx // Guardamos en bx el registro
de cuenta
asm
mov cx, dx // Al registro de cuenta la anchura
bucle2:
asm
lodsb
// Recupera un byte del sprite
asm
or al, al
// Para ver si es cero
asm
jz incdi
// si cero = parte transparente del sprite
asm
stosb
// Si no es cero lo visualizamos
asm
jmp seguir // y volver a empezar...
incdi:
asm
inc di
// Nos saltamos este byte
seguir:
asm
dec cx
asm
jnz bucle2 // Bucle de la anchura
asm
sub di, dx // Nos situamos en
la línea siguiente
asm
add di, 320
asm
mov cx, bx // Recuperamos contador de altura
asm
dec cx
asm
jnz bucle1 // Bucle de altura
asm
pop es
// Recuperamos registros de segmento
asm
pop ds
} |
Espera a que termine el retrazado vertical
de la pantalla
void WaitRetrace(void)
{
asm
mov dx, 03DAh
espera1:
asm
in al, dx
asm
test al, 08h
asm
jnz espera1
espera2:
asm
in al, dx
asm
test al, 08h
asm
jz espera2
} |
Ahora continuación podrás
encontrar la librería gráfica VGALIB.H actualizada con las
rutinas que vimos optimizadas en ensamblador.
Antes de compilar la librería, es
posible que tengan que activar el código para 80286, esto
lo encuentran en los compiladores Borland en:
Options | Compiler | Advanced Code Generation
| Instruction Set
|