Guide to making a Shell program (GM OS)

Discussion in 'Off Topic' started by orSQUADstra, Jan 6, 2018.

  1. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    [​IMG]

    Hi, and welcome to the guide of making your own Shell program for GM OS. Please note that this thread will get edited regularly to be up-to-date with the newest functions and/or changes of the OS.

    The GM OS Project

    Get to know more about GM OS by clicking on the image below:
    [​IMG]

    The basics

    First of all, what are Shell programs?

    [​IMG]

    Shell programs are folders with the ending of ".shl". These folders are recognized as a program by GM OS.

    A Shell folder should contain two files: A text file named "shellcode.txt", which contains code written in GML, and an image named "shellicon.txt". The names should be exactly these, otherwise the OS won't read them. Having the shellicon.png is optional.

    [​IMG]
    Preset fonts

    Here are the fonts that are set in the project file. If you feel like you need to, you can set up your own fonts, or use a sprite font.

    [​IMG]

    The window system


    Before you would start making your Shell program, it is important to know the essential things about windows in GM OS.

    [​IMG]
    The graphic above shows how the display works.

    Here are the default variables set up by the shell_window_create(...) script:
    Some global variables:
    Required scripts:
    • shell_window_create(width (real), height (real), title (string), resizable (real)) - takes care of default variables. Should be used in Create event.
    • window_step() - takes care of everything. Should be put in the Step event.
    • draw_window() - takes care of drawing the base window and resizing (if enabled). Use in Draw event, preferably right in the first line.
    The windows doesn't use any sort of views, just simply draw themselves. Even though, it is highly recommended to use surfaces if you're doing something more complex. Also, what is very important, always make sure to do a surface check, and if you don't need the surface, use a surface_free(...).

    Other useful scripts:
    • point_in_region(x to check, y to check, x1, y1, x2, y2) - returns true if the specified (x, y) is in the (x1, y1, x2, y2) region, otherwise false.
    • mouse_in_region(x1, y1, x2, y2) - returns true if the mouse coordinates are in the (x1, y1, x2, y2) region, otherwise false.
    • get_button(x, y, w, h, str, blocked) - Use in Draw event - returns true if the mouse left button is released within the x, y, x+w, y+h area. in the "blocked" part, always put "mouse_blocked".
    Context menus

    You might want to use context menus in your program, and of course, this is possible.

    [​IMG]

    Here's what you need to know about GM OS' context menus:
    • There is always only one persistent.
    • If you click anywhere outside, it'll be destroyed and the variable selected will be -1
    • When clicking inside, it'll return the number of the text in the selected variable. In the example above, clicking "Open" would return 0, while clicking "Properties" would return 6.
    • Context menus offer you 10 string and 10 real slots to store data in. You can refer to them as storedString0 ... storedString9 and storedReal0 ... storedReal9. By default, stored reals hold 0, while strings "".
    • The maximum number of listed items is 100.
    • Context menus store a variable called linkedTo, which you should always set to the id of your window.
    Working with context menus

    First of all, you need to create the instance objContextmenu.
    Then, as the next step, set up your menues, stored variables, and most importantly the linkedTo variable.
    The listed items use a 2D array, menu[n,0]. The first number is the number of the string.
    Here's the usual way to do it is this:


    Code:
    if mouse_check_button_pressed(mb_right)
    and mouse_blocked = 0
    and mouse_in_region(x,y,x+w,y+h)
    {
       instance_create(mouse_x,mouse_y,objContextmenu)
       with objContextmenu
       {
          linkedTo = other.id
          storedReal0 = 255
          storedString0 = "Just a string"
          menu[0,0] = "Option 1"
          menu[1,0] = "Option 2"
          menu[2,0] = "Option 3"
       }
    }
    Then, let's check for what the user clicks..
    Code:
    if instance_exists(objContextmenu)
    {
       with objContextmenu
       {
          if linkedTo = other.id
             {
                if selected = 0 {/*Code for Option 1 here*/}
                if selected = 1 {/*Code for Option 2 here*/}
                if selected = 2 {/*Code for Option 3 here*/}
             }
       }
    }


    Working with text boxes

    Text boxes are structured similarly to context menus.

    [​IMG]

    To create a text box, use the following code:
    Code:
    inst = instance_create(x, y, objTextbox)
    with inst
    {
       w = 256
       h = 24
       str = "Hello" //you can skip this line entirely if you don't want the text box to contain any string on creation
       linkedTo = other.id //This is very important, do not forget this!
       destroyOnOuterClick = 0 //if it is set to 1, the textbox will be destroyed when you click outside of it.
    }
    To get the text from the textbox:
    Code:
    stringVariable = ""
    with objTextbox
    {
       if linkedTo = other.id
       {
          other.stringVariable = str
       }
    }
    Things to know about text boxes:
    • Text boxes store their string in the str variable, see above how to check it.
    • The textbox will move with the window.
    • The textbox sets its own depth and acts like if it was within the window code.
    • Upon destroying your program's window, the textbox will destroy itself automatically.
    • Text boxes are slightly advanced, as you can a set custom pointer position with mouse, or with the left and right keys.
    • The textbox will only be written to when it is active. It's active if the last clicked mouse position is on it, and wasn't blocked by another instance.
    This thread is not finished yet. By the time of the first public release of the GM OS, it should be finished and get you ready to make your own Shell programs.

     
    Last edited: Dec 2, 2018
  2. andev

    andev Member

    Joined:
    Jul 2, 2017
    Posts:
    444
    This looks pretty cool! But why is the top window bar not included in the height?

    [​IMG]

    EDIT: Also, point_in_region( ) mirrors point_in_rectangle() ?
     
    orSQUADstra likes this.
  3. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    Because it's only important for the drag, the buttons, and the maximizing. Things that the window_step() script does for you. It's just easier if, let's say you want to draw an image at the top left corner of the window under the titlebar, it's simply better to just write draw_sprite(spr,img,x,y) than draw_sprite(spr,img,x,y+global.titlebarheight) (not to mention you don't have to put that +global.titlebarheight thing literally all over your code :D )
     
    andev likes this.
  4. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    The project uses GameMaker 8 to make the usage of these programs work by the functions object_add(), object_event_add(), etc., which are obsolete and not included in GMS 1.4 or GMS 2. In GM 8, point_in_rectangle wasn't a function yet, so it pretty much mirrors that function, yes.
     
  5. andev

    andev Member

    Joined:
    Jul 2, 2017
    Posts:
    444
    What are you using object_add for?
     
    orSQUADstra likes this.
  6. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    For the Shell programs :p

    The way I made 3rd party programs to be possible, if I want to simplify it as much as I can is this:
    The program loads in the .txt and runs it which includes the object_add and object_event_add functions, making an object that will then be added to the room with instance_create().
     
  7. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    Here's an example. This is a Shell program that I made as a test, what it does is only displaying a text of "RAINBOW THEME MOD", and a button, what if you press, the global.syscolor will be constantly changed with make_color_hsv, making a rainbow effect:
    Code:
    12
    objname = "obj"+string(current_time)+"test"
    
    variable_local_set(objname,object_add())
    
    object_set_parent(variable_local_get(objname),objWindow)
    
    object_event_add(variable_local_get(objname),ev_destroy,0,'object_delete(object_index)')
    object_event_add(variable_local_get(objname),ev_create,0,'shell_window_create(240,120,"",0);check=false')
    object_event_add(variable_local_get(objname),ev_step,0,'window_step();if check=true{global.syscolor = make_color_hsv(current_time*0.025,220,220);}')
    object_event_add(variable_local_get(objname),ev_draw,0,'action = draw_window(x,y,w,h,title,resizable);draw_set_font(fontSlimSmall);draw_set_color(c_gray);draw_set_halign(fa_center);draw_set_valign(fa_top);draw_text(x+w*.5,y+16,"RAINBOW THEME MOD");if check = false{if get_button(x+w*.5-50,y+h*.5,100,20,"A Button",mouse_blocked){check = !check}}else{if get_button(x+w*.5-50,y+h*.5,100,20,"DEACTIVATE",mouse_blocked){check = !check}}')
    instance_create(100,100,variable_local_get(objname))
    Note: The first row is always just a number, which should be exactly the number of lines of your .txt file, with the first line included.
     
  8. andev

    andev Member

    Joined:
    Jul 2, 2017
    Posts:
    444
    Does object_add allow you to import and run uncompiled code in a compiled build?
     
    orSQUADstra likes this.
  9. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    Pretty much. It's just what it says. It adds an object, and with object_event_add, you add events to it. Like if it was in the project file, but of course it doesn't get compiled (afaik, at least).
     
    andev likes this.
  10. andev

    andev Member

    Joined:
    Jul 2, 2017
    Posts:
    444
    What is the purpose of this project? If you don't mind me asking :p
    Like, what scenarios will it be used in?
     
    orSQUADstra likes this.
  11. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    It's just a project purely made for fun.
    I think it's just interesting to see something like this being made with GameMaker. Of course many people made fake operating system with gamemaker, but none of them are even close to good (at least the ones I've seen). So, having one that is actually functional, actual windows, window ordering, custom background, actaully functioning file browser, and so on. Just stretchin' GM8 to the limits :D
     
    LucasTheNewbie and andev like this.
  12. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    The guide has been updated with Context menus!
     
  13. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    The guide has been updated with Text boxes!
     
  14. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    I'll be updating this post further more soon! But until then, I have a question:
    Adding sprites and audio files to your project will be explained in this guide, but do you guys think you'll need a specific tutorial video to understand this whole thing better?

    If so, I'd probably recreate something similar to this Shell program I just made:

    [​IMG]

    Probably not 1:1 this, as it has to load in 12 wav files and 4 sprites, but something a bit simplier, just for the sake of simplicity and to make things as short as possible.
     
    Last edited: Jan 9, 2018
  15. trg601

    trg601 Member

    Joined:
    Jun 21, 2016
    Posts:
    144
    I think it would be helpful, but I'm not sure it is necessary.
    Also, when are you going to release this to us? I already made two shell programs XD (I can't be sure if they will work yet though).
     
    orSQUADstra likes this.
  16. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    The OS? Still a few days. I added a few more things to the plan, and I don't want to publish it with heavily unfinished things. :D But I'm going to hit you up with a conv in a moment
     
  17. appleWolf

    appleWolf Member

    Joined:
    Jun 27, 2016
    Posts:
    34
    This looks really awesome. I suggest you consider releasing it under an open source license!

    That way, the community can contribute code, and your system will be adopted more widely.

    Moreover, I'd gladly support this project on Patreon! I'm sure others would as well.

    Consider using the GPLv2 or LGPL. This way, commercial groups can use your codebase and still contribute to the community overall.



    I tend to sound like an ideologue about these things sometimes... I'll try not to persuade you against your best interests. I gave some facts, I ask that you consider them. ;)

    EDIT: Wish we could still do execute_string() :(

    EDIT 2: I'll contribute if you let me.
     
    Last edited: Jan 10, 2018
  18. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    Thanks, I'll think about it! :)
     
    appleWolf likes this.
  19. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    Hi everyone!
    Please note that the Shell programs will work a bit differently from now on. Once it's actually finished, I'll update this thread to represent the current needs. Some of the major changes are already done, so instead of a messy code it'll be much simpler.


    I will also do video tutorials, all function and script will have it's own dedicated short video.

    Hope you guys like the way this project, and the writing of Shell programs goes :D
     
    Last edited: Feb 19, 2019
  20. Misu

    Misu The forum's immigrant

    Joined:
    Jun 20, 2016
    Posts:
    636
    This is Game Maker related. Why is it in the Off-Topic?
     
  21. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    When I created the topic I just wans't sure where I should post it, and I assumed that only people who are interested in the project will even look at this. But I might ask someone to move it to Tutorials (even though it might not fit 100% in there)
     
  22. Mool

    Mool Member

    Joined:
    Nov 6, 2016
    Posts:
    113
    How do u run the shell? with gml_pragma?
     
    orSQUADstra likes this.
  23. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    No, I just make it load in the text files and save them as strings, then with execute_string I make a new object and make them the create, step and draw event of the shells (+ the default window code on top of that)
     
  24. EvanSki

    EvanSki King of Raccoons

    Joined:
    Apr 17, 2018
    Posts:
    578
    So theoretically speaking a person could write malware for GM-OS,
    Will GM-OS come with anti-virus?
     
  25. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    The "runner" runs through the code and checks for some suspicious stuff (like if it would delete a system object or if it would try to access files outside of the main directory of GM OS). Obviously it's not near perfect, but even that is better than nothing. If it does detect something then it'll give a warning, and you have to confirm whether you really want to run it or not. But in all honesty, I don't expect anyone to make an actual virus for it or anything :D
     
    EvanSki likes this.
  26. EvanSki

    EvanSki King of Raccoons

    Joined:
    Apr 17, 2018
    Posts:
    578
    Tempted but Idk yet
     
  27. EvanSki

    EvanSki King of Raccoons

    Joined:
    Apr 17, 2018
    Posts:
    578
    So looking back on this, if the Shellcode.txt allows all GML code you could make a simple Trojan virus, That could use how GML does code to its advantage like, changing how text is drawn, messing with surfaces, changing values of variables and such. then again you could just have one that just runs game_end(); but all of that can be easily blocked, idk how exactly your project can read code from .txt (Would love to know how btw) but using the same system you could put in a filter that finds and either "removes" or tells OS to not run the file, (like windows popping up saying "This file cannot be run as its corrupted or contains harmful scripts"), all in all im just fascinated by this project! :)
     
  28. orSQUADstra

    orSQUADstra Member

    Joined:
    Aug 8, 2017
    Posts:
    236
    Thanks! Originally I wanted to implement a filter and a warning popup if anything suspicious is found, however I didn't work much on that part since.
    Now, I've been thinking about moving the project to GMS 2 (obvious advantages like disabling the alpha channel that would fix the surface problem that is currently present, as well as shaders to replace the blur script, and also it would run much better to begin with). There will be a sandbox on/off toggle in GMS2 sometime in the future if I remember right so that's a good thing, but I'll have to redo how shells will work as my current method relies on object_add() and object_event_add() functions that are not present in GMS2.
    I have been thinking of making up a language that is very close to GML but is structured in a way that I could easily manage it with GM OS.
     
    EvanSki likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice