summaryrefslogtreecommitdiff
path: root/libghack/src/radar.c
diff options
context:
space:
mode:
Diffstat (limited to 'libghack/src/radar.c')
-rwxr-xr-xlibghack/src/radar.c578
1 files changed, 578 insertions, 0 deletions
diff --git a/libghack/src/radar.c b/libghack/src/radar.c
new file mode 100755
index 0000000..10a554b
--- /dev/null
+++ b/libghack/src/radar.c
@@ -0,0 +1,578 @@
+/*****************************************
+ * hRadar (C) 2015 by lnslbrty/dev0, \x90
+ *
+ * Simple, C coded, 2D-SFML API, ...
+ *
+ * Happy Hacking!
+ *****************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <windows.h>
+#include <inttypes.h>
+#include <math.h>
+#include <SFML/Graphics.h>
+#include <SFML/Audio.h>
+
+#include "ghack.h"
+
+
+#define WTITLE_SUFFIX "hRadar"
+#define AIMANGLE_LINELEN 35.0f
+#define AIMLINE_WIDTH 1.3f
+#define ENTITY_CIRCLE_RADIUS 3.5f
+
+static BOOL radarActive = TRUE;
+static sfThread *sThrd;
+static sfVideoMode vMode;
+static sfContextSettings cSettings;
+static sfRenderWindow *rWnd = NULL;
+static sfFont *defFont = NULL;
+static char *wTitle = NULL;
+static unsigned int gr_width = 0;
+static unsigned int gr_height = 0;
+static FLOAT f_vecDistance = 0.0f, f_propX = 1.0f, f_propY = 1.0f;
+static FLOAT f_angle = 0.0f;
+static FLOAT f_playerPos[3] = { 0.0f, 0.0f, 0.0f };
+static struct radarInfo *rdr_ver = NULL;
+static sfRectangleShape *rdr_crosshair[2];
+static sfRectangleShape *aimLine = NULL;
+static sfRectangleShape *rdr_angle = NULL;
+static HANDLE mtx_set = NULL;
+static HANDLE ev_ready = NULL;
+
+static struct radarEntity *rad_entityList = NULL;
+static struct radarInfo *rad_info = NULL;
+#define DEF_RADINFO_X 5.0f
+#define DEF_RADINFO_STARTY 2.0f
+#define DEF_RADINFO_DY 18.0f
+static unsigned int d_radDefY = DEF_RADINFO_STARTY;
+
+//#undef ENABLE_DEBUG
+#ifdef ENABLE_DEBUG
+#define DEBUG_VAR pfile
+#define DEBUG_FILE "./log.txt"
+static FILE *DEBUG_VAR = NULL;
+#define DEBUG_INIT DEBUG_VAR = fopen(DEBUG_FILE,"a+"); if (DEBUG_VAR == NULL) perror("fopen");
+#define DEBUG_LOG(msg, ...) fprintf(DEBUG_VAR, "[%s:%d] ", __FILE__, __LINE__); fprintf(DEBUG_VAR, msg, __VA_ARGS__);
+#define DEBUG_FLUSH fflush(DEBUG_VAR);
+#define DEBUG_CLOSE fclose(DEBUG_VAR);
+#else
+#define DEBUG_VAR
+#define DEBUG_FILE
+#define DEBUG_INIT
+#define DEBUG_LOG(msg, ...)
+#define DEBUG_FLUSH
+#define DEBUG_CLOSE
+#endif // ENABLE_DEBUG
+
+struct graphicEnt
+{
+ sfCircleShape *cr_entShape;
+};
+
+static inline char *strDupExt(char *src, SIZE_T siz)
+{
+ char *txt = calloc(siz+1, sizeof(char));
+
+ memcpy(txt, src, siz);
+ return txt;
+}
+
+static struct radarEntity *radarNewEntity(UINT64 id, BOOL isPlayer, BOOL valid)
+{
+ struct radarEntity *re = calloc(1, sizeof(struct radarEntity));
+ struct graphicEnt *ge = calloc(1, sizeof(struct graphicEnt));
+
+ re->__internal = ge;
+ re->valid = valid;
+ re->isPlayer = isPlayer;
+ re->id = id;
+ ge->cr_entShape = sfCircleShape_create();
+ sfCircleShape_setRadius(ge->cr_entShape, ENTITY_CIRCLE_RADIUS);
+ return re;
+}
+
+static void radarDeleteEntity(struct radarEntity *re)
+{
+ struct graphicEnt *ge = (struct graphicEnt *) re->__internal;
+
+ if (ge != NULL)
+ {
+ sfCircleShape_destroy(ge->cr_entShape);
+ free(ge);
+ }
+ free(re);
+}
+
+static sfColor radarSFMLColor(enum radarColor color)
+{
+ switch (color)
+ {
+ case RC_RED:
+ return sfRed;
+ case RC_BLUE:
+ return sfBlue;
+ case RC_GREEN:
+ return sfGreen;
+ case RC_YELLOW:
+ return sfYellow;
+ case RC_WHITE:
+ return sfWhite;
+ case RC_MAGENTA:
+ return sfMagenta;
+ case RC_CYAN:
+ return sfCyan;
+ case RC_DONTDRAW:
+ default:
+ break;
+ }
+ return sfWhite;
+}
+
+static BOOL _radarInit(void *arg)
+{
+ struct radarConfig *rdr = (struct radarConfig *) arg;
+
+ DEBUG_INIT
+ DEBUG_LOG("%s", "initialized\n");
+ DEBUG_FLUSH
+ wTitle = calloc(strlen(WTITLE_SUFFIX) + strlen(rdr->wnd_name) + 4, sizeof(char)); // + 4: " - " + \0
+ strcat(wTitle, rdr->wnd_name);
+ strcat(wTitle, " - ");
+ strcat(wTitle, WTITLE_SUFFIX);
+
+ mtx_set = CreateMutexA(NULL, FALSE, NULL);
+ ev_ready = CreateEventA(NULL, FALSE, FALSE, "ev_hrad_ready");
+ memset(&cSettings, '\0', sizeof(cSettings));
+ cSettings.majorVersion = 2;
+ cSettings.depthBits = 32;
+ defFont = sfFont_createFromFile("C:\\Windows\\Fonts\\cour.ttf");
+ rad_entityList = radarNewEntity(0x0, FALSE, FALSE);
+ rad_info = calloc(1, sizeof(struct radarInfo));
+ return (rWnd != NULL ? TRUE : FALSE);
+}
+
+extern BOOL radarInit(struct radarConfig *rc)
+{
+ return _radarInit(rc);
+}
+
+extern BOOL radarIsActive(void)
+{
+ return radarActive;
+}
+
+static void radarInfoCleanup(void)
+{
+ struct radarInfo *cur, *next;
+
+ next = rad_info->next;
+ while ( (cur = next) != NULL )
+ {
+ if (cur->__internal != NULL) sfText_destroy(cur->__internal);
+ next = cur->next;
+ if (cur->prefix) free(cur->prefix);
+ free(cur);
+ }
+ d_radDefY = DEF_RADINFO_STARTY;
+ free(rad_info);
+}
+
+extern void radarCleanup(void)
+{
+ if (wTitle == NULL) return;
+ CloseHandle(mtx_set);
+ CloseHandle(ev_ready);
+ sfRenderWindow_destroy(rWnd);
+ radarInfoCleanup();
+ sfFont_destroy(defFont);
+ rWnd = NULL;
+ free(wTitle);
+ wTitle = NULL;
+ DEBUG_CLOSE
+}
+
+extern void radarWaitUntilRdy(void)
+{
+ WaitForSingleObject(ev_ready, INFINITE);
+}
+
+extern void radarReleaseMutex(void)
+{
+ ReleaseMutex(mtx_set);
+}
+
+extern void radarSetMutex(void)
+{
+ WaitForSingleObject(mtx_set, INFINITE);
+}
+
+static void radarInfoSetPos(sfText *sf, FLOAT x, FLOAT y)
+{
+ sfVector2f tf;
+
+ tf.x = x;
+ tf.y = y;
+ sfText_setPosition(sf, tf);
+}
+
+static void radarInfoSet(sfText *st, char *s, unsigned int c_size, enum radarColor color)
+{
+ sfText_setString(st, s);
+ sfText_setColor(st, radarSFMLColor(color));
+ sfText_setCharacterSize(st, c_size);
+ sfText_setFont(st, defFont);
+ sfText_setStyle(st, sfTextBold);
+}
+
+static void radarDrawInfo(void)
+{
+ struct radarInfo *ri = rad_info;
+
+ while ( (ri = ri->next) != NULL )
+ {
+ sfRenderWindow_drawText(rWnd, ri->__internal, NULL);
+ }
+}
+
+static sfRectangleShape *radarDrawLine(FLOAT x, FLOAT y, FLOAT width, FLOAT angle, sfColor color)
+{
+ sfVector2f v1, v2;
+ v1.x = x;
+ v1.y = y;
+ v2.x = width;
+ v2.y = 1.0f;
+
+ sfRectangleShape *rct = sfRectangleShape_create();
+ sfRectangleShape_setPosition(rct, v1);
+ sfRectangleShape_setSize(rct, v2);
+ sfRectangleShape_setRotation(rct, angle);
+ sfRectangleShape_setFillColor(rct, color);
+ return rct;
+}
+
+static void _radarLoop(void *arg)
+{
+ radarUpdateResolution();
+ rWnd = sfRenderWindow_create(vMode, wTitle, sfDefaultStyle, &cSettings);
+ sfRenderWindow_setFramerateLimit(rWnd, HRADAR_FPS);
+ rdr_ver = radarAddInfo("version");
+ radarSetInfo(rdr_ver, GHACK_VERSION);
+ rdr_crosshair[0] = radarDrawLine(0.0f, gr_height/2, gr_width, 0.0f, radarSFMLColor(RC_RED));
+ rdr_crosshair[1] = radarDrawLine(gr_width/2, 0, gr_height, 90.0f, radarSFMLColor(RC_RED));
+ aimLine = radarDrawLine(0.0f, 0.0f, 0.0f, 0.0f, radarSFMLColor(RC_MAGENTA));
+ rdr_angle = radarDrawLine(gr_width/2, gr_height/2, AIMANGLE_LINELEN, 45.0f, radarSFMLColor(RC_MAGENTA));
+ sfRectangleShape_setFillColor(rdr_angle, radarSFMLColor(RC_WHITE));
+
+ radarActive = TRUE;
+ while (sfRenderWindow_isOpen(rWnd) == TRUE)
+ {
+ sfEvent ev;
+ while (sfRenderWindow_pollEvent(rWnd, &ev) == TRUE)
+ {
+ if (ev.type == sfEvtClosed)
+ {
+ radarActive = FALSE;
+ }
+ else if (ev.type == sfEvtResized)
+ {
+ radarUpdateResolution();
+ }
+ }
+ sfRenderWindow_clear(rWnd, sfBlack);
+ sfRenderWindow_drawRectangleShape(rWnd, rdr_crosshair[0], NULL);
+ sfRenderWindow_drawRectangleShape(rWnd, rdr_crosshair[1], NULL);
+ sfRenderWindow_drawRectangleShape(rWnd, aimLine, NULL);
+ WaitForSingleObject(mtx_set, INFINITE);
+ sfRectangleShape_setRotation(rdr_angle, f_angle);
+ sfRenderWindow_drawRectangleShape(rWnd, rdr_angle, NULL);
+ radarDrawEntities();
+ radarDrawInfo();
+ ReleaseMutex(mtx_set);
+
+ sfRenderWindow_display(rWnd);
+ SetEvent(ev_ready);
+ }
+ sfRectangleShape_destroy(rdr_crosshair[0]);
+ sfRectangleShape_destroy(rdr_crosshair[1]);
+ sfRectangleShape_destroy(rdr_angle);
+}
+
+extern void radarUpdateResolution(void)
+{
+ WaitForSingleObject(mtx_set, INFINITE);
+ vMode = sfVideoMode_getDesktopMode();
+ gr_width = vMode.width;
+ gr_height = vMode.height;
+ ReleaseMutex(mtx_set);
+}
+
+extern unsigned int radarGetWidth(void)
+{
+ return gr_width;
+}
+
+extern unsigned int radarGetHeight(void)
+{
+ return gr_height;
+}
+
+extern FLOAT radarPropX(void)
+{
+ return f_propX;
+}
+
+extern FLOAT radarPropY(void)
+{
+ return f_propY;
+}
+
+extern struct radarInfo *radarAddInfo(char *prefix)
+{
+ struct radarInfo *ri = rad_info;
+
+ WaitForSingleObject(mtx_set, INFINITE);
+ while ( ri->next != NULL )
+ {
+ ri = ri->next;
+ }
+ ri->next = calloc(1, sizeof(struct radarInfo));
+ ri->next->__internal = sfText_create();
+ ri->next->prefix = strDupExt(prefix, INFO_LEN);
+ radarInfoSetPos(ri->next->__internal, DEF_RADINFO_X, d_radDefY);
+ d_radDefY += DEF_RADINFO_DY;
+ ReleaseMutex(mtx_set);
+ return ri->next;
+}
+
+extern void radarSetInfo(struct radarInfo *ri, char *text)
+{
+ char tbuf[INFO_LEN*2+3];
+
+ WaitForSingleObject(mtx_set, INFINITE);
+ memset(tbuf, '.', INFO_LEN);
+ strncpy(tbuf, ri->prefix, strlen(ri->prefix));
+ tbuf[INFO_LEN] = ':';
+ tbuf[INFO_LEN+1] = ' ';
+ memset((char *)(tbuf+INFO_LEN+2), '\0', INFO_LEN+1);
+ memcpy((char *)(tbuf+INFO_LEN+2), text, INFO_LEN);
+ radarInfoSet(ri->__internal, tbuf, HRADAR_FONTSIZ, RC_YELLOW);
+ ReleaseMutex(mtx_set);
+}
+
+extern void radarSetInfoF(struct radarInfo *ri, const char *fmt, ...)
+{
+ char buf[INFO_LEN+1];
+ va_list argp;
+
+ memset(buf, '\0', INFO_LEN+1);
+ va_start(argp, fmt);
+ vsnprintf(buf, INFO_LEN, fmt, argp);
+ radarSetInfo(ri, buf);
+ va_end(argp);
+}
+
+extern void radarSetDrawDistance(FLOAT vecDist)
+{
+ radarUpdateResolution();
+ WaitForSingleObject(mtx_set, INFINITE);
+ f_vecDistance = vecDist;
+ /*
+ * (f_vecDistance*2.0f): "absolute" distance from the left window border to the right
+ */
+ f_propX = gr_width/(f_vecDistance*2.0f); // calculate the proportional distance
+ f_propY = gr_height/(f_vecDistance*2.0f);
+ ReleaseMutex(mtx_set);
+}
+
+extern void radarSetPlayerPosition(FLOAT ppos[3], FLOAT angle)
+{
+ WaitForSingleObject(mtx_set, INFINITE);
+ f_angle = angle;
+ memcpy(f_playerPos, ppos, sizeof(FLOAT)*3);
+ ReleaseMutex(mtx_set);
+}
+
+static inline void radarCalcPosition(sfVector2f *ptr_pos, FLOAT pos3f[3])
+{
+ sfVector2f pos;
+ FLOAT f_entPlayerDiff[2];
+
+ f_entPlayerDiff[0] = (pos3f[0] - f_playerPos[0]) + f_vecDistance;
+ f_entPlayerDiff[1] = (pos3f[2] - f_playerPos[2]) + f_vecDistance;
+ pos.x = f_entPlayerDiff[0] * f_propX - ENTITY_CIRCLE_RADIUS;
+ pos.y = f_entPlayerDiff[1] * f_propY - ENTITY_CIRCLE_RADIUS;
+ memcpy(ptr_pos, &pos, sizeof(sfVector2f));
+}
+
+extern void radarSetAimLine(FLOAT enemy_pos3f[3], BOOL enable)
+{
+ sfVector2f v1, v2, tmp;
+ FLOAT a, b, c, angl;
+
+ memset(&v1, '\0', sizeof(sfVector2f));
+ memset(&v2, '\0', sizeof(sfVector2f));
+ if (enable == FALSE)
+ {
+ sfRectangleShape_setPosition(aimLine, v1);
+ sfRectangleShape_setSize(aimLine, v2);
+ }
+ else
+ {
+ a = (f_playerPos[0] - enemy_pos3f[0]) * f_propX;
+ b = (f_playerPos[2] - enemy_pos3f[2]) * f_propY;
+ c = sqrtf( powf(a, 2.0f) + powf(b, 2.0f) );
+ if (a < 0)
+ {
+ angl = 360.0f/(2.0f*M_PI)*atanf( b/a ) + 270.0f;
+ }
+ else angl = 360.0f/(2.0f*M_PI)*atanf( b/a ) + 90.0f;
+ v1.x = gr_width/2;
+ v1.y = gr_height/2;
+ v2.x = AIMLINE_WIDTH;
+ v2.y = c;
+ radarCalcPosition(&tmp, enemy_pos3f);
+ sfRectangleShape_setPosition(aimLine, v1);
+ sfRectangleShape_setSize(aimLine, v2);
+ sfRectangleShape_setRotation(aimLine, angl);
+ }
+}
+
+static void radarUpdateGraphicEnt(struct graphicEnt *ge, FLOAT f_vecPos3f[3], enum radarColor color)
+{
+ sfVector2f pos;
+
+ /*
+ printf("--- %8.2f , %8.2f ---\n", f_vecPos3f[0], f_vecPos3f[2]);
+ if (abs(f_vecPos3f[0]) > f_vecDistance)
+ {
+ f_vecPos3f[0] = f_playerPos[0] + f_vecDistance * (f_vecPos3f[0] > 0 ? 1.0f : -1.0f);
+ }
+ if (abs(f_vecPos3f[2]) > f_vecDistance)
+ {
+ f_vecPos3f[2] = f_playerPos[2] + f_vecDistance * (f_vecPos3f[2] > 0 ? 1.0f : -1.0f);
+ }
+ printf("### %8.2f , %8.2f ---\n", f_vecPos3f[0], f_vecPos3f[2]);
+ */
+ radarCalcPosition(&pos, f_vecPos3f);
+ sfCircleShape_setPosition(ge->cr_entShape, pos);
+ sfCircleShape_setFillColor(ge->cr_entShape, radarSFMLColor(color));
+}
+
+extern void radarUpdateEntity(UINT64 unique_id, FLOAT pos[3], enum radarColor color, BOOL isPlayer, BOOL valid)
+{
+ WaitForSingleObject(mtx_set, INFINITE);
+ struct graphicEnt *ge;
+ struct radarEntity *re = rad_entityList, *prev = rad_entityList;
+
+ if (color == RC_DONTDRAW) goto FIN;
+ if (re == NULL) goto FIN;
+ while ( (re = re->next) != NULL )
+ {
+ if (re->id == unique_id)
+ {
+ re->valid = valid;
+ re->isPlayer = isPlayer;
+ ge = (struct graphicEnt *) re->__internal;
+ radarUpdateGraphicEnt(ge, pos, color);
+ goto FIN;
+ }
+ prev = re;
+ }
+ prev->next = radarNewEntity(unique_id, isPlayer, TRUE);
+ ge = (struct graphicEnt *) prev->next->__internal;
+ radarUpdateGraphicEnt(ge, pos, color);
+FIN:
+ ReleaseMutex(mtx_set);
+}
+
+extern void radarInvalidateAll(void)
+{
+ WaitForSingleObject(mtx_set, INFINITE);
+ struct radarEntity *re = rad_entityList;
+
+ if (re == NULL) goto FIN;
+ while ( (re = re->next) != NULL )
+ {
+ re->valid = FALSE;
+ }
+FIN:
+ ReleaseMutex(mtx_set);
+}
+
+extern void radarRemoveInvalidEntities(void)
+{
+ WaitForSingleObject(mtx_set, INFINITE);
+ struct radarEntity *re = rad_entityList, *prev = rad_entityList;
+
+ if (re != NULL)
+ {
+ while ( (re = re->next) != NULL )
+ {
+ if (re->valid != TRUE)
+ {
+ prev->next = re->next;
+ if (re->next != NULL)
+ {
+ re->next->prev = prev;
+ }
+ radarDeleteEntity(re);
+ re = prev;
+ }
+ else
+ {
+ prev = re;
+ }
+ }
+ }
+ ReleaseMutex(mtx_set);
+}
+
+extern void radarDrawEntities(void)
+{
+ struct graphicEnt *ge;
+ struct radarEntity *re = rad_entityList;
+
+ if (re == NULL) return;
+ // draw everything except for players
+ while ( (re = re->next) != NULL )
+ {
+ ge = (struct graphicEnt *) re->__internal;
+ if (ge != NULL && re->isPlayer == FALSE)
+ {
+ sfRenderWindow_drawCircleShape(rWnd, ge->cr_entShape, NULL);
+ }
+ }
+ re = rad_entityList;
+ // draw players
+ while ( (re = re->next) != NULL )
+ {
+ ge = (struct graphicEnt *) re->__internal;
+ if (ge != NULL && re->isPlayer == TRUE)
+ {
+ sfRenderWindow_drawCircleShape(rWnd, ge->cr_entShape, NULL);
+ }
+ }
+}
+
+extern void radarExecThread(void)
+{
+ sThrd = sfThread_create(_radarLoop, NULL);
+ if (sThrd != NULL)
+ {
+ printf("launching sfml thread ..\n");
+ sfThread_launch(sThrd);
+ }
+}
+
+extern void radarKillThread(void)
+{
+ sfThread_terminate(sThrd);
+}
+
+/* DLL entry point - windoze compat */
+extern int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdParam, int cmdShow)
+{
+ return 0;
+}