Gigantic update with menu
This commit is contained in:
parent
e53e7c5d37
commit
0c63d7c969
Makefileinject-debug.sh
src
cvars.cdetour.c
features
aim.canti_aim.cchams.cesp.cfeatures.hfov.cmisc.cmovement.cnamechanger.cno_recoil.cno_recoil.hthirdperson.cthirdperson.h
globals.chooks.cinclude
cvars.hentityutil.hhooks.hmain.hmathutil.hmenu.hsdk.hsettings.hutil.h
main.cmenu.csettings.cutil.cimgui
backends
imconfig.himgui.cppimgui.himgui_draw.cppimgui_internal.himgui_tables.cppimgui_widgets.cppimstb_rectpack.himstb_textedit.himstb_truetype.h
24
Makefile
24
Makefile
@ -1,11 +1,15 @@
|
||||
|
||||
# Need to use g++ because the sdk headers use classes
|
||||
CC=g++
|
||||
INCLUDES=-Isrc/include/sdk/common -Isrc/include/sdk/public -Isrc/include/sdk/pm_shared -Isrc/include/sdk/engine
|
||||
CFLAGS=-Wall -Wextra -Wno-write-strings -m32 -fPIC $(INCLUDES)
|
||||
LDFLAGS=-lm
|
||||
INCLUDES=-Isrc/include/sdk/common -Isrc/include/sdk/public -Isrc/include/sdk/pm_shared -Isrc/include/sdk/engine -Isrc/include
|
||||
CFLAGS=-Wall -Wextra -Wno-write-strings -m32 -fPIC -fpermissive $(INCLUDES)
|
||||
LDFLAGS=-lm -lGL
|
||||
|
||||
OBJS=obj/main.c.o obj/globals.c.o obj/cvars.c.o obj/hooks.c.o obj/detour.c.o obj/util.c.o obj/features/movement.c.o obj/features/anti_aim.c.o obj/features/fov.c.o obj/features/namechanger.c.o obj/features/esp.c.o obj/features/chams.c.o obj/features/aim.c.o obj/features/misc.c.o obj/game_detection.c.o
|
||||
IMGUI_DIR=src/include/imgui
|
||||
IMGUI_INCLUDES=-I$(IMGUI_DIR)
|
||||
IMGUI_SRCS=$(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl2.cpp
|
||||
IMGUI_OBJS=$(patsubst %.cpp,%.o,$(IMGUI_SRCS))
|
||||
|
||||
OBJS=obj/main.c.o obj/globals.c.o obj/settings.c.o obj/hooks.c.o obj/detour.c.o obj/util.c.o obj/features/movement.c.o obj/features/anti_aim.c.o obj/features/fov.c.o obj/features/namechanger.c.o obj/features/esp.c.o obj/features/chams.c.o obj/features/aim.c.o obj/features/misc.c.o obj/features/thirdperson.c.o obj/game_detection.c.o obj/menu.c.o $(IMGUI_OBJS)
|
||||
BIN=libhlcheat.so
|
||||
|
||||
.PHONY: clean all inject
|
||||
@ -28,6 +32,12 @@ inject: $(BIN)
|
||||
$(BIN): $(OBJS)
|
||||
$(CC) $(CFLAGS) -shared -o $@ $(OBJS) $(LDFLAGS)
|
||||
|
||||
$(OBJS): obj/%.c.o : src/%.c
|
||||
@mkdir -p obj/features/
|
||||
obj/%.c.o: src/%.c
|
||||
@mkdir -p $(@D)
|
||||
$(CC) $(CFLAGS) -c -o $@ $< $(LDFLAGS)
|
||||
|
||||
$(IMGUI_DIR)/backends/%.o: $(IMGUI_DIR)/backends/%.cpp
|
||||
$(CC) $(CFLAGS) $(IMGUI_INCLUDES) -c -o $@ $< $(LDFLAGS)
|
||||
|
||||
%.o: %.cpp
|
||||
$(CC) $(CFLAGS) -c -o $@ $< $(LDFLAGS)
|
||||
|
217
inject-debug.sh
Executable file
217
inject-debug.sh
Executable file
@ -0,0 +1,217 @@
|
||||
#!/bin/bash
|
||||
|
||||
pid=$(pidof "hl_linux")
|
||||
libpath=$(realpath "libhlcheat.so")
|
||||
|
||||
if [ "$pid" == "" ]; then
|
||||
echo "inject-debug.sh: process not running."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
show_help() {
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo "Options:"
|
||||
echo " --help Show this help message"
|
||||
echo " --unload Debug the unload process interactively"
|
||||
echo " --inject Debug the injection process interactively"
|
||||
echo ""
|
||||
echo "Common GDB commands to use during debugging:"
|
||||
echo " bt Show backtrace"
|
||||
echo " info locals Show local variables"
|
||||
echo " n Step over (next line)"
|
||||
echo " s Step into function"
|
||||
echo " c Continue execution"
|
||||
echo " p expression Print value of expression"
|
||||
echo " finish Run until current function returns"
|
||||
echo ""
|
||||
echo "Without options, the script will inject the cheat normally."
|
||||
exit 0
|
||||
}
|
||||
|
||||
UNLOAD_MODE=0
|
||||
INJECT_MODE=0
|
||||
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
--help)
|
||||
show_help
|
||||
;;
|
||||
--unload)
|
||||
UNLOAD_MODE=1
|
||||
;;
|
||||
--inject)
|
||||
INJECT_MODE=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
cat > /tmp/gdbinit-goldsrc << EOF
|
||||
set confirm off
|
||||
set pagination off
|
||||
set print pretty on
|
||||
|
||||
define hook-stop
|
||||
echo \nBREAKPOINT HIT\n
|
||||
bt
|
||||
echo \nLOCAL VARIABLES:\n
|
||||
info locals
|
||||
echo \nSTACK FRAME:\n
|
||||
info frame
|
||||
echo \nCommands: n (next), s (step), c (continue), bt (backtrace), finish (run until function returns)\n
|
||||
end
|
||||
|
||||
EOF
|
||||
|
||||
if [ $UNLOAD_MODE -eq 1 ]; then
|
||||
echo "Starting interactive unload debugging session..."
|
||||
|
||||
cat >> /tmp/gdbinit-goldsrc << EOF
|
||||
# Set up functions to help with dlopen/dlclose
|
||||
set \$dlopen = (void* (*)(char*, int))dlopen
|
||||
set \$dlclose = (int (*)(void*))dlclose
|
||||
set \$dlerror = (char* (*)(void))dlerror
|
||||
|
||||
# Set breakpoints on critical functions
|
||||
break self_unload
|
||||
break unload
|
||||
break safe_unload_with_debug
|
||||
break UNINJECT_CommandHandler
|
||||
break hooks_restore
|
||||
break globals_restore
|
||||
break GL_UNHOOK
|
||||
|
||||
# Command to manually invoke the unload from GDB
|
||||
define uninject
|
||||
set \$self = \$dlopen("$libpath", 6)
|
||||
p \$self
|
||||
call \$dlclose(\$self)
|
||||
call \$dlclose(\$self)
|
||||
call \$dlerror()
|
||||
end
|
||||
|
||||
define call_uninject_cmd
|
||||
call UNINJECT_CommandHandler()
|
||||
end
|
||||
|
||||
echo \nType 'call_uninject_cmd' to execute the uninject command\n
|
||||
echo Type 'uninject' to manually trigger the unload process\n
|
||||
EOF
|
||||
|
||||
sudo gdb -x /tmp/gdbinit-goldsrc -p $pid
|
||||
|
||||
echo "Interactive unload debugging session ended."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ $INJECT_MODE -eq 1 ]; then
|
||||
echo "Starting interactive injection debugging session..."
|
||||
|
||||
cat >> /tmp/gdbinit-goldsrc << EOF
|
||||
# Set up functions to help with dlopen/dlclose
|
||||
set \$dlopen = (void* (*)(char*, int))dlopen
|
||||
set \$dlclose = (int (*)(void*))dlclose
|
||||
set \$dlerror = (char* (*)(void))dlerror
|
||||
|
||||
# Set breakpoints on critical functions
|
||||
break load
|
||||
break globals_init
|
||||
break cvars_init
|
||||
break hooks_init
|
||||
|
||||
# Command to manually inject the library
|
||||
define inject
|
||||
call \$dlopen("$libpath", 2)
|
||||
call \$dlerror()
|
||||
end
|
||||
|
||||
echo \nType 'inject' to load the library\n
|
||||
EOF
|
||||
|
||||
sudo gdb -x /tmp/gdbinit-goldsrc -p $pid
|
||||
|
||||
echo "Interactive injection debugging session ended."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Injecting cheat..."
|
||||
|
||||
if grep -q "$libpath" "/proc/$pid/maps"; then
|
||||
echo -e "goldsource-cheat already loaded. Reloading...\n"
|
||||
|
||||
cat > /tmp/gdbinit-goldsrc << EOF
|
||||
set confirm off
|
||||
set pagination off
|
||||
set print pretty on
|
||||
set \$dlopen = (void* (*)(char*, int))dlopen
|
||||
set \$dlclose = (int (*)(void*))dlclose
|
||||
set \$dlerror = (char* (*)(void))dlerror
|
||||
|
||||
# Reload library
|
||||
define reload_lib
|
||||
set \$self = \$dlopen("$libpath", 6)
|
||||
call \$dlclose(\$self)
|
||||
call \$dlclose(\$self)
|
||||
call \$dlopen("$libpath", 2)
|
||||
call \$dlerror()
|
||||
echo "\nReload complete. Library has been reloaded.\n"
|
||||
echo "You can now debug interactively.\n"
|
||||
echo "Type 'continue' or 'c' to let the game run normally.\n"
|
||||
echo "Type 'call_uninject_cmd' to trigger the uninject command.\n"
|
||||
end
|
||||
|
||||
# Command to manually trigger uninject
|
||||
define call_uninject_cmd
|
||||
call UNINJECT_CommandHandler()
|
||||
end
|
||||
|
||||
# Execute reload automatically
|
||||
reload_lib
|
||||
|
||||
# Break on uninject command
|
||||
break UNINJECT_CommandHandler
|
||||
break safe_unload_with_debug
|
||||
break self_unload
|
||||
|
||||
echo "\nType 'help' for GDB commands or 'continue' to let the game run.\n"
|
||||
EOF
|
||||
|
||||
sudo gdb -x /tmp/gdbinit-goldsrc -p $pid
|
||||
else
|
||||
cat > /tmp/gdbinit-goldsrc << EOF
|
||||
set confirm off
|
||||
set pagination off
|
||||
set print pretty on
|
||||
set \$dlopen = (void* (*)(char*, int))dlopen
|
||||
set \$dlclose = (int (*)(void*))dlclose
|
||||
set \$dlerror = (char* (*)(void))dlerror
|
||||
|
||||
# Initial library load
|
||||
define load_lib
|
||||
call \$dlopen("$libpath", 2)
|
||||
call \$dlerror()
|
||||
echo "\nInjection complete. Library has been loaded.\n"
|
||||
echo "You can now debug interactively.\n"
|
||||
echo "Type 'continue' or 'c' to let the game run normally.\n"
|
||||
echo "Type 'call_uninject_cmd' to trigger the uninject command.\n"
|
||||
end
|
||||
|
||||
# Command to manually trigger uninject
|
||||
define call_uninject_cmd
|
||||
call UNINJECT_CommandHandler()
|
||||
end
|
||||
|
||||
# Execute load automatically
|
||||
load_lib
|
||||
|
||||
# Break on uninject command
|
||||
break UNINJECT_CommandHandler
|
||||
break safe_unload_with_debug
|
||||
break self_unload
|
||||
|
||||
echo "\nType 'help' for GDB commands or 'continue' to let the game run.\n"
|
||||
EOF
|
||||
|
||||
sudo gdb -x /tmp/gdbinit-goldsrc -p $pid
|
||||
fi
|
||||
|
||||
echo -e "\nDebug session ended."
|
53
src/cvars.c
53
src/cvars.c
@ -1,53 +0,0 @@
|
||||
|
||||
#include "include/cvars.h"
|
||||
#include "include/sdk.h"
|
||||
#include "include/globals.h"
|
||||
#include "include/game_detection.h"
|
||||
|
||||
DECL_CVAR(movement_bhop);
|
||||
DECL_CVAR(movement_autostrafe);
|
||||
DECL_CVAR(aim_aimbot);
|
||||
DECL_CVAR(aim_autoshoot);
|
||||
DECL_CVAR(visuals_esp);
|
||||
DECL_CVAR(visuals_chams);
|
||||
DECL_CVAR(visuals_crosshair);
|
||||
DECL_CVAR(visuals_tracers);
|
||||
DECL_CVAR(movement_clmove);
|
||||
DECL_CVAR(watermark);
|
||||
DECL_CVAR(watermark_rainbow);
|
||||
DECL_CVAR(aim_aimbot_silent);
|
||||
DECL_CVAR(visuals_friendly);
|
||||
DECL_CVAR(movement_antiaim);
|
||||
DECL_CVAR(movement_antiaim_view);
|
||||
DECL_CVAR(movement_fakeduck);
|
||||
DECL_CVAR(misc_namechanger);
|
||||
DECL_CVAR(misc_namechanger_speed);
|
||||
DECL_CVAR(visuals_fov);
|
||||
|
||||
|
||||
bool cvars_init(void) {
|
||||
REGISTER_CVAR(movement_bhop, 1);
|
||||
REGISTER_CVAR(movement_autostrafe, 1);
|
||||
REGISTER_CVAR(aim_aimbot, 0);
|
||||
REGISTER_CVAR(aim_autoshoot, 0); /* Only works with aimbot enabled */
|
||||
REGISTER_CVAR(visuals_esp, 3);
|
||||
REGISTER_CVAR(visuals_chams, 1);
|
||||
REGISTER_CVAR(visuals_crosshair, 0);
|
||||
REGISTER_CVAR(movement_clmove, 0);
|
||||
REGISTER_CVAR(watermark, 1);
|
||||
REGISTER_CVAR(watermark_rainbow, 1);
|
||||
REGISTER_CVAR(aim_aimbot_silent, 1);
|
||||
REGISTER_CVAR(visuals_friendly, 0);
|
||||
REGISTER_CVAR(movement_antiaim, 0);
|
||||
REGISTER_CVAR(movement_antiaim_view, 0);
|
||||
REGISTER_CVAR(movement_fakeduck, 0);
|
||||
REGISTER_CVAR(misc_namechanger, 0);
|
||||
REGISTER_CVAR(misc_namechanger_speed, 10);
|
||||
REGISTER_CVAR(visuals_fov, 90);
|
||||
if (IsCS16()) {
|
||||
REGISTER_CVAR(visuals_tracers, 0);
|
||||
} else {
|
||||
REGISTER_CVAR(visuals_tracers, 1);
|
||||
}
|
||||
return true;
|
||||
}
|
101
src/detour.c
101
src/detour.c
@ -11,6 +11,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h> /* getpagesize */
|
||||
#include <sys/mman.h> /* mprotect */
|
||||
#include <stdio.h> /* printf */
|
||||
|
||||
#include "include/detour.h"
|
||||
|
||||
@ -19,6 +20,11 @@
|
||||
#define PAGE_ALIGN(x) ((x + PAGE_SIZE - 1) & PAGE_MASK)
|
||||
#define PAGE_ALIGN_DOWN(x) (PAGE_ALIGN(x) - PAGE_SIZE)
|
||||
|
||||
/* Store detour data for functions we've hooked */
|
||||
#define MAX_HOOKS 32
|
||||
static detour_data_t g_hooks[MAX_HOOKS];
|
||||
static int g_hook_count = 0;
|
||||
|
||||
static bool protect_addr(void* ptr, int new_flags) {
|
||||
void* p = (void*)PAGE_ALIGN_DOWN((detour_ptr_t)ptr);
|
||||
int pgsz = getpagesize();
|
||||
@ -49,6 +55,9 @@ static uint8_t def_jmp_bytes[] = { 0x48, 0xB8, 0x00, 0x00, 0x00, 0x00,
|
||||
#endif
|
||||
|
||||
void detour_init(detour_data_t* data, void* orig, void* hook) {
|
||||
if (!orig || !hook)
|
||||
return;
|
||||
|
||||
data->detoured = false;
|
||||
data->orig = orig;
|
||||
data->hook = hook;
|
||||
@ -108,3 +117,95 @@ bool detour_del(detour_data_t* d) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get existing hook data for an original function pointer */
|
||||
static detour_data_t* find_hook_data(void* orig) {
|
||||
for (int i = 0; i < g_hook_count; i++) {
|
||||
if (g_hooks[i].orig == orig) {
|
||||
return &g_hooks[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Wrapper functions for backward compatibility with code using
|
||||
* DetourFunction and DetourRemove naming convention */
|
||||
|
||||
/*
|
||||
* Wrapper for detour_add that saves and returns the original
|
||||
* function pointer as required by the DetourFunction interface
|
||||
*/
|
||||
void* DetourFunction(void* orig, void* hook) {
|
||||
if (!orig || !hook) {
|
||||
printf("DetourFunction error: NULL pointer provided\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check if we already have a hook for this function */
|
||||
detour_data_t* existing = find_hook_data(orig);
|
||||
if (existing) {
|
||||
/* If the function was already hooked but with a different hook,
|
||||
restore the original first */
|
||||
if (existing->hook != hook) {
|
||||
printf("DetourFunction: Function at %p already hooked, updating\n", orig);
|
||||
detour_del(existing);
|
||||
existing->hook = hook;
|
||||
/* Recreate the jump instruction with new hook */
|
||||
memcpy(existing->jmp_bytes, &def_jmp_bytes, sizeof(def_jmp_bytes));
|
||||
memcpy(&existing->jmp_bytes[JMP_BYTES_PTR], &hook, sizeof(detour_ptr_t));
|
||||
if (!detour_add(existing)) {
|
||||
printf("DetourFunction error: Failed to update hook for %p\n", orig);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return existing->orig;
|
||||
}
|
||||
|
||||
/* No existing hook, create a new one if we have space */
|
||||
if (g_hook_count >= MAX_HOOKS) {
|
||||
printf("DetourFunction error: Max hooks (%d) reached\n", MAX_HOOKS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
detour_data_t* data = &g_hooks[g_hook_count++];
|
||||
memset(data, 0, sizeof(detour_data_t)); // Clear memory before use
|
||||
detour_init(data, orig, hook);
|
||||
if (detour_add(data))
|
||||
return data->orig;
|
||||
|
||||
/* If detour failed, decrement the counter */
|
||||
printf("DetourFunction error: Failed to add hook for %p\n", orig);
|
||||
g_hook_count--;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper for detour_del that takes the original and hook
|
||||
* function pointers directly
|
||||
*/
|
||||
bool DetourRemove(void* orig, void* hook) {
|
||||
if (!orig) {
|
||||
printf("DetourRemove error: NULL original function pointer\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Find the hook in our array */
|
||||
detour_data_t* data = find_hook_data(orig);
|
||||
if (!data) {
|
||||
printf("DetourRemove error: Hook for function %p not found\n", orig);
|
||||
return false; /* Not found */
|
||||
}
|
||||
|
||||
/* If hook is specified, make sure it matches */
|
||||
if (hook && data->hook != hook) {
|
||||
printf("DetourRemove error: Hook function mismatch for %p\n", orig);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Remove the hook */
|
||||
bool result = detour_del(data);
|
||||
if (!result) {
|
||||
printf("DetourRemove error: Failed to remove hook for %p\n", orig);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1,142 +1,356 @@
|
||||
#include <math.h>
|
||||
#include <cfloat>
|
||||
#include <string.h>
|
||||
|
||||
#include "features.h"
|
||||
#include "../include/sdk.h"
|
||||
#include "../include/cvars.h"
|
||||
#include "../include/util.h"
|
||||
#include "../include/game_detection.h"
|
||||
#include "../include/entityutil.h"
|
||||
#include "../include/mathutil.h"
|
||||
#include "../include/menu.h"
|
||||
#include "../include/settings.h"
|
||||
#include "features.h"
|
||||
|
||||
/* Game units to add to the entity origin to get the head */
|
||||
#define HL1_HEAD_OFFSET 25.f
|
||||
#define CS16_HEAD_OFFSET 22.f
|
||||
#define CS16_HORIZONTAL_OFFSET 8.0f
|
||||
#define DOD_HEAD_OFFSET 22.f
|
||||
#define DOD_HORIZONTAL_OFFSET 8.0f
|
||||
#define HITBOX_HEAD 0
|
||||
#define HITBOX_CHEST 1
|
||||
#define HITBOX_STOMACH 2
|
||||
#define HITBOX_PELVIS 3
|
||||
#define HITBOX_LEFTARM 4
|
||||
#define HITBOX_RIGHTARM 5
|
||||
#define HITBOX_LEFTLEG 6
|
||||
#define HITBOX_RIGHTLEG 7
|
||||
#define HITBOX_NEAREST 4
|
||||
#define MAX_HITBOXES 7
|
||||
|
||||
/* Scale factor for aim punch */
|
||||
#define AIM_PUNCH_MULT 2
|
||||
#define AIM_PUNCH_MULT 2.0f
|
||||
|
||||
static float vec_length(vec3_t v) {
|
||||
return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
|
||||
}
|
||||
#define SMOOTHING_FACTOR 3.0f
|
||||
|
||||
#define PITCH 0
|
||||
#define YAW 1
|
||||
#define ROLL 2
|
||||
|
||||
static bool is_visible(vec3_t start, vec3_t end) {
|
||||
pmtrace_t* tr = i_engine->PM_TraceLine(start, end, PM_TRACELINE_PHYSENTSONLY, 2, -1);
|
||||
if (tr->ent <= 0) return false;
|
||||
const int ent_idx = i_pmove->physents[tr->ent].info;
|
||||
return get_player(ent_idx) != NULL;
|
||||
}
|
||||
#define PRIORITY_NONE 0
|
||||
#define PRIORITY_LOW 1
|
||||
#define PRIORITY_MEDIUM 2
|
||||
#define PRIORITY_HIGH 3
|
||||
|
||||
static vec3_t get_closest_delta(vec3_t viewangles) {
|
||||
// Compensate for aim punch
|
||||
viewangles.x += g_punchAngles.x * AIM_PUNCH_MULT;
|
||||
viewangles.y += g_punchAngles.y * AIM_PUNCH_MULT;
|
||||
viewangles.z += g_punchAngles.z * AIM_PUNCH_MULT;
|
||||
extern const char* hitbox_options[];
|
||||
extern int current_hitbox;
|
||||
|
||||
vec3_t view_height;
|
||||
i_engine->pEventAPI->EV_LocalPlayerViewheight(view_height);
|
||||
vec3_t local_eyes = vec_add(localplayer->origin, view_height);
|
||||
const char* hitbox_names[] = {
|
||||
"Head",
|
||||
"Chest",
|
||||
"Stomach",
|
||||
"Pelvis",
|
||||
"Nearest Point"
|
||||
};
|
||||
|
||||
float min_distance = FLT_MAX; // For tracking the closest player
|
||||
float best_fov = dz_aim_aimbot->value;
|
||||
vec3_t best_delta = { 0, 0, 0 };
|
||||
int current_hitbox = HITBOX_HEAD;
|
||||
|
||||
for (int i = 1; i <= i_engine->GetMaxClients(); i++) {
|
||||
cl_entity_t* ent = get_player(i);
|
||||
typedef struct {
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
vec3_t origin;
|
||||
float radius;
|
||||
} hitbox_t;
|
||||
|
||||
if (!is_alive(ent) || is_friend(ent)) {
|
||||
continue; // Skip if not alive or is a friend
|
||||
}
|
||||
bool get_hitbox(cl_entity_t* ent, int hitbox_index, hitbox_t* out_hitbox) {
|
||||
if (!ent || !ent->model || !out_hitbox)
|
||||
return false;
|
||||
|
||||
vec3_t head_pos = ent->origin;
|
||||
|
||||
if (ent->curstate.usehull != 1) { // Not crouched
|
||||
if (IsCS16()) {
|
||||
head_pos.z += CS16_HEAD_OFFSET;
|
||||
head_pos.x += CS16_HORIZONTAL_OFFSET;
|
||||
} else if (IsDayOfDefeat()) {
|
||||
head_pos.z += DOD_HEAD_OFFSET;
|
||||
head_pos.x += DOD_HORIZONTAL_OFFSET;
|
||||
} else {
|
||||
head_pos.z += HL1_HEAD_OFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
float distance = vec_length(vec_sub(ent->origin, local_eyes));
|
||||
if (distance > min_distance) {
|
||||
continue; // Skip players that are further than the current closest target
|
||||
}
|
||||
|
||||
const vec3_t enemy_angle = vec_to_ang(vec_sub(head_pos, local_eyes));
|
||||
const vec3_t delta = vec_sub(enemy_angle, viewangles);
|
||||
vec_norm(delta);
|
||||
|
||||
float fov = hypotf(delta.x, delta.y);
|
||||
if (fov > 360.0f) {
|
||||
fov = remainderf(fov, 360.0f);
|
||||
}
|
||||
if (fov > 180.0f) {
|
||||
fov = 360.0f - fov;
|
||||
}
|
||||
|
||||
// Only check visibility for potential targets
|
||||
if (fov < best_fov && is_visible(local_eyes, head_pos)) {
|
||||
best_fov = fov;
|
||||
vec_copy(best_delta, delta);
|
||||
min_distance = distance; // Update the closest target's distance
|
||||
}
|
||||
studiohdr_t* studio_model = (studiohdr_t*)i_enginestudio->Mod_Extradata(ent->model);
|
||||
if (!studio_model)
|
||||
return false;
|
||||
|
||||
mstudiobbox_t* studio_box = NULL;
|
||||
if (studio_model->hitboxindex) {
|
||||
studio_box = (mstudiobbox_t*)((byte*)studio_model + studio_model->hitboxindex);
|
||||
if (hitbox_index >= studio_model->numhitboxes || hitbox_index < 0)
|
||||
return false;
|
||||
|
||||
studio_box += hitbox_index;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return best_delta;
|
||||
|
||||
vec_copy(out_hitbox->mins, studio_box->bbmin);
|
||||
vec_copy(out_hitbox->maxs, studio_box->bbmax);
|
||||
|
||||
vec3_t center;
|
||||
center.x = (out_hitbox->mins.x + out_hitbox->maxs.x) * 0.5f;
|
||||
center.y = (out_hitbox->mins.y + out_hitbox->maxs.y) * 0.5f;
|
||||
center.z = (out_hitbox->mins.z + out_hitbox->maxs.z) * 0.5f;
|
||||
|
||||
vec3_t angles;
|
||||
vec_copy(angles, ent->angles);
|
||||
|
||||
int bone = studio_box->bone;
|
||||
if (bone >= 0 && bone < studio_model->numbones) {
|
||||
mstudiobone_t* pbone = (mstudiobone_t*)((byte*)studio_model + studio_model->boneindex);
|
||||
pbone += bone;
|
||||
|
||||
angles[0] = pbone->value[0];
|
||||
angles[1] = pbone->value[1];
|
||||
angles[2] = pbone->value[2];
|
||||
}
|
||||
|
||||
vec3_t forward, right, up;
|
||||
i_engine->pfnAngleVectors(angles, forward, right, up);
|
||||
|
||||
vec3_t offset;
|
||||
offset.x = center.x * forward.x + center.y * right.x + center.z * up.x;
|
||||
offset.y = center.x * forward.y + center.y * right.y + center.z * up.y;
|
||||
offset.z = center.x * forward.z + center.y * right.z + center.z * up.z;
|
||||
|
||||
out_hitbox->origin = vec_add(ent->origin, offset);
|
||||
|
||||
if (hitbox_index == HITBOX_HEAD) {
|
||||
out_hitbox->origin.z += 8.0f;
|
||||
}
|
||||
|
||||
vec3_t size;
|
||||
size.x = fabs(out_hitbox->maxs.x - out_hitbox->mins.x) * 0.5f;
|
||||
size.y = fabs(out_hitbox->maxs.y - out_hitbox->mins.y) * 0.5f;
|
||||
size.z = fabs(out_hitbox->maxs.z - out_hitbox->mins.z) * 0.5f;
|
||||
|
||||
out_hitbox->radius = sqrtf(size.x * size.x + size.y * size.y + size.z * size.z);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void aimbot(usercmd_t* cmd) {
|
||||
static bool shouldShootNextFrame = false; // If you're not using this variable, you can remove it.
|
||||
static bool hasAdjustedView = false;
|
||||
bool is_hitbox_visible(vec3_t eye_pos, hitbox_t* hitbox) {
|
||||
if (!hitbox)
|
||||
return false;
|
||||
|
||||
pmtrace_t* trace = i_engine->PM_TraceLine(eye_pos, hitbox->origin, PM_TRACELINE_PHYSENTSONLY, 2, -1);
|
||||
|
||||
if (g_settings.aimbot_rage_mode && trace->fraction > 0.5f) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (trace->fraction < 1.0f && trace->ent <= 0)
|
||||
return false;
|
||||
|
||||
if (trace->ent > 0) {
|
||||
const int ent_idx = i_pmove->physents[trace->ent].info;
|
||||
if (get_player(ent_idx))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CVAR_ON(aim_aimbot) || !can_shoot())
|
||||
return;
|
||||
typedef struct {
|
||||
cl_entity_t* entity;
|
||||
float fov;
|
||||
vec3_t aim_point;
|
||||
bool is_visible;
|
||||
int priority;
|
||||
float distance;
|
||||
} target_t;
|
||||
|
||||
vec3_t engine_viewangles;
|
||||
i_engine->GetViewAngles(engine_viewangles);
|
||||
vec3_t best_delta = get_closest_delta(engine_viewangles);
|
||||
int get_target_priority(cl_entity_t* ent) {
|
||||
if (!ent)
|
||||
return PRIORITY_NONE;
|
||||
|
||||
if (g_settings.aimbot_rage_mode) {
|
||||
return PRIORITY_HIGH;
|
||||
}
|
||||
|
||||
return PRIORITY_MEDIUM;
|
||||
}
|
||||
|
||||
if (!vec_is_zero(best_delta)) {
|
||||
/*
|
||||
if (!lastShotHit) {
|
||||
// If the last shot missed, adjust the angle slightly
|
||||
// This is a simple approach and might need further tweaking
|
||||
best_delta.y += 0.5f; // Adjust yaw slightly
|
||||
}
|
||||
*/
|
||||
engine_viewangles.x += best_delta.x;
|
||||
engine_viewangles.y += best_delta.y;
|
||||
engine_viewangles.z += best_delta.z;
|
||||
|
||||
if (CVAR_ON(aim_aimbot_silent)) {
|
||||
vec_copy(cmd->viewangles, engine_viewangles);
|
||||
if (cmd->buttons & IN_ATTACK) {
|
||||
cmd->buttons |= IN_ATTACK;
|
||||
}
|
||||
} else {
|
||||
if (cmd->buttons & IN_ATTACK) {
|
||||
if (hasAdjustedView) {
|
||||
hasAdjustedView = false; // Reset flag
|
||||
} else {
|
||||
i_engine->SetViewAngles(engine_viewangles);
|
||||
hasAdjustedView = true;
|
||||
cmd->buttons &= ~IN_ATTACK; // Defer the shot to the next frame
|
||||
static bool get_best_hitbox(cl_entity_t* ent, vec3_t eye_pos, hitbox_t* out_hitbox) {
|
||||
if (!ent || !out_hitbox)
|
||||
return false;
|
||||
|
||||
if (current_hitbox == HITBOX_NEAREST) {
|
||||
float best_distance = 9999.0f;
|
||||
bool found_hitbox = false;
|
||||
|
||||
for (int i = 0; i < MAX_HITBOXES; i++) {
|
||||
hitbox_t temp_hitbox;
|
||||
if (get_hitbox(ent, i, &temp_hitbox)) {
|
||||
if (is_hitbox_visible(eye_pos, &temp_hitbox)) {
|
||||
vec3_t to_hitbox = vec_sub(temp_hitbox.origin, eye_pos);
|
||||
float distance = vec_len2d(to_hitbox);
|
||||
|
||||
if (distance < best_distance) {
|
||||
best_distance = distance;
|
||||
*out_hitbox = temp_hitbox;
|
||||
found_hitbox = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (CVAR_ON(aim_autoshoot) && (cmd->buttons & IN_ATTACK)) {
|
||||
cmd->buttons &= ~IN_ATTACK;
|
||||
|
||||
return found_hitbox;
|
||||
}
|
||||
else {
|
||||
if (get_hitbox(ent, current_hitbox, out_hitbox)) {
|
||||
return is_hitbox_visible(eye_pos, out_hitbox);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static target_t get_best_target(vec3_t viewangles, vec3_t eye_pos) {
|
||||
target_t best_target = {NULL, 0.0f, {0, 0, 0}, false, PRIORITY_NONE, 9999.0f};
|
||||
float best_score = 0.0f;
|
||||
float max_fov = g_settings.aimbot_fov;
|
||||
|
||||
if (g_settings.aimbot_rage_mode && max_fov < 90.0f) {
|
||||
max_fov = 90.0f;
|
||||
}
|
||||
|
||||
for (int i = 1; i <= i_engine->GetMaxClients(); i++) {
|
||||
cl_entity_t* ent = get_player(i);
|
||||
|
||||
if (!ent || !is_alive(ent))
|
||||
continue;
|
||||
|
||||
if (!g_settings.aimbot_friendly_fire && is_friend(ent))
|
||||
continue;
|
||||
|
||||
hitbox_t target_hitbox;
|
||||
bool hitbox_found = false;
|
||||
|
||||
hitbox_found = get_best_hitbox(ent, eye_pos, &target_hitbox);
|
||||
|
||||
if (!hitbox_found)
|
||||
continue;
|
||||
|
||||
vec3_t to_target = vec_sub(target_hitbox.origin, eye_pos);
|
||||
vec3_t aim_angles = vec_to_ang(to_target);
|
||||
|
||||
vec3_t angle_delta = vec_sub(aim_angles, viewangles);
|
||||
vec_norm(&angle_delta);
|
||||
ang_clamp(&angle_delta);
|
||||
|
||||
float fov_distance = sqrtf(angle_delta.x * angle_delta.x + angle_delta.y * angle_delta.y);
|
||||
|
||||
if (fov_distance > max_fov)
|
||||
continue;
|
||||
|
||||
float distance = sqrtf(to_target.x * to_target.x + to_target.y * to_target.y + to_target.z * to_target.z);
|
||||
|
||||
float fov_score = 1.0f - (fov_distance / max_fov);
|
||||
|
||||
float priority_score = 0.0f;
|
||||
if (g_settings.aimbot_rage_mode) {
|
||||
int priority = get_target_priority(ent);
|
||||
priority_score = priority / (float)PRIORITY_HIGH;
|
||||
}
|
||||
|
||||
float final_score = fov_score;
|
||||
if (g_settings.aimbot_rage_mode) {
|
||||
final_score = (fov_score * 0.5f) + (priority_score * 0.5f);
|
||||
}
|
||||
|
||||
if (final_score > best_score) {
|
||||
best_score = final_score;
|
||||
best_target.entity = ent;
|
||||
best_target.fov = fov_distance;
|
||||
vec_copy(best_target.aim_point, target_hitbox.origin);
|
||||
best_target.is_visible = true;
|
||||
best_target.priority = get_target_priority(ent);
|
||||
best_target.distance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
return best_target;
|
||||
}
|
||||
|
||||
void aimbot(usercmd_t* cmd) {
|
||||
if (!g_settings.aimbot_enabled)
|
||||
return;
|
||||
|
||||
bool should_run_aimbot = true;
|
||||
bool should_autoshoot = g_settings.aimbot_autoshoot;
|
||||
|
||||
switch (0) {
|
||||
case 0:
|
||||
should_run_aimbot = true;
|
||||
break;
|
||||
case 1:
|
||||
should_run_aimbot = (cmd->buttons & IN_ATTACK) != 0;
|
||||
break;
|
||||
case 2:
|
||||
should_run_aimbot = (cmd->buttons & IN_ATTACK2) != 0;
|
||||
break;
|
||||
default:
|
||||
should_run_aimbot = true;
|
||||
}
|
||||
|
||||
if (!should_run_aimbot && !g_settings.aimbot_rage_mode)
|
||||
return;
|
||||
|
||||
if (g_settings.aimbot_rage_mode)
|
||||
should_run_aimbot = true;
|
||||
|
||||
bool can_fire = can_shoot();
|
||||
|
||||
vec3_t view_height;
|
||||
i_engine->pEventAPI->EV_LocalPlayerViewheight(view_height);
|
||||
vec3_t eye_pos = vec_add(localplayer->origin, view_height);
|
||||
|
||||
vec3_t engine_viewangles;
|
||||
i_engine->GetViewAngles(engine_viewangles);
|
||||
|
||||
vec3_t adjusted_viewangles = engine_viewangles;
|
||||
if (g_settings.aimbot_norecoil) {
|
||||
adjusted_viewangles.x += g_punchAngles.x * AIM_PUNCH_MULT;
|
||||
adjusted_viewangles.y += g_punchAngles.y * AIM_PUNCH_MULT;
|
||||
adjusted_viewangles.z += g_punchAngles.z * AIM_PUNCH_MULT;
|
||||
}
|
||||
|
||||
target_t best_target = get_best_target(adjusted_viewangles, eye_pos);
|
||||
|
||||
if (best_target.entity && best_target.is_visible) {
|
||||
vec3_t to_target = vec_sub(best_target.aim_point, eye_pos);
|
||||
vec3_t aim_angles = vec_to_ang(to_target);
|
||||
|
||||
vec3_t delta = vec_sub(aim_angles, engine_viewangles);
|
||||
vec_norm(&delta);
|
||||
ang_clamp(&delta);
|
||||
|
||||
if (g_settings.aimbot_silent) {
|
||||
cmd->viewangles.x = engine_viewangles.x + delta.x;
|
||||
cmd->viewangles.y = engine_viewangles.y + delta.y;
|
||||
cmd->viewangles.z = engine_viewangles.z + delta.z;
|
||||
} else {
|
||||
float smoothing = SMOOTHING_FACTOR;
|
||||
|
||||
smoothing = g_settings.aimbot_smooth > 0 ? g_settings.aimbot_smooth : SMOOTHING_FACTOR;
|
||||
|
||||
if (g_settings.aimbot_rage_mode) {
|
||||
smoothing = 1.2f;
|
||||
}
|
||||
|
||||
engine_viewangles.x += delta.x / smoothing;
|
||||
engine_viewangles.y += delta.y / smoothing;
|
||||
engine_viewangles.z += delta.z / smoothing;
|
||||
|
||||
ang_clamp(&engine_viewangles);
|
||||
|
||||
i_engine->SetViewAngles(engine_viewangles);
|
||||
|
||||
cmd->viewangles.x = engine_viewangles.x;
|
||||
cmd->viewangles.y = engine_viewangles.y;
|
||||
cmd->viewangles.z = engine_viewangles.z;
|
||||
}
|
||||
|
||||
if (should_autoshoot && can_fire) {
|
||||
if (g_settings.aimbot_rage_mode) {
|
||||
cmd->buttons |= IN_ATTACK;
|
||||
} else {
|
||||
float aim_error = sqrtf(delta.x * delta.x + delta.y * delta.y);
|
||||
if (aim_error < 5.0f) {
|
||||
cmd->buttons |= IN_ATTACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (should_autoshoot) {
|
||||
cmd->buttons &= ~IN_ATTACK;
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "features.h"
|
||||
#include "../include/sdk.h"
|
||||
#include "../include/cvars.h"
|
||||
#include "../include/settings.h"
|
||||
#include "../include/util.h"
|
||||
|
||||
float random_float(float min, float max) {
|
||||
@ -16,7 +16,7 @@ float random_float(float min, float max) {
|
||||
bool isSpacebarPressed() {
|
||||
Display* display = XOpenDisplay(NULL);
|
||||
if (!display) {
|
||||
return false; // Could not open the display, assume not pressed
|
||||
return false;
|
||||
}
|
||||
|
||||
char keys_return[32];
|
||||
@ -38,7 +38,7 @@ void anti_aim(usercmd_t* cmd) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CVAR_ON(movement_antiaim)) {
|
||||
if (!g_settings.antiaim) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -68,8 +68,7 @@ void anti_aim(usercmd_t* cmd) {
|
||||
bool isBunnyHopping = cmd->buttons & IN_JUMP;
|
||||
bool isStationary = (cmd->forwardmove == 0.0f && cmd->sidemove == 0.0f);
|
||||
|
||||
// This shit busted right now
|
||||
if (CVAR_ON(movement_fakeduck) && (isStationary || isBunnyHopping || isSpacebarPressed())) {
|
||||
if (g_settings.fakeduck && (isStationary || isBunnyHopping || isSpacebarPressed())) {
|
||||
static int duckCounter = 0;
|
||||
if (duckCounter < 2) {
|
||||
cmd->buttons |= IN_DUCK;
|
||||
@ -84,7 +83,7 @@ void anti_aim(usercmd_t* cmd) {
|
||||
if (view_angles.y > 180.0f) view_angles.y -= 360.0f;
|
||||
if (view_angles.y < -180.0f) view_angles.y += 360.0f;
|
||||
|
||||
if (CVAR_ON(movement_antiaim_view)) {
|
||||
if (g_settings.antiaim_view) {
|
||||
i_engine->SetViewAngles(view_angles);
|
||||
i_engine->pfnClientCmd("echo \"Set view angles directly using movement_antiaim_view.\"");
|
||||
} else {
|
||||
|
@ -1,7 +1,6 @@
|
||||
|
||||
#include "features.h"
|
||||
#include "../include/globals.h"
|
||||
#include "../include/cvars.h"
|
||||
#include "../include/settings.h"
|
||||
#include "../include/util.h"
|
||||
|
||||
#include <GL/gl.h>
|
||||
@ -15,7 +14,7 @@ enum chams_settings {
|
||||
visible_flags visible_mode;
|
||||
|
||||
bool chams(void* this_ptr) {
|
||||
const int setting = dz_visuals_chams->value == 5.0f ? 7 : dz_visuals_chams->value;
|
||||
const int setting = g_settings.chams ? PLAYER_CHAMS : DISABLED;
|
||||
if (setting == DISABLED)
|
||||
return false;
|
||||
|
||||
@ -39,8 +38,7 @@ bool chams(void* this_ptr) {
|
||||
|
||||
const bool friendly = is_friend(ent);
|
||||
|
||||
// Check if the player is friendly and if visuals_friendly is 0
|
||||
if (friendly && dz_visuals_friendly->value == 0)
|
||||
if (friendly && !g_settings.esp_friendly)
|
||||
return false; // Do not render chams for friendlies
|
||||
|
||||
/* If we got here it means we are rendering a valid player */
|
||||
|
@ -1,18 +1,11 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include "features.h"
|
||||
#include "../include/globals.h"
|
||||
#include "../include/cvars.h"
|
||||
#include "../include/settings.h"
|
||||
#include "../include/util.h"
|
||||
#include "../include/game_detection.h"
|
||||
|
||||
/* For dz_esp */
|
||||
enum esp_values {
|
||||
ESP_OFF = 0,
|
||||
ESP_BOX = 1,
|
||||
ESP_NAME = 2,
|
||||
/* ESP_ALL should be 3 but we can just OR box and name */
|
||||
};
|
||||
// ESP enums moved to settings.h as esp_mode_t
|
||||
|
||||
bool gl_draw3dbox(vec3_t o, int bh, int bw, int lw) {
|
||||
/*
|
||||
@ -99,7 +92,7 @@ static bool gl_draw2dbox(vec3_t o, int bh) {
|
||||
}
|
||||
|
||||
void esp(void) {
|
||||
const int setting = (int)dz_visuals_esp->value;
|
||||
const int setting = g_settings.esp_mode;
|
||||
if (setting == ESP_OFF)
|
||||
return;
|
||||
|
||||
@ -109,7 +102,7 @@ void esp(void) {
|
||||
if (!valid_player(ent) || !is_alive(ent) || vec_is_zero(ent->origin))
|
||||
continue;
|
||||
|
||||
if (is_friend(ent) && dz_visuals_friendly->value == 0)
|
||||
if (is_friend(ent) && !g_settings.esp_friendly)
|
||||
continue;
|
||||
|
||||
int bh = 70;
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#ifndef FEATURES_H_
|
||||
#define FEATURES_H_
|
||||
|
||||
@ -11,8 +10,13 @@ enum visible_flags {
|
||||
FRIEND_VISIBLE = 3,
|
||||
FRIEND_NOT_VISIBLE = 4,
|
||||
HANDS = 5,
|
||||
SCOPE = 6,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/* src/features/movement.c */
|
||||
@ -42,4 +46,13 @@ void anti_aim(usercmd_t* cmd);
|
||||
/* src/features/fov.c */
|
||||
void fov_adjust(usercmd_t* cmd);
|
||||
|
||||
/* src/features/thirdperson.c */
|
||||
void thirdperson_init(void);
|
||||
void thirdperson_update(void);
|
||||
bool thirdperson_key_event(int keynum, int down);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FEATURES_H_ */
|
@ -2,9 +2,9 @@
|
||||
#include "../include/globals.h"
|
||||
#include "../include/sdk.h"
|
||||
#include "../include/util.h"
|
||||
#include "../include/settings.h"
|
||||
#include "features.h"
|
||||
|
||||
extern cvar_t* dz_visuals_fov;
|
||||
extern float* scr_fov_value;
|
||||
|
||||
void fov_adjust(usercmd_t* cmd) {
|
||||
@ -13,7 +13,7 @@ void fov_adjust(usercmd_t* cmd) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dz_visuals_fov->value) {
|
||||
*scr_fov_value = dz_visuals_fov->value;
|
||||
if (g_settings.fov > 0) {
|
||||
*scr_fov_value = g_settings.fov;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
|
||||
#include "features.h"
|
||||
#include "../include/sdk.h"
|
||||
#include "../include/globals.h"
|
||||
#include "../include/cvars.h"
|
||||
#include "../include/util.h"
|
||||
#include "../include/game_detection.h"
|
||||
#include "../include/settings.h"
|
||||
|
||||
void custom_crosshair(void) {
|
||||
if (!CVAR_ON(visuals_crosshair))
|
||||
if (!g_settings.custom_crosshair)
|
||||
return;
|
||||
|
||||
/* Get window size, and then the center. */
|
||||
@ -15,7 +14,7 @@ void custom_crosshair(void) {
|
||||
int my = game_info->m_height / 2;
|
||||
|
||||
/* The real length is sqrt(2 * (len^2)) */
|
||||
const int len = dz_visuals_crosshair->value;
|
||||
const int len = 5;
|
||||
const int gap = 1;
|
||||
const float w = 1;
|
||||
const rgb_t col = { 255, 255, 255 };
|
||||
@ -37,7 +36,7 @@ static double lastTracerTime = 0;
|
||||
static bool attackReleased = true;
|
||||
|
||||
void bullet_tracers(usercmd_t* cmd) {
|
||||
if (!CVAR_ON(visuals_tracers) || !is_alive(localplayer))
|
||||
if (!g_settings.tracers || !is_alive(localplayer))
|
||||
return;
|
||||
|
||||
if (IsCS16()) {
|
||||
|
@ -1,11 +1,10 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "features.h"
|
||||
#include "../include/sdk.h"
|
||||
#include "../include/globals.h"
|
||||
#include "../include/cvars.h"
|
||||
#include "../include/settings.h"
|
||||
#include "../include/util.h"
|
||||
|
||||
static void autostrafe_legit(usercmd_t* cmd) {
|
||||
@ -65,7 +64,7 @@ static void autostrafe_rage(usercmd_t* cmd) {
|
||||
}
|
||||
|
||||
void bhop(usercmd_t* cmd) {
|
||||
if (!CVAR_ON(movement_bhop) || i_pmove->movetype != MOVETYPE_WALK)
|
||||
if (!g_settings.bhop || i_pmove->movetype != MOVETYPE_WALK)
|
||||
return;
|
||||
|
||||
static bool was_in_air = false;
|
||||
@ -81,18 +80,8 @@ void bhop(usercmd_t* cmd) {
|
||||
was_in_air = (i_pmove->flags & FL_ONGROUND) == 0;
|
||||
|
||||
/* Autostrafe if enabled. Check if we are in the air and holding space. */
|
||||
if (is_jumping) {
|
||||
switch ((int)dz_movement_autostrafe->value) {
|
||||
case 1:
|
||||
autostrafe_rage(cmd);
|
||||
break;
|
||||
case 2:
|
||||
autostrafe_legit(cmd);
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (is_jumping && g_settings.autostrafe) {
|
||||
autostrafe_rage(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <vector>
|
||||
#include "features.h"
|
||||
#include "../include/globals.h"
|
||||
#include "../include/cvars.h"
|
||||
#include "../include/settings.h"
|
||||
#include "../include/util.h"
|
||||
#include "../include/game_detection.h"
|
||||
|
||||
@ -70,14 +70,20 @@ void change_name_all_players() {
|
||||
}
|
||||
|
||||
void change_name_based_on_mode(usercmd_t* cmd) {
|
||||
if (!CVAR_ON(misc_namechanger)) return;
|
||||
if (!g_settings.namechanger) return;
|
||||
|
||||
if (++change_counter < dz_misc_namechanger_speed->value) {
|
||||
if (++change_counter < g_settings.namechanger_speed) {
|
||||
return;
|
||||
}
|
||||
change_counter = 0;
|
||||
|
||||
switch ((int)dz_misc_namechanger->value) {
|
||||
int mode = 3;
|
||||
|
||||
if (g_settings.namechanger) {
|
||||
mode = 3;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case 1:
|
||||
change_name_teammates();
|
||||
break;
|
||||
@ -93,7 +99,7 @@ void change_name_based_on_mode(usercmd_t* cmd) {
|
||||
}
|
||||
|
||||
void check_namechanger_mode_and_execute(usercmd_t* cmd) {
|
||||
if (!CVAR_ON(misc_namechanger)) return;
|
||||
if (!g_settings.namechanger) return;
|
||||
|
||||
change_name_based_on_mode(cmd);
|
||||
}
|
||||
|
24
src/features/no_recoil.c
Normal file
24
src/features/no_recoil.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include "../include/sdk.h"
|
||||
#include "../include/settings.h"
|
||||
#include "../include/util.h"
|
||||
#include "../include/globals.h"
|
||||
#include <stdio.h> // For printf
|
||||
#include <time.h> // For time
|
||||
|
||||
static time_t last_log_time = 0;
|
||||
|
||||
void no_recoil(usercmd_t* cmd) {
|
||||
if (!g_settings.aimbot_norecoil || !is_alive(localplayer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
time_t current_time = time(NULL);
|
||||
if (current_time - last_log_time >= 5) {
|
||||
printf("Applying anti-recoil: Punch Angles (X: %f, Y: %f)\n", g_punchAngles[0], g_punchAngles[1]);
|
||||
last_log_time = current_time;
|
||||
}
|
||||
|
||||
float anti_recoil_value = 100.0f;
|
||||
cmd->viewangles[0] -= (g_punchAngles[0] * anti_recoil_value);
|
||||
cmd->viewangles[1] -= (g_punchAngles[1] * anti_recoil_value);
|
||||
}
|
8
src/features/no_recoil.h
Normal file
8
src/features/no_recoil.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef NO_RECOIL_H
|
||||
#define NO_RECOIL_H
|
||||
|
||||
#include "../include/sdk.h"
|
||||
|
||||
void aim_no_recoil(usercmd_t* cmd);
|
||||
|
||||
#endif
|
122
src/features/thirdperson.c
Normal file
122
src/features/thirdperson.c
Normal file
@ -0,0 +1,122 @@
|
||||
#include "../include/sdk.h"
|
||||
#include "../include/settings.h"
|
||||
#include "../include/globals.h"
|
||||
#include "../include/util.h"
|
||||
#include "thirdperson.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define TP_MIN_DIST 30.0f
|
||||
#define TP_MAX_DIST 800.0f
|
||||
#define TP_DEFAULT_DIST 150.0f
|
||||
|
||||
#define YAW 1
|
||||
#define PITCH 0
|
||||
#define ROLL 2
|
||||
|
||||
static bool s_initialized = false;
|
||||
static bool s_thirdperson_enabled = false;
|
||||
static vec3_t s_camera_origin = {0, 0, 0};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void thirdperson_init(void) {
|
||||
s_initialized = true;
|
||||
s_thirdperson_enabled = false;
|
||||
i_engine->Con_Printf("Third-person system initialized\n");
|
||||
}
|
||||
|
||||
void thirdperson_toggle(void) {
|
||||
g_settings.thirdperson = !g_settings.thirdperson;
|
||||
s_thirdperson_enabled = g_settings.thirdperson;
|
||||
|
||||
if (s_thirdperson_enabled) {
|
||||
i_engine->Con_Printf("Third-person view enabled (distance: %.1f)\n", g_settings.thirdperson_dist);
|
||||
} else {
|
||||
i_engine->Con_Printf("Third-person view disabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
bool thirdperson_key_event(int keynum, int down) {
|
||||
if (down && (keynum == 'C' || keynum == 'c' || keynum == 99)) {
|
||||
thirdperson_toggle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (down && keynum == g_settings.thirdperson_key &&
|
||||
g_settings.thirdperson_key != 'C' && g_settings.thirdperson_key != 'c') {
|
||||
thirdperson_toggle();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void thirdperson_modify_view(ref_params_t* pparams) {
|
||||
if (!g_settings.thirdperson) {
|
||||
return;
|
||||
}
|
||||
|
||||
float distance = g_settings.thirdperson_dist;
|
||||
|
||||
vec3_t forward, right, up;
|
||||
|
||||
i_engine->pfnAngleVectors(pparams->viewangles, forward, right, up);
|
||||
|
||||
vec3_t camera_offset;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
camera_offset[i] = -forward[i] * distance;
|
||||
}
|
||||
|
||||
vec3_t newOrigin;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
newOrigin[i] = pparams->vieworg[i] + camera_offset[i];
|
||||
}
|
||||
|
||||
vec_copy(s_camera_origin, newOrigin);
|
||||
|
||||
pmtrace_t trace;
|
||||
i_engine->pEventAPI->EV_SetTraceHull(2);
|
||||
i_engine->pEventAPI->EV_PlayerTrace(pparams->vieworg, newOrigin, PM_NORMAL, -1, &trace);
|
||||
|
||||
if (trace.fraction < 1.0) {
|
||||
vec3_t dir;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
dir[i] = newOrigin[i] - pparams->vieworg[i];
|
||||
}
|
||||
|
||||
float len = sqrtf(dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]);
|
||||
if (len > 0) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
dir[i] /= len;
|
||||
}
|
||||
}
|
||||
|
||||
vec3_t collisionPoint;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
collisionPoint[i] = pparams->vieworg[i] + (trace.fraction * distance - 5.0f) * forward[i];
|
||||
}
|
||||
vec_copy(newOrigin, collisionPoint);
|
||||
}
|
||||
|
||||
vec_copy(pparams->vieworg, newOrigin);
|
||||
|
||||
static int debug_count = 0;
|
||||
if (++debug_count % 300 == 0) {
|
||||
i_engine->Con_Printf("Camera position: [%.1f, %.1f, %.1f], distance=%.1f\n",
|
||||
newOrigin[0], newOrigin[1], newOrigin[2], distance);
|
||||
}
|
||||
}
|
||||
|
||||
void thirdperson_update(void) {
|
||||
s_thirdperson_enabled = g_settings.thirdperson;
|
||||
}
|
||||
|
||||
int thirdperson_is_active(void) {
|
||||
return g_settings.thirdperson ? 1 : 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
28
src/features/thirdperson.h
Normal file
28
src/features/thirdperson.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef THIRDPERSON_H_
|
||||
#define THIRDPERSON_H_
|
||||
|
||||
#include "../include/sdk.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void thirdperson_init(void);
|
||||
|
||||
int thirdperson_is_active(void);
|
||||
|
||||
void thirdperson_get_offset(float* offset);
|
||||
|
||||
void thirdperson_update(void);
|
||||
|
||||
void thirdperson_toggle(void);
|
||||
|
||||
bool thirdperson_key_event(int keynum, int down);
|
||||
|
||||
void thirdperson_modify_view(ref_params_t* pparams);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -2,7 +2,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/mman.h> /* PROT_* */
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "include/globals.h"
|
||||
#include "include/sdk.h"
|
||||
@ -11,7 +11,6 @@
|
||||
game_id this_game_id = HL;
|
||||
vec3_t g_punchAngles = { 0, 0, 0 };
|
||||
|
||||
/* Weapon info */
|
||||
float g_flNextAttack = 0.f, g_flNextPrimaryAttack = 0.f;
|
||||
int g_iClip = 0;
|
||||
|
||||
@ -26,13 +25,10 @@ DECL_INTF(playermove_t, pmove);
|
||||
DECL_INTF(engine_studio_api_t, enginestudio);
|
||||
DECL_INTF(StudioModelRenderer_t, studiomodelrenderer);
|
||||
|
||||
/* Game struct with some useful info */
|
||||
game_t* game_info;
|
||||
|
||||
/* Array of extra_player_info's for each player */
|
||||
void* player_extra_info;
|
||||
|
||||
/* Updated in CL_CreateMove hook */
|
||||
cl_entity_t* localplayer = NULL;
|
||||
|
||||
float* scr_fov_value = NULL;
|
||||
@ -40,11 +36,6 @@ float* scr_fov_value = NULL;
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
bool globals_init(void) {
|
||||
/*
|
||||
* Get handler for hw.so
|
||||
* RTLD_LAZY: If the symbol is never referenced, then it is never resolved.
|
||||
* RTLD_NOLOAD: Don't load the shared object.
|
||||
*/
|
||||
hw = dlopen("hw.so", RTLD_LAZY | RTLD_NOLOAD);
|
||||
if (!hw) {
|
||||
printf("goldsource-cheat: globals_init: can't open hw.so\n");
|
||||
@ -57,7 +48,6 @@ bool globals_init(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get symbol addresses using dlsym and the handler we just opened */
|
||||
i_engine = (cl_enginefunc_t*)dlsym(hw, "cl_enginefuncs");
|
||||
i_client = (cl_clientfunc_t*)dlsym(hw, "cl_funcs");
|
||||
i_pmove = *(playermove_t**)dlsym(hw, "pmove");
|
||||
|
464
src/hooks.c
464
src/hooks.c
@ -1,11 +1,43 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "include/settings.h"
|
||||
#include "include/hooks.h"
|
||||
#include "include/sdk.h"
|
||||
#include "include/globals.h"
|
||||
#include "include/util.h"
|
||||
#include "include/cvars.h"
|
||||
#include "include/sdk.h"
|
||||
#include "include/detour.h" /* 8dcc/detour-lib */
|
||||
#include "include/main.h" /* For self_unload() */
|
||||
#include "include/menu.h" /* ImGui menu */
|
||||
#include "features/features.h" /* bhop(), esp(), etc. */
|
||||
#include "include/entityutil.h"
|
||||
#include "include/game_detection.h"
|
||||
#include "features/thirdperson.h"
|
||||
|
||||
// For ImGui context access
|
||||
#define IMGUI_IMPLEMENTATION
|
||||
#include "include/imgui/imgui.h"
|
||||
#include "include/imgui/backends/imgui_impl_opengl2.h"
|
||||
|
||||
// Include for mouse button constants
|
||||
#include "include/sdk/public/keydefs.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <GL/gl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h> // usleep()
|
||||
|
||||
// For DetourFunction and DetourRemove
|
||||
extern void* DetourFunction(void* orig, void* hook);
|
||||
extern bool DetourRemove(void* orig, void* hook);
|
||||
|
||||
// Define BYTE as unsigned char for GL hooks
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* Forward declarations of hook functions */
|
||||
void h_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
||||
void h_CL_Move(void);
|
||||
int h_CL_IsThirdPerson(void);
|
||||
void h_CL_CameraOffset(float* ofs);
|
||||
|
||||
/* Normal VMT hooks */
|
||||
DECL_HOOK(CL_CreateMove);
|
||||
@ -13,63 +45,209 @@ DECL_HOOK(HUD_Redraw);
|
||||
DECL_HOOK(StudioRenderModel);
|
||||
DECL_HOOK(CalcRefdef);
|
||||
DECL_HOOK(HUD_PostRunCmd);
|
||||
key_event_func_t ho_HUD_Key_Event = NULL; // Manually declare the hook
|
||||
|
||||
/* OpenGL hooks */
|
||||
DECL_HOOK(glColor4f);
|
||||
// Manual declarations for third-person hooks
|
||||
int (*ho_CL_IsThirdPerson)(void) = NULL;
|
||||
void (*ho_CL_CameraOffset)(float* ofs) = NULL;
|
||||
|
||||
/* OpenGL hooks - use function pointer as we get actual addresses from game */
|
||||
void (*real_glColor4f)(GLfloat, GLfloat, GLfloat, GLfloat) = NULL;
|
||||
|
||||
/* Detour hooks */
|
||||
static detour_data_t detour_data_clmove;
|
||||
DECL_DETOUR_TYPE(void, clmove_type);
|
||||
DECL_HOOK(CL_Move);
|
||||
|
||||
/* Flag to delay uninject until next frame */
|
||||
static bool g_should_uninject = false;
|
||||
|
||||
/* Mouse position tracking independent from the game engine */
|
||||
static int g_menu_mouse_x = 0;
|
||||
static int g_menu_mouse_y = 0;
|
||||
static bool g_mouse_down[5] = {false, false, false, false, false}; // Tracking mouse buttons
|
||||
|
||||
/* Store last known camera angles for locking */
|
||||
static vec3_t s_locked_view_angles = {0, 0, 0};
|
||||
static bool s_lock_initialized = false;
|
||||
|
||||
/* Forward declarations */
|
||||
static void force_view_angles(void);
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
bool hooks_init(void) {
|
||||
/* Initialize ImGui menu before hooking any rendering functions */
|
||||
if (!menu_init()) {
|
||||
i_engine->Con_Printf("Failed to initialize ImGui menu\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Initialize third-person camera system */
|
||||
thirdperson_init();
|
||||
|
||||
/* VMT hooking */
|
||||
HOOK(i_client, CL_CreateMove);
|
||||
HOOK(i_client, HUD_Redraw);
|
||||
HOOK(i_studiomodelrenderer, StudioRenderModel);
|
||||
HOOK(i_client, CalcRefdef);
|
||||
HOOK(i_client, HUD_PostRunCmd);
|
||||
|
||||
/* Third-person hooks - use direct replacement approach */
|
||||
ho_CL_IsThirdPerson = i_client->CL_IsThirdPerson;
|
||||
i_client->CL_IsThirdPerson = h_CL_IsThirdPerson;
|
||||
i_engine->Con_Printf("CL_IsThirdPerson hook installed at %p -> %p\n",
|
||||
ho_CL_IsThirdPerson, h_CL_IsThirdPerson);
|
||||
|
||||
/* Camera offset hook - critical for third-person view */
|
||||
ho_CL_CameraOffset = i_client->CL_CameraOffset;
|
||||
i_client->CL_CameraOffset = h_CL_CameraOffset;
|
||||
i_engine->Con_Printf("CL_CameraOffset hook installed at %p -> %p\n",
|
||||
ho_CL_CameraOffset, h_CL_CameraOffset);
|
||||
|
||||
/* Manual hook for HUD_Key_Event - avoiding type cast issues */
|
||||
ho_HUD_Key_Event = (key_event_func_t)i_client->HUD_Key_Event;
|
||||
i_client->HUD_Key_Event = (key_event_func_t)h_HUD_Key_Event;
|
||||
|
||||
/* OpenGL hooks */
|
||||
GL_HOOK(glColor4f);
|
||||
|
||||
/* Manual OpenGL hooks - get functions from the game engine's GL context */
|
||||
real_glColor4f = (void (*)(GLfloat, GLfloat, GLfloat, GLfloat))glColor4f;
|
||||
if (real_glColor4f) {
|
||||
void* result = DetourFunction((void*)real_glColor4f, (void*)h_glColor4f);
|
||||
if (!result) {
|
||||
i_engine->Con_Printf("Failed to hook glColor4f\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* We don't hook swap buffers directly anymore - we use HUD_Redraw instead
|
||||
which is more reliable in GoldSrc engine */
|
||||
|
||||
/* Detour hooks */
|
||||
void* clmove_ptr = dlsym(hw, "CL_Move");
|
||||
if (!clmove_ptr)
|
||||
if (!clmove_ptr) {
|
||||
i_engine->Con_Printf("Failed to find CL_Move\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Initialize detour_data_clmove struct for detour, and add the hook */
|
||||
detour_init(&detour_data_clmove, clmove_ptr, (void*)h_CL_Move);
|
||||
detour_add(&detour_data_clmove);
|
||||
if (!detour_add(&detour_data_clmove)) {
|
||||
i_engine->Con_Printf("Failed to hook CL_Move\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Initialize debug info */
|
||||
if (g_settings.thirdperson) {
|
||||
i_engine->Con_Printf("Third-person mode initialized with distance %.1f\n",
|
||||
g_settings.thirdperson_dist);
|
||||
}
|
||||
|
||||
i_engine->Con_Printf("All hooks initialized successfully\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
void hooks_restore(void) {
|
||||
detour_del(&detour_data_clmove);
|
||||
/* First shut down ImGui to prevent any rendering after hooks are removed */
|
||||
menu_shutdown();
|
||||
|
||||
/* Remove CL_Move detour */
|
||||
if (detour_data_clmove.detoured) {
|
||||
detour_del(&detour_data_clmove);
|
||||
}
|
||||
|
||||
/* Remove OpenGL hooks */
|
||||
if (real_glColor4f) {
|
||||
DetourRemove((void*)real_glColor4f, (void*)h_glColor4f);
|
||||
real_glColor4f = NULL;
|
||||
}
|
||||
|
||||
/* Restore VMT hooks */
|
||||
if (i_client) {
|
||||
i_client->CL_CreateMove = ho_CL_CreateMove;
|
||||
i_client->HUD_Redraw = ho_HUD_Redraw;
|
||||
i_client->CalcRefdef = ho_CalcRefdef;
|
||||
i_client->HUD_PostRunCmd = ho_HUD_PostRunCmd;
|
||||
i_client->CL_IsThirdPerson = ho_CL_IsThirdPerson;
|
||||
i_client->CL_CameraOffset = ho_CL_CameraOffset;
|
||||
|
||||
if (ho_HUD_Key_Event) {
|
||||
i_client->HUD_Key_Event = ho_HUD_Key_Event;
|
||||
ho_HUD_Key_Event = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (i_studiomodelrenderer) {
|
||||
i_studiomodelrenderer->StudioRenderModel = ho_StudioRenderModel;
|
||||
}
|
||||
|
||||
i_engine->Con_Printf("All hooks restored\n");
|
||||
}
|
||||
|
||||
void hooks_schedule_uninject(void) {
|
||||
g_should_uninject = true;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
void h_CL_CreateMove(float frametime, usercmd_t* cmd, int active) {
|
||||
ORIGINAL(CL_CreateMove, frametime, cmd, active);
|
||||
|
||||
vec3_t old_angles = cmd->viewangles;
|
||||
/* Check if we should uninject before doing anything else */
|
||||
if (g_should_uninject) {
|
||||
g_should_uninject = false;
|
||||
self_unload();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Declared in globals.c */
|
||||
localplayer = i_engine->GetLocalPlayer();
|
||||
|
||||
bhop(cmd);
|
||||
aimbot(cmd);
|
||||
bullet_tracers(cmd);
|
||||
anti_aim(cmd);
|
||||
check_namechanger_mode_and_execute(cmd);
|
||||
fov_adjust(cmd);
|
||||
// First call original function to let the game set up movement commands
|
||||
ORIGINAL(CL_CreateMove, frametime, cmd, active);
|
||||
|
||||
vec3_t old_angles = cmd->viewangles;
|
||||
|
||||
// Store original movement commands
|
||||
float origForward = cmd->forwardmove;
|
||||
float origSide = cmd->sidemove;
|
||||
float origUp = cmd->upmove;
|
||||
int origButtons = cmd->buttons;
|
||||
|
||||
// If menu is open and movement is not allowed, zero out movement commands
|
||||
if (g_menu_open && !g_settings.menu_allow_movement) {
|
||||
cmd->forwardmove = 0.0f;
|
||||
cmd->sidemove = 0.0f;
|
||||
cmd->upmove = 0.0f;
|
||||
cmd->buttons = 0;
|
||||
|
||||
// If menu is open and movement is not allowed, only force angles
|
||||
if (s_lock_initialized) {
|
||||
vec_copy(cmd->viewangles, s_locked_view_angles);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Menu is closed OR movement is allowed, process all features
|
||||
|
||||
// Restore original movement values if menu is open with movement allowed
|
||||
if (g_menu_open && g_settings.menu_allow_movement) {
|
||||
cmd->forwardmove = origForward;
|
||||
cmd->sidemove = origSide;
|
||||
cmd->upmove = origUp;
|
||||
cmd->buttons = origButtons;
|
||||
}
|
||||
|
||||
// Always process features if movement is allowed or menu is closed
|
||||
bhop(cmd);
|
||||
aimbot(cmd);
|
||||
bullet_tracers(cmd);
|
||||
anti_aim(cmd);
|
||||
check_namechanger_mode_and_execute(cmd);
|
||||
fov_adjust(cmd);
|
||||
|
||||
// If menu is open with movement allowed, still need to lock view angles
|
||||
if (g_menu_open && s_lock_initialized) {
|
||||
vec_copy(cmd->viewangles, s_locked_view_angles);
|
||||
}
|
||||
}
|
||||
|
||||
// Always maintain view angle control and clamp angles
|
||||
correct_movement(cmd, old_angles);
|
||||
vec_clamp(cmd->viewangles);
|
||||
ang_clamp(&cmd->viewangles);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -85,23 +263,53 @@ rgb_t rainbow_color(float time) {
|
||||
}
|
||||
|
||||
int h_HUD_Redraw(float time, int intermission) {
|
||||
// Force set view angles every frame when menu is open
|
||||
force_view_angles();
|
||||
|
||||
// Call original function to let the game draw
|
||||
int ret = ORIGINAL(HUD_Redraw, time, intermission);
|
||||
|
||||
if (dz_watermark->value) {
|
||||
/* Determine the color for the watermark */
|
||||
rgb_t color;
|
||||
|
||||
if (dz_watermark_rainbow->value) {
|
||||
color = rainbow_color(time);
|
||||
} else {
|
||||
color = (rgb_t){ 0, 255, 255 }; // default color
|
||||
}
|
||||
/* Watermark */
|
||||
// Draw watermark if enabled
|
||||
if (g_settings.watermark) {
|
||||
rgb_t color = g_settings.watermark_rainbow ? rainbow_color(time) : (rgb_t){ 0, 255, 255 };
|
||||
engine_draw_text(5, 5, "https://git.deadzone.lol/Wizzard/goldsrc-cheat", color);
|
||||
}
|
||||
|
||||
// Draw ESP
|
||||
esp();
|
||||
|
||||
// Draw custom crosshair
|
||||
custom_crosshair();
|
||||
|
||||
// Handle cursor for ImGui when menu is open
|
||||
if (g_menu_open && g_imgui_context) {
|
||||
// Get screen dimensions
|
||||
SCREENINFO scr_inf;
|
||||
scr_inf.iSize = sizeof(SCREENINFO);
|
||||
i_engine->pfnGetScreenInfo(&scr_inf);
|
||||
|
||||
// Get mouse position from engine
|
||||
int mouse_x, mouse_y;
|
||||
i_engine->GetMousePosition(&mouse_x, &mouse_y);
|
||||
|
||||
// Update ImGui mouse position
|
||||
ImGui::SetCurrentContext(g_imgui_context);
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Update mouse buttons - using our tracked state from key events
|
||||
io.MouseDown[0] = g_mouse_down[0];
|
||||
io.MouseDown[1] = g_mouse_down[1];
|
||||
|
||||
// Update mouse position (clamped to screen)
|
||||
if (mouse_x >= 0 && mouse_x < scr_inf.iWidth &&
|
||||
mouse_y >= 0 && mouse_y < scr_inf.iHeight) {
|
||||
io.MousePos.x = (float)mouse_x;
|
||||
io.MousePos.y = (float)mouse_y;
|
||||
}
|
||||
}
|
||||
|
||||
// Render ImGui menu (if open)
|
||||
menu_render();
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -118,8 +326,14 @@ void h_StudioRenderModel(void* this_ptr) {
|
||||
void h_CalcRefdef(ref_params_t* params) {
|
||||
/* Store punch angles for CreateMove */
|
||||
vec_copy(g_punchAngles, params->punchangle);
|
||||
|
||||
|
||||
/* Call original CalcRefdef */
|
||||
ORIGINAL(CalcRefdef, params);
|
||||
|
||||
/* Apply third-person camera with direct view modification */
|
||||
if (g_settings.thirdperson) {
|
||||
thirdperson_modify_view(params);
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -181,16 +395,186 @@ void h_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
||||
break;
|
||||
}
|
||||
|
||||
ORIGINAL(glColor4f, r, g, b, a);
|
||||
/* This part is executed regardless of the visible_mode.
|
||||
* NOTE: Not calling original breaks chams. */
|
||||
if (real_glColor4f)
|
||||
real_glColor4f(r, g, b, a);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
void h_CL_Move() {
|
||||
if (dz_movement_clmove->value != 0) {
|
||||
for (int i = 0; i < (int)dz_movement_clmove->value; i++)
|
||||
CALL_ORIGINAL(detour_data_clmove, clmove_type);
|
||||
/*
|
||||
* Simple passthrough to thirdperson module
|
||||
*/
|
||||
int h_CL_IsThirdPerson(void) {
|
||||
// We still need this to tell the engine we're in third person view
|
||||
return thirdperson_is_active();
|
||||
}
|
||||
|
||||
/*
|
||||
* This isn't used anymore - our direct camera control in CalcRefdef handles everything
|
||||
*/
|
||||
void h_CL_CameraOffset(float* ofs) {
|
||||
// Not used by our new implementation
|
||||
ofs[0] = ofs[1] = ofs[2] = 0.0f;
|
||||
}
|
||||
|
||||
// Function to handle CL_Move
|
||||
void h_CL_Move(void)
|
||||
{
|
||||
// Get original function address safely
|
||||
void (*original_func)(void) = NULL;
|
||||
if (detour_data_clmove.detoured) {
|
||||
detour_del(&detour_data_clmove);
|
||||
original_func = (void (*)(void))detour_data_clmove.orig;
|
||||
}
|
||||
|
||||
// Call original function if we have it
|
||||
if (original_func) {
|
||||
original_func();
|
||||
}
|
||||
|
||||
// Update third-person camera every frame
|
||||
thirdperson_update();
|
||||
|
||||
// Restore the detour
|
||||
if (detour_data_clmove.orig) {
|
||||
detour_add(&detour_data_clmove);
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
int h_HUD_Key_Event(int down, int keynum, const char* pszCurrentBinding) {
|
||||
// Debug output but only for specific keys to avoid spam
|
||||
if (keynum == 'C' || keynum == g_settings.thirdperson_key || keynum == K_INS) {
|
||||
i_engine->Con_Printf("Key event: down=%d, keynum=%d, binding=%s\n",
|
||||
down, keynum, pszCurrentBinding ? pszCurrentBinding : "none");
|
||||
}
|
||||
|
||||
// Check if thirdperson feature wants to handle this key
|
||||
if (thirdperson_key_event(down, keynum)) {
|
||||
return 0; // The key was handled by thirdperson
|
||||
}
|
||||
|
||||
// Toggle menu with Insert key or specific binding
|
||||
if (down && (keynum == K_INS || (pszCurrentBinding && strcmp(pszCurrentBinding, "dz_menu") == 0))) {
|
||||
i_engine->Con_Printf("Menu toggle key detected!\n");
|
||||
menu_key_event(keynum, down);
|
||||
return 0; // Block this key from reaching the game
|
||||
}
|
||||
|
||||
CALL_ORIGINAL(detour_data_clmove, clmove_type);
|
||||
// ImGui gets priority on all input when menu is open
|
||||
if (g_menu_open) {
|
||||
// For mouse buttons, update our own tracking to help ImGui
|
||||
if (keynum == K_MOUSE1 || keynum == K_MOUSE2) {
|
||||
if (keynum == K_MOUSE1)
|
||||
g_mouse_down[0] = down ? true : false;
|
||||
else if (keynum == K_MOUSE2)
|
||||
g_mouse_down[1] = down ? true : false;
|
||||
|
||||
return 0; // Block mouse buttons from game
|
||||
}
|
||||
|
||||
// Let ESC pass through to the game to close console/etc.
|
||||
if (keynum == K_ESCAPE && down) {
|
||||
if (ho_HUD_Key_Event)
|
||||
return ho_HUD_Key_Event(down, keynum, pszCurrentBinding);
|
||||
}
|
||||
|
||||
// Allow WASD movement keys if the setting is enabled
|
||||
if (g_settings.menu_allow_movement) {
|
||||
// Check for movement key bindings instead of specific keys
|
||||
if (pszCurrentBinding && (
|
||||
strstr(pszCurrentBinding, "+forward") ||
|
||||
strstr(pszCurrentBinding, "+back") ||
|
||||
strstr(pszCurrentBinding, "+moveleft") ||
|
||||
strstr(pszCurrentBinding, "+moveright") ||
|
||||
strstr(pszCurrentBinding, "+jump") ||
|
||||
strstr(pszCurrentBinding, "+duck") ||
|
||||
strstr(pszCurrentBinding, "+speed"))) {
|
||||
|
||||
i_engine->Con_Printf("Passing movement key to game: %s\n", pszCurrentBinding);
|
||||
if (ho_HUD_Key_Event)
|
||||
return ho_HUD_Key_Event(down, keynum, pszCurrentBinding);
|
||||
}
|
||||
|
||||
// Also allow WASD keys directly
|
||||
if (keynum == 'W' || keynum == 'A' || keynum == 'S' || keynum == 'D' ||
|
||||
keynum == ' ' || // Space for jump
|
||||
keynum == K_CTRL || // Crouch
|
||||
keynum == K_SHIFT) { // Walk
|
||||
|
||||
i_engine->Con_Printf("Passing direct movement key to game: %d\n", keynum);
|
||||
if (ho_HUD_Key_Event)
|
||||
return ho_HUD_Key_Event(down, keynum, pszCurrentBinding);
|
||||
}
|
||||
}
|
||||
|
||||
// Block all other keys from reaching the game
|
||||
return 0;
|
||||
}
|
||||
|
||||
// When menu is closed, let all keys pass to the game
|
||||
if (ho_HUD_Key_Event) {
|
||||
return ho_HUD_Key_Event(down, keynum, pszCurrentBinding);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
// Force set view angles through the engine when menu is open
|
||||
static void force_view_angles(void) {
|
||||
// Only do anything when menu is open/closed state changes
|
||||
static bool s_was_menu_open = false;
|
||||
|
||||
// Get the current time for smoother transitions
|
||||
float current_time = i_engine->GetClientTime();
|
||||
static float s_menu_close_time = 0.0f;
|
||||
static bool s_is_restoring = false;
|
||||
|
||||
// Handle menu state changes
|
||||
if (g_menu_open != s_was_menu_open) {
|
||||
// Menu state changed
|
||||
if (g_menu_open) {
|
||||
// Menu just opened - store current view angles
|
||||
i_engine->GetViewAngles(s_locked_view_angles);
|
||||
s_lock_initialized = true;
|
||||
i_engine->Con_Printf("Stored view angles: %.1f %.1f %.1f\n",
|
||||
s_locked_view_angles[0], s_locked_view_angles[1], s_locked_view_angles[2]);
|
||||
s_is_restoring = false;
|
||||
} else {
|
||||
// Menu just closed - set up restoration timing
|
||||
s_menu_close_time = current_time;
|
||||
s_is_restoring = true;
|
||||
|
||||
// Immediately restore angles
|
||||
if (s_lock_initialized) {
|
||||
i_engine->SetViewAngles(s_locked_view_angles);
|
||||
i_engine->Con_Printf("Restored view angles: %.1f %.1f %.1f\n",
|
||||
s_locked_view_angles[0], s_locked_view_angles[1], s_locked_view_angles[2]);
|
||||
}
|
||||
}
|
||||
|
||||
s_was_menu_open = g_menu_open;
|
||||
}
|
||||
|
||||
// When menu is open, continuously force the locked view angles
|
||||
if (g_menu_open && s_lock_initialized) {
|
||||
// Force the engine angles to match our locked angles
|
||||
i_engine->SetViewAngles(s_locked_view_angles);
|
||||
}
|
||||
|
||||
// Continue restoring angles for a short time after menu close to prevent flicker
|
||||
if (!g_menu_open && s_is_restoring) {
|
||||
if (current_time - s_menu_close_time < 0.2f) {
|
||||
// Still in restoration period, keep forcing angles
|
||||
i_engine->SetViewAngles(s_locked_view_angles);
|
||||
} else {
|
||||
// Done restoring
|
||||
s_is_restoring = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
|
||||
#ifndef CVARS_H_
|
||||
#define CVARS_H_
|
||||
|
||||
#include "sdk.h"
|
||||
#include "globals.h"
|
||||
|
||||
#define CVAR_PREFIX "dz_"
|
||||
#define CVAR_HACK_ID 0x4000 /* (1<<14) One that is not in use by the game */
|
||||
|
||||
/*
|
||||
* DECL_CVAR: Declares cvar variable in source file.
|
||||
* DECL_CVAR_EXTERN: Same but for headers.
|
||||
* REGISTER_CVAR: Create the cvar, return cvar_t*
|
||||
* CVAR_ON: Returns true if the cvar is non-zero
|
||||
*
|
||||
* prefix | meaning
|
||||
* -------+-------------------------------
|
||||
* dz_* | cvar variable
|
||||
*/
|
||||
#define DECL_CVAR(name) cvar_t* dz_##name = NULL;
|
||||
|
||||
#define DECL_CVAR_EXTERN(name) extern cvar_t* dz_##name;
|
||||
|
||||
#define REGISTER_CVAR(name, value) \
|
||||
dz_##name = \
|
||||
i_engine->pfnRegisterVariable(CVAR_PREFIX #name, #value, CVAR_HACK_ID);
|
||||
|
||||
#define CVAR_ON(name) (dz_##name->value != 0.0f)
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
DECL_CVAR_EXTERN(movement_bhop);
|
||||
DECL_CVAR_EXTERN(movement_autostrafe);
|
||||
DECL_CVAR_EXTERN(aim_aimbot);
|
||||
DECL_CVAR_EXTERN(aim_autoshoot);
|
||||
DECL_CVAR_EXTERN(visuals_esp);
|
||||
DECL_CVAR_EXTERN(visuals_chams);
|
||||
DECL_CVAR_EXTERN(visuals_crosshair);
|
||||
DECL_CVAR_EXTERN(visuals_tracers);
|
||||
DECL_CVAR_EXTERN(movement_clmove);
|
||||
DECL_CVAR_EXTERN(watermark);
|
||||
DECL_CVAR_EXTERN(watermark_rainbow);
|
||||
DECL_CVAR_EXTERN(aim_aimbot_silent);
|
||||
DECL_CVAR_EXTERN(visuals_friendly);
|
||||
DECL_CVAR_EXTERN(movement_antiaim);
|
||||
DECL_CVAR_EXTERN(movement_antiaim_view);
|
||||
DECL_CVAR_EXTERN(movement_fakeduck);
|
||||
DECL_CVAR_EXTERN(misc_namechanger)
|
||||
DECL_CVAR_EXTERN(misc_namechanger_speed)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
bool cvars_init(void);
|
||||
|
||||
#endif /* CVARS_H_ */
|
14
src/include/entityutil.h
Normal file
14
src/include/entityutil.h
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
#ifndef ENTITY_H_
|
||||
#define ENTITY_H_ 1
|
||||
|
||||
#include "sdk.h"
|
||||
|
||||
cl_entity_t* get_player(int ent_idx);
|
||||
bool is_alive(cl_entity_t* ent);
|
||||
bool valid_player(cl_entity_t* ent);
|
||||
bool is_friend(cl_entity_t* ent);
|
||||
bool can_shoot(void);
|
||||
char* get_name(int ent_idx);
|
||||
|
||||
#endif /* ENTITY_H_ */
|
@ -1,4 +1,3 @@
|
||||
|
||||
#ifndef HOOKS_H_
|
||||
#define HOOKS_H_
|
||||
|
||||
@ -8,6 +7,12 @@
|
||||
|
||||
#include <dlfcn.h> /* dlsym */
|
||||
#include <GL/gl.h> /* GLFloat */
|
||||
#include <stdint.h>
|
||||
|
||||
typedef void (*hook_func_t)(void);
|
||||
|
||||
typedef int (*key_event_func_t)(int down, int keynum, const char* pszCurrentBinding);
|
||||
|
||||
/*
|
||||
* Table of prefixes:
|
||||
* prefix | meaning
|
||||
@ -51,18 +56,15 @@
|
||||
* GL_HOOK: Hooks a OpenGL function. Example:
|
||||
*
|
||||
* GL_HOOK(glColor4f);
|
||||
* void** hp_glColor4f = (void**)dlsym(hw, "qglColor4f"); // Ptr
|
||||
* ho_glColor4f = (glColor4f_t)(*hp_glColor4f); // Original from ptr
|
||||
* *hp_glColor4f = (void*)h_glColor4f; // Set ptr to our func
|
||||
|
||||
* Note: ho_glColor4f and h_glColor4f sould be declared with DECL_HOOK_EXTERN
|
||||
*
|
||||
* Will store the original function in o_glColor4f and set the function to
|
||||
* h_glColor4f (which must be defined)
|
||||
*
|
||||
* GL_UNHOOK: Restores a OpenGL hook created by GL_HOOK. Example:
|
||||
*
|
||||
* GL_UNHOOK(glColor4f);
|
||||
* void** hp_glColor4f = (void**)dlsym(hw, "qglColor4f"); // Ptr
|
||||
* *hp_glColor4f = (void*)ho_glColor4f; // Set to original
|
||||
*
|
||||
* Will restore the original function from o_glColor4f to the original pointer.
|
||||
*/
|
||||
#define DECL_HOOK_EXTERN(type, name, ...) \
|
||||
typedef type (*name##_t)(__VA_ARGS__); \
|
||||
@ -77,19 +79,27 @@
|
||||
|
||||
#define ORIGINAL(name, ...) ho_##name(__VA_ARGS__);
|
||||
|
||||
#define GL_HOOK(name) \
|
||||
void** hp_##name = (void**)dlsym(hw, "q" #name); \
|
||||
ho_##name = (name##_t)(*hp_##name); \
|
||||
*hp_##name = (void*)h_##name;
|
||||
#define GL_HOOK(ret_type, name, ...) \
|
||||
typedef ret_type (*name##_t)(__VA_ARGS__); \
|
||||
name##_t h_##name; \
|
||||
name##_t o_##name;
|
||||
|
||||
#define GL_UNHOOK(name) \
|
||||
void** hp_##name = (void**)dlsym(hw, "q" #name); \
|
||||
*hp_##name = (void*)ho_##name;
|
||||
#define GL_UNHOOK(name) \
|
||||
o_##name = h_##name;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* For GL hooking */
|
||||
typedef void (*glColor4f_t)(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
||||
typedef void* (*wglSwapBuffers_t)(void*);
|
||||
|
||||
bool hooks_init(void);
|
||||
void hooks_restore(void);
|
||||
/* OpenGL hooks */
|
||||
extern void h_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
||||
extern void* o_glColor4f;
|
||||
|
||||
extern wglSwapBuffers_t o_wglSwapBuffers;
|
||||
|
||||
/* HUD_Key_Event hook */
|
||||
extern int h_HUD_Key_Event(int down, int keynum, const char* pszCurrentBinding);
|
||||
extern key_event_func_t ho_HUD_Key_Event;
|
||||
|
||||
/* VMT hooks */
|
||||
DECL_HOOK_EXTERN(void, CL_CreateMove, float, usercmd_t*, int);
|
||||
@ -100,10 +110,16 @@ DECL_HOOK_EXTERN(void, HUD_PostRunCmd, struct local_state_s*,
|
||||
struct local_state_s*, struct usercmd_s*, int, double,
|
||||
unsigned int);
|
||||
|
||||
/* OpenGL hooks */
|
||||
DECL_HOOK_EXTERN(void, glColor4f, GLfloat, GLfloat, GLfloat, GLfloat);
|
||||
|
||||
/* Detour hooks */
|
||||
DECL_HOOK_EXTERN(void, CL_Move);
|
||||
|
||||
/* Detour for CL_Move */
|
||||
#define ORIGINAL_DETOUR(type) ((type)detour_get_original(&detour_data_clmove))()
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
bool hooks_init(void);
|
||||
void hooks_restore(void);
|
||||
void hooks_schedule_uninject(void);
|
||||
|
||||
#endif /* HOOKS_H_ */
|
||||
|
321
src/include/imgui/backends/imgui_impl_opengl2.cpp
Normal file
321
src/include/imgui/backends/imgui_impl_opengl2.cpp
Normal file
@ -0,0 +1,321 @@
|
||||
// dear imgui: Renderer Backend for OpenGL2 (legacy OpenGL, fixed pipeline)
|
||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// Missing features or Issues:
|
||||
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
|
||||
// **Prefer using the code in imgui_impl_opengl3.cpp**
|
||||
// This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read.
|
||||
// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more
|
||||
// complicated, will require your code to reset every single OpenGL attributes to their initial state, and might
|
||||
// confuse your GPU driver.
|
||||
// The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API.
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-10-07: OpenGL: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-06-28: OpenGL: ImGui_ImplOpenGL2_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL2_DestroyFontsTexture(). (#7748)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-12-08: OpenGL: Fixed mishandling of the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-01-03: OpenGL: Backup, setup and restore GL_SHADE_MODEL state, disable GL_STENCIL_TEST and disable GL_NORMAL_ARRAY client state to increase compatibility with legacy OpenGL applications.
|
||||
// 2020-01-23: OpenGL: Backup, setup and restore GL_TEXTURE_ENV to increase compatibility with legacy OpenGL applications.
|
||||
// 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||
// 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
|
||||
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
|
||||
// 2018-08-03: OpenGL: Disabling/restoring GL_LIGHTING and GL_COLOR_MATERIAL to increase compatibility with legacy OpenGL applications.
|
||||
// 2018-06-08: Misc: Extracted imgui_impl_opengl2.cpp/.h away from the old combined GLFW/SDL+OpenGL2 examples.
|
||||
// 2018-06-08: OpenGL: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
|
||||
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplOpenGL2_RenderDrawData() in the .h file so you can call it yourself.
|
||||
// 2017-09-01: OpenGL: Save and restore current polygon mode.
|
||||
// 2016-09-10: OpenGL: Uploading font texture as RGBA32 to increase compatibility with users shaders (not ideal).
|
||||
// 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_opengl2.h"
|
||||
#include <stdint.h> // intptr_t
|
||||
|
||||
// Clang/GCC warnings with -Weverything
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used
|
||||
#pragma clang diagnostic ignored "-Wnonportable-system-include-path"
|
||||
#endif
|
||||
|
||||
// Include OpenGL header (without an OpenGL loader) requires a bit of fiddling
|
||||
#if defined(_WIN32) && !defined(APIENTRY)
|
||||
#define APIENTRY __stdcall // It is customary to use APIENTRY for OpenGL function pointer declarations on all platforms. Additionally, the Windows OpenGL header needs APIENTRY.
|
||||
#endif
|
||||
#if defined(_WIN32) && !defined(WINGDIAPI)
|
||||
#define WINGDIAPI __declspec(dllimport) // Some Windows OpenGL headers need this
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
#define GL_SILENCE_DEPRECATION
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
// [Debugging]
|
||||
//#define IMGUI_IMPL_OPENGL_DEBUG
|
||||
#ifdef IMGUI_IMPL_OPENGL_DEBUG
|
||||
#include <stdio.h>
|
||||
#define GL_CALL(_CALL) do { _CALL; GLenum gl_err = glGetError(); if (gl_err != 0) fprintf(stderr, "GL error 0x%x returned from '%s'.\n", gl_err, #_CALL); } while (0) // Call with error check
|
||||
#else
|
||||
#define GL_CALL(_CALL) _CALL // Call without error check
|
||||
#endif
|
||||
|
||||
// OpenGL data
|
||||
struct ImGui_ImplOpenGL2_Data
|
||||
{
|
||||
GLuint FontTexture;
|
||||
|
||||
ImGui_ImplOpenGL2_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
// Functions
|
||||
bool ImGui_ImplOpenGL2_Init()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplOpenGL2_Data* bd = IM_NEW(ImGui_ImplOpenGL2_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_opengl2";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL2_Shutdown()
|
||||
{
|
||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL2_NewFrame()
|
||||
{
|
||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplOpenGL2_Init()?");
|
||||
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplOpenGL2_CreateDeviceObjects();
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplOpenGL2_CreateFontsTexture();
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height)
|
||||
{
|
||||
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill.
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
//glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // In order to composite our output buffer we need to preserve alpha
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
|
||||
// you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below.
|
||||
// (DO NOT MODIFY THIS FILE! Add the code in your calling function)
|
||||
// GLint last_program;
|
||||
// glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
|
||||
// glUseProgram(0);
|
||||
// ImGui_ImplOpenGL2_RenderDrawData(...);
|
||||
// glUseProgram(last_program)
|
||||
// There are potentially many more states you could need to clear/setup that we can't access from default headers.
|
||||
// e.g. glBindBuffer(GL_ARRAY_BUFFER, 0), glDisable(GL_TEXTURE_CUBE_MAP).
|
||||
|
||||
// Setup viewport, orthographic projection matrix
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
GL_CALL(glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height));
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(draw_data->DisplayPos.x, draw_data->DisplayPos.x + draw_data->DisplaySize.x, draw_data->DisplayPos.y + draw_data->DisplaySize.y, draw_data->DisplayPos.y, -1.0f, +1.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
// OpenGL2 Render function.
|
||||
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly.
|
||||
// This is in order to be able to run within an OpenGL engine that doesn't do so.
|
||||
void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
if (fb_width == 0 || fb_height == 0)
|
||||
return;
|
||||
|
||||
// Backup GL state
|
||||
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
||||
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
|
||||
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
|
||||
GLint last_shade_model; glGetIntegerv(GL_SHADE_MODEL, &last_shade_model);
|
||||
GLint last_tex_env_mode; glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &last_tex_env_mode);
|
||||
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
|
||||
|
||||
// Setup desired GL state
|
||||
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
|
||||
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, pos)));
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, uv)));
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, col)));
|
||||
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
|
||||
else
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply scissor/clipping rectangle (Y is inverted in OpenGL)
|
||||
glScissor((int)clip_min.x, (int)((float)fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y));
|
||||
|
||||
// Bind texture, Draw
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID());
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer + pcmd->IdxOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Restore modified GL state
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]);
|
||||
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
|
||||
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
|
||||
glShadeModel(last_shade_model);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_tex_env_mode);
|
||||
}
|
||||
|
||||
bool ImGui_ImplOpenGL2_CreateFontsTexture()
|
||||
{
|
||||
// Build texture atlas
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
|
||||
|
||||
// Upload texture to graphics system
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
GLint last_texture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||
glGenTextures(1, &bd->FontTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, bd->FontTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
|
||||
|
||||
// Restore state
|
||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL2_DestroyFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
||||
if (bd->FontTexture)
|
||||
{
|
||||
glDeleteTextures(1, &bd->FontTexture);
|
||||
io.Fonts->SetTexID(0);
|
||||
bd->FontTexture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplOpenGL2_CreateDeviceObjects()
|
||||
{
|
||||
return ImGui_ImplOpenGL2_CreateFontsTexture();
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL2_DestroyDeviceObjects()
|
||||
{
|
||||
ImGui_ImplOpenGL2_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
41
src/include/imgui/backends/imgui_impl_opengl2.h
Normal file
41
src/include/imgui/backends/imgui_impl_opengl2.h
Normal file
@ -0,0 +1,41 @@
|
||||
// dear imgui: Renderer Backend for OpenGL2 (legacy OpenGL, fixed pipeline)
|
||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// Missing features or Issues:
|
||||
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
|
||||
// **Prefer using the code in imgui_impl_opengl3.cpp**
|
||||
// This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read.
|
||||
// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more
|
||||
// complicated, will require your code to reset every single OpenGL attributes to their initial state, and might
|
||||
// confuse your GPU driver.
|
||||
// The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API.
|
||||
|
||||
#pragma once
|
||||
#include "../imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_Init();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data);
|
||||
|
||||
// Called by Init/NewFrame/Shutdown
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyFontsTexture();
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
141
src/include/imgui/imconfig.h
Normal file
141
src/include/imgui/imconfig.h
Normal file
@ -0,0 +1,141 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// DEAR IMGUI COMPILE-TIME OPTIONS
|
||||
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
|
||||
// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
|
||||
//-----------------------------------------------------------------------------
|
||||
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
|
||||
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
||||
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
||||
// Call IMGUI_CHECKVERSION() from your .cpp file to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//---- Define assertion handler. Defaults to calling assert().
|
||||
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
||||
|
||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
|
||||
// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
|
||||
// - Windows DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
|
||||
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
|
||||
//#define IMGUI_API __declspec(dllexport) // MSVC Windows: DLL export
|
||||
//#define IMGUI_API __declspec(dllimport) // MSVC Windows: DLL import
|
||||
//#define IMGUI_API __attribute__((visibility("default"))) // GCC/Clang: override visibility when set is hidden
|
||||
|
||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
|
||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
|
||||
//---- Disable all of Dear ImGui or don't implement standard windows/tools.
|
||||
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
|
||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
||||
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty.
|
||||
//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty.
|
||||
|
||||
//---- Don't implement some functions to reduce linkage requirements.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
|
||||
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
|
||||
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
||||
//#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS // Don't implement default platform_io.Platform_OpenInShellFn() handler (Win32: ShellExecute(), require shell32.lib/.a, Mac/Linux: use system("")).
|
||||
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
||||
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
||||
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded font (ProggyClean.ttf), remove ~9.5 KB from output binary. AddFontDefault() will assert.
|
||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||
|
||||
//---- Enable Test Engine / Automation features.
|
||||
//#define IMGUI_ENABLE_TEST_ENGINE // Enable imgui_test_engine hooks. Generally set automatically by include "imgui_te_config.h", see Test Engine for details.
|
||||
|
||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||
// May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included.
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
|
||||
|
||||
//---- Pack vertex colors as BGRA8 instead of RGBA8 (to avoid converting from one to another). Need dedicated backend support.
|
||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
|
||||
//---- Use legacy CRC32-adler tables (used before 1.91.6), in order to preserve old .ini data that you cannot afford to invalidate.
|
||||
//#define IMGUI_USE_LEGACY_CRC32_ADLER
|
||||
|
||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||
//#define IMGUI_USE_WCHAR32
|
||||
|
||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
||||
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
||||
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined.
|
||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined.
|
||||
|
||||
//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
||||
// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h.
|
||||
//#define IMGUI_USE_STB_SPRINTF
|
||||
|
||||
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
||||
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
||||
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
||||
//#define IMGUI_ENABLE_FREETYPE
|
||||
|
||||
//---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT)
|
||||
// Only works in combination with IMGUI_ENABLE_FREETYPE.
|
||||
// - plutosvg is currently easier to install, as e.g. it is part of vcpkg. It will support more fonts and may load them faster. See misc/freetype/README for instructions.
|
||||
// - Both require headers to be available in the include path + program to be linked with the library code (not provided).
|
||||
// - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
|
||||
//#define IMGUI_ENABLE_FREETYPE_PLUTOSVG
|
||||
//#define IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
|
||||
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
||||
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
|
||||
//#define IMGUI_ENABLE_STB_TRUETYPE
|
||||
|
||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
//---- ...Or use Dear ImGui's own very basic math operators.
|
||||
//#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
|
||||
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
|
||||
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
|
||||
//#define ImDrawIdx unsigned int
|
||||
|
||||
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
|
||||
//struct ImDrawList;
|
||||
//struct ImDrawCmd;
|
||||
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
||||
//#define ImDrawCallback MyImDrawCallback
|
||||
|
||||
//---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase)
|
||||
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
||||
//#define IM_DEBUG_BREAK __debugbreak()
|
||||
|
||||
//---- Debug Tools: Enable slower asserts
|
||||
//#define IMGUI_DEBUG_PARANOID
|
||||
|
||||
//---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files)
|
||||
/*
|
||||
namespace ImGui
|
||||
{
|
||||
void MyFunction(const char* name, MyMatrix44* mtx);
|
||||
}
|
||||
*/
|
17080
src/include/imgui/imgui.cpp
Normal file
17080
src/include/imgui/imgui.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3777
src/include/imgui/imgui.h
Normal file
3777
src/include/imgui/imgui.h
Normal file
File diff suppressed because it is too large
Load Diff
4831
src/include/imgui/imgui_draw.cpp
Normal file
4831
src/include/imgui/imgui_draw.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3638
src/include/imgui/imgui_internal.h
Normal file
3638
src/include/imgui/imgui_internal.h
Normal file
File diff suppressed because it is too large
Load Diff
4525
src/include/imgui/imgui_tables.cpp
Normal file
4525
src/include/imgui/imgui_tables.cpp
Normal file
File diff suppressed because it is too large
Load Diff
10452
src/include/imgui/imgui_widgets.cpp
Normal file
10452
src/include/imgui/imgui_widgets.cpp
Normal file
File diff suppressed because it is too large
Load Diff
627
src/include/imgui/imstb_rectpack.h
Normal file
627
src/include/imgui/imstb_rectpack.h
Normal file
@ -0,0 +1,627 @@
|
||||
// [DEAR IMGUI]
|
||||
// This is a slightly modified version of stb_rect_pack.h 1.01.
|
||||
// Grep for [DEAR IMGUI] to find the changes.
|
||||
//
|
||||
// stb_rect_pack.h - v1.01 - public domain - rectangle packing
|
||||
// Sean Barrett 2014
|
||||
//
|
||||
// Useful for e.g. packing rectangular textures into an atlas.
|
||||
// Does not do rotation.
|
||||
//
|
||||
// Before #including,
|
||||
//
|
||||
// #define STB_RECT_PACK_IMPLEMENTATION
|
||||
//
|
||||
// in the file that you want to have the implementation.
|
||||
//
|
||||
// Not necessarily the awesomest packing method, but better than
|
||||
// the totally naive one in stb_truetype (which is primarily what
|
||||
// this is meant to replace).
|
||||
//
|
||||
// Has only had a few tests run, may have issues.
|
||||
//
|
||||
// More docs to come.
|
||||
//
|
||||
// No memory allocations; uses qsort() and assert() from stdlib.
|
||||
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
|
||||
//
|
||||
// This library currently uses the Skyline Bottom-Left algorithm.
|
||||
//
|
||||
// Please note: better rectangle packers are welcome! Please
|
||||
// implement them to the same API, but with a different init
|
||||
// function.
|
||||
//
|
||||
// Credits
|
||||
//
|
||||
// Library
|
||||
// Sean Barrett
|
||||
// Minor features
|
||||
// Martins Mozeiko
|
||||
// github:IntellectualKitty
|
||||
//
|
||||
// Bugfixes / warning fixes
|
||||
// Jeremy Jaussaud
|
||||
// Fabian Giesen
|
||||
//
|
||||
// Version history:
|
||||
//
|
||||
// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
|
||||
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
|
||||
// 0.99 (2019-02-07) warning fixes
|
||||
// 0.11 (2017-03-03) return packing success/fail result
|
||||
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
|
||||
// 0.09 (2016-08-27) fix compiler warnings
|
||||
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
|
||||
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
|
||||
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
|
||||
// 0.05: added STBRP_ASSERT to allow replacing assert
|
||||
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
||||
// 0.01: initial release
|
||||
//
|
||||
// LICENSE
|
||||
//
|
||||
// See end of file for license information.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INCLUDE SECTION
|
||||
//
|
||||
|
||||
#ifndef STB_INCLUDE_STB_RECT_PACK_H
|
||||
#define STB_INCLUDE_STB_RECT_PACK_H
|
||||
|
||||
#define STB_RECT_PACK_VERSION 1
|
||||
|
||||
#ifdef STBRP_STATIC
|
||||
#define STBRP_DEF static
|
||||
#else
|
||||
#define STBRP_DEF extern
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct stbrp_context stbrp_context;
|
||||
typedef struct stbrp_node stbrp_node;
|
||||
typedef struct stbrp_rect stbrp_rect;
|
||||
|
||||
typedef int stbrp_coord;
|
||||
|
||||
#define STBRP__MAXVAL 0x7fffffff
|
||||
// Mostly for internal use, but this is the maximum supported coordinate value.
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
||||
// Assign packed locations to rectangles. The rectangles are of type
|
||||
// 'stbrp_rect' defined below, stored in the array 'rects', and there
|
||||
// are 'num_rects' many of them.
|
||||
//
|
||||
// Rectangles which are successfully packed have the 'was_packed' flag
|
||||
// set to a non-zero value and 'x' and 'y' store the minimum location
|
||||
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
|
||||
// if you imagine y increasing downwards). Rectangles which do not fit
|
||||
// have the 'was_packed' flag set to 0.
|
||||
//
|
||||
// You should not try to access the 'rects' array from another thread
|
||||
// while this function is running, as the function temporarily reorders
|
||||
// the array while it executes.
|
||||
//
|
||||
// To pack into another rectangle, you need to call stbrp_init_target
|
||||
// again. To continue packing into the same rectangle, you can call
|
||||
// this function again. Calling this multiple times with multiple rect
|
||||
// arrays will probably produce worse packing results than calling it
|
||||
// a single time with the full rectangle array, but the option is
|
||||
// available.
|
||||
//
|
||||
// The function returns 1 if all of the rectangles were successfully
|
||||
// packed and 0 otherwise.
|
||||
|
||||
struct stbrp_rect
|
||||
{
|
||||
// reserved for your use:
|
||||
int id;
|
||||
|
||||
// input:
|
||||
stbrp_coord w, h;
|
||||
|
||||
// output:
|
||||
stbrp_coord x, y;
|
||||
int was_packed; // non-zero if valid packing
|
||||
|
||||
}; // 16 bytes, nominally
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
|
||||
// Initialize a rectangle packer to:
|
||||
// pack a rectangle that is 'width' by 'height' in dimensions
|
||||
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
|
||||
//
|
||||
// You must call this function every time you start packing into a new target.
|
||||
//
|
||||
// There is no "shutdown" function. The 'nodes' memory must stay valid for
|
||||
// the following stbrp_pack_rects() call (or calls), but can be freed after
|
||||
// the call (or calls) finish.
|
||||
//
|
||||
// Note: to guarantee best results, either:
|
||||
// 1. make sure 'num_nodes' >= 'width'
|
||||
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
|
||||
//
|
||||
// If you don't do either of the above things, widths will be quantized to multiples
|
||||
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
|
||||
//
|
||||
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
|
||||
// may run out of temporary storage and be unable to pack some rectangles.
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
|
||||
// Optionally call this function after init but before doing any packing to
|
||||
// change the handling of the out-of-temp-memory scenario, described above.
|
||||
// If you call init again, this will be reset to the default (false).
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
|
||||
// Optionally select which packing heuristic the library should use. Different
|
||||
// heuristics will produce better/worse results for different data sets.
|
||||
// If you call init again, this will be reset to the default.
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP_HEURISTIC_Skyline_default=0,
|
||||
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
|
||||
STBRP_HEURISTIC_Skyline_BF_sortHeight
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// the details of the following structures don't matter to you, but they must
|
||||
// be visible so you can handle the memory allocations for them
|
||||
|
||||
struct stbrp_node
|
||||
{
|
||||
stbrp_coord x,y;
|
||||
stbrp_node *next;
|
||||
};
|
||||
|
||||
struct stbrp_context
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int align;
|
||||
int init_mode;
|
||||
int heuristic;
|
||||
int num_nodes;
|
||||
stbrp_node *active_head;
|
||||
stbrp_node *free_head;
|
||||
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPLEMENTATION SECTION
|
||||
//
|
||||
|
||||
#ifdef STB_RECT_PACK_IMPLEMENTATION
|
||||
#ifndef STBRP_SORT
|
||||
#include <stdlib.h>
|
||||
#define STBRP_SORT qsort
|
||||
#endif
|
||||
|
||||
#ifndef STBRP_ASSERT
|
||||
#include <assert.h>
|
||||
#define STBRP_ASSERT assert
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define STBRP__NOTUSED(v) (void)(v)
|
||||
#define STBRP__CDECL __cdecl
|
||||
#else
|
||||
#define STBRP__NOTUSED(v) (void)sizeof(v)
|
||||
#define STBRP__CDECL
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP__INIT_skyline = 1
|
||||
};
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
|
||||
{
|
||||
switch (context->init_mode) {
|
||||
case STBRP__INIT_skyline:
|
||||
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
|
||||
context->heuristic = heuristic;
|
||||
break;
|
||||
default:
|
||||
STBRP_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
|
||||
{
|
||||
if (allow_out_of_mem)
|
||||
// if it's ok to run out of memory, then don't bother aligning them;
|
||||
// this gives better packing, but may fail due to OOM (even though
|
||||
// the rectangles easily fit). @TODO a smarter approach would be to only
|
||||
// quantize once we've hit OOM, then we could get rid of this parameter.
|
||||
context->align = 1;
|
||||
else {
|
||||
// if it's not ok to run out of memory, then quantize the widths
|
||||
// so that num_nodes is always enough nodes.
|
||||
//
|
||||
// I.e. num_nodes * align >= width
|
||||
// align >= width / num_nodes
|
||||
// align = ceil(width/num_nodes)
|
||||
|
||||
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < num_nodes-1; ++i)
|
||||
nodes[i].next = &nodes[i+1];
|
||||
nodes[i].next = NULL;
|
||||
context->init_mode = STBRP__INIT_skyline;
|
||||
context->heuristic = STBRP_HEURISTIC_Skyline_default;
|
||||
context->free_head = &nodes[0];
|
||||
context->active_head = &context->extra[0];
|
||||
context->width = width;
|
||||
context->height = height;
|
||||
context->num_nodes = num_nodes;
|
||||
stbrp_setup_allow_out_of_mem(context, 0);
|
||||
|
||||
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
|
||||
context->extra[0].x = 0;
|
||||
context->extra[0].y = 0;
|
||||
context->extra[0].next = &context->extra[1];
|
||||
context->extra[1].x = (stbrp_coord) width;
|
||||
context->extra[1].y = (1<<30);
|
||||
context->extra[1].next = NULL;
|
||||
}
|
||||
|
||||
// find minimum y position if it starts at x1
|
||||
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
|
||||
{
|
||||
stbrp_node *node = first;
|
||||
int x1 = x0 + width;
|
||||
int min_y, visited_width, waste_area;
|
||||
|
||||
STBRP__NOTUSED(c);
|
||||
|
||||
STBRP_ASSERT(first->x <= x0);
|
||||
|
||||
#if 0
|
||||
// skip in case we're past the node
|
||||
while (node->next->x <= x0)
|
||||
++node;
|
||||
#else
|
||||
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
|
||||
#endif
|
||||
|
||||
STBRP_ASSERT(node->x <= x0);
|
||||
|
||||
min_y = 0;
|
||||
waste_area = 0;
|
||||
visited_width = 0;
|
||||
while (node->x < x1) {
|
||||
if (node->y > min_y) {
|
||||
// raise min_y higher.
|
||||
// we've accounted for all waste up to min_y,
|
||||
// but we'll now add more waste for everything we've visted
|
||||
waste_area += visited_width * (node->y - min_y);
|
||||
min_y = node->y;
|
||||
// the first time through, visited_width might be reduced
|
||||
if (node->x < x0)
|
||||
visited_width += node->next->x - x0;
|
||||
else
|
||||
visited_width += node->next->x - node->x;
|
||||
} else {
|
||||
// add waste area
|
||||
int under_width = node->next->x - node->x;
|
||||
if (under_width + visited_width > width)
|
||||
under_width = width - visited_width;
|
||||
waste_area += under_width * (min_y - node->y);
|
||||
visited_width += under_width;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
*pwaste = waste_area;
|
||||
return min_y;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x,y;
|
||||
stbrp_node **prev_link;
|
||||
} stbrp__findresult;
|
||||
|
||||
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
|
||||
{
|
||||
int best_waste = (1<<30), best_x, best_y = (1 << 30);
|
||||
stbrp__findresult fr;
|
||||
stbrp_node **prev, *node, *tail, **best = NULL;
|
||||
|
||||
// align to multiple of c->align
|
||||
width = (width + c->align - 1);
|
||||
width -= width % c->align;
|
||||
STBRP_ASSERT(width % c->align == 0);
|
||||
|
||||
// if it can't possibly fit, bail immediately
|
||||
if (width > c->width || height > c->height) {
|
||||
fr.prev_link = NULL;
|
||||
fr.x = fr.y = 0;
|
||||
return fr;
|
||||
}
|
||||
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
while (node->x + width <= c->width) {
|
||||
int y,waste;
|
||||
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
|
||||
// bottom left
|
||||
if (y < best_y) {
|
||||
best_y = y;
|
||||
best = prev;
|
||||
}
|
||||
} else {
|
||||
// best-fit
|
||||
if (y + height <= c->height) {
|
||||
// can only use it if it first vertically
|
||||
if (y < best_y || (y == best_y && waste < best_waste)) {
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
best_x = (best == NULL) ? 0 : (*best)->x;
|
||||
|
||||
// if doing best-fit (BF), we also have to try aligning right edge to each node position
|
||||
//
|
||||
// e.g, if fitting
|
||||
//
|
||||
// ____________________
|
||||
// |____________________|
|
||||
//
|
||||
// into
|
||||
//
|
||||
// | |
|
||||
// | ____________|
|
||||
// |____________|
|
||||
//
|
||||
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
|
||||
//
|
||||
// This makes BF take about 2x the time
|
||||
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
|
||||
tail = c->active_head;
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
// find first node that's admissible
|
||||
while (tail->x < width)
|
||||
tail = tail->next;
|
||||
while (tail) {
|
||||
int xpos = tail->x - width;
|
||||
int y,waste;
|
||||
STBRP_ASSERT(xpos >= 0);
|
||||
// find the left position that matches this
|
||||
while (node->next->x <= xpos) {
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
|
||||
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
|
||||
if (y + height <= c->height) {
|
||||
if (y <= best_y) {
|
||||
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
||||
best_x = xpos;
|
||||
//STBRP_ASSERT(y <= best_y); [DEAR IMGUI]
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
tail = tail->next;
|
||||
}
|
||||
}
|
||||
|
||||
fr.prev_link = best;
|
||||
fr.x = best_x;
|
||||
fr.y = best_y;
|
||||
return fr;
|
||||
}
|
||||
|
||||
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
|
||||
{
|
||||
// find best position according to heuristic
|
||||
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
|
||||
stbrp_node *node, *cur;
|
||||
|
||||
// bail if:
|
||||
// 1. it failed
|
||||
// 2. the best node doesn't fit (we don't always check this)
|
||||
// 3. we're out of memory
|
||||
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
|
||||
res.prev_link = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
// on success, create new node
|
||||
node = context->free_head;
|
||||
node->x = (stbrp_coord) res.x;
|
||||
node->y = (stbrp_coord) (res.y + height);
|
||||
|
||||
context->free_head = node->next;
|
||||
|
||||
// insert the new node into the right starting point, and
|
||||
// let 'cur' point to the remaining nodes needing to be
|
||||
// stiched back in
|
||||
|
||||
cur = *res.prev_link;
|
||||
if (cur->x < res.x) {
|
||||
// preserve the existing one, so start testing with the next one
|
||||
stbrp_node *next = cur->next;
|
||||
cur->next = node;
|
||||
cur = next;
|
||||
} else {
|
||||
*res.prev_link = node;
|
||||
}
|
||||
|
||||
// from here, traverse cur and free the nodes, until we get to one
|
||||
// that shouldn't be freed
|
||||
while (cur->next && cur->next->x <= res.x + width) {
|
||||
stbrp_node *next = cur->next;
|
||||
// move the current node to the free list
|
||||
cur->next = context->free_head;
|
||||
context->free_head = cur;
|
||||
cur = next;
|
||||
}
|
||||
|
||||
// stitch the list back in
|
||||
node->next = cur;
|
||||
|
||||
if (cur->x < res.x + width)
|
||||
cur->x = (stbrp_coord) (res.x + width);
|
||||
|
||||
#ifdef _DEBUG
|
||||
cur = context->active_head;
|
||||
while (cur->x < context->width) {
|
||||
STBRP_ASSERT(cur->x < cur->next->x);
|
||||
cur = cur->next;
|
||||
}
|
||||
STBRP_ASSERT(cur->next == NULL);
|
||||
|
||||
{
|
||||
int count=0;
|
||||
cur = context->active_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
cur = context->free_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
STBRP_ASSERT(count == context->num_nodes+2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
if (p->h > q->h)
|
||||
return -1;
|
||||
if (p->h < q->h)
|
||||
return 1;
|
||||
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
||||
}
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
||||
{
|
||||
int i, all_rects_packed = 1;
|
||||
|
||||
// we use the 'was_packed' field internally to allow sorting/unsorting
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = i;
|
||||
}
|
||||
|
||||
// sort according to heuristic
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
|
||||
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
if (rects[i].w == 0 || rects[i].h == 0) {
|
||||
rects[i].x = rects[i].y = 0; // empty rect needs no space
|
||||
} else {
|
||||
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
|
||||
if (fr.prev_link) {
|
||||
rects[i].x = (stbrp_coord) fr.x;
|
||||
rects[i].y = (stbrp_coord) fr.y;
|
||||
} else {
|
||||
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unsort
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
|
||||
|
||||
// set was_packed flags and all_rects_packed status
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
|
||||
if (!rects[i].was_packed)
|
||||
all_rects_packed = 0;
|
||||
}
|
||||
|
||||
// return the all_rects_packed status
|
||||
return all_rects_packed;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
1469
src/include/imgui/imstb_textedit.h
Normal file
1469
src/include/imgui/imstb_textedit.h
Normal file
File diff suppressed because it is too large
Load Diff
5085
src/include/imgui/imstb_truetype.h
Normal file
5085
src/include/imgui/imstb_truetype.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,10 @@
|
||||
|
||||
#ifndef MAIN_H_
|
||||
#define MAIN_H_
|
||||
|
||||
void load(void);
|
||||
void unload(void);
|
||||
void self_unload(void);
|
||||
void UNINJECT_CommandHandler(void);
|
||||
void safe_unload_with_debug(void);
|
||||
|
||||
#endif /* MAIN_H_ */
|
||||
|
39
src/include/mathutil.h
Normal file
39
src/include/mathutil.h
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
#ifndef MATHUTIL_H_
|
||||
#define MATHUTIL_H_ 1
|
||||
|
||||
#include "sdk.h"
|
||||
|
||||
/* Vector 2 for 2d points */
|
||||
typedef float vec2_t[2];
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#define DEG2RAD(n) ((n)*M_PI / 180.0f)
|
||||
#define RAD2DEG(n) ((n)*180.0f / M_PI)
|
||||
#define CLAMP(val, min, max) \
|
||||
(((val) > (max)) ? (max) : (((val) < (min)) ? (min) : (val)))
|
||||
|
||||
/* Use indexes so it works for float[] as well as vec3_t */
|
||||
#define vec_copy(dst, src) \
|
||||
do { \
|
||||
dst[0] = src[0]; \
|
||||
dst[1] = src[1]; \
|
||||
dst[2] = src[2]; \
|
||||
} while (0)
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
vec3_t vec3(float x, float y, float z);
|
||||
vec3_t vec_add(vec3_t a, vec3_t b);
|
||||
vec3_t vec_sub(vec3_t a, vec3_t b);
|
||||
bool vec_is_zero(vec3_t v);
|
||||
float vec_len2d(vec3_t v);
|
||||
void ang_clamp(vec3_t* v);
|
||||
void vec_norm(vec3_t* v);
|
||||
float angle_delta_rad(float a, float b);
|
||||
vec3_t vec_to_ang(vec3_t v);
|
||||
vec3_t matrix_3x4_origin(matrix_3x4 m);
|
||||
bool world_to_screen(vec3_t vec, vec2_t screen);
|
||||
|
||||
#endif /* MATHUTIL_H_ */
|
23
src/include/menu.h
Normal file
23
src/include/menu.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "imgui/imgui.h"
|
||||
#include "imgui/backends/imgui_impl_opengl2.h"
|
||||
#include "sdk.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool menu_init(void);
|
||||
void menu_shutdown(void);
|
||||
void menu_render(void);
|
||||
void menu_key_event(int keynum, int down);
|
||||
|
||||
extern bool g_menu_open;
|
||||
extern bool g_imgui_initialized;
|
||||
extern ImGuiContext* g_imgui_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -35,6 +35,38 @@
|
||||
/* engine_studio_api_t */
|
||||
#include "sdk/common/r_studioint.h"
|
||||
|
||||
#define K_TAB 9
|
||||
#define K_ENTER 13
|
||||
#define K_ESCAPE 27
|
||||
#define K_SPACE 32
|
||||
#define K_BACKSPACE 127
|
||||
#define K_UPARROW 128
|
||||
#define K_DOWNARROW 129
|
||||
#define K_LEFTARROW 130
|
||||
#define K_RIGHTARROW 131
|
||||
#define K_ALT 132
|
||||
#define K_CTRL 133
|
||||
#define K_SHIFT 134
|
||||
#define K_F1 135
|
||||
#define K_F2 136
|
||||
#define K_F3 137
|
||||
#define K_F4 138
|
||||
#define K_F5 139
|
||||
#define K_F6 140
|
||||
#define K_F7 141
|
||||
#define K_F8 142
|
||||
#define K_F9 143
|
||||
#define K_F10 144
|
||||
#define K_F11 145
|
||||
#define K_F12 146
|
||||
#define K_INS 147
|
||||
#define K_DEL 148
|
||||
#define K_PGDN 149
|
||||
#define K_PGUP 150
|
||||
#define K_HOME 151
|
||||
#define K_END 152
|
||||
#define K_PAUSE 255
|
||||
|
||||
typedef float matrix_3x4[3][4];
|
||||
typedef matrix_3x4 bone_matrix[128];
|
||||
|
||||
|
82
src/include/settings.h
Normal file
82
src/include/settings.h
Normal file
@ -0,0 +1,82 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
ESP_OFF = 0,
|
||||
ESP_BOX = 1,
|
||||
ESP_NAME = 2,
|
||||
ESP_ALL = 3
|
||||
} esp_mode_t;
|
||||
|
||||
typedef struct {
|
||||
esp_mode_t esp_mode;
|
||||
bool esp_friendly;
|
||||
float fov;
|
||||
bool chams;
|
||||
bool tracers;
|
||||
bool custom_crosshair;
|
||||
bool watermark;
|
||||
bool watermark_rainbow;
|
||||
|
||||
bool aimbot_enabled;
|
||||
float aimbot_fov;
|
||||
float aimbot_smooth;
|
||||
bool aimbot_silent;
|
||||
bool aimbot_autoshoot;
|
||||
bool aimbot_norecoil;
|
||||
bool aimbot_recoil_comp;
|
||||
bool aimbot_friendly_fire;
|
||||
bool aimbot_rage_mode;
|
||||
bool aimbot_team_attack;
|
||||
int aimbot_hitbox;
|
||||
|
||||
bool bhop;
|
||||
bool autostrafe;
|
||||
bool antiaim;
|
||||
bool antiaim_view;
|
||||
bool fakeduck;
|
||||
bool clmove;
|
||||
|
||||
bool namechanger;
|
||||
float namechanger_speed;
|
||||
bool menu_allow_movement;
|
||||
|
||||
bool thirdperson;
|
||||
int thirdperson_key;
|
||||
float thirdperson_dist;
|
||||
} cheat_settings_t;
|
||||
|
||||
extern cheat_settings_t g_settings;
|
||||
|
||||
void settings_init(void);
|
||||
|
||||
void settings_reset(void);
|
||||
|
||||
inline void init_default_settings(void) {
|
||||
memset(&g_settings, 0, sizeof(g_settings));
|
||||
|
||||
g_settings.aimbot_fov = 5.0f;
|
||||
g_settings.aimbot_smooth = 10.0f;
|
||||
g_settings.aimbot_hitbox = 0;
|
||||
|
||||
g_settings.esp_mode = ESP_OFF;
|
||||
g_settings.fov = 90.0f;
|
||||
|
||||
g_settings.namechanger_speed = 5.0f;
|
||||
|
||||
g_settings.thirdperson = false;
|
||||
g_settings.thirdperson_dist = 300.0f;
|
||||
g_settings.thirdperson_key = 'C';
|
||||
|
||||
g_settings.menu_allow_movement = true;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -14,6 +14,13 @@ typedef struct {
|
||||
uint8_t r, g, b;
|
||||
} rgb_t;
|
||||
|
||||
#define ERR(...) \
|
||||
do { \
|
||||
fprintf(stderr, "hl-cheat: %s: ", __func__); \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
fputc('\n', stderr); \
|
||||
} while (0)
|
||||
|
||||
#define DEG2RAD(n) ((n)*M_PI / 180.0f)
|
||||
#define RAD2DEG(n) ((n)*180.0f / M_PI)
|
||||
#define CLAMP(val, min, max) \
|
||||
@ -24,9 +31,11 @@ typedef struct {
|
||||
|
||||
/* Use indexes so it works for float[] as well as vec3_t */
|
||||
#define vec_copy(dst, src) \
|
||||
dst[0] = src[0]; \
|
||||
dst[1] = src[1]; \
|
||||
dst[2] = src[2];
|
||||
do { \
|
||||
dst[0] = src[0]; \
|
||||
dst[1] = src[1]; \
|
||||
dst[2] = src[2]; \
|
||||
} while (0)
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
@ -36,13 +45,14 @@ bool valid_player(cl_entity_t* ent);
|
||||
bool is_friend(cl_entity_t* ent);
|
||||
bool can_shoot(void);
|
||||
char* get_name(int ent_idx);
|
||||
game_id get_cur_game(void);
|
||||
vec3_t vec3(float x, float y, float z);
|
||||
vec3_t vec_add(vec3_t a, vec3_t b);
|
||||
vec3_t vec_sub(vec3_t a, vec3_t b);
|
||||
bool vec_is_zero(vec3_t v);
|
||||
float vec_len2d(vec3_t v);
|
||||
void vec_clamp(vec3_t v);
|
||||
void vec_norm(vec3_t v);
|
||||
void ang_clamp(vec3_t* v);
|
||||
void vec_norm(vec3_t* v);
|
||||
float angle_delta_rad(float a, float b);
|
||||
vec3_t vec_to_ang(vec3_t v);
|
||||
vec3_t matrix_3x4_origin(matrix_3x4 m);
|
||||
@ -53,4 +63,4 @@ void gl_drawbox(int x, int y, int w, int h, rgb_t c);
|
||||
void gl_drawline(int x0, int y0, int x1, int y1, float w, rgb_t col);
|
||||
bool protect_addr(void* ptr, int new_flags);
|
||||
|
||||
#endif /* UTIL_H_ */
|
||||
#endif /* UTIL_H_ */
|
160
src/main.c
160
src/main.c
@ -1,18 +1,128 @@
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "include/main.h"
|
||||
#include "include/sdk.h"
|
||||
#include "include/globals.h"
|
||||
#include "include/cvars.h"
|
||||
#include "include/settings.h"
|
||||
#include "include/hooks.h"
|
||||
#include "include/util.h"
|
||||
#include "include/game_detection.h"
|
||||
|
||||
static bool loaded = false;
|
||||
|
||||
/* Create a debug log file */
|
||||
void debug_log(const char* message) {
|
||||
FILE* logfile = fopen("/tmp/cheat-unload-debug.log", "a");
|
||||
if (logfile) {
|
||||
time_t now = time(NULL);
|
||||
char timestamp[64];
|
||||
strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", localtime(&now));
|
||||
fprintf(logfile, "[%s] %s\n", timestamp, message);
|
||||
fclose(logfile);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enhanced unloading with debug logging */
|
||||
void safe_unload_with_debug(void) {
|
||||
debug_log("Starting safe unload with debug logging");
|
||||
|
||||
/* Log important function addresses for debugging */
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf), "Function addresses - self_unload: %p, unload: %p, hooks_restore: %p",
|
||||
(void*)self_unload, (void*)unload, (void*)hooks_restore);
|
||||
debug_log(buf);
|
||||
|
||||
/* Reset all settings to safe values */
|
||||
debug_log("Resetting all settings to default values");
|
||||
i_engine->pfnClientCmd("echo \"Step 0: Resetting all settings...\"");
|
||||
settings_reset();
|
||||
|
||||
/* Unhook everything first in an orderly manner */
|
||||
i_engine->pfnClientCmd("echo \"Step 1: Unhooking functions...\"");
|
||||
debug_log("Unhooking all functions");
|
||||
|
||||
/* First OpenGL hooks since they're most likely to crash if not restored */
|
||||
debug_log("Restoring OpenGL hooks");
|
||||
// Don't manually unhook GL functions, it's already handled in hooks_restore
|
||||
|
||||
/* Then restore other hooks */
|
||||
debug_log("Restoring VMT hooks");
|
||||
hooks_restore();
|
||||
|
||||
/* Restore globals */
|
||||
debug_log("Restoring globals");
|
||||
globals_restore();
|
||||
|
||||
/* Remove our command */
|
||||
debug_log("Removing custom commands");
|
||||
i_engine->pfnClientCmd("echo \"Step 2: Removing custom commands...\"");
|
||||
|
||||
/* Wait a bit to ensure all hooks are properly removed */
|
||||
debug_log("Waiting for hooks to settle");
|
||||
i_engine->pfnClientCmd("echo \"Step 3: Waiting for hooks to settle...\"");
|
||||
usleep(250000); /* 250ms */
|
||||
|
||||
/* Now try to unload the library */
|
||||
debug_log("Beginning library unload sequence");
|
||||
i_engine->pfnClientCmd("echo \"Step 4: Unloading library...\"");
|
||||
|
||||
/*
|
||||
* RTLD_LAZY: If the symbol is never referenced, then it is never resolved.
|
||||
* RTLD_NOLOAD: Don't load the shared object.
|
||||
*/
|
||||
void* self = dlopen("libhlcheat.so", RTLD_LAZY | RTLD_NOLOAD);
|
||||
|
||||
snprintf(buf, sizeof(buf), "dlopen result: %p", self);
|
||||
debug_log(buf);
|
||||
|
||||
if (self) {
|
||||
/* Close the call we just made to dlopen() */
|
||||
debug_log("Closing first dlopen reference");
|
||||
int result = dlclose(self);
|
||||
snprintf(buf, sizeof(buf), "First dlclose result: %d", result);
|
||||
debug_log(buf);
|
||||
|
||||
/* Close the call our injector made */
|
||||
debug_log("Closing second dlopen reference");
|
||||
result = dlclose(self);
|
||||
snprintf(buf, sizeof(buf), "Second dlclose result: %d", result);
|
||||
debug_log(buf);
|
||||
} else {
|
||||
debug_log("ERROR: Failed to get handle to library");
|
||||
const char* error = dlerror();
|
||||
if (error) {
|
||||
debug_log(error);
|
||||
i_engine->pfnClientCmd("echo \"ERROR: Failed to get handle to library\"");
|
||||
}
|
||||
}
|
||||
|
||||
debug_log("Safe unload completed");
|
||||
i_engine->pfnClientCmd("echo \"Unload procedure completed\"");
|
||||
}
|
||||
|
||||
/* Handler for dz_uninject command */
|
||||
void UNINJECT_CommandHandler(void) {
|
||||
i_engine->pfnClientCmd("echo \"Uninjecting goldsource-cheat with debug logging...\"");
|
||||
|
||||
/* Use the safe unload with debug instead of scheduling uninjection */
|
||||
safe_unload_with_debug();
|
||||
}
|
||||
|
||||
/* Handler for dz_menu command */
|
||||
void MENU_CommandHandler(void) {
|
||||
extern bool g_menu_open;
|
||||
g_menu_open = !g_menu_open;
|
||||
i_engine->Con_Printf("Menu toggled to %s\n", g_menu_open ? "open" : "closed");
|
||||
}
|
||||
|
||||
__attribute__((constructor)) /* Entry point when injected */
|
||||
void load(void) {
|
||||
printf("goldsource-cheat injected!\n");
|
||||
@ -24,12 +134,8 @@ void load(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create cvars for settings */
|
||||
if (!cvars_init()) {
|
||||
fprintf(stderr, "goldsource-cheat: load: error creating cvars, aborting\n");
|
||||
self_unload();
|
||||
return;
|
||||
}
|
||||
/* Initialize settings with defaults */
|
||||
settings_init();
|
||||
|
||||
/* Hook functions */
|
||||
if (!hooks_init()) {
|
||||
@ -38,33 +144,42 @@ void load(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get game version after injecting */
|
||||
/* Register custom commands */
|
||||
i_engine->pfnAddCommand("dz_uninject", UNINJECT_CommandHandler);
|
||||
i_engine->pfnAddCommand("dz_menu", MENU_CommandHandler);
|
||||
|
||||
// Bind INSERT key to dz_menu command (for menu toggle)
|
||||
i_engine->pfnClientCmd("bind INS dz_menu");
|
||||
i_engine->Con_Printf("Bound INSERT key to menu toggle\n");
|
||||
|
||||
/* Play sound to indicate successful injection */
|
||||
if (IsCS16()) {
|
||||
i_engine->pfnClientCmd("play 'sound/radio/go.wav'");
|
||||
i_engine->pfnClientCmd("play weapons/knife_deploy1.wav");
|
||||
i_engine->pfnClientCmd("speak \"Cheat successfully loaded\"");
|
||||
}
|
||||
else if (IsDayOfDefeat()) {
|
||||
i_engine->pfnClientCmd("play 'sound/player/gersniper.wav'");
|
||||
i_engine->pfnClientCmd("play weapons/kar_cock.wav");
|
||||
i_engine->pfnClientCmd("speak \"Cheat successfully loaded\"");
|
||||
}
|
||||
else if (IsTFC()) {
|
||||
i_engine->pfnClientCmd("play 'sound/misc/party2.wav'");
|
||||
i_engine->pfnClientCmd("play misc/party2.wav");
|
||||
i_engine->pfnClientCmd("speak \"Cheat successfully loaded\"");
|
||||
}
|
||||
else if (IsDeathmatchClassic()) {
|
||||
i_engine->pfnClientCmd("play 'sound/items/suit.wav'");
|
||||
}
|
||||
else if (IsSpaceLife()) {
|
||||
i_engine->pfnClientCmd("play 'sound/finley/soccer_ball.wav'");
|
||||
i_engine->pfnClientCmd("play items/r_item1.wav");
|
||||
i_engine->pfnClientCmd("speak \"Cheat successfully loaded\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
i_engine->pfnClientCmd("play 'valve/sound/vox/suit.wav'");
|
||||
i_engine->pfnClientCmd("play weapons/cbar_hit1.wav");
|
||||
i_engine->pfnClientCmd("speak \"Cheat successfully loaded\"");
|
||||
}
|
||||
|
||||
i_engine->pfnClientCmd("echo \"goldsource-cheat loaded successfully!\"");
|
||||
i_engine->pfnClientCmd("echo \"Deadzone rulez!\"");
|
||||
i_engine->pfnClientCmd("echo \"https://git.deadzone.lol/Wizzard/goldsrc-cheat\"");
|
||||
|
||||
|
||||
/* Get game version after injecting */
|
||||
GameType game = get_current_game();
|
||||
switch(game) {
|
||||
case GAME_HALFLIFE:
|
||||
@ -90,20 +205,19 @@ void load(void) {
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
__attribute__((destructor)) /* Entry point when unloaded */
|
||||
void unload(void) {
|
||||
if (loaded) {
|
||||
/* TODO: Remove our cvars */
|
||||
|
||||
/* Reset all settings to default values */
|
||||
settings_reset();
|
||||
|
||||
globals_restore();
|
||||
hooks_restore();
|
||||
|
||||
GL_UNHOOK(glColor4f); /* Manually restore OpenGL hooks here */
|
||||
// Don't manually unhook GL functions, it's already handled in hooks_restore
|
||||
}
|
||||
|
||||
printf("goldsource-cheat unloaded.\n\n");
|
||||
|
580
src/menu.c
Normal file
580
src/menu.c
Normal file
@ -0,0 +1,580 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// This file needs to be compiled as C++
|
||||
#define IMGUI_IMPLEMENTATION
|
||||
#include "include/menu.h"
|
||||
#include "include/sdk.h"
|
||||
#include "include/globals.h"
|
||||
#include "include/settings.h"
|
||||
#include "include/hooks.h" // For hook function declarations
|
||||
#include <GL/gl.h>
|
||||
|
||||
// Include for mouse button constants
|
||||
#include "include/sdk/public/keydefs.h"
|
||||
|
||||
// Access to hitbox enum from aim.c
|
||||
extern const char* hitbox_names[];
|
||||
extern int current_hitbox;
|
||||
|
||||
// Menu state
|
||||
bool g_menu_open = false;
|
||||
|
||||
// ImGui context and state
|
||||
ImGuiContext* g_imgui_context = NULL;
|
||||
bool g_imgui_initialized = false;
|
||||
|
||||
// Key binding state
|
||||
static bool g_waiting_for_key_bind = false;
|
||||
static const char* g_current_key_binding_action = NULL;
|
||||
|
||||
// Fallback menu if ImGui fails
|
||||
static void render_fallback_menu(void);
|
||||
|
||||
// Verify OpenGL state is valid
|
||||
static bool check_gl_state(void) {
|
||||
GLenum error = glGetError();
|
||||
if (error != GL_NO_ERROR) {
|
||||
const char* err_str = "Unknown";
|
||||
switch (error) {
|
||||
case GL_INVALID_ENUM: err_str = "GL_INVALID_ENUM"; break;
|
||||
case GL_INVALID_VALUE: err_str = "GL_INVALID_VALUE"; break;
|
||||
case GL_INVALID_OPERATION: err_str = "GL_INVALID_OPERATION"; break;
|
||||
case GL_STACK_OVERFLOW: err_str = "GL_STACK_OVERFLOW"; break;
|
||||
case GL_STACK_UNDERFLOW: err_str = "GL_STACK_UNDERFLOW"; break;
|
||||
case GL_OUT_OF_MEMORY: err_str = "GL_OUT_OF_MEMORY"; break;
|
||||
}
|
||||
printf("OpenGL error: %s (0x%x)\n", err_str, error);
|
||||
i_engine->Con_Printf("OpenGL error: %s (0x%x)\n", err_str, error);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" bool menu_init(void) {
|
||||
// Print debug message
|
||||
printf("Initializing ImGui menu...\n");
|
||||
i_engine->Con_Printf("Initializing ImGui menu...\n");
|
||||
|
||||
// Check for existing context and cleanup
|
||||
if (g_imgui_context) {
|
||||
printf("ImGui context already exists, shutting down first\n");
|
||||
menu_shutdown();
|
||||
}
|
||||
|
||||
// Check OpenGL state
|
||||
if (!check_gl_state()) {
|
||||
printf("OpenGL not ready for ImGui initialization\n");
|
||||
i_engine->Con_Printf("Warning: OpenGL state not clean, continuing anyway\n");
|
||||
// Not fatal, just a warning
|
||||
}
|
||||
|
||||
// Create ImGui context
|
||||
g_imgui_context = ImGui::CreateContext();
|
||||
if (!g_imgui_context) {
|
||||
printf("Failed to create ImGui context\n");
|
||||
i_engine->Con_Printf("Error: Failed to create ImGui context\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("ImGui context created successfully\n");
|
||||
i_engine->Con_Printf("ImGui context created successfully\n");
|
||||
|
||||
// Configure ImGui
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
||||
|
||||
// Enable mouse input
|
||||
io.MouseDrawCursor = false; // Don't draw cursor until menu is open
|
||||
|
||||
// Get initial screen dimensions
|
||||
SCREENINFO scr_inf;
|
||||
scr_inf.iSize = sizeof(SCREENINFO);
|
||||
i_engine->pfnGetScreenInfo(&scr_inf);
|
||||
|
||||
// Verify and set default dimensions
|
||||
if (scr_inf.iWidth <= 0 || scr_inf.iHeight <= 0) {
|
||||
scr_inf.iWidth = 800;
|
||||
scr_inf.iHeight = 600;
|
||||
i_engine->Con_Printf("Using default screen dimensions: %dx%d\n",
|
||||
scr_inf.iWidth, scr_inf.iHeight);
|
||||
} else {
|
||||
i_engine->Con_Printf("Screen dimensions: %dx%d\n",
|
||||
scr_inf.iWidth, scr_inf.iHeight);
|
||||
}
|
||||
|
||||
// Set initial display size - critical for NewFrame to succeed
|
||||
io.DisplaySize = ImVec2((float)scr_inf.iWidth, (float)scr_inf.iHeight);
|
||||
|
||||
// Initialize OpenGL implementation for ImGui
|
||||
bool init_result = ImGui_ImplOpenGL2_Init();
|
||||
if (!init_result) {
|
||||
printf("Failed to initialize ImGui OpenGL2 backend\n");
|
||||
i_engine->Con_Printf("Error: Failed to initialize ImGui OpenGL2 backend\n");
|
||||
ImGui::DestroyContext(g_imgui_context);
|
||||
g_imgui_context = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("ImGui OpenGL2 backend initialized successfully\n");
|
||||
i_engine->Con_Printf("ImGui OpenGL2 backend initialized successfully\n");
|
||||
|
||||
// Set ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style.WindowRounding = 5.0f;
|
||||
style.FrameRounding = 3.0f;
|
||||
style.ItemSpacing = ImVec2(8, 4);
|
||||
style.Colors[ImGuiCol_WindowBg] = ImVec4(0.1f, 0.1f, 0.1f, 0.9f);
|
||||
style.Colors[ImGuiCol_TitleBg] = ImVec4(0.15f, 0.15f, 0.15f, 1.0f);
|
||||
style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.15f, 0.15f, 0.15f, 1.0f);
|
||||
style.Colors[ImGuiCol_Button] = ImVec4(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.3f, 0.3f, 0.3f, 1.0f);
|
||||
style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.4f, 0.4f, 0.4f, 1.0f);
|
||||
|
||||
// Menu starts closed
|
||||
g_menu_open = false;
|
||||
g_imgui_initialized = true;
|
||||
|
||||
// Ensure game has mouse control at start
|
||||
i_client->IN_ActivateMouse();
|
||||
|
||||
i_engine->Con_Printf("ImGui menu initialized successfully\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" void menu_shutdown(void) {
|
||||
if (g_imgui_initialized) {
|
||||
i_engine->Con_Printf("Shutting down ImGui...\n");
|
||||
|
||||
if (g_imgui_context) {
|
||||
ImGui_ImplOpenGL2_Shutdown();
|
||||
ImGui::DestroyContext(g_imgui_context);
|
||||
g_imgui_context = NULL;
|
||||
}
|
||||
|
||||
g_imgui_initialized = false;
|
||||
i_engine->Con_Printf("ImGui shutdown complete\n");
|
||||
}
|
||||
|
||||
// Always reset menu state on shutdown
|
||||
g_menu_open = false;
|
||||
|
||||
// Make sure the game mouse is active when we shut down
|
||||
i_client->IN_ActivateMouse();
|
||||
|
||||
// Restore mouse bindings
|
||||
i_engine->pfnClientCmd("bind mouse1 +attack; bind mouse2 +attack2");
|
||||
}
|
||||
|
||||
extern "C" void menu_render(void) {
|
||||
// Skip rendering if menu is not open
|
||||
if (!g_menu_open)
|
||||
return;
|
||||
|
||||
if (g_imgui_initialized && g_imgui_context) {
|
||||
// Set the current context
|
||||
ImGui::SetCurrentContext(g_imgui_context);
|
||||
|
||||
// Get screen dimensions
|
||||
SCREENINFO scr_inf;
|
||||
scr_inf.iSize = sizeof(SCREENINFO);
|
||||
i_engine->pfnGetScreenInfo(&scr_inf);
|
||||
|
||||
// Validate screen dimensions
|
||||
if (scr_inf.iWidth <= 0 || scr_inf.iHeight <= 0) {
|
||||
i_engine->Con_Printf("Warning: Invalid screen dimensions, using defaults\n");
|
||||
scr_inf.iWidth = 800;
|
||||
scr_inf.iHeight = 600;
|
||||
}
|
||||
|
||||
// Set display size for ImGui
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.DisplaySize = ImVec2((float)scr_inf.iWidth, (float)scr_inf.iHeight);
|
||||
|
||||
// Start new ImGui frame
|
||||
ImGui_ImplOpenGL2_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
// Set window position and size
|
||||
ImGui::SetNextWindowPos(ImVec2(scr_inf.iWidth * 0.5f, scr_inf.iHeight * 0.5f),
|
||||
ImGuiCond_Once, ImVec2(0.5f, 0.5f));
|
||||
ImGui::SetNextWindowSize(ImVec2(600, 400), ImGuiCond_Once);
|
||||
|
||||
// Begin main window
|
||||
if (ImGui::Begin("GoldSource Cheat", &g_menu_open,
|
||||
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize)) {
|
||||
|
||||
// Create tabs
|
||||
if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_None)) {
|
||||
|
||||
// Aimbot tab
|
||||
if (ImGui::BeginTabItem("Aimbot")) {
|
||||
if (ImGui::Checkbox("Enable Aimbot", &g_settings.aimbot_enabled)) {
|
||||
// No need to set cvar value
|
||||
}
|
||||
|
||||
if (g_settings.aimbot_enabled) {
|
||||
if (ImGui::SliderFloat("FOV", &g_settings.aimbot_fov, 0.1f, 180.0f, "%.1f")) {
|
||||
// No need to set cvar value
|
||||
}
|
||||
|
||||
if (ImGui::SliderFloat("Smoothing", &g_settings.aimbot_smooth, 1.0f, 100.0f, "%.1f")) {
|
||||
// No need to set cvar value
|
||||
}
|
||||
|
||||
const char* hitbox_items[] = { "Head", "Chest", "Stomach", "Pelvis", "Nearest" };
|
||||
if (ImGui::Combo("Hitbox", &g_settings.aimbot_hitbox, hitbox_items, 5)) {
|
||||
current_hitbox = g_settings.aimbot_hitbox;
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Auto Shoot", &g_settings.aimbot_autoshoot);
|
||||
ImGui::Checkbox("Silent Aim", &g_settings.aimbot_silent);
|
||||
ImGui::Checkbox("No Recoil", &g_settings.aimbot_norecoil);
|
||||
ImGui::Checkbox("Recoil Compensation", &g_settings.aimbot_recoil_comp);
|
||||
ImGui::Checkbox("Shoot Teammates", &g_settings.aimbot_team_attack);
|
||||
ImGui::Checkbox("Rage Mode", &g_settings.aimbot_rage_mode);
|
||||
}
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
// Visuals tab
|
||||
if (ImGui::BeginTabItem("Visuals")) {
|
||||
const char* esp_modes[] = {"Off", "2D Box", "Name", "All"};
|
||||
int esp_mode = (int)g_settings.esp_mode;
|
||||
if (ImGui::Combo("ESP", &esp_mode, esp_modes, 4)) {
|
||||
g_settings.esp_mode = (esp_mode_t)esp_mode;
|
||||
}
|
||||
|
||||
ImGui::Checkbox("ESP Friendly", &g_settings.esp_friendly);
|
||||
|
||||
if (ImGui::SliderFloat("FOV Changer", &g_settings.fov, 70.0f, 140.0f, "%.1f")) {
|
||||
// No need to set cvar value
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Chams", &g_settings.chams);
|
||||
|
||||
ImGui::Checkbox("Custom Crosshair", &g_settings.custom_crosshair);
|
||||
|
||||
ImGui::Checkbox("Bullet Tracers", &g_settings.tracers);
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
// Movement tab
|
||||
if (ImGui::BeginTabItem("Movement")) {
|
||||
ImGui::Checkbox("Bunny Hop", &g_settings.bhop);
|
||||
|
||||
ImGui::Checkbox("Auto Strafe", &g_settings.autostrafe);
|
||||
|
||||
ImGui::Checkbox("Anti-Aim", &g_settings.antiaim);
|
||||
|
||||
if (g_settings.antiaim) {
|
||||
ImGui::Checkbox("Anti-Aim View", &g_settings.antiaim_view);
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Fake Duck", &g_settings.fakeduck);
|
||||
|
||||
ImGui::Checkbox("CL_Move", &g_settings.clmove);
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
// Misc tab with extra options
|
||||
if (ImGui::BeginTabItem("Misc")) {
|
||||
ImGui::Checkbox("Name Changer", &g_settings.namechanger);
|
||||
|
||||
if (g_settings.namechanger) {
|
||||
ImGui::SliderFloat("Name Change Speed", &g_settings.namechanger_speed, 1.0f, 50.0f, "%.1f");
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Watermark", &g_settings.watermark);
|
||||
|
||||
if (g_settings.watermark) {
|
||||
ImGui::Checkbox("Rainbow Watermark", &g_settings.watermark_rainbow);
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
// Menu options
|
||||
ImGui::Text("Menu Settings:");
|
||||
ImGui::Checkbox("Allow Movement (WASD) With Menu Open", &g_settings.menu_allow_movement);
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::Button("Uninject Cheat", ImVec2(150, 30))) {
|
||||
i_engine->pfnClientCmd("dz_uninject");
|
||||
g_menu_open = false;
|
||||
}
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
// View settings tab
|
||||
if (ImGui::BeginTabItem("View")) {
|
||||
ImGui::Text("Camera Settings:");
|
||||
|
||||
// Third-person settings
|
||||
bool thirdperson_changed = ImGui::Checkbox("Third-Person View", &g_settings.thirdperson);
|
||||
|
||||
if (g_settings.thirdperson) {
|
||||
// Distance preset buttons with direct setting of values
|
||||
ImGui::BeginGroup();
|
||||
if (ImGui::Button("100")) {
|
||||
g_settings.thirdperson_dist = 100.0f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("270")) {
|
||||
g_settings.thirdperson_dist = 270.0f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("500")) {
|
||||
g_settings.thirdperson_dist = 500.0f;
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
|
||||
// Distance slider - DIRECTLY changes the value without console commands
|
||||
ImGui::SliderFloat("Camera Distance", &g_settings.thirdperson_dist, 30.0f, 800.0f, "%.1f");
|
||||
|
||||
// Remove multiplier message since we don't multiply anymore
|
||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Camera distance updates in real-time");
|
||||
|
||||
// Key binding for third-person toggle
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Keybind for Third-Person Toggle:");
|
||||
|
||||
// Display current key binding
|
||||
const char* key_name = "None";
|
||||
if (g_settings.thirdperson_key > 0) {
|
||||
// Get better key names
|
||||
switch(g_settings.thirdperson_key) {
|
||||
case 'F': key_name = "F"; break;
|
||||
case 'V': key_name = "V"; break;
|
||||
case 'T': key_name = "T"; break;
|
||||
case 'P': key_name = "P"; break;
|
||||
case 'C': key_name = "C"; break;
|
||||
case K_F1: key_name = "F1"; break;
|
||||
case K_F2: key_name = "F2"; break;
|
||||
case K_F3: key_name = "F3"; break;
|
||||
case K_F4: key_name = "F4"; break;
|
||||
case K_F5: key_name = "F5"; break;
|
||||
case K_TAB: key_name = "Tab"; break;
|
||||
case K_SPACE: key_name = "Space"; break;
|
||||
case K_CTRL: key_name = "Ctrl"; break;
|
||||
case K_SHIFT: key_name = "Shift"; break;
|
||||
case K_ALT: key_name = "Alt"; break;
|
||||
case K_MOUSE1: key_name = "Mouse1"; break;
|
||||
case K_MOUSE2: key_name = "Mouse2"; break;
|
||||
case K_MOUSE3: key_name = "Mouse3"; break;
|
||||
default: {
|
||||
// For printable characters
|
||||
if (g_settings.thirdperson_key >= 32 && g_settings.thirdperson_key <= 126) {
|
||||
static char chr[2] = {0};
|
||||
chr[0] = (char)g_settings.thirdperson_key;
|
||||
key_name = chr;
|
||||
} else {
|
||||
// For other keys, show keycode
|
||||
static char code[32] = {0};
|
||||
snprintf(code, sizeof(code), "Key %d", g_settings.thirdperson_key);
|
||||
key_name = code;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Text("Current Key: %s", key_name);
|
||||
|
||||
// TEMP: Disabled key binding until fixed
|
||||
// Disable any active key bindings
|
||||
if (g_waiting_for_key_bind) {
|
||||
g_waiting_for_key_bind = false;
|
||||
g_current_key_binding_action = NULL;
|
||||
}
|
||||
|
||||
// Show preset buttons instead
|
||||
if (ImGui::Button("Bind to C", ImVec2(100, 25))) {
|
||||
g_settings.thirdperson_key = 'C';
|
||||
i_engine->Con_Printf("Third-person toggle bound to C key\n");
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Bind to V", ImVec2(100, 25))) {
|
||||
g_settings.thirdperson_key = 'V';
|
||||
i_engine->Con_Printf("Third-person toggle bound to V key\n");
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Bind to F", ImVec2(100, 25))) {
|
||||
g_settings.thirdperson_key = 'F';
|
||||
i_engine->Con_Printf("Third-person toggle bound to F key\n");
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Clear", ImVec2(80, 25))) {
|
||||
g_settings.thirdperson_key = 0;
|
||||
i_engine->Con_Printf("Third-person key binding cleared\n");
|
||||
}
|
||||
|
||||
ImGui::Text("Note: Default binding is C key");
|
||||
}
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// Render ImGui
|
||||
ImGui::Render();
|
||||
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
|
||||
} else {
|
||||
render_fallback_menu();
|
||||
}
|
||||
}
|
||||
|
||||
// This is our fallback menu that we know works
|
||||
static void render_fallback_menu(void) {
|
||||
// Get screen dimensions
|
||||
SCREENINFO scr_inf;
|
||||
scr_inf.iSize = sizeof(SCREENINFO);
|
||||
i_engine->pfnGetScreenInfo(&scr_inf);
|
||||
|
||||
// Draw simple menu background
|
||||
int x1 = scr_inf.iWidth / 4;
|
||||
int y1 = scr_inf.iHeight / 4;
|
||||
int x2 = scr_inf.iWidth * 3 / 4;
|
||||
int y2 = scr_inf.iHeight * 3 / 4;
|
||||
|
||||
// More visible background (darker black with higher alpha)
|
||||
i_engine->pfnFillRGBA(x1, y1, x2-x1, y2-y1, 0, 0, 0, 230);
|
||||
|
||||
// Draw bright border for visibility
|
||||
i_engine->pfnFillRGBA(x1, y1, x2-x1, 2, 255, 0, 0, 255); // Top
|
||||
i_engine->pfnFillRGBA(x1, y2-2, x2-x1, 2, 255, 0, 0, 255); // Bottom
|
||||
i_engine->pfnFillRGBA(x1, y1, 2, y2-y1, 255, 0, 0, 255); // Left
|
||||
i_engine->pfnFillRGBA(x2-2, y1, 2, y2-y1, 255, 0, 0, 255); // Right
|
||||
|
||||
// Title
|
||||
i_engine->pfnDrawSetTextColor(1.0f, 1.0f, 0.0f);
|
||||
i_engine->pfnDrawConsoleString(x1+10, y1+10, "===== GoldSource Cheat Menu (Fallback) =====");
|
||||
|
||||
// Reset color for menu items
|
||||
i_engine->pfnDrawSetTextColor(0.0f, 1.0f, 1.0f);
|
||||
|
||||
// Draw menu items
|
||||
int y = y1 + 40;
|
||||
i_engine->pfnDrawConsoleString(x1+20, y, "-- Aimbot Settings --");
|
||||
y += 20;
|
||||
|
||||
char buffer[128];
|
||||
|
||||
bool aimbot_enabled = g_settings.aimbot_enabled;
|
||||
snprintf(buffer, sizeof(buffer), "- Aimbot: %s", aimbot_enabled ? "ON" : "OFF");
|
||||
i_engine->pfnDrawConsoleString(x1+30, y, buffer);
|
||||
y += 15;
|
||||
|
||||
if (aimbot_enabled) {
|
||||
snprintf(buffer, sizeof(buffer), "- FOV: %.1f", g_settings.aimbot_fov);
|
||||
i_engine->pfnDrawConsoleString(x1+30, y, buffer);
|
||||
y += 15;
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "- Smoothing: %.1f", g_settings.aimbot_smooth);
|
||||
i_engine->pfnDrawConsoleString(x1+30, y, buffer);
|
||||
y += 15;
|
||||
}
|
||||
|
||||
y += 10;
|
||||
i_engine->pfnDrawSetTextColor(0.0f, 1.0f, 1.0f);
|
||||
i_engine->pfnDrawConsoleString(x1+20, y, "-- Visual Settings --");
|
||||
y += 20;
|
||||
|
||||
int esp_mode = (int)g_settings.esp_mode;
|
||||
snprintf(buffer, sizeof(buffer), "- ESP: %s", esp_mode > 0 ? "ON" : "OFF");
|
||||
i_engine->pfnDrawConsoleString(x1+30, y, buffer);
|
||||
y += 15;
|
||||
|
||||
bool chams_enabled = g_settings.chams;
|
||||
snprintf(buffer, sizeof(buffer), "- Chams: %s", chams_enabled ? "ON" : "OFF");
|
||||
i_engine->pfnDrawConsoleString(x1+30, y, buffer);
|
||||
y += 30;
|
||||
|
||||
// Instructions
|
||||
i_engine->pfnDrawSetTextColor(1.0f, 1.0f, 0.0f);
|
||||
i_engine->pfnDrawConsoleString(x1+20, y, "Press INSERT to close menu");
|
||||
y += 20;
|
||||
i_engine->pfnDrawConsoleString(x1+20, y, "Use console to change settings");
|
||||
|
||||
// Draw help in bottom corner
|
||||
i_engine->pfnDrawSetTextColor(0.7f, 0.7f, 0.7f);
|
||||
i_engine->pfnDrawConsoleString(5, scr_inf.iHeight - 20, "Type 'dz_menu' in console to toggle menu");
|
||||
}
|
||||
|
||||
// Update the key event handler to support key binding
|
||||
extern "C" void menu_key_event(int keynum, int down) {
|
||||
// Add debug output
|
||||
i_engine->Con_Printf("menu_key_event called: keynum=%d, down=%d\n", keynum, down);
|
||||
|
||||
// If we're waiting for a key bind and a key is pressed down
|
||||
if (g_waiting_for_key_bind && down && keynum != K_ESCAPE) {
|
||||
// Don't bind mouse wheel or menu toggle key
|
||||
if (keynum != K_MWHEELDOWN && keynum != K_MWHEELUP && keynum != K_INS) {
|
||||
// Bind the key based on current action
|
||||
if (g_current_key_binding_action && strcmp(g_current_key_binding_action, "thirdperson") == 0) {
|
||||
g_settings.thirdperson_key = keynum;
|
||||
i_engine->Con_Printf("Third-person key bound to keycode: %d\n", keynum);
|
||||
}
|
||||
|
||||
// Exit binding mode
|
||||
g_waiting_for_key_bind = false;
|
||||
g_current_key_binding_action = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel key binding if escape is pressed
|
||||
if (g_waiting_for_key_bind && down && keynum == K_ESCAPE) {
|
||||
g_waiting_for_key_bind = false;
|
||||
g_current_key_binding_action = NULL;
|
||||
i_engine->Con_Printf("Key binding canceled\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (keynum == K_INS && down) {
|
||||
// Toggle menu state
|
||||
g_menu_open = !g_menu_open;
|
||||
i_engine->Con_Printf("Menu %s\n", g_menu_open ? "opened" : "closed");
|
||||
|
||||
// Update ImGui IO if initialized
|
||||
if (g_imgui_initialized && g_imgui_context) {
|
||||
ImGui::SetCurrentContext(g_imgui_context);
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MouseDrawCursor = g_menu_open;
|
||||
}
|
||||
|
||||
// Activate or deactivate mouse based on menu state
|
||||
if (g_menu_open) {
|
||||
// When opening menu, deactivate mouse in game and use our own cursor
|
||||
i_client->IN_DeactivateMouse();
|
||||
i_client->IN_ClearStates();
|
||||
|
||||
// Fixes potential issues with key state
|
||||
i_engine->pfnClientCmd("unbind mouse1; unbind mouse2");
|
||||
i_engine->Con_Printf("Mouse deactivated for game, using ImGui cursor\n");
|
||||
} else {
|
||||
// When closing menu, reactivate mouse in game
|
||||
i_client->IN_ActivateMouse();
|
||||
|
||||
// Restore default bindings
|
||||
i_engine->pfnClientCmd("bind mouse1 +attack; bind mouse2 +attack2");
|
||||
i_engine->Con_Printf("Mouse reactivated for game\n");
|
||||
}
|
||||
}
|
||||
}
|
56
src/settings.c
Normal file
56
src/settings.c
Normal file
@ -0,0 +1,56 @@
|
||||
#include "include/settings.h"
|
||||
#include "include/sdk.h"
|
||||
#include "include/globals.h"
|
||||
#include "include/game_detection.h"
|
||||
|
||||
|
||||
cheat_settings_t g_settings;
|
||||
|
||||
|
||||
void settings_init(void) {
|
||||
|
||||
init_default_settings();
|
||||
|
||||
|
||||
g_settings.thirdperson_key = 'C';
|
||||
|
||||
i_engine->Con_Printf("Settings initialized with defaults. Third-person key bound to C.\n");
|
||||
}
|
||||
|
||||
|
||||
void settings_reset(void) {
|
||||
|
||||
g_settings.esp_mode = ESP_OFF;
|
||||
g_settings.esp_friendly = false;
|
||||
g_settings.chams = false;
|
||||
g_settings.tracers = false;
|
||||
g_settings.custom_crosshair = false;
|
||||
g_settings.watermark = false;
|
||||
g_settings.watermark_rainbow = false;
|
||||
|
||||
g_settings.aimbot_enabled = false;
|
||||
g_settings.aimbot_autoshoot = false;
|
||||
g_settings.aimbot_silent = false;
|
||||
g_settings.aimbot_norecoil = false;
|
||||
g_settings.aimbot_recoil_comp = false;
|
||||
g_settings.aimbot_friendly_fire = false;
|
||||
g_settings.aimbot_rage_mode = false;
|
||||
g_settings.aimbot_team_attack = false;
|
||||
|
||||
g_settings.bhop = false;
|
||||
g_settings.autostrafe = false;
|
||||
g_settings.antiaim = false;
|
||||
g_settings.antiaim_view = false;
|
||||
g_settings.fakeduck = false;
|
||||
g_settings.clmove = false;
|
||||
|
||||
g_settings.namechanger = false;
|
||||
|
||||
g_settings.fov = 90.0f;
|
||||
|
||||
g_settings.thirdperson = false;
|
||||
g_settings.thirdperson_key = 0;
|
||||
g_settings.thirdperson_dist = 150.0f;
|
||||
|
||||
i_engine->pfnClientCmd("echo \"All cheat settings have been reset to default values\"");
|
||||
}
|
16
src/util.c
16
src/util.c
@ -108,16 +108,16 @@ float vec_len2d(vec3_t v) {
|
||||
return sqrtf(v.x * v.x + v.y * v.y);
|
||||
}
|
||||
|
||||
void vec_clamp(vec3_t v) {
|
||||
v.x = CLAMP(v.x, -89.0f, 89.0f);
|
||||
v.y = CLAMP(remainderf(v.y, 360.0f), -180.0f, 180.0f); /* v.y % 360 */
|
||||
v.z = CLAMP(v.z, -50.0f, 50.0f);
|
||||
void ang_clamp(vec3_t* v) {
|
||||
v->x = CLAMP(v->x, -89.0f, 89.0f);
|
||||
v->y = CLAMP(remainderf(v->y, 360.0f), -180.0f, 180.0f);
|
||||
v->z = CLAMP(v->z, -50.0f, 50.0f);
|
||||
}
|
||||
|
||||
void vec_norm(vec3_t v) {
|
||||
v.x = isfinite(v.x) ? remainder(v.x, 360) : 0;
|
||||
v.y = isfinite(v.y) ? remainder(v.y, 360) : 0;
|
||||
v.z = 0.0f;
|
||||
void vec_norm(vec3_t* v) {
|
||||
v->x = isfinite(v->x) ? remainderf(v->x, 360.f) : 0.f;
|
||||
v->y = isfinite(v->y) ? remainderf(v->y, 360.f) : 0.f;
|
||||
v->z = 0.0f;
|
||||
}
|
||||
|
||||
float angle_delta_rad(float a, float b) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user