Revisando (muy) antiguos proyectos encontré este trocito de código en ensamblador (o assembler) que hice (o copié, ya no recuerdo) alrededor de 1992, para el juego Defender, que en realidad es un remake de Command Comander, sólo que no sabíamos que se llamaba así... :P
El código en ensamblador es para procesadores 80286, las famosas PC AT 286. Y pinta el pixel en el modo gráfico #13 de las VGA (320x200 pixeles y 256 colores).
Está preparado para funcionar dentro del código fuente del Turbo Pascal, por eso está declarado como una función, con parámetros de coordenada X/Y de inicio y fin, el color a pintar y otro parámetro que no sé que es :D
No tengo idea si esto le será de utilidad a alguien, espero que sí.
Procedure LineaASM( x1_,y1_,x2_,y2_:Integer; Color_,Poner_:Byte); assembler;Relacionado: El algoritmo de Bresenham
var
x1,
y1,
x2,
y2,
delp,
delr,
delrx,
delry,
deldx,
deldy,
delre,
delde :Word;
asm
{ tomar parametros }
mov ax,x1_
mov x1,ax { X1 }
mov ax,y1_
mov y1,ax { Y1 }
mov ax,x2_
mov x2,ax { X2 }
mov ax,y2_
mov y2,ax { Y2 }
{ inc de perder todo }
mov si,1
mov di,1
{ calcular /x2-/y1/ }
mov dx,y2_
sub dx,y1_
jge @almay
neg di
neg dx
@almay:
mov deldy,di
{ calcular /x2-x1/ }
mov cx,x2
sub cx,x1
jge @almax
neg si
neg cx
@almax:
mov deldx,si
{ clasificar /y2-y1/ y /x2-x1/ }
cmp cx,dx
jge @mover
mov si,0
xchg cx,dx
jmp @alma
@mover:
mov di,0
{ almacenar delr,delp,delrx y delry }
@alma:
mov delr,cx
mov delp,dx
mov delrx,si
mov delry,di
{ obtener valores iniciales para x e y }
mov si,x1
mov di,y1
{ calcular valor inicial e incrementos para la funcion de error }
mov ax,delp
sal ax,1
mov delre,ax
sub ax,cx
mov bx,ax
sub ax,cx
mov delde,ax
{ ajustar contador }
inc cx
{ ------------------------------ }
{ estructura del bucle principal }
{ ------------------------------ }
@bucle:
{ dibujar punto en (x,y) }
push bx
push ax
push cx
push es
mov BX,SI { si=x }
mov AX,DI { di=y }
{ PQLL: AX = coordenada y (0-199)
; BX = coordenada x (399)
;
; Devuelve: BX = desplazamiento de byte en el buffer
; ES = segmento del buffer de v¡deo}
xchg ah,al { AX := 256 * y }
add bx,ax { BX := 256 * y + x }
shr ax,1
shr ax,1 { AX := 64 * y }
add bx,ax { BX := 320 * y + x }
mov ax, $A000
mov es,ax { ES:BX := direcci¢n de byte del pixel }
{ pone el punto }
mov al,Color_ { Color }
mov es:[bx],al
pop es
pop cx
pop ax
pop bx
cmp bx,0
jge @diagonal
{ caso linea recta }
@recta:
add si,delrx
add di,delry
add bx,delre
loop @bucle
jmp @fin
{ caso linea diagonal }
@diagonal:
add si,deldx
add di,deldy
add bx,delde
loop @bucle
{ restaurar registros afectados }
@fin:
end;
Un interesante aporte: Proyectos robóticos
En la web Proyectos robóticos se pueden encontrar programas con ejemplos del Algoritmo de Bresenham para 2D, 3D... hasta 6D. Este algoritmo no sólo sirve para hacer líneas.
En mi caso lo uso para coordinar los movimientos de un simulador de Brazo Robot de 5 grados de libertad (la mano no se cuenta como grado de libertad). Todo el brazo se mueve a la vez para la realización de cualquier trayectorias. En mis simuladores el brazo robot llega a dibujar. Para esta tarea uso los ficheros de extensión ".PLT" (HPGL).
Los ejemplos están escrito en FreeBasic y en este caso compatibles con QBasic. Las variables están declaras en tipo, así que es bien fácil traducirlo a cualquier lenguaje de programación.
3 Comentarios
y cual es la utilidad de esta mierda?
ResponderEliminarPues por ejemplo: Admirar la belleza de un juego escrito en puro ensamblador.
ResponderEliminarley_de_plomo: me gusta esa utilidad :)
ResponderEliminar