Ability to use an unique screen buffer

Advanced game related topics
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Ability to use an unique screen buffer

Post by Psychophanta »

Are there a way to use a screen with an unique screen buffer.

I need to show a sprite as mouse pointer at time i want to see plotted static pixels on screen. I have find nothing about this. :cry:
dmoc
Enthusiast
Enthusiast
Posts: 739
Joined: Sat Apr 26, 2003 12:40 am

Post by dmoc »

me no understand you :cry:
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

I made it:

Code: Select all

If InitMouse()=0 Or InitSprite()=0 Or InitKeyboard()=0 Or InitPalette(10) = 0
  MessageRequester("Error", "Can't open DirectX", 0)
  End
EndIf
DefType .f

#bitplanes=8    ; =====> 256 colors
#RX=800:#RY=600
#b=15

If OpenScreen(#RX,#RY,#bitplanes,"circl")=0:ReleaseMouse(1):End:EndIf

LoadPalette(1,"Sprite.bmp");  <--- your mouse pointer sprite
DisplayPalette(1)
LoadSprite(0,"Sprite.bmp",0)
MouseLocate(#RX/2,#RY/2)
ExamineMouse():x=MouseX():y=MouseY()
GrabSprite(1,x,y,32,32,0)
FlipBuffers()
GrabSprite(2,x,y,32,32,0)
FlipBuffers()

Xr=61:Yr=0
d=1/35;<-speed
k=Sqr(1+Pow(d,2))
c=Sqr(2+Pow(d,2)+1/Pow(d,2))
Repeat

  ExamineMouse()
  Gosub r1
  
  ExamineKeyboard()
Until KeyboardPushed(#PB_Key_Escape)
ReleaseMouse(1):FreeSprite(2):FreeSprite(1):FreeSprite(0):FreePalette(1):CloseScreen()
End

r1:
    xr=Xr:yr=Yr
    xa=-yr*d:ya=xr*d

    xold=x:yold=y
    DisplaySprite(1,xold,yold)
    x=MouseX():y=MouseY()
    GrabSprite(1,x,y,32,32,0)
    DisplayTransparentSprite(0,x,y)
    StartDrawing(ScreenOutput())
    Plot(x+xr,y+yr,1)
    StopDrawing()
    
    FlipBuffers()

    DisplaySprite(2,xold,yold)
    GrabSprite(2,x,y,32,32,0)
    StartDrawing(ScreenOutput())
    Plot(x+xr,y+yr,1)
    StopDrawing()

    Xr=(xa+xr)/k:Yr=(ya+yr)/k
                              
    ExamineMouse()
Return
Note that i don't use ClearScreen() function or other similars, i only use GrabSprite() to save the rectangle where the sprite will be drawn, in order to leave intact the background of the sprite.
However, i don't know why appear a flicking line at top of screen :?:

dmoc, when we open a screen with OpenScreen() function we opening 2 buffers of the same screen size. My question was if it is possible to work with ONLY ONE of these buffers, but i guess no. :?
And it could be useful for some concrete things, i think.
In my example i try to simulate one buffer only, writting the same drawing info in both two.
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

The last code works, but i realize that when we put a sprite on screen (with DisplaySprite() or similar function), we are drawing it onto both two buffers, but not with 2D drawing commands. So this is a corrected:

Code: Select all

;----------------------------------------------------------------------------
;Son 2 algoritmos bien distintos que hacen girar circularmente un item
;alrededor de un punto (centro).
;La hazana es que en ninguno de los dos se usa la trigonometria y por
;tanto son muy rapidos.
;----------------------------------------------------------------------------

If InitMouse()=0 Or InitSprite()=0 Or InitKeyboard()=0 Or InitPalette(10) = 0
  MessageRequester("Error", "Can't open DirectX", 0)
  End
EndIf
DefType .f

#bitplanes=8    ; =====> 256 colores
#RX=800:#RY=600

If OpenScreen(#RX,#RY,#bitplanes,"")=0:End:EndIf

LoadPalette(1,"Sprites\h2.bmp")
DisplayPalette(1)
LoadSprite(0,"Sprites\h2.bmp",0)
SW.w=SpriteWidth(0):SH.w=SpriteHeight(0)
MouseLocate(#RX/2,#RY/2)
ExamineMouse():x=MouseX():y=MouseY()
Gosub text
GrabSprite(1,x,y,SW,SH,0)
FlipBuffers()
Gosub text

X_r=61:Y_r=0       ;Inicializacion del vector director del radio.
d=1/30             ;Velocidad de giro. El signo da el sentido del giro (en la primera rutina).
k=Sqr(1+Pow(d,2))
c=Sqr(2+Pow(d,2)+1/Pow(d,2))
Repeat

  ExamineMouse()
  Gosub r

  ExamineKeyboard()
Until KeyboardPushed(#PB_Key_LeftControl)
ReleaseMouse(1):FreeSprite(1):FreeSprite(0):FreePalette(1):CloseScreen()
End

;**********************************************************************************
r:
  If MouseButton(1)
    xr=X_r:yr=Y_r       ;Actualizo vector director del radio (distancia desde el
                        ;centro al objeto)=(x,y)->(x+xr,y+yr).
    xa=-yr*d:ya=xr*d    ;(xa,ya) es un vector normal al (xr,yr)
                        ;pero con el modulo multiplicado por la
                        ;constante preestablecida d.
    xold=x:yold=y
    x=MouseX():y=MouseY()       ;Actuales coordenadas del centro

    DisplayTransparentSprite(0,x,y);draw our mouse pointer sprite just here
    Gosub draw;<--Draw on this buffer

    FlipBuffers();<--swap buffers
    DisplaySprite(1,xold,yold);<--restore the old background
    GrabSprite(1,x,y,SW,SH,0);<--and save the new one
    Gosub draw;<--Draw on this buffer
    X_r=(xa+xr)/k:Y_r=(ya+yr)/k  ;Nuevo vector director del radio.
                              ;NOTA: Probar con X_r=(xa-xr)/k:Y_r=(ya-yr)/k
                              ;Se suman los vectores directores (xa,ya)
                              ;y (xr,yr) dando lugar a un vector director
                              ;hipotenusa del triangulo formado por
                              ;aquellos dos. Este nuevo vector debe
                              ;ser recortado para que su modulo sea
                              ;el de el radio, o sea el de el cateto
                              ;(xr,yr). Dicho recorte viene dado por
                              ;la cte. k, establecida como sqr(1+d^2)
                              ;(NOTA: teorema de pitagoras y proporcio-
                              ;nalidad de triangulos).
                              ;Ahora (X_r,Y_r) es el nuevo vector director,
                              ;o sea, el que se buscaba.

    ExamineMouse()
;NOTA: En esta rutina d es el valor de la tangente del angulo avanzado
;en cada bucle, o sea la pendiente del vector (X_r,Y_r) respecto al anterior (xr,yr).
;El avance maximo pues, sera de 90 grados cuando d=infinito.
;El sentido de giro depende del signo de d.
;---------------------------------------------------------------------------------
  ElseIf MouseButton(2)
    xr=X_r:yr=Y_r       ;Vector director del radio (distancia del
                        ;centro al objeto)=(x,y)->(x+xr,y+yr)
    xa=yr*d:ya=-xr*d    ;(xa,ya) es un vector normal al (xr,yr)
                        ;pero con el modulo multiplicado por la
                        ;constante preestablecida d.

    xold=x:yold=y
    x=MouseX():y=MouseY()      ;Actuales coordenadas del centro
    DisplayTransparentSprite(0,x,y);draw our mouse pointer just here
    Gosub draw;<--Draw on buffer

    FlipBuffers();<--swap buffers

    DisplaySprite(1,xold,yold);<--restore the old sprite background
    GrabSprite(1,x,y,SW,SH,0);<--and save the new one

    Gosub draw;<--Draw on the other buffer

    X_r+(ya-yr)*2/c:Y_r+(xr-xa)*2/c ;El vector director (xr-xa,yr-ya)
                               ;es la hipotenusa del triangulo
                               ;(0,0)-(xr,yr)-(xa,ya).
                               ;(ya-yr,xr-xa) es por tanto su normal.
                               ;(NOTA:con (yr+ya,-xa-xr) se invierte
                               ;el sentido del giro.)
                               ;Se reduce dicha normal multiplican-
                               ;dola por 2/c, y finalmente se tras-
                               ;lada el vector director obtenido
                               ;al punto item (xr,yr) obteniendo
                               ;un nuevo (X_r,Y_r).
                               ;(NOTA:c es hallada mediante la aplicacion
                               ;del teorema de pitagoras y la propor-
                               ;cionalidad de triangulos, igual que k).
    ExamineMouse()
;NOTA: En esta otra rutina, mas compleja que la anterior, el valor de d
;corresponderia a una funcion trigonometrica que seria la longitud, en el
;eje de ordenadas, desde el origen de coordenadas hasta el punto de corte
;con la recta normal, tomada esta desde el extremo (u origen) del ángulo,
;a la que une origen con extremo del ángulo.
;Por tanto, entre 0 y 90 grados d está entre 0 y 1 (0 y -1 si se toma desde el origen),
;y de 90 a 180 d pasa de 1 a infinito (-1 a -infinito si se toma desde el origen).
;---------------------------------------------------------------------------------
  EndIf
Return
text:
  StartDrawing(ScreenOutput())
    BackColor(0,0,0):FrontColor(255,100,240)
    Locate(#RX/2-150,#RY/2-20)
    DrawText("Push LMB for circle algorithm 1, RMB for circle algorithm 2")
    Locate(#RX/2-100,#RY/2+30)
    DrawText("Left CTRL key to exit")
  StopDrawing()
Return
draw:
  StartDrawing(ScreenOutput());<--Draw on the second buffer
    Plot(x+xr,y+yr,$c8faff)
  StopDrawing()
Return

Post Reply