CPCWiki forum

General Category => Demos => Topic started by: Bytebreaker on 00:37, 11 January 17

Title: Char Rotation Magic in Loco BASIC
Post by: Bytebreaker on 00:37, 11 January 17

Hello!


I am happy to present some floating point based char rotation with the superior, royal and imperial Locomotive BASIC. :-)


I have no source txt file to upload as I did everything directly in WinCPC to enjoy the original editor, which outclasses all other native 8 bit BASIC editors of that time.


I was thinking hard if such effects can be ported to C128, Plus/4 or C64. As far as I am aware, even the advanced Commodore 3.5 and 7.0 BASIC versions do not have an equivalent to the "test" command, which was the key to realize this little project without using machine language.


The "charrot" effect works perfectly whereas the "sinrot" effect does not. The precision decreases slowly the more letters I keep rotating. The result is still readable. The "sinrot" effect addresses bitmap areas that are not aligned with the char coordinate grid. The "charrot" effect instead uses pixel coordinates that begin exactly at a real char coordinate position which is also addressable via locate command. I don't know if this is the reason for precision loss while repeating rotations or whether my code is faulty or due to precision limitations of the Amstrad floating point capabilities.


Another nice thing to add is vertical and horizontal char flipping, which I will add in the next days. Or maybe AMSDOS, SRS or litwr are faster and show me how to flip a char properly and perfectly. :-)


Greetings,


Vincent
Title: Re: Char Rotation Magic in Loco BASIC
Post by: AMSDOS on 04:49, 11 January 17
Quote from: Bytebreaker on 00:37, 11 January 17

The "charrot" effect works perfectly whereas the "sinrot" effect does not. The precision decreases slowly the more letters I keep rotating. The result is still readable. The "sinrot" effect addresses bitmap areas that are not aligned with the char coordinate grid. The "charrot" effect instead uses pixel coordinates that begin exactly at a real char coordinate position which is also addressable via locate command. I don't know if this is the reason for precision loss while repeating rotations or whether my code is faulty or due to precision limitations of the Amstrad floating point capabilities.

The sinrot program is graphically aligning the text I noticed, the "x co-ordinate" looks fine, where's the "y co-ordinate" isn't aligning with the text y co-ordinate position, though that's not the problem you're having. I can see once it's all been written out in it's upright state, it starts deleting a letter at a time, before redrawing it, though when the redrawing takes place, some extra lines appear to be drawn in and then are removed, I don't know why that's happening. A bit of the "B" towards the bottom for example, appears to have an extra pixel in it, where's the "A" next to it is missing a pixel through it's centre. Some of the "o's" towards the top appear to have a line drawn in and then it's removed, the odd thing about it all is once it's gone through the overall size of the letters appears correct, unfortunately I'm unsure where to point point the cause, only guessing it's somewhere in between the TESTing of the points and plotting them.

QuoteAnother nice thing to add is vertical and horizontal char flipping, which I will add in the next days. Or maybe AMSDOS, SRS or litwr are faster and show me how to flip a char properly and perfectly. :-)

