Seite 5 von 7

Verfasst: 29.01.2005 18:08
von Danilo
OK, hab den Fehler wohl gefunden.

In PureBasic/sdk/c/include/Sprite/Sprite.h:

Code: Alles auswählen

#define FastClipping()\
\
    if (x+Width > PB_Screen_Width)\
      Width = PB_Screen_Width-x;\
\
    if (y+Height> PB_Screen_Height)\
      Height = PB_Screen_Height-y;\
\
    if (x<0)\
    {\
      xOffset = -x;\
      x = 0;\
    }\
    else\
      xOffset = 0;\
\
    if (y<0)\
    {\
      yOffset = -y;\
      y = 0;\
    }\
    else\
      yOffset = 0;\
Wenn x oder y kleiner als 0 sind, dann werden diese
Variablen auf 0 gesetzt und das Clipping-Offset korrigiert.
Die Breite und Hoehe werden aber nicht angepasst.

Da müßten wahrscheinlich noch 2 Zeilen rein:

Code: Alles auswählen

#define FastClipping()\
\
    if (x+Width > PB_Screen_Width)\
      Width = PB_Screen_Width-x;\
\
    if (y+Height> PB_Screen_Height)\
      Height = PB_Screen_Height-y;\
\
    if (x<0)\
    {\
      xOffset = -x;\
      x = 0;\
      Width += x;\
    }\
    else\
      xOffset = 0;\
\
    if (y<0)\
    {\
      yOffset = -y;\
      y = 0;\
      Height += y;\
    }\
    else\
      yOffset = 0;\
Also "Width += x;" und "Height += y;". Da beide negativ
sind wird der negative Wert von Width/Height abgezogen.

Ich kann es natürlich nicht testen, da die Sourcen zu PB
nicht mitgeliefert werden, aber sollte doch funktionieren.

Vielleicht kann ja mal Jemand vom PB-Team die Sprite-LIB
neu kompilieren und mein Beispiel dann nochmals testen.

Verfasst: 02.02.2005 17:14
von Andre
Die Sprite-Lib für Linux ist gefixt:
www.purebasic.com/beta/linux/

Danke an Danilo im Namen von Fred !

Verfasst: 02.02.2005 23:29
von MARTIN
Ja, jetzt funktioniert.

Verfasst: 03.02.2005 03:18
von Danilo
Andre hat geschrieben:Die Sprite-Lib für Linux ist gefixt:
www.purebasic.com/beta/linux/

Danke an Danilo im Namen von Fred !
Danke, Andre!

Jetzt funktioniert AnimSprite/Linux auch richtig. :)

Aber ein kleiner Fehler: Der Unterordner "/userlibraries" wird
nicht genutzt.
Kopier ich meine Lib dort rein, werden die Befehle nicht erkannt
und können nicht benutzt werden. Kopiere ich es ins Hauptverzeichniss
"/purelibraries", dann funktioniert alles.


Fehlen noch korrekte Drawing-Befehle. DrawingMode sollte
hier eine interne Variable für den aktuellen Modus setzen.
Die Drawing-Befehle könnten somit trotzdem korrekt funktionieren,
d.h. wenn DrawingMode=0, zeichnet Fred Kreise, Ellipsen
und Box selbst ausgefüllt - Die entspr. Algorithmen sind
ja bekannt, und man braucht dafür lediglich ein paar Linien
ziehen.
Text im DrawingMode(0) hätte als Hintergrund eine Box mit
der Farbe BackColor() und darauf dann den Text.

Bisher funktioniert DrawingMode nicht und es ist eine
Kombination aus DrawingMode 1 und 4 - Text ist immer
transparent und Box, Circle sowie Ellipse funktionieren nur
im Outline-Modus.
Das sollte schon genauso wie auf Windows funktionieren,
wenn man Codes platformunabhängig verwenden können
soll.
Bisher ist es so das ein Programm im ScreenModus auf
Linux ganz anders aussehen kann als auf Windows, wenn
man die Drawing-Befehle benutzte ((z.B. für einen WindowManager ;)).

