Skip to content

Aliases

Otavio edited this page Jan 26, 2023 · 48 revisions

Aliases

Here is where the magic happens:

So, you're probably wondering how this library can work on multiple graphics APIs right? Well, the answer to that is simple. We will use aliases. (..Or templates/pointers. Honestly, I couldn't came up with a decent name.) I won't explain what an alias is or does, but in C the closest thing to it, is a typedef. If you are familiar with function hooking or variadic templates this won't be a problem for you.

Setting up:

Here, you'll understand why this library can work with DirectX 9/10, OpenGL and with some little tweaking it can work with some other rendering apis as well.

First things first:

In the FGUI/internal folder you will find a file called "aliases.hpp". This is the file containing all aliases that the library currently use. (Text, Rectangle, Line, Gradient, etc.)

There you will find something like this:

using pDrawRectangle = std::add_pointer_t<void(int x, int y, int width, int height, FGUI::COLOR color)>;
  • Where x and y being the position where the rectangle will be rendered on your screen;
  • width and height being its size.
  • And FGUI::COLOR is a struct with a constructor that can hold 3 or 4 unsigned char as arguments. FGUI::COLOR(255, 0, 0, 255) It uses RGBA as a color system. In other words its just the color of the rectangle.
using pGetKeyHeld = std::add_pointer_t<bool(unsigned int key)>;
  • Where key being the key that you want to check if it's being held. The key argument is an unsigned int because it usually holds the ASCII value of the key that you want to check, but depending on your input system or even the platform that you are on, this can be different.
Now what?

Now it's the not so fun part. You'll need to have your own drawing/input functions.

In this example I will be using Valve's DirectX wrapper called Surface and their input wrapper (InputSystem).

What we will need:

  1. Have functions matching the template declared on the aliases header file.
  2. Replace the templates with your own functions.

Examples:

void Your_DrawRectangle(int x, int y, int w, int h, FGUI::COLOR color) 
{
    ISurface->DrawSetColor(color.m_ucRed, color.m_ucGreen, color.m_ucBlue, color.m_ucAlpha);
    ISurface->DrawFilledRect(x, y, x + w, y + h);
}

NOTE: Note that the first function is following the rectangle template declared on the aliases header file.

NOTE: In theory FGUI can work with anything that can draw shapes and text. As long as you have the functions to draw it, you can just point your drawing functions to the FGUI aliases and it should work. Even if FGUI doesn't explicitly supports it. (The same thing goes for the input aliases)

std::array<bool, 256> m_prgpCurrentPressedKeys, m_prgpOldPressedKeys;
void Your_PullInput()
{
  // copy new keys (currently being held) to old keys (already pressed)
  std::copy(m_prgpCurrentPressedKeys.begin(), m_prgpCurrentPressedKeys.end(), m_prgpOldPressedKeys.begin());

  for (std::size_t i = 0; i < 256; i++)
  {
    m_prgpCurrentPressedKeys.at(i) = InputSystem->IsButtonDown(i);
  }
}

//

bool Your_IsKeyHeld(unsigned int key_code)
{
  return m_prgpCurrentPressedKeys.at(key_code); // this array returns true if the key_code matches the current key being pressed (the key press check is being done in the `PullInput` alias/function.)
}

After setting up your wrapper functions, or switching the arguments of existing functions to match the templates, you will need to replace the aliases with your own functions.

How can I do that?

It's simple. Follow the code below to replace the aliases:

FGUI::RENDER.Rectangle = Your_DrawRectangle;
// 
FGUI::INPUT.PullInput = Your_PullInput;
FGUI::INPUT.IsKeyHeld = Your_IsKeyHeld;

NOTE: You will need to do that for the aliases that the library is currently using.

NOTE: Make sure to do that only once! I recommend doing this before your application starts using the library.


What's next?

Next you will learn how to create your first Container (Window).