Desktop fullscreen window example in Mojo1

Jimmy

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
576
Simple native code example how to create a window that fills the complete desktop screen in Mojo1.

code_language.cerberus:
#GLFW_WINDOW_TITLE = "Invisible"
#GLFW_WINDOW_SAMPLES = 0
#GLFW_WINDOW_RESIZABLE = False
#GLFW_WINDOW_DECORATED = False
#GLFW_WINDOW_FLOATING = False
#GLFW_WINDOW_FULLSCREEN = False
#GLFW_WINDOW_WIDTH = 0 ' crashes Mojo2
#GLFW_WINDOW_HEIGHT = 0 ' crashes Mojo2
Strict
' Public
Import mojo
Import "commands.cpp"
Extern ' Bindings
Function SetWindowPosition:Void(X:Int, Y:Int) = "commands::setWindowPosition"
Function GetMonitorCanvas:Void(Output:Int[], MinimumHeight:Bool=False) = "commands::getMonitorCanvas"
Function GetMonitorCanvas:Int[](MinimumHeight:Bool=False) = "commands::getMonitorCanvas"
Public
' -------------------------------------------------
Function Main:Int()
    New Application()
    Return 0
End

Class Application Extends App Final
    
    Field Color:Float
    Field canvas:Canvas
    
    Method OnCreate:Int()
        ' canvas = New Canvas()
        SetUpdateRate 0
        Local Desktop := GetMonitorCanvas()       
        SetDeviceWindow(Desktop[2],Desktop[3],0)       
        SetWindowPosition(Desktop[0],Desktop[1])
        Return 0
    End
    
    Method OnUpdate:Int()
        If KeyHit(KEY_ESCAPE) Then OnClose()   
        Color = Sin(Float(Millisecs()/10))*255
        Return 0
    End
    
    Method OnRender:Int()
        Cls Color,0.0,0.0
        ' canvas.Flush
        Return 0
    End
End
' -------------------------------------------------

[CODE lang="cpp" title="commands.cpp"]namespace commands
{
// ------------------------------------------------------------------
void setWindowPosition(int X, int Y)
{
glfwSetWindowPos(BBGlfwGame::GlfwGame()->GetGLFWwindow(), X, Y);
return;
}
// ------------------------------------------------------------------
void getMonitorCanvas(Array<int> output, bool minimumHeight=false)
{
int count;
GLFWmonitor** monitors = glfwGetMonitors(&count);
int minx = 0;
int miny = 0;
int width = 0;
int height = 0;
for (int i = 0; i < count; i++)
{
GLFWmonitor* monitor = monitors;
int xpos, ypos;
const GLFWvidmode* video = glfwGetVideoMode(monitor);
width += video->width;
if (!minimumHeight)
{
height += video->height;
}
else
{
if ((i == 0) || video->height < height)
{
height = video->height;
}
}
glfwGetMonitorPos(monitor, &xpos, &ypos);
if (xpos < minx)
{
minx = xpos;
}
if (ypos < miny)
{
miny = ypos;
}
}
output[0] = minx;
output[1] = miny;
output[2] = width;
output[3] = height;
return;
}
// ------------------------------------------------------------------
Array<int> getMonitorCanvas(bool minimumHeight=false)
{
Array<int> output = Array<int>(4);
getMonitorCanvas(output, minimumHeight);
return output;
}
// ------------------------------------------------------------------
}[/CODE]
 

Jimmy

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
576
Just for interests here's a Mojo2 version that shows how it works differently, without modification it'll show only a 640x480 limited active area, the rest is cleared or filled with garbage.

code_language.cerberus:
#GLFW_WINDOW_TITLE = "Invisible"
#GLFW_WINDOW_SAMPLES = 0
#GLFW_WINDOW_RESIZABLE = False
#GLFW_WINDOW_DECORATED = False
#GLFW_WINDOW_FLOATING = False
#GLFW_WINDOW_FULLSCREEN = False
' #GLFW_WINDOW_WIDTH = 0 ' 0 crashes Mojo2
' #GLFW_WINDOW_HEIGHT = 0 ' 0 crashes Mojo2
Strict
' Public
Import mojo2
Import "commands.cpp"
Extern ' Bindings
Function SetWindowPosition:Void(X:Int, Y:Int) = "commands::setWindowPosition"
Function GetMonitorCanvas:Void(Output:Int[], MinimumHeight:Bool=False) = "commands::getMonitorCanvas"
Function GetMonitorCanvas:Int[](MinimumHeight:Bool=False) = "commands::getMonitorCanvas"
Public
' -------------------------------------------------
Function Main:Int()
    New Application()
    Return 0
End

Class Application Extends App Final
   
    Field Color:Float
    Field canvas:Canvas
   
    Method OnCreate:Int()
        canvas = New Canvas()
        SetUpdateRate 0
        Local Desktop := GetMonitorCanvas()      
        SetDeviceWindow(Desktop[2],Desktop[3],0)      
        SetWindowPosition(Desktop[0],Desktop[1])
        Return 0
    End
   
    Method OnUpdate:Int()
        If KeyHit(KEY_ESCAPE) Then OnClose()  
        Color = Sin(Float(Millisecs()/10))
        Return 0
    End
   
    Method OnRender:Int()
        canvas.Clear Color,0.0,0.0
        canvas.Flush
        Return 0
    End
End
' -------------------------------------------------
 
Last edited:

Jimmy

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
576
Adding a few lines to the Mojo2 version seem to fix it and I think this is the correct way to do it?

Here's the complete Mojo2 version :

