Fast way to rotate screen 180 degrees?

BlitzMax Forums/BlitzMax Programming/Fast way to rotate screen 180 degrees?

Digital Anime(Posted 2008) [#1]
I'm writing a Pacman clone for my cocktail arcade cabinet which is still under construction, and noticed that my TFT screen has a better viewing angle when it's upside down...

If I do this I need to rotate every drawed screen before flip.

I tried the following codes and hoped it would be fast enough.

Test 1

GrabImage fullscreen_image,0,0
Cls
SetScale (-1,-1)
SetColor 255,255,255
DrawImage (fullscreen_image,width/2,height/2)
SetScale (1,1)


Test 2

GrabImage fullscreen_image,0,0
Cls
SetScale (-1,-1)
SetColor 255,255,255
DrawImage (fullscreen_image,width/2,height/2)
SetScale (1,1)


But GrabImage slows everything down too much...

What I am hoping for is some code which can be added without changing too much code. Something like grabbing everything and rotate it afterwards, or a way that I can declare the right bottom of the screen as position 0,0 and left top 1024,768 before I even start drawing.


ImaginaryHuman(Posted 2008) [#2]
I believe it is the Viewport or the projection matrix which manages the translation from world coordinates to screen coordinates. You could either look at using SetRotation() in your code in the appropriate places to draw everything rotated in the first place, or you could try fiddling with SetViewport. I'm not sure if BlitzMax's interface to it does error checking or adjusts the values you give it, but maybe you can tell it to think of your window as from 0,height to width,0. If that doesn't work you'd have to change the projection matrix which means dipping into lower-level code. Change the projection matrix, which defines the viewing volumne, would let you define that the left of the screen is actually coordinate 512, the right is -512, or whatever.


tonyg(Posted 2008) [#3]
If it's DX driver this might help


Digital Anime(Posted 2008) [#4]
I'm using DX indeed.

I think the projection matrix is the answer to my question, but I will need some time to check this.

Thanks a lot!


TaskMaster(Posted 2008) [#5]
If you plan to install the monitor upside down, then you should find something that makes the entire operating system flip. Maybe there is something you can run in Windows that does it for "everything"?!?!

A cocktail arcade machine huh? Sounds cool!

I have an upright MAME cabinet with a 27 inch TV in it and it is awesome. I thought about doing a cocktail as well. Any reason you don't just use MAME, rather than writing your own clone? Or are you just doing it for the experience?


Digital Anime(Posted 2008) [#6]
Well, I have bought 3 8-way joysticks for this project in the colors red, green and blue and want to make games for 3 players in total. I am also using a webcam which will be used to save a picture instead of a name with the hiscore. Further I am using a USB relais interface to control lights and coin mechanism. I got those dll's working already in Blitzmax.

The game looks like this at the moment :



Images where done in Blitzmax itself with loads of math. :-)

3 Pacmans eating their way through the maze for points. And each level I can change the size of the grid to any other 4:3 format. I can make levels using Windows best working piece of software (Notepad).

I want to write more small games for this cabinet only.

And I allready made a 2 player Mame Cabinet :-)


Digital Anime(Posted 2008) [#7]
Searched the internet for a good tool to rotate the display and I finally found one that is free and works under WinXP in combination with a BlitzMax application in fullscreen :

http://www.softpedia.com/get/Tweak/Video-Tweak/iRotate.shtml

iRotate 1.2

This solution saves me loads of time.

Normally every graphic card has it's own rotation software included, but Intel drivers + Blitzmax = Trouble :-)


xlsior(Posted 2008) [#8]
If you plan to install the monitor upside down, then you should find something that makes the entire operating system flip. Maybe there is something you can run in Windows that does it for "everything"?!?!


Depending on the video card, it might be as simple as a checkbox under Control Panel -> Display properties -> Settings -> Advanced -> (look around graphics-card specific settings)

Even the intel onboard video adapters have an option there to rotate the display.


Digital Anime(Posted 2008) [#9]
I checked that before and indeed the Intel driver has this option, but it didn't work as soon as my game started.

Intel chipsets can be turned with mostly with CTRL + ALT and one of the cusor keys.

the 3th party app IRotate worked perfect, so i keep with that.


SoggyP(Posted 2008) [#10]
Hello.

Move your chair?

Goodbye.


Digital Anime(Posted 2008) [#11]

Hello.

Move your chair?



Nah, I'm not looking for a cheap rumble effect ;-)


MGE(Posted 2008) [#12]
If the monitor is going to run all the time in vertical mode, then just code the game from the get go in the correct rotation. Easy fix. ;)


Digital Anime(Posted 2008) [#13]
I want to be able to make a version to be run from normal computers also. And this game won't be played in vertical mode.

The only trouble is the display that I'm using for the cocktail cabinet project is to dark when I build it in normal and viewed from the players side. When the display is rotated 180 the colors and brightness are good.

I know now when I need to do this with Blitzmax I need to change all x and y positions and rotation correctly to draw it upside down. This could be done with something like Width - x, Height - y and Rotation + 180.


Space Fractal(Posted 2008) [#14]
You can use SetRotatation to rotate the graphics using graphicscard GPU. it very fast (which I used for all realtime rotations in the Jukebox Application, MultiJuke).

Then you should only need to reposition and draw them from the other corner.

You should not need to recompute the polygons itself, also the gameplay tecnical does not need to been rotated.

This game look very nice, and you should maybe post this game at www.arcadecontrols.com under software.

Make sure the game run in 640x480 and max 60hz, so it can been used in a real arcade monitor, like the cabinet I have.


Digital Anime(Posted 2008) [#15]
640x480 is no problem at all, I started working on a loose configure utility as well and resolutions can be set from 320x240 to 1600x1200 in 60Hz.

I think I'll post this game on the arcadecontrols website and overhere as well when it is finished. It still needs a better menu and I need to upgrade the config util bit more.

It will be Win32 only because of dll's I need to use.

What works so far :

- Game can be played with 3 players Red, Green and Blue only with joypad at this stage
- Dots can be eaten and give points, if al dots are gone new map will be loaded automaticly
- Levels can be made easily with a text editor :-)
- Config utility (only resolution and webcam selection at this time)
- If player hits a ghost player will die and loose a live, if all players have 0 live you go back to the start screen
- Ghosts randomly move through the maze, but in a way that it seems that they actually go somewhere
- Bit of a glowing effect on players and ghosts

Worklist :

- Game has no real menu yet, priority number 1
- Small changes on graphics, dots needs some changes
- Hiscore list for day, week and all-time
- Photo of winner saved with hiscore
- Adding sounds
- Add music
- More levels
- level difficulty setting
- Rules for powerpills and who can eat ghosts and what will happen rules (still thinking on this one)
- Insert credit option for my coin mechanism
- Want to add option for customs controls Keyboard/Joypad in config

Stuff I want to add, but will be saved for the last :

- Effects when music plays (VU meter blocks maybe) and flashing objects on the beat of music
- adding different set of rules to alter gameplay
- If no webcam is used for hiscore picture, option to enter the name using controls
- Option edit amount of players possible
- Level editor with possibility for custom blocks to be added
- Add custom music/sounds with level editor
- Create a frontend for this game and future games with possibility to remember amount of credits inserted


Digital Anime(Posted 2008) [#16]
And back to topic... I came up with the following code wich I only need to include and replace draw functions for the new ones in the application.

I even upgraded it with the option to shake the screen and zoom in and out :-)

It's not finished yet, needs a lot more draw functions, but it is fast.
When this is finished I will post the code here.

Here is the ZRM.bmx
'########################################
'### Zoom Rotate And Move Version 1.0 ###
'########################################
'
' This file is used to zoom, rotate and move everything that you want by using the ZRM functions
' and can be implemented in your project even when you are almost done
'
' I needed only the rotate function at first to rotate all stuff 180 on the display, so I only need
' ZRM_Rotate (180) to determine how every ZRM draw function should be rotated
'
' DrawImage will be replaced by ZRM_DrawImage
'
' include this file in your Blitzmax application with :
' 
' include "ZRM.bmx"
'
' This needs to be done after the setgraphics command
'
' Functions :
'
' - ZRM_Zoom (x:Float, y:Float)                                : Zooms everything on the screen drawn with ZRM_Draw functions
'                                                                Is used the same as SetScale
'
' - ZRM_Rotate (angle:Float)                                   : Rotates everything on the screen drawn with ZRM_Draw functions
'                                                                Is used the same as SetRotation
'
' - ZRM_Move (x:Float, y:Float)                                : Moves everything from the middle of the screen drawn with ZRM_Draw functions
'                                                                X stands for - or + amount of pixels to go left or right
'                                                                Y stands for - or + amount of pixels to go up or down
'
' - ZRM_SetScale (x:Float, y:Float)                            : Replacement for SetScale
'
' - ZRM_SetRotation (angle:Float)                              : Replacement for SetRotation
' 
' - ZRM_DrawText (Text:String, x:Float, y:Float)               : Replacement for DrawText
'
' - ZRM_DrawImage (Image:TImage, x:Float, y:Float)             : Replacement for DrawImage (Works the same, but won't work with more frames)
'
' - ZRM_DrawRect (x:Float, y:Float, Width:Float, Heigth:Float) : Replacement for DrawRect
'
' - ZRM_DrawRect (x:Float, y:Float, Width:Float, Heigth:Float) : Replacement for DrawOval
'
' - ZRM_DrawLine (x1:Float, y1:Float, x2:Float, y2:Float)      : Replacement for DrawLine
'
' - More functions will be added
'
'Written by Mark Gerritsen

Global ZRM_Zoom_X:Float = 1
Global ZRM_Zoom_Y:Float = 1
Global ZRM_Rotate_Angle:Float = 0
Global ZRM_Move_X:Float = 0
Global ZRM_Move_Y:Float = 0
Global ZRM_SetScale_X:Float = 1
Global ZRM_SetScale_Y:Float = 1
Global ZRM_SetRotation_Angle:Float = 0
Global ZRM_Width:Int
Global ZRM_Height:Int
Global ZRM_Temp_X_X:Float
Global ZRM_Temp_X_Y:Float
Global ZRM_Temp_Y_X:Float
Global ZRM_Temp_Y_Y:Float

ZRM_Width  = GraphicsWidth()
ZRM_Height = GraphicsHeight()

Function ZRM_Zoom (X:Float, Y:Float)
	ZRM_Zoom_X = X
	ZRM_Zoom_Y = Y
End Function

Function ZRM_Rotate (Angle:Float)
	ZRM_Rotate_Angle = Angle
End Function

Function ZRM_Move (X:Float, Y:Float)
	ZRM_Move_X = X
	ZRM_Move_Y = Y
End Function

Function ZRM_SetScale (X:Float, Y:Float)
	ZRM_SetScale_X = X
	ZRM_SetScale_Y = Y
End Function

Function ZRM_SetRotation (Angle:Float)
	ZRM_SetRotation_Angle = Angle
End Function

Function ZRM_Drawtext (Text:String, X:Float, Y:Float)
		
	ZRM_Calculate (X, Y)
	DrawText Text, ((ZRM_Width / 2) + ZRM_Temp_X_X - ZRM_Temp_X_Y + ZRM_Move_X), ((ZRM_Height / 2) + ZRM_Temp_Y_X + ZRM_Temp_Y_Y + ZRM_Move_Y)

End Function

Function ZRM_DrawImage (Image:TImage, X:Float, Y:Float)

	ZRM_Calculate (X, Y)
	DrawImage Image, ((ZRM_Width / 2) + ZRM_Temp_X_X - ZRM_Temp_X_Y + ZRM_Move_X), ((ZRM_Height / 2) + ZRM_Temp_Y_X + ZRM_Temp_Y_Y + ZRM_Move_Y)

End Function

Function ZRM_DrawRect (X:Float, Y:Float, Width:Float, Height:Float)

	ZRM_Calculate (X, Y)
	DrawRect ((ZRM_Width / 2) + ZRM_Temp_X_X - ZRM_Temp_X_Y + ZRM_Move_X), ((ZRM_Height / 2) + ZRM_Temp_Y_X + ZRM_Temp_Y_Y + ZRM_Move_Y), Width, Height

End Function

Function ZRM_DrawOval (X:Float, Y:Float, Width:Float, Height:Float)

	ZRM_Calculate (X, Y)
	DrawOval ((ZRM_Width / 2) + ZRM_Temp_X_X - ZRM_Temp_X_Y + ZRM_Move_X), ((ZRM_Height / 2) + ZRM_Temp_Y_X + ZRM_Temp_Y_Y + ZRM_Move_Y), Width, Height

End Function 

Function ZRM_DrawLine (X1:Float, Y1:Float, X2:Float, Y2:Float)

	ZRM_Calculate (X1, Y1)
	Local X1_New:Float = ((ZRM_Width / 2) + ZRM_Temp_X_X - ZRM_Temp_X_Y + ZRM_Move_X)
	Local Y1_New:Float = ((ZRM_Height / 2) + ZRM_Temp_Y_X + ZRM_Temp_Y_Y + ZRM_Move_Y)
	ZRM_Calculate (X2, Y2)
	Local X2_New:Float = ((ZRM_Width / 2) + ZRM_Temp_X_X - ZRM_Temp_X_Y + ZRM_Move_X)
	Local Y2_New:Float = ((ZRM_Height / 2) + ZRM_Temp_Y_X + ZRM_Temp_Y_Y + ZRM_Move_Y)
	SetScale (1, 1)
	SetRotation (0)
	DrawLine X1_New, Y1_New, X2_New, Y2_New 

End Function 

Function ZRM_Calculate(X:Float, Y:Float)

	SetRotation (ZRM_SetRotation_Angle + ZRM_Rotate_Angle)
	SetScale (ZRM_SetScale_X * ZRM_Zoom_X), (ZRM_SetScale_Y * ZRM_Zoom_Y)
	ZRM_Temp_X_X = ((Cos(ZRM_Rotate_Angle) * (X - (ZRM_Width / 2)) * (ZRM_Zoom_X)))
	ZRM_Temp_X_Y = ((Sin(ZRM_Rotate_Angle) * (Y - (ZRM_Height / 2)) * (ZRM_Zoom_Y)))
	ZRM_Temp_Y_X = ((Sin(ZRM_Rotate_Angle) * (X - (ZRM_Width / 2)) * (ZRM_Zoom_X)))
	ZRM_Temp_Y_Y = ((Cos(ZRM_Rotate_Angle) * (Y - (ZRM_Height / 2)) * (ZRM_Zoom_Y)))

End Function


<Edit : Fixed some small bugs, should work perfectly with all functions now>

I wonder if this is usefull for anyone else, please test it if any flaws are found, please reply.