I recall a program from AA17 type-ins (http://www.cpcwiki.eu/index.php/Amstrad_Action_February_1987_Type-Ins) which did that, but was submitted as a BASIC m/c loader program, the program takes the text from the Top Left and places it Bottom Right, which I presume is what you don't want.
Title: Re: Char Rotation Magic in Loco BASIC
Post by: Bytebreaker on 07:46, 11 January 17
@ amsdos

The deletion before redrawing was inserted to prevent graphical rubbish that might be left for whatever reason. In fact the sinrot letters look more shitty when you use 45 degree steps as I originally intended because that strange test /plot behavior has a stronger impact when doing so.

The first couple of letters look ok, then these errors begin.
The bad effect can be reduced or made worse by changing the value +6.4 /-6.4 in the lines 7030 and 61. These are the relative coordinates to address the rotation centre of each character. This value must be adjusted according to the sinus wave offset in line 7030 (currently at 0.16*150 if I remember correctly).

The charrot program parses the pixels always from the same position which equates "locate 10,10" without tag based graphic cursor addressing. You say that does not make a difference, ok then. On the other hand, charrot rotates only once. There are no iterations which might produce the same result as sinrot after a couple of times.

In sub routine 3000 I generate a table of angles and radi for each pixel of a char relative to the center ccx,ccy of the char. So I can make a rotation with each pixel as I know radius and angle.

The flipping concept you explained in the end of your posting is not exactly what I would describe as flipping.

For horizontal flipping the pixels must be swapped from right to left while maintaining the order of the horizontal lines in y direction.
Vertical flipping maintains the horizontal Order but swaps the vertical one, the order of y lines. At least that's how it works in my head I still have to code it and prove that it works.


Edit:
In 4000 you find the plot routine. (...) *1*grid (...)
The "1" is the magnification factor. Charrot uses 10 instead of 1 and thus we have a spread grid instead of 1:1 char copy in size.
Title: Re: Char Rotation Magic in Loco BASIC
Post by: Bytebreaker on 00:28, 13 January 17
As promised, please find attached the modified version "charflip.bas" added on charrot.dsk file that supports vertical and horizontal bitmap flipping in addition to rotation. The rotation takes place after flipping. A rotation angle of 0 only flips and suppresses rotation.
Title: Re: Char Rotation Magic in Loco BASIC
Post by: AMSDOS on 09:08, 13 January 17
Quote from: Bytebreaker on 07:46, 11 January 17
@ amsdos

The deletion before redrawing was inserted to prevent graphical rubbish that might be left for whatever reason. In fact the sinrot letters look more shitty when you use 45 degree steps as I originally intended because that strange test /plot behavior has a stronger impact when doing so.


Yes, so that was Line 61 which was deleting the character before redrawing.

QuoteThe first couple of letters look ok, then these errors begin.
The bad effect can be reduced or made worse by changing the value +6.4 /-6.4 in the lines 7030 and 61. These are the relative coordinates to address the rotation centre of each character. This value must be adjusted according to the sinus wave offset in line 7030 (currently at 0.16*150 if I remember correctly).


I'm sorry, but the math behind this process is baffling, I can see 7030 is used for placing the text, 61 for each character before redrawing at a rotated angle, but don't really know what 6.4 or -6.4 represents. Earlier when you asked if BASIC needed for decimal places for precision, had you tried placing a second number e.g. 6.41, 6.42, etc to see if it was getting a better result?

QuoteThe charrot program parses the pixels always from the same position which equates "locate 10,10" without tag based graphic cursor addressing. You say that does not make a difference, ok then. On the other hand, charrot rotates only once. There are no iterations which might produce the same result as sinrot after a couple of times.


Sorry, I was only looking at the sinrot program and analysing how the Characters were placed in relation to the text cursor. The characters along xpos position were placed correctly while the ypos position was going through 2 ypos positions, though was saying that's all working just fine.
Title: Re: Char Rotation Magic in Loco BASIC
Post by: Bytebreaker on 21:29, 13 January 17
Regarding the +6.4 / -6.4 workaround:


In fact, 6.4 is a bad compromise because it looks worse if I do it the way it is supposed to be:


Instead of 6.4 it should say +/-7. Why? Because I work with a 15*15 dot matrix which is represented by the grid(225,2) array.
15*15 = 225. 0=color, 1=angle, 2=radius of each pixel of a 15*15 char.


-7... 0...+7


        0   <------------------centre of char rotation     


-7...0....+7 


This works well with charrot.bas.
Sinrot.bas uses almost the same code. Still, the rotation center is no longer precisley located as soon as I work with tag based text coordinates. At least it seems so to me as this is the only difference to charrot.bas, where the text position exactly fits into the char grid that you address with the locate command.


Using +/- 6.4 as the relative coordinates of the centre of char rotation was the value that produced the least rubbish. I tried float values between 6 and 8 and even enlarged the grid array for it but the results were not satisfying.


The tag based x/y position of a char is the upper left corner. So the rotation centre should be at x+7, y-7. In fact, in contrary to charrot.bas I have to use 6.4 instead of 7 to achieve somewhat presentable results when hanging the chars on a sinus line.


Edit:


When you change the 6.4 value in line 7030 you have to change it in line 61 too in an analogue way, otherwise the setting of coordinates won't work properly.
Title: Re: Char Rotation Magic in Loco BASIC
Post by: Bytebreaker on 21:33, 13 January 17
wrong post.
Title: Re: Char Rotation Magic in Loco BASIC
Post by: AMSDOS on 21:50, 13 January 17
I remember altering the values in those FOR loops so they were "-6.4 to 6.4" and "6.4 to -6.4 step -1", but I only made the change to one set of those FOR loops, I didn't notice the second pair in 6010..6020, but I think when I did that it was causing problems for the "IF i=0 and j=0 then 3100" statement.
Title: Re: Char Rotation Magic in Loco BASIC
Post by: Bytebreaker on 22:26, 13 January 17
The for loops were never changed by me. All my experiments where about changing the 6.x values in lines 7030 and 61.
I think the next steps to do must be in assembler anyway. For example, I will never get real time rotating dot grids with changing letters using Basic. Also, sinus scrollers with rotating letters will only work in assembler.


Basic is still VERY important as proof of concept and for precalculations you can store on disk.


Maybe I should do it one day all over again using integers instead of floats.
Title: Re: Char Rotation Magic in Loco BASIC
Post by: Bytebreaker on 17:09, 15 January 17
Please find attached a modified version that saves your chars on disk and makes them re-usable!


1. Use inputchr.bas as often as you like and save the chars on disk under the name you specify in the beginning
2. Edit line 100 of sinwrite.bas and insert the names of the chars saved on disk into the data area. You have space for 20 chars in mode 1 with 2x magnification as it is configured by me. Empty spaces " " are skipped automatically. You can adjust the sinus height in line 30 if you like, too.


Please note that with the use of floats and trignometric math, the pixel-perfect addressing of rotated pixels becomes unprecise. Angles that can be divided by 90 will work fine, all other angles might produce empty dots or strange effects with 1x magnification (as seen in sinrot.bas).


As long as I do not build my own chunky resolution and work with integers, these glitches seem inevitable.
Title: Re: Char Rotation Magic in Loco BASIC
Post by: Bytebreaker on 14:34, 16 January 17
Hello,


please find attached aonther version that contains an additional "showchar.bas" Basic program. It plots a selected char that you saved on disk upfront.


This might come in handy if your filenames do not reveal information about the character which is encoded and its rotation / flipping / colors.
Powered by SMFPacks Menu Editor Mod