The Starport
  • Categories
  • Recent
  • Users
  • Groups
  • Starport Blog
  • Knowledge Base
  • The Forge
  • Discord
  • Register
  • Login

[Clientside]Custom key commands

Scheduled Pinned Locked Moved Freelancer-related Programming
8 Posts 6 Posters 8.3k Views
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Cannon
    wrote on global:last_edited_by,
    #1

    The following code provides a means to override or extend the key commands in freelancer. In the example below I’ve added a USER_HUD to toggle the hud visibility.

    In KeyMap.ini

    [KeyCmd]
    nickname = USER_HUD
    ids_name = 1983 ; replace these with new ids 
    ids_info = 3217 ; replace these with new ids
    state = keydown
    key = "L"
    
    [KeyMap]
    nickname = IDR_ALWAYS_PRESENT
    key = USER_HUD
    
    

    In keylist.ini

    [key]
    id = USER_HUD
    
    

    And in the client side DLL

    void __stdcall HkCb_HandleKeyCmd(int keycmd, int dunno)
    {
     if (keycmd == 0x0000008d) // key index of USER_STEALTH which is renamed USER_HUD.
     {
          // do stuff here
     }
    }
    
    __declspec(naked) void HkCb_HandleKeyCmdNaked(void)
    {
     __asm
     {
      push [esp+8] 
      push [esp+8]
      call HkCb_HandleKeyCmd
    
      sub esp, 80h
      push ebx
      mov ecx, 0x00576417
      jmp ecx
     }
    }
    
    Patch()
    {
     // Patch keynames
     {
      char patch[] = "USER_HUD\x00\x00\x00\x00";
      WriteProcMem((char*)0x5E376C, &patch, 13);
     }
    
     // Patch keycmd processor
     {
      BYTE patch[] = { 0xB9, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE1 }; // mov ecx HkCb_HandleKeyCmdNaked, jmp ecx
      DWORD *iAddr = (DWORD*)((char*)&patch + 1);
      *iAddr = reinterpret_cast<dword>((void*)HkCb_HandleKeyCmdNaked);
      WriteProcMem((char*)0x576410, &patch, 7); 
     }
    }</dword> 
    

    With a patch a on the keyname list it should be possible to add any number of new key command but in the above example I’ve just renamed an existing but unused command (USER_STEALTH).

    EDIT: it turns out that there are heaps of unused commands, i’ve added 8 new commands so far.

    1 Reply Last reply
    0
  • F Offline
    F Offline
    FriendlyFire
    wrote on global:last_edited_by,
    #2

    Very nice find 🙂

    1 Reply Last reply
    0
  • W Offline
    W Offline
    w0dk4
    wrote on global:last_edited_by,
    #3

    You may also be interested in this:

    uint iState = *(int*)0x067C290; // iState == 0 -> keyup | iState == 1 -> keydown
    

    There are indeed a lot of unused keys, btw. here is an enum:

    enum INPUT_COMMANDS
    {
    	USER_NONE,
    	USER_KEY,
    	USER_CHAR,
    	USER_BUTTON,
    	USER_WHEEL,
    	USER_MOVE,
    	USER_BUTTON0,
    	USER_BUTTON1,
    	USER_BUTTON2,
    	USER_BUTTON3,
    	USER_BUTTON4,
    	USER_BUTTON5,
    	USER_BUTTON6,
    	USER_BUTTON7,
    	USER_EVENTS,
    	USER_CANCEL,
    	USER_STACKABLE_CANCEL,
    	USER_ENTER,
    	USER_NO,
    	USER_YES,
    	USER_PAUSE,
    	USER_RESET,
    	USER_SAVE_GAME,
    	USER_FULLSCREEN,
    	USER_USE_ITEM,
    	USER_ACTIVATE_ITEM,
    	USER_NEXT_ITEM,
    	USER_PREV_ITEM,
    	USER_SET_TARGET,
    	USER_NEXT_TARGET,
    	USER_PREV_TARGET,
    	USER_NEXT_WEAPON_SUBTARGET,
    	USER_PREV_WEAPON_SUBTARGET,
    	USER_NEXT_SUBTARGET,
    	USER_PREV_SUBTARGET,
    	USER_CLEAR_TARGET,
    	USER_NEXT_ENEMY,
    	USER_PREV_ENEMY,
    	USER_CLOSEST_ENEMY,
    	USER_ZOOM_IN,
    	USER_ZOOM_OUT,
    	USER_ZOOM_TOGGLE,
    	USER_X_ROTATE,
    	USER_X_UNROTATE,
    	USER_Y_ROTATE,
    	USER_Y_UNROTATE,
    	USER_Z_ROTATE,
    	USER_Z_UNROTATE,
    	USER_VIEW_RESET,
    	USER_COCKPIT_CAMERA_MODE,
    	USER_LOOK_ROTATE_CAMERA_LEFT,
    	USER_LOOK_ROTATE_CAMERA_RIGHT,
    	USER_LOOK_ROTATE_CAMERA_UP,
    	USER_LOOK_ROTATE_CAMERA_DOWN,
    	USER_LOOK_ROTATE_CAMERA_RESET,
    	USER_CHASE_CAMERA_MODE,
    	USER_REARVIEW_CAMERA_MODE,
    	USER_REARVIEW_CAMERA_MODE_OFF,
    	USER_AFTERBURN,
    	USER_AFTERBURN_OFF,
    	USER_AFTERBURN_ON,
    	USER_TOGGLE_AUTO_AVOIDANCE,
    	USER_TOGGLE_AUTO_LEVEL,
    	USER_TOGGLE_LEVEL_CAMERA,
    	USER_WARP,
    	USER_ENGINE_TOGGLE,
    	USER_SET_THROTTLE,
    	USER_INC_THROTTLE,
    	USER_DEC_THROTTLE,
    	USER_CRUISE,
    	USER_THROTTLE_0,
    	USER_THROTTLE_10,
    	USER_THROTTLE_20,
    	USER_THROTTLE_25,
    	USER_THROTTLE_30,
    	USER_THROTTLE_40,
    	USER_THROTTLE_50,
    	USER_THROTTLE_60,
    	USER_THROTTLE_70,
    	USER_THROTTLE_75,
    	USER_THROTTLE_80,
    	USER_THROTTLE_90,
    	USER_THROTTLE_100,
    	USER_RADAR,
    	USER_CONTACT_LIST,
    	USER_RADAR_ZOOM,
    	USER_SWITCH_TO_PLAYER_SHIP,
    	USER_SWITCH_TO_WEAPON_LIST,
    	USER_SWITCH_TO_TARGET,
    	USER_FORMATION_LIST,
    	USER_RADAR_ZOOM_IN,
    	USER_RADAR_ZOOM_OUT,
    	USER_RADIO,
    	USER_CHAT,
    	USER_STATUS,
    	USER_TARGET,
    	USER_STATUS_MODE,
    	USER_TOGGLE_MAINFRAME,
    	USER_NN,
    	USER_NAV_MAP,
    	USER_NAVMAP,
    	USER_PLAYER_STATS,
    	USER_INVENTORY,
    	USER_STORY_STAR,
    	USER_CHAT_WINDOW,
    	USER_GROUP_WINDOW,
    	USER_HELP,
    	USER_INVENTORY_CLOSE,
    	NN_TOGGLE_OPEN,
    	USER_MINIMIZE_HUD,
    	USER_DISPLAY_LAST_OBJECTIVE,
    	USER_COLLECT_LOOT,
    	USER_ACTIONS,
    	USER_MANEUVER,
    	USER_SET_MANEUVER_DIRECTION,
    	USER_MANEUVER_WINDOW,
    	USER_MANEUVER_TRAIL,
    	USER_MANEUVER_AFTERBURNER,
    	USER_MANEUVER_EVADE,
    	USER_MANEUVER_ENGINEKILL,
    	USER_MANEUVER_BRAKE_REVERSE,
    	USER_MANEUVER_DOCK,
    	USER_MANEUVER_GOTO,
    	USER_MANEUVER_FACE,
    	USER_MANEUVER_CRUISE,
    	USER_MANEUVER_TRADE_LANE,
    	USER_MANEUVER_DRASTIC_EVADE,
    	USER_MANEUVER_FORMATION,
    	USER_MANEUVER_STRAFE,
    	USER_MANEUVER_TRAIL_CLOSER,
    	USER_MANEUVER_TRAIL_FARTHER,
    	USER_MANEUVER_CORKSCREW_EVADE,
    	USER_MANEUVER_SLIDE_EVADE,
    	USER_MANEUVER_SLIDE_EVADE_LEFT,
    	USER_MANEUVER_SLIDE_EVADE_RIGHT,
    	USER_MANEUVER_SLIDE_EVADE_UP,
    	USER_MANEUVER_SLIDE_EVADE_DOWN,
    	USER_ACTIVATE_MANEUVER,
    	USER_SCAN_CARGO,
    	USER_TRACTOR_BEAM,
    	USER_JAMMER,
    	USER_STEALTH,
    	USER_CLOAK,
    	USER_REPAIR_HEALTH,
    	USER_REPAIR_SHIELD,
    	USER_WEAPON_GROUP1,
    	USER_WEAPON_GROUP2,
    	USER_WEAPON_GROUP3,
    	USER_WEAPON_GROUP4,
    	USER_WEAPON_GROUP5,
    	USER_WEAPON_GROUP6,
    	USER_TOGGLE_WEAPON1,
    	USER_TOGGLE_WEAPON2,
    	USER_TOGGLE_WEAPON3,
    	USER_TOGGLE_WEAPON4,
    	USER_TOGGLE_WEAPON5,
    	USER_TOGGLE_WEAPON6,
    	USER_TOGGLE_WEAPON7,
    	USER_TOGGLE_WEAPON8,
    	USER_TOGGLE_WEAPON9,
    	USER_TOGGLE_WEAPON10,
    	USER_FIRE_WEAPON1,
    	USER_FIRE_WEAPON2,
    	USER_FIRE_WEAPON3,
    	USER_FIRE_WEAPON4,
    	USER_FIRE_WEAPON5,
    	USER_FIRE_WEAPON6,
    	USER_FIRE_WEAPON7,
    	USER_FIRE_WEAPON8,
    	USER_FIRE_WEAPON9,
    	USER_FIRE_WEAPON10,
    	USER_FIRE_WEAPON_GROUP1,
    	USER_FIRE_WEAPON_GROUP2,
    	USER_FIRE_WEAPON_GROUP3,
    	USER_FIRE_WEAPON_GROUP4,
    	USER_FIRE_WEAPON_GROUP5,
    	USER_FIRE_WEAPON_GROUP6,
    	USER_ASSIGN_WEAPON_GROUP1,
    	USER_ASSIGN_WEAPON_GROUP2,
    	USER_ASSIGN_WEAPON_GROUP3,
    	USER_ASSIGN_WEAPON_GROUP4,
    	USER_ASSIGN_WEAPON_GROUP5,
    	USER_ASSIGN_WEAPON_GROUP6,
    	USER_REMAPPABLE_LEFT,
    	USER_REMAPPABLE_RIGHT,
    	USER_REMAPPABLE_UP,
    	USER_REMAPPABLE_DOWN,
    	USER_FIRE_FORWARD,
    	USER_LAUNCH_MISSILES,
    	USER_LAUNCH_MINES,
    	USER_LAUNCH_COUNTERMEASURES,
    	USER_AUTO_TURRET,
    	USER_LAUNCH_TORPEDOS,
    	USER_LAUNCH_CRUISE_DISRUPTORS,
    	USER_TURN,
    	USER_NEXT_OBJECT,
    	USER_PREV_OBJECT,
    	USER_EXIT_GAME,
    	USER_MANEUVER_FREE_FLIGHT,
    	USER_FIRE_WEAPONS,
    	USER_TURN_SHIP,
    	USER_GROUP_INVITE,
    	USER_TRADE_REQUEST,
    	USER_SCREEN_SHOT
    };
    
    
    1 Reply Last reply
    0
  • adoxaA Offline
    adoxaA Offline
    adoxa
    wrote on global:last_edited_by,
    #4

    The keys that aren’t used are here.

    1 Reply Last reply
    0
  • C Offline
    C Offline
    Crazy
    wrote on global:last_edited_by,
    #5

    Checking if the chat input window is open:

    typedef void* (*_GetObjByStr)(char*);
    _GetObjByStr GetObjByStr = (_GetObjByStr)0x59DA10;
    
    
    void __stdcall HkCb_HandleKeyCmd(int keycmd, int dunno)
    {
    	    ...
    
    	    void* Obj = GetObjByStr("CTID");
    	    byte byIsChatOpen;
     	  ReadProcMem((char*)Obj+1337, &byIsChatOpen, 1);
    	    if(byIsChatOpen)
    		       return;
    
        ...
    
    
    1 Reply Last reply
    0
  • adoxaA Offline
    adoxaA Offline
    adoxa
    wrote on global:last_edited_by,
    #6

    I don’t understand all this use of ReadProcMem. Plugins are loaded into the address space of the process, so there’s no need for it. What’s wrong with just:

    struct SomeObjectType
    {
      byte todo[0x1337];
      bool bIsOpen;
      // byte more_todo[];
    };
    
    typedef SomeObjectType* (*_GetObjByStr)(const char*);
    
    SomeObjectType* obj = _GetObjByStr("CTID");
    if (obj->bIsOpen)
      return;
    
    
    1 Reply Last reply
    0
  • C Offline
    C Offline
    Cannon
    wrote on global:last_edited_by,
    #7

    An update to the code so that a keypress that is processed by a custom command will not be printed into the chat box, if the chat box is open.

    bool __stdcall HkCb_HandleKeyCmd(int keycmd, int dunno)
    {
        switch (keycmd)
        case blah:
           return true; // if you process it
         default:
            return false; // if you don't
    }  
    
    __declspec(naked) void HkCb_HandleKeyCmdNaked(void)
    {
    	__asm
    	{
    		push [esp+8] 
    		push [esp+8]
    		call HkCb_HandleKeyCmd
    		test al, al
    		jz   cmd_not_processed
    		ret
    
    cmd_not_processed:
    		sub esp, 80h
    		push ebx
    		mov ecx, 0x00576417
    		jmp ecx
    
    	}
    }
    
    

    I guess there’s no reason to have this in the private section. I’m not sure why I put it here so if a site admin wants to move it then do so please….

    1 Reply Last reply
    0
  • LazL Offline
    LazL Offline
    Laz Administrators Starport Developer
    wrote on global:last_edited_by,
    #8

    A bit of a grave dig, but I was wondering if anybody knows the location of the function for handling the release of input.

    From what I can tell, any key defined inside of keymap.ini with a state of “keydown, keyup” will only fire an event in the above function for the initial keydown state. This is great for intercepting calls, but sometimes I want to supress the cancelation.

    1 Reply Last reply
    0

  • Story Mission level requirement
    C
    CommanderArgelo
    0
    11
    52

  • Crash Offsets
    J
    josbyte
    0
    231
    251.4k

  • Capital ships shield collision detection
    C
    CommanderArgelo
    0
    3
    17

  • Dropping a phantomloot cargo from an NPC
    C
    CommanderArgelo
    0
    5
    26

  • Incorrect Shield Value on HUD
    C
    CommanderArgelo
    0
    4
    19

  • @Adoxa - Wheel Scroll plugin improvements
    AingarA
    Aingar
    0
    3
    20

  • Release: Advanced Renderer v. 1.1 beta 1
    S
    SWAT_OP-R8R
    3
    50
    428

  • German Mod Tutorials? 2024 Mod Tutorial?
    S
    SWAT_OP-R8R
    0
    18
    66
  • First post
    Last post
0
  • Categories
  • Recent
  • Users
  • Groups
  • Starport Blog
  • Knowledge Base
  • The Forge
  • Discord