## MultiPut V2.0 :-)

leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

### Re: MultiPut V2.0 :-)

for the rotation, will you use the full 0 to 360 degrees, or just steps like 0,45,90,135,180,225,etc....?
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

### Re: MultiPut V2.0 :-)

bcohio2001 wrote:Trying to just save memory. ... I have a MINUMUM of 53 images, 52 'cards' and at least one 'back'. Maybe the two Jokers.
About the only thing that I could think of at the moment would be create another temp image, Put the 'ShowThis' in it using the PReset.
Then use Multiput to rotate and put it on screen.

that ain't alot of memory usage at all.. I would say to definitely do it with a second ShowThis...

Code: Select all

'Rot value (Rotate) not used at the moment
Sub Card.DrawImg(ByVal XLoc As Integer, ByVal YLoc As Integer, GetCard As Integer, Selected As Integer, Rot As Single=0)
Dim As Any Ptr ShowThis(1)
ShowThis(0)  = 0
'
Select Case GetCard
Case -1
ShowThis(0) = Backs(CurBackGr)
Case 0 To 51
ShowThis(0) = Deck52(GetCard)
Case 52
If Jokers Then ShowThis(0) = JokerBlack
Case 53
If Jokers Then ShowThis(0) = JokerRed
Case Else
'54+
'special image
'As Integer Special
'As Any Ptr SpecialRC(Any)
If Special > GetCard - 54 Then ShowThis(0) = SpecialRC(GetCard - 54)
End Select
'If Rot > 0 Then
'   'insert rotation code or call a sub/function
'EndIf
......put ShowThis(0) into ShowThis(1) using PRESET here
if ShowThis(0) then MultiPut ,xloc,yloc,ShowThis(Selected),1,1,rotation,transparent
End Sub
bcohio2001
Posts: 556
Joined: Mar 10, 2007 15:44
Location: Ohio, USA
Contact:

### Re: MultiPut V2.0 :-)

Is there a way via the parameters sent to change the point of rotation?
As I see it, it is like putting a "pin" in the center of a picture and to be able to spin it.
I would like the "pin" to be somewhere else, for my use, in the upper left corner.
Posts: 134
Joined: May 28, 2009 20:07

### Re: MultiPut V2.0 :-)

@bcohio2001:
I have always tried to discover the secret of Multiput, there I have never succeeded ... :(
So the following snippet is more a homage to dj... great work!
but it contains exactly the feature you are looking for:
https://www.freebasic-portal.de/porticula/rotput5-bi-1827.html

Mutton
D.J.Peters
Posts: 8299
Joined: May 28, 2005 3:28
Contact:

### Re: MultiPut V2.0 :-)

I open only the the door for you
but you must self going thru it :-)

Joshy
Dr_D
Posts: 2430
Joined: May 27, 2005 4:59
Contact:

### Re: MultiPut V2.0 :-)

Here is a tip... translate, rotate, translate back. :)
bcohio2001
Posts: 556
Joined: Mar 10, 2007 15:44
Location: Ohio, USA
Contact:

### Re: MultiPut V2.0 :-)

@Mutton
Thanks.
RotPut.bas(14) error 14: Expected identifier, found 'Image' in 'dim as Image ptr Src_Header,Dest_Header 'Zeiger um an die Daten im ImageHeader zu kommen'
Assuming that you included 'fbgfx.bi' somewhere else in a larger project.
Will just use ImageInfo in my copy.

*Edit*
I guess I ASSuMEd wrong, notice the emphasis on 'me'.
Is not in 'fbgfx.bi'!
Much more to it than just getting ImageInfo and like you is beyond me.
Last edited by bcohio2001 on May 26, 2016 17:17, edited 1 time in total.
Dr_D
Posts: 2430
Joined: May 27, 2005 4:59
Contact:

### Re: MultiPut V2.0 :-)

Alas, Rotozoom has the capability as well, but it has fallen by the wayside. :p
bcohio2001
Posts: 556
Joined: Mar 10, 2007 15:44
Location: Ohio, USA
Contact:

### Re: MultiPut V2.0 :-)

@D.J. Peters

Please specify in either the code or in the first post text that rotating an image with an odd width or height can result in loss of an edge of the image.
All your tests are with images with even dimensions.
angros47
Posts: 1872
Joined: Jun 21, 2005 19:04

### Re: MultiPut V2.0 :-)

