hex007 / freej2me

A free J2ME emulator with libretro, awt and sdl2 frontends.
Other
500 stars 78 forks source link

AWT Frontend - screen rotation is not implemented #11

Closed colossal-squid closed 1 year ago

colossal-squid commented 7 years ago

At the moment

private boolean rotateDisplay = false;

is defined, but never used. I'll try to handle this today

recompileorg commented 7 years ago

It's used by the libretro build to rotate the display 90 degrees anticlockwise.

For AWT and JavaFx builds, you can leverage the static method PlatformImage.transformImage.

You'll also want to make sure mouse events are adjusted for the rotated display. Doom II RPG is great for testing those.

colossal-squid commented 7 years ago

you can leverage the static method PlatformImage.transformImage

Just a side-note - I did quite of playing with AWT docs yesterday as well as stackoverflow stuff, and i suppose in transformImage impl you should add gc.dispose(); statement before returning.

Now regarding the rotation:

I've tried both AffineTransform method, the static method from PlatformImage and many more - all of them both affect the canvas viewport, so the image gets dispositioned and cut See here: https://imgur.com/a/qxLqH Blue is canvas position shifted against frame, and white is another shift in canvas. Could you please advise on where should I rotate? (I'll handle touch recognition as its done in JavaFX already after I crack the rendering, I promise)

This is the diff of changes I have so far

===================================================================
--- src/org/recompile/freej2me/FreeJ2ME.java    (revision ba4fde16c5d4eb27d24d62a6e30f1b61c46ca9be)
+++ src/org/recompile/freej2me/FreeJ2ME.java    (revision )
@@ -24,6 +24,7 @@

 import java.awt.*;
 import java.awt.event.*;
+import java.awt.geom.AffineTransform;
 import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.FilenameFilter;
@@ -58,7 +59,7 @@
        main.setBackground(new Color(0,0,64));
        try
        {
-           main.setIconImage(ImageIO.read(main.getClass().getResourceAsStream("/org/recompile/icon.png")));    
+           main.setIconImage(ImageIO.read(main.getClass().getResourceAsStream("/org/recompile/icon.png")));
        }
        catch (Exception e) { }

@@ -199,6 +200,7 @@
    {
        int w = Integer.parseInt(config.settings.get("width"));
        int h = Integer.parseInt(config.settings.get("height"));
+       boolean isRotated = "on".equals(config.settings.get("rotate"));

        String sound = config.settings.get("sound");
        if(sound.equals("on")) { Mobile.getPlatform().sound = true; }
@@ -210,9 +212,15 @@

        if(lcdWidth != w || lcdHeight != h)
        {
+         if (isRotated!=this.rotateDisplay){
+            this.rotateDisplay = isRotated;
+            int t = h;
+            h = w;
+            w = t;
+         }
+
            lcdWidth = w;
            lcdHeight = h;
-
            Mobile.getPlatform().resizeLCD(w, h);

            resize();
@@ -324,7 +332,17 @@
                }
                else
                {
-                   g.drawImage(Mobile.getPlatform().getLCD(), cx, cy, cw, ch, null);
+                  BufferedImage i = Mobile.getPlatform().getLCD();
+                  if (rotateDisplay) {
+                       // rotates image within the canvas
+                       ((Graphics2D) g).transform(AffineTransform
+                               .getQuadrantRotateInstance(3, i.getWidth() / 2,
+                                       i.getHeight() / 2));
+                       g.drawImage(i, cy, cx, ch, cw, null);
+                   } else {
+                       g.drawImage(i, cx, cy, cw, ch, null);
+                   }
+
                }
            }
            catch (Exception e)
@@ -332,5 +350,5 @@
                System.out.println(e.getMessage());
            }
        }
-   }
+   }
 }
hex007 commented 7 years ago

@colossal-squid If you are running on Linux you can install the SDL frontend that supports rotation using the additional flag -r DEGREES eg java -jar freej2me-sdl.jar "works/Asphalt6.480x800.r270.jar" 480 800 -r 270

It also supports custom angles

screenshot from 2017-09-27 00-50-13

screenshot from 2017-09-27 00-50-30

colossal-squid commented 7 years ago

It was more of an improvement plan, not troubleshooting, but seems like my codebase knowledge is not sufficient at the moment. I'll just keep reading and trying

recompileorg commented 7 years ago

You'll need to swap lcdWidth and lcdHeight so that resize() can compute the correct size and position for the UI.

The trouble, of course, is that you don't want to actually change those values as settingsChanged will resize the display as the game sees it. You'll want to swap them just in the resize and updateScale methods.

Alternately, you could keep a second copy of the display dimensions, one for passing along to MobilePlatform and another just for use in the UI. That way you could do everything in settingsChanged. Whatever you think is more readable.

colossal-squid commented 7 years ago

Thanks for an insight - Indeed it works. I'll handle the scaling/touch control and post a PR, thanks so much for clarifying it 👍

recompileorg commented 7 years ago

Any luck?

AShiningRay commented 1 year ago

I think this one can be closed due to #157 being merged, seeing as the changes are related to this issue.