Cookies helfen bei der Bereitstellung dieser Website. Durch die Nutzung dieser Website erklären Sie sich damit einverstanden, dass Cookies gesetzt werden. Mehr erfahrenOK

Buchempfehlung
Windows System Programming
Windows System Programming
Das Kompendium liefert viele interessante Informationen zur Windows-Programmierung auf Englisch. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

fb:porticula NoPaste

Info
Info / Hilfe
Liste
Übersicht / Liste
Neu
Datei hochladen
Suche
Quellcode suchen
Download
Dateidownload

MultiPut (verbessert)

Uploader:RedakteurJojo
Datum/Zeit:11.05.2008 14:47:00

' #define UseRad

'(c) by D.J. Peters, modified by Saga-Games (added "center" parameter and deleted some "mustlock" stuff...)

'wenn du mit X und Y die linke obere Ecke verwenden willst, muss Center auf 0 bleiben,
'ansonsten einfach 1 als Parameter übergeben!
'da die erste zeile (#define useread) auskommentiert ist, wird bei Rotate eine Grad-
'zahl erwartet, also 0 bis 360 grad. Du willst ja, so weit ich weiß, nur 90,180 und 270 ;)

Sub MultiPut(Byval lpTarget As Any Ptr= 0, _
    Byval xMidPos  As Integer= 0, _
    Byval yMidPos  As Integer= 0, _
    Byval lpSource As Any Ptr   , _
    Byval xScale   As Single = 1, _
    Byval yScale   As Single = 1, _
    Byval Rotate   As Single = 0, _
    Byval Center   As Integer= 0, _
    Byval ColorKey As Integer=-1)

    If (Screenptr=0) Or (lpSource=0) Then Exit Sub

    If xScale < 0.001 Then xScale=0.001
    If yScale < 0.001 Then yScale=0.001

    Dim As Integer MustLock,MustRotate,MustKeying

    If lpTarget= 0 Then MustLock  =1
    If Rotate  <>0 Then MustRotate=1
    If ColorKey>-1 Then MustKeying=1

    Dim As Byte  Ptr TargetPtr,SourcePtr
    Dim As Byte      val8
    Dim As Short Ptr ptr16
    Dim As Short     val16
    Dim As Integer   val32,TargetWidth,TargetHeight,TargetBytes
    If MustLock Then
        Screeninfo TargetWidth,TargetHeight,TargetBytes
        TargetPtr=Screenptr:TargetBytes=TargetBytes Shr 3
    Else
        ptr16=Cptr(Short Ptr,lpTarget):TargetPtr=Cptr(Byte Ptr,lpTarget)
        val16=ptr16[0]:TargetBytes =val16 And &H0007:TargetWidth=val16 Shr 3
        val16=ptr16[1]:TargetHeight=val16:TargetPtr+=4
    End If
    mustlock = 0
    If (TargetWidth<4) Or (TargetHeight<4) Then Exit Sub

    Dim As Integer   SourceWidth,SourceHeight,SourceBytes
    ptr16=Cptr(Short Ptr,lpSource):SourcePtr=Cptr(Byte Ptr,lpSource)
    val16=ptr16[0]:SourceBytes =val16 And &H0007:SourceWidth=val16 Shr 3
    val16=ptr16[1]:SourceHeight=val16:SourcePtr+=4
    If (SourceWidth<2) Or (SourceHeight<2) Then Exit Sub

    If TargetBytes<>SourceBytes Then Exit Sub

    If Center = 0 Then
        xMidPos+=SourceWidth/(2/xScale)
        yMidPos+=SourceHeight/(2/yScale)
    End If

    #define xs 0 'screen
    #define ys 1
    #define xt 2 'texture
    #define yt 3
    Dim As Single Points(4,5)
    points(0,xs)=-SourceWidth/2 * xScale
    points(1,xs)= SourceWidth/2 * xScale
    points(2,xs)= points(1,xs)
    points(3,xs)= points(0,xs)

    points(0,ys)=-SourceHeight/2 * yScale
    points(1,ys)= points(0,ys)
    points(2,ys)= SourceHeight/2 * yScale
    points(3,ys)= points(2,ys)

    points(1,xt)= SourceWidth-1
    points(2,xt)= points(1,xt)
    points(2,yt)= SourceHeight-1
    points(3,yt)= points(2,yt)

    Dim As Uinteger i
    Dim As Single x,y
    If MustRotate Then
        #ifndef UseRad
        Rotate*=0.017453292 'degre 2 rad
        #Endif
        While Rotate< 0
            rotate+=6.2831853
        Wend
        While Rotate>=6.2831853
            rotate-=6.2831853
        Wend
        For i=0 To 3
            x=points(i,xs)*Cos(Rotate) - points(i,ys)*Sin(Rotate)
            y=points(i,xs)*Sin(Rotate) + points(i,ys)*Cos(Rotate)
            points(i,xs)=x:points(i,ys)=y
        Next
    End If

    Dim As Integer yStart,yEnd,xStart,xEnd
    yStart=100000:yEnd=-yStart:xStart=yStart:xEnd=yEnd

    #define LI 0   'LeftIndex
    #define RI 1   'RightIndex
    #define  IND 0 'Index
    #define NIND 1 'NextIndex
    Dim As Integer CNS(2,2) 'Counters

    For i=0 To 3
        points(i,xs)=Int(points(i,xs)+xMidPos)
        points(i,ys)=Int(points(i,ys)+yMidPos)
        If points(i,ys)<yStart Then yStart=points(i,ys):CNS(LI,IND)=i
        If points(i,ys)>yEnd   Then yEnd  =points(i,ys)
        If points(i,xs)<xStart Then xStart=points(i,xs)
        If points(i,xs)>xEnd   Then xEnd  =points(i,xs)
    Next
    If yStart =yEnd         Then Exit Sub
    If yStart>=TargetHeight Then Exit Sub
    If yEnd   <0            Then Exit Sub
    If xStart = xEnd        Then Exit Sub
    If xStart>=TargetWidth  Then Exit Sub
    If xEnd   <0            Then Exit Sub

    Dim As Byte    Ptr t1,s1
    Dim As Short   Ptr t2,s2
    Dim As Integer Ptr t4,s4


    #define ADD 0
    #define CMP 1
    #define SET 2
    Dim As Integer ACS(2,3) 'add compare and set
    ACS(LI,ADD)=-1:ACS(LI,CMP)=-1:ACS(LI,SET)=3
    ACS(RI,ADD)= 1:ACS(RI,CMP)= 4:ACS(RI,SET)=0

    #define EX  0
    #define EU  1
    #define EV  2
    #define EXS 3
    #define EUS 4
    #define EVS 5
    Dim As Single E(2,6),S(6),Length,uSlope,vSlope
    Dim As Integer U,UV,UA,UN,V,VV,VA,VN

    ' share the same highest point
    CNS(RI,IND)=CNS(LI,IND)
    If MustLock Then Screenlock
    ' loop from Top to Bottom
    While yStart<yEnd

        'Scan Left and Right sides together
        For i=LI To RI
            ' bad to read but fast and short ;-)
            If yStart=points(CNS(i,IND),ys) Then
                CNS(i,NIND)=CNS(i,IND)+ACS(i,Add)
                If CNS(i,NIND)=ACS(i,CMP) Then CNS(i,NIND)=ACS(i,SET)
                While points(CNS(i,IND),ys) = points(CNS(i,NIND),ys)
                    CNS(i, IND)=CNS(i,NIND)
                    CNS(i,NIND)=CNS(i, IND)+ACS(i,Add)
                    If CNS(i,NIND)=ACS(i,CMP) Then CNS(i,NIND)=ACS(i,SET)
                Wend
                E(i,EX) = points(CNS(i, IND),xs)
                E(i,EU) = points(CNS(i, IND),xt)
                E(i,EV) = points(CNS(i, IND),yt)
                Length  = points(CNS(i,NIND),ys)
                Length -= points(CNS(i, IND),ys)
                If Length <> 0.0 Then
                    E(i,EXS) = points(CNS(i, NIND),xs)-E(i,EX):E(i,EXS)/=Length
                    E(i,EUS) = points(CNS(i, NIND),xt)-E(i,EU):E(i,EUS)/=Length
                    E(i,EVS) = points(CNS(i, NIND),yt)-E(i,EV):E(i,EVS)/=Length
                End If
                CNS(i,IND)=CNS(i,NIND)
            End If
        Next

        If yStart<  0                          Then Goto SkipScanLine
        xStart=E(LI,EX)+0.5:If xStart>=TargetWidth Then Goto SkipScanLine
        xEnd  =E(RI,EX)-0.5:If xEnd  < 0           Then Goto SkipScanLine
        If xStart=xEnd                         Then Goto SkipScanLine
        'if xEnd  <xStart                       then goto SkipScanLine
        Length=xEnd-xStart
        uSlope=E(RI,EU)-E(LI,EU):uSlope/=Length
        vSlope=E(RI,EV)-E(LI,EV):vSlope/=Length
        If xstart<0 Then
            Length=Abs(xStart)
            U=Int(E(LI,EU)+uSlope*Length)
            V=Int(E(LI,EV)+vSlope*Length)
            xStart = 0
        Else
            U=Int(E(LI,EU)):V=Int(E(LI,EV))
        End If
        If xEnd>=TargetWidth Then xEnd=TargetWidth-1
        UV=Int(uSlope):UA=(uSlope-UV)*10000:UN=0
        VV=Int(vSlope):VA=(vSlope-VV)*10000:VN=0
        xEnd-=xStart
        Select Case TargetBytes
        Case 1
            t1=TargetPtr:t1+=yStart*TargetWidth:t1+=xStart:xStart=0
            If MustKeying=0 Then
                While xStart<xEnd
                    s1=SourcePtr:s1+=V*SourceWidth:s1+=U
                    t1[xStart]=s1[0]
                    U+=UV:UN+=UA:If UN>=10000 Then U+=1:UN-=10000
                    V+=VV:VN+=VA:If VN>=10000 Then V+=1:VN-=10000
                    If u<0 Then u=0
                    If v<0 Then v=0
                    xStart+=1
                Wend
            Else
                val8=ColorKey And &HFF
                While xStart<xEnd
                    s1=SourcePtr:s1+=V*SourceWidth:s1+=U
                    If s1[0]<>val8 Then t1[xStart]=s1[0]
                    U+=UV:UN+=UA:If UN>=10000 Then U+=1:UN-=10000
                    V+=VV:VN+=VA:If VN>=10000 Then V+=1:VN-=10000
                    If u<0 Then u=0
                    If v<0 Then v=0
                    xStart+=1
                Wend

            End If
        Case 2
            t2=Cptr(Short Ptr,TargetPtr)
            t2+=yStart*TargetWidth:t2+=xStart:xStart=0
            If MustKeying=0 Then
                While xStart<xEnd
                    s2=Cptr(Short Ptr,SourcePtr):s2+=V*SourceWidth:s2+=U
                    t2[xStart]=s2[0]
                    U+=UV:UN+=UA:If UN>=10000 Then U+=1:UN-=10000
                    V+=VV:VN+=VA:If VN>=10000 Then V+=1:VN-=10000
                    If u<0 Then u=0
                    If v<0 Then v=0
                    xStart+=1
                Wend
            Else
                val16=ColorKey And &HFFFF
                While xStart<xEnd
                    s2=Cptr(Short Ptr,SourcePtr):s2+=V*SourceWidth:s2+=U
                    If s2[0]<>val16 Then t2[xStart]=s2[0]
                    U+=UV:UN+=UA:If UN>=10000 Then U+=1:UN-=10000
                    V+=VV:VN+=VA:If VN>=10000 Then V+=1:VN-=10000
                    If u<0 Then u=0
                    If v<0 Then v=0
                    xStart+=1
                Wend
            End If
        Case 4
            t4=Cptr(Integer Ptr,TargetPtr)
            t4+=yStart*TargetWidth:t4+=xStart:xStart=0
            If MustKeying=0 Then
                While xStart<xEnd
                    s4=Cptr(Integer Ptr,SourcePtr):s4+=V*SourceWidth:s4+=U
                    t4[xStart]=s4[0]
                    U+=UV:UN+=UA:If UN>=10000 Then U+=1:UN-=10000
                    V+=VV:VN+=VA:If VN>=10000 Then V+=1:VN-=10000
                    If u<0 Then u=0
                    If v<0 Then v=0
                    xStart+=1
                Wend
            Else
                val32=ColorKey And &HFFFFFF
                While xStart<xEnd
                    s4=Cptr(Integer Ptr,SourcePtr):s4+=V*SourceWidth:s4+=U
                    If s4[0]<>val32 Then t4[xStart]=s4[0]
                    U+=UV:UN+=UA:If UN>=10000 Then U+=1:UN-=10000
                    V+=VV:VN+=VA:If VN>=10000 Then V+=1:VN-=10000
                    If u<0 Then u=0
                    If v<0 Then v=0
                    xStart+=1
                Wend
            End If
        End Select

        SkipScanLine:
        E(LI,EX)+=E(LI,EXS):E(LI,EU)+=E(LI,EUS):E(LI,EV)+=E(LI,EVS)
        E(RI,EX)+=E(RI,EXS):E(RI,EU)+=E(RI,EUS):E(RI,EV)+=E(RI,EVS)
        yStart+=1:If yStart=TargetHeight Then yStart=yEnd 'exit loop
    Wend
    If MustLock Then Screenunlock
End Sub