Personally I think MultiPut should be added to the GFX library. Along with some collision detection routine, perhaps, too
wio
Posts: 17
Joined: Feb 05, 2021 4:58

### Re: MultiPut V2.0 :-)

Hi all, old coder, new user here.

I am trying to use MultiPut V2 and am having slightly more success with it than with the first few iterations. It looks like a great tool but I still can't seem to get it to work properly.

When I display my 8x8 sprite on screen using multiput, if the rotation is 0 or 90 degrees the sprite is stretched, if it is at 270 degrees it is moved over to the right by 1 pixel (seemingly), at 180 degrees it looks fine (but upside down though obvs). Should it still work? I am on the latest version of FB, Win10 64bit.

Is there a version of FB that is ideal for using MultiPut and if so will it run in the 64bit version of that release? I have tried a few versions of FB along with most of the iterations of MultiPut that I came across. I could never get MultiPut to even show anything until I found V2, the version with the yellow smiley didn't work and also the version with the white square grid. Nothing would happen.

Thanks in advance for any help.

EDIT: I just tested it by scaling it up to 2 instead of 1. It now shows better but there is a line of pixels missing from the bottom of the sprite at 0 degrees, at 90 it seems stretched or there is an extra row of pixels added at the top and one missing at the bottom again. At 180 and 270 degrees everything looks perfect.

This is my code...

Code: Select all

' FB 1.07.3 Win64
#include "multiput.bi"

screen 18,32
Dim spr_pedehead As Any Ptr  = ImageCreate(8,8)

Do

screensync

Loop Until inkey <>""

The second 'put' is there just to draw the sprite as it is meant to look, for comparison

Result of code (cropped) image link https://ibb.co/tpHMdQj
Actual sprite bmp that I am using https://ibb.co/tDY03yX

This is the version of multiput.bi that I am using...

Code: Select all

#ifndef __MULTIPUT_BI__
#define __MULTIPUT_BI__

' Multiput by D.J.Peters (Joshy)
' MultiPut [destination],[xmidpos],[ymidpos], source,[xScale],[yScale],[Trans]

type FP16 ' fixed point 16:16
union
type
as ushort l
as  short h
end type
as integer v
end union
end type

#define _ADD_ 0 ' increment a value
#define _CMP_ 1 ' compare values
#define _SET_ 2 ' set a value

#define _XScreen_  0
#define _YScreen_  1
#define _UTexture_ 2
#define _VTexture_ 3

#define _LeftIndex_    0
#define _RightIndex_   1

#define _CurrentIndex_ 0
#define _NextIndex_    1

#define _EdgeXStart_ 0
#define _EdgeUStart_ 1
#define _EdgeVStart_ 2
#define _EdgeXStep_  3
#define _EdgeUStep_  4
#define _EdgeVStep_  5

'#define UseRad 'if not then Rotate are in degrees

Sub MultiPut(Byval pTarget As Any Ptr= 0, _
Byval xMidPos As Integer= 0, _
Byval yMidPos As Integer= 0, _
Byval pSource As Any Ptr   , _
Byval xScale  As Single = 1, _
Byval yScale  As Single = 1, _
Byval Rotate  As Single = 0, _
Byval Transparent As boolean = false)
Dim As Integer SourceWidth=any,SourceHeight=any,SourceBytes=any,SourcePitch=any
Dim as Integer TargetWidth=any,TargetHeight=any,TargetBytes=any,TargetPitch=any
Dim As Integer i=any,yStart=any,yEnd=any,xStart=any,xEnd=any
Dim As Integer CNS(1,1)=any 'Counters
Dim As Integer ACS(1,2)=any '_ADD_ compare and _SET_
Dim As Single fPoints(3,3)=any,fEdges(2,6)=any,fLength=any,fUSlope=any,fVSlope=any
Dim As FP16 U=any,V=any,US=any,VS=any
Dim As boolean MustRotate = iif(Rotate<>0,true,false)

If (ScreenPtr()=0) Or (pSource=0) Then Exit Sub

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

If pTarget=0 Then
ScreenInfo     _
TargetWidth  , _
TargetHeight,, _
TargetBytes  , _
TargetPitch
pTarget=ScreenPtr()
Else
ImageInfo     _
pTarget     , _
TargetWidth , _
TargetHeight, _
TargetBytes , _
TargetPitch , _
pTarget
End If
If (TargetWidth<4) Or (TargetHeight<4) Then Exit Sub