Verfasst: 03.02.2005 03:50
von Danilo
Danilo hat geschrieben:Bisher funktioniert DrawingMode nicht und es ist eine
Kombination aus DrawingMode 1 und 4 - Text ist immer
transparent und Box, Circle sowie Ellipse funktionieren nur
im Outline-Modus.
Zu früh gefreut:
Im Moment gibt es bei jeder Benutzung der Zeichenfunktionen
einen SDL-Crash.

Beispiel:

Code: Alles auswählen

If InitSprite()=0 Or InitKeyboard()=0
  MessageRequester("ERROR","Cant init game engine !"):End
EndIf

If OpenScreen(800,600,32,"DrawingMode")=0
  If OpenScreen(800,600,24,"DrawingMode")=0
    If OpenScreen(800,600,16,"DrawingMode")=0
      MessageRequester("ERROR","Cant open screen !"):End
EndIf:EndIf:EndIf

Repeat
  FlipBuffers()
  If isScreenActive()
    ClearScreen($80,$80,$80)

    ;DrawText("Hello!")
    ;Box(100,100,100,100,$FFFF00)
    ;Circle(400,300,100,$FFFFFF)
    ;Ellipse(400,300,50,100,$FF0000)
    ;Line(200,200,100,100,$00FF00)
    ;LineXY(0,0,800,600,$00FFFF)
  EndIf
  ExamineKeyboard()
  Delay(1)
Until KeyboardPushed(#PB_KEY_ESCAPE)
Sobald einer dieser auskommentierten Befehle verwendet
wird beendet sich das Programm, und auf der Console
kommt:

Code: Alles auswählen

Fatal signal: Segmentation Fault (SDL Parachute Deployed)
Entweder es ist ein neuer Fehler, oder es liegt daran das
jetzt neue Beta-Libs in der normalen 3.92-Installation
gemixt wurden. Obwohl ja keine Drawing-Lib dabei war,
nur die Sprite-Lib.
Die Sprite-Befehle funktionieren weiterhin, nur die Drawing-
Funktionen nicht mehr.
Die liefen aber vorher schonmal, nur nicht korrekt (3.91 oder 3.91beta2).

Verfasst: 03.02.2005 17:56
von MARTIN
>Im Moment gibt es bei jeder Benutzung der Zeichenfunktionen einen SDL-Crash.
Bei mir funktioniert, nur in dem Code fehlt StartDrawing(ScreenOutput()) StopDrawing().

Verfasst: 03.02.2005 18:31
von Danilo
MARTIN hat geschrieben:in dem Code fehlt StartDrawing(ScreenOutput()) StopDrawing().
Ohhh Shit. Danke... :oops:

Verfasst: 03.02.2005 20:19
von Andre
Danilo hat geschrieben:
MARTIN hat geschrieben:in dem Code fehlt StartDrawing(ScreenOutput()) StopDrawing().
Ohhh Shit. Danke... :oops:
Heißt das jetzt, dass doch keine Drawing Lib Bugs mehr vorhanden sind?

(Ich habe Fred nämlich bereits drauf angesetzt.)

Verfasst: 04.02.2005 01:20
von Danilo
Andre hat geschrieben:Heißt das jetzt, dass doch keine Drawing Lib Bugs mehr vorhanden sind?

(Ich habe Fred nämlich bereits drauf angesetzt.)
Es crasht nicht mehr und funktioniert wenn man Start-/StopDrawing
benutzt. 8)

Es fehlt allerdings immernoch DrawingMode() um:
1.) DrawText mit Hintergrund zu benutzen - ist immer Transparent
2.) Box, Circle & Ellipse auch gefüllt darzustellen - die sind immer nur 'outlined'

Ich habe jetzt mal ein paar alternative Funktionen geschrieben
die Du Fred gerne als Anregung mal zeigen kannst.
Damit werden für DrawText(), Box(), Circle() und Ellipse()
jeweils 2 Versionen nutzbar, einmal gefüllt und einmal
'outlined'/'transparenter Text'.