code_language.cerberus:
#GLFW_WINDOW_TITLE = "Invisible"
#GLFW_WINDOW_SAMPLES = 0
#GLFW_WINDOW_RESIZABLE = False
#GLFW_WINDOW_DECORATED = False
#GLFW_WINDOW_FLOATING = False
#GLFW_WINDOW_FULLSCREEN = False
' #GLFW_WINDOW_WIDTH = 0 ' crashes Mojo2
' #GLFW_WINDOW_HEIGHT = 0 ' crashes Mojo2
Strict
' Public
Import mojo2
Import "commands.cpp"
Extern ' Bindings
Function SetWindowPosition:Void(X:Int, Y:Int) = "commands::setWindowPosition"
Function GetMonitorCanvas:Void(Output:Int[], MinimumHeight:Bool=False) = "commands::getMonitorCanvas"
Function GetMonitorCanvas:Int[](MinimumHeight:Bool=False) = "commands::getMonitorCanvas"
Public
' -------------------------------------------------
Function Main:Int()
    New Application()
    Return 0
End

Class Application Extends App Final
    
    Field Color:Float
    Field canvas:Canvas
    
    Method OnCreate:Int()
        canvas = New Canvas()
        SetUpdateRate 0 
        Local Desktop := GetMonitorCanvas()        
        SetDeviceWindow(Desktop[2],Desktop[3],0)        
        SetWindowPosition(Desktop[0],Desktop[1])
        
        ' These command seem accepible in OnCreate or should it go in OnRender?
         ' SetDeviceWindow DeviceWidth(),DeviceHeight(),2
         ' canvas.SetScissor 0,0,DeviceWidth(),DeviceHeight()
         canvas.SetViewport 0,0,DeviceWidth(),DeviceHeight()
         canvas.SetProjection2d 0,DeviceWidth(),0,DeviceHeight()
                 
        Return 0
    End
    
    Method OnUpdate:Int()
        If KeyHit(KEY_ESCAPE) Then OnClose()    
        Color = Sin(Float(Millisecs()/10))
        Return 0
    End
    
    Method OnRender:Int()
        canvas.Clear Color,0.0,0.0
        canvas.Flush
        Return 0
    End
End
' -------------------------------------------------
 
Last edited:

Jimmy

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
576
The only thing I never got working is the title. It's stuck to CerberusGame, I've tried all directives I know by now.

code_language.cerberus:
#MOJO_AUTO_SUSPEND_ENABLED = False
#GLFW_WINDOW_RENDER_WHILE_RESIZING = True
#GLFW_APP_LABEL = "My Game title"
#GLFW_WINDOW_TITLE = "Invisible"
#GLFW_WINDOW_SAMPLES = 0
#GLFW_WINDOW_RESIZABLE = False ' True
#GLFW_WINDOW_DECORATED = False
#GLFW_WINDOW_FLOATING = False
#GLFW_WINDOW_FULLSCREEN = False
' #GLFW_APP_ICON = "wonderful.png"
' #GLFW_WINDOW_WIDTH = 0 ' crashes Mojo2
' #GLFW_WINDOW_HEIGHT = 0 ' crashes Mojo2
' #GLFW_MACOS_RETINA_ENABLED = True

Strict
' Public
Import mojo2
Import "commands.cpp"
Extern ' Bindings
Function SetWindowPosition:Void(X:Int, Y:Int) = "commands::setWindowPosition"
Function GetMonitorCanvas:Void(Output:Int[], MinimumHeight:Bool=False) = "commands::getMonitorCanvas"
Function GetMonitorCanvas:Int[](MinimumHeight:Bool=False) = "commands::getMonitorCanvas"
Public
' -------------------------------------------------
Function Main:Int()
    New Application()
    Return 0
End

Class Application Extends App Final

    Field Color:Float
    Field canvas:Canvas

    Method OnCreate:Int()
        canvas = New Canvas()
        SetUpdateRate 0
        Local Desktop := GetMonitorCanvas() 
        SetDeviceWindow Desktop[2],Desktop[3],0
        SetWindowPosition Desktop[0],Desktop[1]
  
        ' These command seem accepible in OnCreate or should it go in OnRender?
         ' SetDeviceWindow DeviceWidth(),DeviceHeight(),2
         ' canvas.SetScissor 0,0,DeviceWidth(),DeviceHeight()
         canvas.SetViewport 0,0,DeviceWidth(),DeviceHeight()
         canvas.SetProjection2d 0,DeviceWidth(),0,DeviceHeight()
          
        ' Local a:Int = DeviceWidth()
        ' Local b:Int = DeviceHeight()
        ' Local c:Int = DeviceWindowWidth()
        ' Local d:Int = DeviceWindowHeight()

        Return 0
    End

    Method OnUpdate:Int()
        If KeyHit(KEY_ESCAPE) Then OnClose()
        Color = Sin(Float(Millisecs()/10))
        Return 0
    End

    Method OnRender:Int()
        canvas.Clear Color,0.0,0.0
        canvas.Flush
        Return 0
    End
End
' -------------------------------------------------

Screenshot 2020-12-25 at 07.08.30.png
 
Last edited:

Jimmy

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
576
In Windows this code kind of takes over the complete screen, you can't see any trace of the Windows desktop.
So it's abit different there. On Linux I'm not sure but it will have the effect one of these two I'm sure.
 

MikeHart

Administrator
Joined
Jun 19, 2017
Messages
2,845
Nice showing how to interface native code.

May I ask why you replicated existing functionality like SetDeviceWindowSize or SetDeviceWindowPosition? Just for the exercise?
 

Jimmy

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
576
Just an exercise really and spreading what I'm learning for myself. Cerberus-X is amazing when you have this native possibility absolutely everything becomes possible.
 
Top Bottom