ImageInfo     _
pSource     , _
SourceWidth , _
SourceHeight, _
SourceBytes , _
SourcePitch , _
pSource

Select Case as const TargetBytes
case 1    ' TargetPitch shr=0 : SourcePitch shr=0
case 2    : TargetPitch shr=1 : SourcePitch shr=1
case 4    : TargetPitch shr=2 : SourcePitch shr=2
case else : exit sub
end select

fPoints(0,_XScreen_)=-SourceWidth/2 * xScale
fPoints(1,_XScreen_)= SourceWidth/2 * xScale
fPoints(2,_XScreen_)= fPoints(1,_XScreen_)
fPoints(3,_XScreen_)= fPoints(0,_XScreen_)

fPoints(0,_YScreen_)=-SourceHeight/2 * yScale
fPoints(1,_YScreen_)= fPoints(0,_YScreen_)
fPoints(2,_YScreen_)= SourceHeight/2 * yScale
fPoints(3,_YScreen_)= fPoints(2,_YScreen_)

fPoints(0,_UTexture_)=0
fPoints(1,_UTexture_)= SourceWidth
fPoints(2,_UTexture_)= fPoints(1,_UTexture_)
fPoints(3,_UTexture_)=0

fPoints(0,_VTexture_)=0
fPoints(1,_VTexture_)=0
fPoints(2,_VTexture_)= SourceHeight
fPoints(3,_VTexture_)= fPoints(2,_VTexture_)

If MustRotate=true Then
#endif
var co = cos(rotate)
var si = sin(rotate)
For i=0 To 3
var x = fPoints(i,_XScreen_)*co - fPoints(i,_YScreen_)*si
var y = fPoints(i,_XScreen_)*si + fPoints(i,_YScreen_)*co
fPoints(i,_XScreen_) = x
fPoints(i,_YScreen_) = y
Next
End If
yStart=30^2:yEnd=-yStart:xStart=yStart:xEnd=yEnd

' get min max
For i=0 To 3
fPoints(i,_XScreen_)=Int(fPoints(i,_XScreen_)+xMidPos)
fPoints(i,_YScreen_)=Int(fPoints(i,_YScreen_)+yMidPos)
If fPoints(i,_YScreen_)<yStart Then yStart=fPoints(i,_YScreen_):CNS(_LeftIndex_,_CurrentIndex_)=i
If fPoints(i,_YScreen_)>yEnd   Then yEnd  =fPoints(i,_YScreen_)
If fPoints(i,_XScreen_)<xStart Then xStart=fPoints(i,_XScreen_)
If fPoints(i,_XScreen_)>xEnd   Then xEnd  =fPoints(i,_XScreen_)
Next

If yStart = yEnd        Then Exit Sub
If xStart = xEnd        Then Exit Sub
If yEnd   < 0           Then Exit Sub
If xEnd   < 0           Then Exit Sub
If yStart>=TargetHeight Then Exit Sub
If xStart>=TargetWidth  Then Exit Sub

' share the same highest point
CNS(_RightIndex_,_CurrentIndex_)=CNS(_LeftIndex_,_CurrentIndex_)

' loop from Top to Bottom
While yStart<yEnd
'Scan Left and Right edges together
For i=_LeftIndex_ To _RightIndex_
If yStart=fPoints(CNS(i,_CurrentIndex_),_YScreen_) Then
If CNS(i,_NextIndex_)=ACS(i,_CMP_) Then CNS(i,_NextIndex_)=ACS(i,_SET_)
While fPoints(CNS(i,_CurrentIndex_),_YScreen_) = fPoints(CNS(i,_NextIndex_),_YScreen_)
CNS(i,_CurrentIndex_)=CNS(i,_NextIndex_)
If CNS(i,_NextIndex_)=ACS(i,_CMP_) Then CNS(i,_NextIndex_)=ACS(i,_SET_)
Wend
fEdges(i,_EdgeXStart_) = fPoints(CNS(i,_CurrentIndex_),_XScreen_)
fEdges(i,_EdgeUStart_) = fPoints(CNS(i,_CurrentIndex_),_UTexture_)
fEdges(i,_EdgeVStart_) = fPoints(CNS(i,_CurrentIndex_),_VTexture_)
fLength  = fPoints(CNS(i,_NextIndex_),_YScreen_) - fPoints(CNS(i,_CurrentIndex_),_YScreen_)
If fLength <> 0.0 Then
fLength=1/fLength
fEdges(i,_EdgeXStep_) = fPoints(CNS(i,_NextIndex_),_XScreen_ )-fEdges(i,_EdgeXStart_):fEdges(i,_EdgeXStep_)*=fLength
fEdges(i,_EdgeUStep_) = fPoints(CNS(i,_NextIndex_),_UTexture_)-fEdges(i,_EdgeUStart_):fEdges(i,_EdgeUStep_)*=fLength
fEdges(i,_EdgeVStep_) = fPoints(CNS(i,_NextIndex_),_VTexture_)-fEdges(i,_EdgeVStart_):fEdges(i,_EdgeVStep_)*=fLength
End If
CNS(i,_CurrentIndex_)=CNS(i,_NextIndex_)
End If
Next