Code: Alles auswählen

#SCREEN_W = 800 ; screen width
#SCREEN_H = 600 ; screen height

Procedure _Locate(x,y)
  Shared Drawing2D_LocationX
  Shared Drawing2D_LocationY

  Drawing2D_LocationX = x
  Drawing2D_LocationY = y
  Locate(x,y)
EndProcedure

Procedure _DrawingMode(mode)
  Shared Drawing2D_Mode

  Drawing2D_Mode = mode
EndProcedure

Procedure _BackColor(Red,Green,Blue)
  Shared Drawing2D_BackColor

  Drawing2D_BackColor = RGB(Red,Green,Blue)
  BackColor(Red,Green,Blue)
EndProcedure

Procedure _DrawText(text$)
  Shared Drawing2D_Mode
  Shared Drawing2D_LocationX
  Shared Drawing2D_LocationY
  Shared Drawing2D_BackColor

  #Current_TextHeight = 8

  If Drawing2D_Mode = 0
    Box(Drawing2D_LocationX-1,Drawing2D_LocationY-1,TextLength(text$)+2,#Current_TextHeight+2,Drawing2D_BackColor)
    DrawText(text$)
  ElseIf Drawing2D_Mode = 1
    DrawText(text$)
  ElseIf Drawing2D_Mode = 2
    ; direct screen access to XOR text?
  ElseIf Drawing2D_Mode = 4
    ; draw outlined text?
  EndIf
EndProcedure

Procedure _Box(x,y,w,h,color)
  Shared Drawing2D_Mode

  If Drawing2D_Mode = 0
    Box(x,y,w,h,color)
  ;ElseIf Drawing2D_Mode = 1
    ; only used for text
  ElseIf Drawing2D_Mode = 2
    ; direct screen access to XOR box?
  ElseIf Drawing2D_Mode = 4
    Line( x , y , w , 0 ,color)  ;  -
    Line(x+w, y , 0 , h ,color)  ;   |
    Line( x , y , 0 , h ,color)  ; |
    Line( x ,y+h, w , 0 ,color)  ;  -
  EndIf
EndProcedure

Procedure _Circle(x,y,radius,color)
  ; Bresenham circle algorithm
  Shared Drawing2D_Mode

  temp_x = 0
  d = 3 - 2 * radius

  While temp_x <= radius
    If Drawing2D_Mode = 0 ; filled
      LineXY(x-temp_x, y+radius, x+temp_x, y+radius, color) ; part 1
      LineXY(x-radius, y+temp_x, x+radius, y+temp_x, color) ; part 2
      LineXY(x-radius, y-temp_x, x+radius, y-temp_x, color) ; part 3
      LineXY(x-temp_x, y-radius, x+temp_x, y-radius, color) ; part 4
    ;ElseIf Drawing2D_Mode = 1
      ; only used for text
    ElseIf Drawing2D_Mode = 2
      ; direct screen access to XOR circle?
    ElseIf Drawing2D_Mode = 4 ; outlined
      Plot(x+temp_x, y+radius, color) ; part 1
      Plot(x-temp_x, y+radius, color)
      Plot(x+radius, y+temp_x, color) ; part 2
      Plot(x-radius, y+temp_x, color)
      Plot(x+radius, y-temp_x, color) ; part 3
      Plot(x-radius, y-temp_x, color)
      Plot(x-temp_x, y-radius, color) ; part 4
      Plot(x+temp_x, y-radius, color)
    EndIf

    If d < 0
      d + 4*temp_x + 6
    Else
      d + 4*(temp_x - radius) + 10
      radius - 1
    EndIf
    temp_x + 1
  Wend
EndProcedure

Procedure _Ellipse(x,y,radius_x,radius_y,color)
  ; middle-point ellipse algorithm
  Shared Drawing2D_Mode

  temp_x         = 0
  temp_y         = radius_y
  temp_radius_x1 = radius_x*radius_x
  temp_radius_y1 = radius_y*radius_y
  temp_radius_x2 = temp_radius_x1*2
  temp_radius_y2 = temp_radius_y1*2
  temp_fx        = 0
  temp_fy        = temp_radius_x2*radius_y
  p              = temp_radius_y1 - temp_radius_x1*radius_y + Int(0.25*temp_radius_x1)

  If radius_x = radius_y
    _Circle(x,y,radius_x,color)
    ProcedureReturn
  EndIf

  While temp_fx <= temp_fy
    If Drawing2D_Mode = 0 ; filled
      LineXY(x-temp_x, y+temp_y, x+temp_x, y+temp_y, color) ; part 1
      LineXY(x-temp_x, y-temp_y, x+temp_x, y-temp_y, color) ; part 4
    ;ElseIf Drawing2D_Mode = 1
      ; only used for text
    ElseIf Drawing2D_Mode = 2
      ; direct screen access to XOR ellipse?
    ElseIf Drawing2D_Mode = 4 ; outlined
      Plot(x+temp_x, y+temp_y, color) ; part 1
      Plot(x-temp_x, y+temp_y, color)
      Plot(x-temp_x, y-temp_y, color) ; part 4
      Plot(x+temp_x, y-temp_y, color)
    EndIf

    temp_x  + 1
    temp_fx + temp_radius_y2
    If p < 0
      p + temp_fx + temp_radius_y1
    Else
      temp_y  - 1
      temp_fy - temp_radius_x2
      p       + temp_fx + temp_radius_y1 - temp_fy
    EndIf
  Wend

  If Drawing2D_Mode = 0 ; filled
    LineXY(x-temp_x, y+temp_y, x+temp_x, y+temp_y, color) ; part 1
    LineXY(x-temp_x, y-temp_y, x+temp_x, y-temp_y, color) ; part 4
  ElseIf Drawing2D_Mode = 2
    ; direct screen access to XOR ellipse?
  ElseIf Drawing2D_Mode = 4 ; outlined
    Plot(x+temp_x, y+temp_y, color) ; part 1
    Plot(x-temp_x, y+temp_y, color)
    Plot(x-temp_x, y-temp_y, color) ; part 4
    Plot(x+temp_x, y-temp_y, color)
  EndIf

  p = temp_radius_y1 * (temp_x - 0.5)*(temp_x+0.5)+temp_radius_x1*(temp_y-1)*(temp_y-1)-temp_radius_x1*temp_radius_y1

  While temp_y > 0
    temp_y  - 1
    temp_fy - temp_radius_x2
    If p >= 0
      p - temp_fy + temp_radius_x1
    Else
      temp_x  + 1
      temp_fx + temp_radius_y2
      p       + temp_fx - temp_fy + temp_radius_x1
    EndIf

    If Drawing2D_Mode = 0 ; filled
      LineXY(x-temp_x, y+temp_y, x+temp_x, y+temp_y, color) ; part 1
      LineXY(x-temp_x, y-temp_y, x+temp_x, y-temp_y, color) ; part 4
    ElseIf Drawing2D_Mode = 2
      ; direct screen access to XOR ellipse?
    ElseIf Drawing2D_Mode = 4 ; outlined
      Plot(x+temp_x, y+temp_y, color) ; part 1
      Plot(x-temp_x, y+temp_y, color)
      Plot(x-temp_x, y-temp_y, color) ; part 4
      Plot(x+temp_x, y-temp_y, color)
    EndIf
  Wend
EndProcedure



If InitSprite()=0 Or InitKeyboard()=0
  MessageRequester("ERROR","Cant init game engine !"):End
EndIf

If OpenScreen(#SCREEN_W,#SCREEN_H,32,"DrawingMode")=0
  If OpenScreen(#SCREEN_W,#SCREEN_H,24,"DrawingMode")=0
    If OpenScreen(#SCREEN_W,#SCREEN_H,16,"DrawingMode")=0
      MessageRequester("ERROR","Cant open screen !"):End
EndIf:EndIf:EndIf

Repeat
  FlipBuffers()
  If isScreenActive()
    ClearScreen($80,$80,$80)

    If StartDrawing(ScreenOutput())
      ; Text with Background
      _DrawingMode(0)
      _Locate(100,10)
      FrontColor($00,$00,$00)
      _BackColor($FF,$FF,$00)
      _DrawText("Hello! xyz")
      ; Transparent Text
      _DrawingMode(1)
      _Locate(300,10)
      FrontColor($FF,$FF,$FF)
      _DrawText("Hello! xyz")

      ; filled box
      _DrawingMode(0)
      _Box(100,50,100,100,$FFFF00)
      ; outlined Boxes
      _DrawingMode(4)
      _Box(300,50,100,100,$FFFFFF)

      ; filled circle
      _DrawingMode(0)
      _Circle(150,250,50,$FFFF00)
      ; outlined circle
      _DrawingMode(4)
      _Circle(350,250,50,$FFFFFF)


      ; filled ellipse
      _DrawingMode(0)
      _Ellipse(150,400,90,50,$FFFF00)

      ; outlined ellipse
      _DrawingMode(4)
      _Ellipse(350,400,90,50,$FFFFFF)





      ; animated things
      Line(0,525,800,0,$FFFFFF)

      ; filled
      _DrawingMode(0)
      _Box    (offX+100-anim,525-anim,anim*2,anim*2,$FF00FF)
      _Circle (offX+250,     525     ,anim         ,$FF00FF)
      _Ellipse(offX+450,     525     ,anim*2,anim  ,$FF00FF)
      _Ellipse(offX+650,     525     ,anim  ,anim*2,$FF00FF)

      ; outlined
      _DrawingMode(4)
      _Box    (offX+050+anim,475+anim,100-anim*2,100-anim*2,$00FF00)
      _Circle (offX+250,525,50-anim,       $00FF00)
      _Ellipse(offX+450,525,100-anim*2,50-anim,       $00FF00)
      _Ellipse(offX+650,525,50-anim,100-anim*2,       $00FF00)

      _DrawingMode(0)
      _Circle(offX+100,525,1,$000000)
      _Circle(offX+250,525,1,$000000)
      _Circle(offX+450,525,1,$000000)
      _Circle(offX+650,525,1,$000000)

      If animflag=0
        anim + 2
        if anim > 50 : anim = 50 : animflag+1 : EndIf
      Else
        anim - 2
        If anim < 0   : anim = 0   : animflag!1 : EndIf
      EndIf

      offX + 1
      If offX = #SCREEN_W : offX = -#SCREEN_W : EndIf

      counter + 1
      DrawingMode(0)
      _Locate(10,10)
      _BackColor($00,$00,$FF)
      FrontColor($80,$80,$FF)
      _DrawText(StrU(counter,#LONG))

      StopDrawing()
    EndIf
  EndIf
  ExamineKeyboard()
  Delay(1)
Until KeyboardPushed(#PB_KEY_ESCAPE)
DrawText(): Bei DrawingMode(0) wird vorher eine Box() gezeichnet mit der Farbe von BackColor()
Box(): Bei DrawingMode(0) wird die Box gefüllt gezeichnet, mit Hilfe von Line()
Circle(): Bresenham Circle Algorithmus, gefüllt und outlined
Ellipse(): Mittenpunkt-Algorithmus für Ellipsen, gefüllt und outlined

Könnte Fred also mal einbauen.

Verfasst: 04.02.2005 01:49
von Andre
Danilo hat geschrieben:Es fehlt allerdings immernoch DrawingMode() um:
1.) DrawText mit Hintergrund zu benutzen - ist immer Transparent
2.) Box, Circle & Ellipse auch gefüllt darzustellen - die sind immer nur 'outlined'

Ich habe jetzt mal ein paar alternative Funktionen geschrieben
die Du Fred gerne als Anregung mal zeigen kannst.
Ok, habe ihn informiert. :D

Aber stand nicht eben grad im Post noch etwas von "clipping bug" ????
Habe dies nämlich grad in meiner Mail noch mit geschrieben.