First Commit
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* https://github.com/SamuelTulach/OverlayCord
|
||||
*/
|
||||
|
||||
#ifndef OVERLAYCORD_H
|
||||
#define OVERLAYCORD_H
|
||||
|
||||
#include <Windows.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace OverlayCord
|
||||
{
|
||||
namespace Communication
|
||||
{
|
||||
typedef struct _Header
|
||||
{
|
||||
UINT Magic;
|
||||
UINT FrameCount;
|
||||
UINT NoClue;
|
||||
UINT Width;
|
||||
UINT Height;
|
||||
BYTE Buffer[1];
|
||||
} Header;
|
||||
|
||||
typedef struct _ConnectedProcessInfo
|
||||
{
|
||||
UINT ProcessId;
|
||||
HANDLE File;
|
||||
Header* MappedAddress;
|
||||
} ConnectedProcessInfo;
|
||||
|
||||
inline bool ConnectToProcess(ConnectedProcessInfo& processInfo)
|
||||
{
|
||||
std::string mappedFilename = "DiscordOverlay_Framebuffer_Memory_" + std::to_string(processInfo.ProcessId);
|
||||
processInfo.File = OpenFileMappingA(FILE_MAP_ALL_ACCESS, false, mappedFilename.c_str());
|
||||
if (!processInfo.File || processInfo.File == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
processInfo.MappedAddress = static_cast<Header*>(MapViewOfFile(processInfo.File, FILE_MAP_ALL_ACCESS, 0, 0, 0));
|
||||
return processInfo.MappedAddress;
|
||||
}
|
||||
|
||||
inline void DisconnectFromProcess(ConnectedProcessInfo& processInfo)
|
||||
{
|
||||
UnmapViewOfFile(processInfo.MappedAddress);
|
||||
processInfo.MappedAddress = nullptr;
|
||||
|
||||
CloseHandle(processInfo.File);
|
||||
processInfo.File = nullptr;
|
||||
}
|
||||
|
||||
inline void SendFrame(ConnectedProcessInfo& processInfo, UINT width, UINT height, void* frame, UINT size)
|
||||
{
|
||||
// frame is in B8G8R8A8 format
|
||||
// size can be nearly anything since it will get resized
|
||||
// for the screen appropriately, although the maximum size is
|
||||
// game window width * height * 4 (BGRA)
|
||||
processInfo.MappedAddress->Width = width;
|
||||
processInfo.MappedAddress->Height = height;
|
||||
|
||||
memcpy(processInfo.MappedAddress->Buffer, frame, size);
|
||||
|
||||
processInfo.MappedAddress->FrameCount++; // this will cause the internal module to copy over the framebuffer
|
||||
}
|
||||
}
|
||||
|
||||
namespace Drawing
|
||||
{
|
||||
typedef struct _Frame
|
||||
{
|
||||
UINT Width;
|
||||
UINT Height;
|
||||
UINT Size;
|
||||
void* Buffer;
|
||||
} Frame;
|
||||
|
||||
typedef struct _Pixel
|
||||
{
|
||||
BYTE B, G, R, A;
|
||||
} Pixel;
|
||||
|
||||
inline Frame CreateFrame(UINT width, UINT height)
|
||||
{
|
||||
Frame output;
|
||||
output.Width = width;
|
||||
output.Height = height;
|
||||
output.Size = width * height * 4;
|
||||
|
||||
output.Buffer = malloc(output.Size);
|
||||
memset(output.Buffer, 0, output.Size);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
inline void CleanFrame(Frame& frame)
|
||||
{
|
||||
memset(frame.Buffer, 0, frame.Size);
|
||||
}
|
||||
|
||||
inline void SetPixel(Frame& frame, UINT x, UINT y, Pixel color)
|
||||
{
|
||||
if (x < frame.Width && y < frame.Height)
|
||||
{
|
||||
Pixel* buf = static_cast<Pixel*>(frame.Buffer);
|
||||
buf[y * frame.Width + x] = color;
|
||||
}
|
||||
}
|
||||
|
||||
inline void DrawLine(Frame& frame, UINT x1, UINT y1, UINT x2, UINT y2, Pixel color)
|
||||
{
|
||||
int dx = abs(static_cast<int>(x2 - x1)), sx = x1 < x2 ? 1 : -1;
|
||||
int dy = -abs(static_cast<int>(y2 - y1)), sy = y1 < y2 ? 1 : -1;
|
||||
int err = dx + dy, e2;
|
||||
|
||||
while (true)
|
||||
{
|
||||
SetPixel(frame, x1, y1, color);
|
||||
if (x1 == x2 && y1 == y2)
|
||||
break;
|
||||
e2 = 2 * err;
|
||||
if (e2 >= dy) { err += dy; x1 += sx; }
|
||||
if (e2 <= dx) { err += dx; y1 += sy; }
|
||||
}
|
||||
}
|
||||
|
||||
inline void DrawRectangle(Frame& frame, UINT x1, UINT y1, UINT width, UINT height, Pixel color)
|
||||
{
|
||||
for (UINT x = x1; x < x1 + width; x++)
|
||||
{
|
||||
SetPixel(frame, x, y1, color);
|
||||
SetPixel(frame, x, y1 + height - 1, color);
|
||||
}
|
||||
|
||||
for (UINT y = y1; y < y1 + height; y++)
|
||||
{
|
||||
SetPixel(frame, x1, y, color);
|
||||
SetPixel(frame, x1 + width - 1, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
inline void DrawCircle(Frame& frame, UINT x0, UINT y0, UINT radius, Pixel color)
|
||||
{
|
||||
int x = radius;
|
||||
int y = 0;
|
||||
int radiusError = 1 - x;
|
||||
|
||||
while (x >= y)
|
||||
{
|
||||
SetPixel(frame, x0 + x, y0 + y, color);
|
||||
SetPixel(frame, x0 - x, y0 + y, color);
|
||||
SetPixel(frame, x0 - x, y0 - y, color);
|
||||
SetPixel(frame, x0 + x, y0 - y, color);
|
||||
SetPixel(frame, x0 + y, y0 + x, color);
|
||||
SetPixel(frame, x0 - y, y0 + x, color);
|
||||
SetPixel(frame, x0 - y, y0 - x, color);
|
||||
SetPixel(frame, x0 + y, y0 - x, color);
|
||||
|
||||
y++;
|
||||
if (radiusError < 0)
|
||||
{
|
||||
radiusError += 2 * y + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x--;
|
||||
radiusError += 2 * (y - x + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
#include <numbers>
|
||||
#include <cmath>
|
||||
|
||||
int screen_x = GetSystemMetrics(SM_CXSCREEN);
|
||||
int screen_y = GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
struct view_matrix_t {
|
||||
float* operator[ ](int index) {
|
||||
return matrix[index];
|
||||
}
|
||||
|
||||
float matrix[4][4];
|
||||
};
|
||||
|
||||
struct Vector3
|
||||
{
|
||||
// constructor
|
||||
constexpr Vector3(
|
||||
const float x = 0.f,
|
||||
const float y = 0.f,
|
||||
const float z = 0.f) noexcept :
|
||||
x(x), y(y), z(z) { }
|
||||
|
||||
// operator overloads
|
||||
constexpr const Vector3& operator-(const Vector3& other) const noexcept
|
||||
{
|
||||
return Vector3{ x - other.x, y - other.y, z - other.z };
|
||||
}
|
||||
|
||||
constexpr const Vector3& operator+(const Vector3& other) const noexcept
|
||||
{
|
||||
return Vector3{ x + other.x, y + other.y, z + other.z };
|
||||
}
|
||||
|
||||
constexpr const Vector3& operator/(const float factor) const noexcept
|
||||
{
|
||||
return Vector3{ x / factor, y / factor, z / factor };
|
||||
}
|
||||
|
||||
constexpr const Vector3& operator*(const float factor) const noexcept
|
||||
{
|
||||
return Vector3{ x * factor, y * factor, z * factor };
|
||||
}
|
||||
|
||||
constexpr const bool operator>(const Vector3& other) const noexcept {
|
||||
return x > other.x && y > other.y && z > other.z;
|
||||
}
|
||||
|
||||
constexpr const bool operator>=(const Vector3& other) const noexcept {
|
||||
return x >= other.x && y >= other.y && z >= other.z;
|
||||
}
|
||||
|
||||
constexpr const bool operator<(const Vector3& other) const noexcept {
|
||||
return x < other.x && y < other.y && z < other.z;
|
||||
}
|
||||
|
||||
constexpr const bool operator<=(const Vector3& other) const noexcept {
|
||||
return x <= other.x && y <= other.y && z <= other.z;
|
||||
}
|
||||
|
||||
// utils
|
||||
constexpr const Vector3& ToAngle() const noexcept
|
||||
{
|
||||
return Vector3{
|
||||
std::atan2(-z, std::hypot(x, y)) * (180.0f / std::numbers::pi_v<float>),
|
||||
std::atan2(y, x) * (180.0f / std::numbers::pi_v<float>),
|
||||
0.0f };
|
||||
}
|
||||
|
||||
float length() const {
|
||||
return std::sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
float length2d() const {
|
||||
return std::sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
constexpr const bool IsZero() const noexcept
|
||||
{
|
||||
return x == 0.f && y == 0.f && z == 0.f;
|
||||
}
|
||||
|
||||
Vector3 world_to_screen(view_matrix_t matrix) const {
|
||||
float _x = matrix[0][0] * x + matrix[0][1] * y + matrix[0][2] * z + matrix[0][3];
|
||||
float _y = matrix[1][0] * x + matrix[1][1] * y + matrix[1][2] * z + matrix[1][3];
|
||||
|
||||
float w = matrix[3][0] * x + matrix[3][1] * y + matrix[3][2] * z + matrix[3][3];
|
||||
|
||||
float inv_w = 1.f / w;
|
||||
_x *= inv_w;
|
||||
_y *= inv_w;
|
||||
|
||||
float x = screen_x * .5f;
|
||||
float y = screen_y * .5f;
|
||||
|
||||
x += 0.5f * _x * screen_x + 0.5f;
|
||||
y -= 0.5f * _y * screen_y + 0.5f;
|
||||
|
||||
return { x, y, w };
|
||||
}
|
||||
|
||||
// struct data
|
||||
float x, y, z;
|
||||
};
|
||||
Reference in New Issue
Block a user