If (yStart<0)                                                   Then Goto NextScanLine
xStart=fEdges(_LeftIndex_ ,_EdgeXStart_):If xStart>=TargetWidth Then Goto NextScanLine
xEnd  =fEdges(_RightIndex_,_EdgeXStart_):If xEnd  < 0           Then Goto NextScanLine
If (xStart=xEnd)                                                Then Goto NextScanLine
if xEnd  <xStart                                                Then goto NextScanLine

fLength=1/(xEnd-xStart)
fUSlope=fEdges(_RightIndex_,_EdgeUStart_)-fEdges(_LeftIndex_,_EdgeUStart_):fUSlope*=fLength
fVSlope=fEdges(_RightIndex_,_EdgeVStart_)-fEdges(_LeftIndex_,_EdgeVStart_):fVSlope*=fLength
If xStart<0 Then
fLength=-xStart
U.v=(fEdges(_LeftIndex_,_EdgeUStart_)+fUSlope*fLength)*&HFFFF
V.v=(fEdges(_LeftIndex_,_EdgeVStart_)+fVSlope*fLength)*&HFFFF
xStart = 0
Else
U.v=fEdges(_LeftIndex_,_EdgeUStart_)*&HFFFF
V.v=fEdges(_LeftIndex_,_EdgeVStart_)*&HFFFF
End If
If u.v<0 Then u.v=0
If v.v<0 Then v.v=0
US.v=fUSlope*&HFFFF
VS.v=fVSlope*&HFFFF

If xEnd>=TargetWidth Then xEnd=TargetWidth-1

Select Case as const TargetBytes
Case 1
var s=cptr(ubyte ptr,pSource)
var t=cptr(ubyte ptr,pTarget)+yStart*TargetPitch+xStart
var e=t+(xEnd-xStart)
If Transparent=false Then
While t<e
*t=*(s+V.h*SourcePitch+U.h)
V.v+=VS.v : U.v+=US.v : t+=1
Wend
Else
While t<e
dim as ubyte c=*(s+V.h*SourcePitch+U.h)
If c Then *t=c
V.v+=VS.v : U.v+=US.v : t+=1
Wend
End If
Case 2
var s=cptr(ushort ptr,pSource)
var t=cptr(ushort ptr,pTarget)+yStart*TargetPitch+xStart
var e=t+(xEnd-xStart)
If Transparent=false Then
While t<e
*t=*(s+V.h*SourcePitch+U.h)
V.v+=VS.v : U.v+=US.v : t+=1
Wend
Else
While t<e
dim as ushort c=*(s+V.h*SourcePitch+U.h)
If c<>&HF81F Then *t=c
V.v+=VS.v : U.v+=US.v : t+=1
Wend
End If
Case 4
var s=cptr(ulong ptr,pSource)
var t=cptr(ulong ptr,pTarget)+yStart*TargetPitch+xStart
var e=t+(xEnd-xStart)
If Transparent=false Then
While t<e
*t=*(s+V.h*SourcePitch+U.h)
V.v+=VS.v : U.v+=US.v : t+=1
Wend
Else
While t<e
dim as ulong c=*(s+V.h*SourcePitch+U.h)
If c<>&HFFFF00FF Then *t=c
V.v+=VS.v : U.v+=US.v : t+=1
Wend
End If
End Select

NextScanLine:
yStart+=1 : If yStart=TargetHeight Then exit while
fEdges(_LeftIndex_ ,_EdgeXStart_)+=fEdges(_LeftIndex_ ,_EdgeXStep_)
fEdges(_LeftIndex_ ,_EdgeUStart_)+=fEdges(_LeftIndex_ ,_EdgeUStep_)
fEdges(_LeftIndex_ ,_EdgeVStart_)+=fEdges(_LeftIndex_ ,_EdgeVStep_)
fEdges(_RightIndex_,_EdgeXStart_)+=fEdges(_RightIndex_,_EdgeXStep_)
fEdges(_RightIndex_,_EdgeUStart_)+=fEdges(_RightIndex_,_EdgeUStep_)
fEdges(_RightIndex_,_EdgeVStart_)+=fEdges(_RightIndex_,_EdgeVStep_)
Wend
End Sub
#endif ' __MULTIPUT_BI__

Dan.
Dr_D
Posts: 2430
Joined: May 27, 2005 4:59
Contact:

### Re: MultiPut V2.0 :-)

wio wrote:Hi all, old coder, new user here.

I am trying to use MultiPut V2 and am having slightly more success with it than with the first few iterations. It looks like a great tool but I still can't seem to get it to work properly.

When I display my 8x8 sprite on screen using multiput, if the rotation is 0 or 90 degrees the sprite is stretched, if it is at 270 degrees it is moved over to the right by 1 pixel (seemingly), at 180 degrees it looks fine (but upside down though obvs). Should it still work? I am on the latest version of FB, Win10 64bit.

Is there a version of FB that is ideal for using MultiPut and if so will it run in the 64bit version of that release? I have tried a few versions of FB along with most of the iterations of MultiPut that I came across. I could never get MultiPut to even show anything until I found V2, the version with the yellow smiley didn't work and also the version with the white square grid. Nothing would happen.

Thanks in advance for any help.

EDIT: I just tested it by scaling it up to 2 instead of 1. It now shows better but there is a line of pixels missing from the bottom of the sprite at 0 degrees, at 90 it seems stretched or there is an extra row of pixels added at the top and one missing at the bottom again. At 180 and 270 degrees everything looks perfect.

Dan.

Hi, Dan. Welcome! Maybe this is what's wrong?
bcohio2001 wrote:@D.J. Peters

Please specify in either the code or in the first post text that rotating an image with an odd width or height can result in loss of an edge of the image.
All your tests are with images with even dimensions.
wio
Posts: 17
Joined: Feb 05, 2021 4:58

### Re: MultiPut V2.0 :-)

Hi, thanks for the reply :)

I am not sure what you mean by this "Please specify in either the code or in the first post text that rotating an image with an odd width or height can result in loss of an edge of the image. All your tests are with images with even dimensions."

My image has an even amount of pixels, it is 8x8. Also, I don't have to change the rotation for it to 'fail', it does it at 0 rotation / 0 degrees.
sero
Posts: 53
Joined: Mar 06, 2018 13:26
Location: USA

### Re: MultiPut V2.0 :-)

Here is a 2x zoomed in screenshot of my experience of what is happening with this multiput using an 8x8 sprite. The titles 32bit and 64bit refers to how the code was compiled.

* original image removed because host is stupid *

Code: Select all

#include "multiput.bi"

screen 18,32
Dim spr_pedehead As Any Ptr  = ImageCreate(8,8)

dim as long rotate = 0
dim as long yoffset = 102

Do

screenlock()
draw string(120,yoffset - 16),"no trans"
draw string(120,yoffset),"original"

line(230,yoffset+8)-(250,yoffset+28),rgb(0,0,0),bf
draw string(240,yoffset),"rotating"

draw string(360,yoffset),"90 multiput"
draw string(360,yoffset+40),"180 multiput"
draw string(360,yoffset+80),"270 multiput"

yoffset += 160
draw string(120,yoffset - 16),"using trans"
draw string(120,yoffset),"original"

line(230,yoffset+8)-(250,yoffset+28),rgb(0,0,0),bf
draw string(240,yoffset),"rotating"

draw string(360,yoffset),"90 multiput"
draw string(360,yoffset+40),"180 multiput"
draw string(360,yoffset+80),"270 multiput"
yoffset -= 160
screenunlock()

rotate += 3
if rotate > 360 then rotate -= 360
sleep 1
Loop Until inkey <>""

Last edited by sero on Feb 12, 2021 3:12, edited 1 time in total.
Dr_D
Posts: 2430
Joined: May 27, 2005 4:59
Contact:

### Re: MultiPut V2.0 :-)

A long time ago, I made a rotozoomer, but the link in the original post is dead. I'm working on putting a new archive up for it. If you're interested, I'll post the link when I'm done.