#1 17-09-2010 02:16

Deji
From: UK
Registered: 09-11-2008
Posts: 189
Website

On-Screen Keyboard - Help

Here's the code for an on-screen keyboard I'm creating for joypad users...

{$CLEO}

0000:

:KeyBoard

while true
    wait 250
    if or
        80E1:   not player 0 pressed_key 14
        80E1:   not player 0 pressed_key 18
    jf break
end

0006: 7@ = 0
0006: 12@ = 0
01B4: set_player $PLAYER_CHAR can_move 0
0391: release_textures
0390: load_txd "LD_BUM"
038F: load_texture "blkdot" as 1
0AC6: 0@ = label @KeyBoardKeys offset
0AC8: 13@ = allocate_memory_size 15

while true
    wait 0
    00E2: get_player 0 key 0 state_to 10@
    00E2: get_player 0 key 1 state_to 11@
    if
        8039:   not 12@ == 1
    then
        if
            0019:   10@ > 100
        then
            0006: 12@ = 1
            if 001B:   35 > 7@
            then 000A: 7@ += 1
            end
        end
        if
            001B:   -100 > 10@
        then
            0006: 12@ = 1
            if 0019:   7@ > 0
            then 000E: 7@ -= 1
            end
        end
    else
        if 0039:   10@ == 0 
        then 0006: 12@ = 0
        end
    end
    if
        8039:   not 12@ == 2
    then
        if
            0019:   11@ > 100
        then
            0006: 12@ = 2
            if 001B:   19 > 7@
            then 000A: 7@ += 10
            else 000A: 7@ += 9
            end
        end
        if
            001B:   -100 > 11@
        then
            0006: 12@ = 2
            if 001B:   20 > 7@
            then 000E: 7@ -= 10
            else 000E: 7@ -= 9
            end
        end
    else
        if 0039:   11@ == 0 
        then 0006: 12@ = 0
        end
    end
    if 001B:   0 > 7@
    then 0006: 7@ = 0
    end
    if 0019:   7@ > 35
    then 0006: 7@ = 35
    end
    
    03F0: enable_drawing 0
    03F0: enable_drawing 1
    
    0006: 3@ = 0
    0007: 5@ = 60.0
    0007: 6@ = 60.0
    038E: draw_text 175.0 75.0 size 250.0 80.0 RGBA 0 0 10 200
    
    0ADF: add_gxt "KBTMP" text 0x969110
    033E: set_draw_text_position 80.0 40.0 GXT "KBTMP"
     
    for 1@ = 0 to 35
        if
            0039:   1@ == 10
        then
            0007: 5@ = 66.0
            000B: 6@ += 14.0
        end
        if
            0039:   1@ == 20
        then
            0007: 5@ = 74.0
            000B: 6@ += 14.0
        end
        if
            0039:   1@ == 29
        then
            0007: 5@ = 80.0
            000B: 6@ += 14.0
        end
        0A90: 3@ = 1@ * 2
        0A8E: 2@ = 3@ + 0@
        0AD3: 8@s = format "KBTMP%d" 1@
        0ADF: add_gxt 8@s text 2@
        if
            003B:   7@ == 1@
        then
            0340: draw_RGBA 255 255 120 255
            if
                00E1:   player 0 pressed_key 16
            then
                // This is assuming the key just pressed is added to the cheat string.. it will overwrite it.
                // It is possible that it may have to be replaced by moving 15 bytes across by 1.
                0A8C: write_memory 0x969110 size 1 value 2@ virtual_protect 0
            end
        else
            0340: draw_RGBA 200 200 200 255
        end
        081C: draw_outline 1 RGBA 0 0 0 255
        033E: draw_text 5@ 6@ GXT 8@s
        000B: 5@ += 24.0
    end
    if 00E1:   player 0 pressed_key 15
    then break
    end
end

0AC9: free_allocated_memory 13@
0AE0: remove_dynamic_GXT_entry "KBTMP"
for 0@ = 0 to 35
    0AD3: 1@s = format "KBTMP%d" 0@
    0AE0: remove_dynamic_GXT_entry 1@s
end
jump @KeyBoard

:KeyBoardKeys
hex
  "1" 00 "2" 00 "3" 00 "4" 00 "5" 00 "6" 00 "7" 00 "8" 00 "9" 00 "0" 00
    "Q" 00 "W" 00 "E" 00 "R" 00 "T" 00 "Y" 00 "U" 00 "I" 00 "O" 00 "P" 00
      "A" 00 "S" 00 "D" 00 "F" 00 "G" 00 "H" 00 "J" 00 "K" 00 "L" 00
         "Z" 00 "X" 00 "C" 00 "V" 00 "B" 00 "N" 00 "M" 00
end

The idea is simple.. Control the on-screen keyboard with the directional buttons, pressing the sprint key to select a character. The users input will be added straight to the cheat string.

I'm not sure what the problem is but I have the Russian SA Translation and Russian symbols are appearing in the cheat string as well as other odd characters that shouldn't exist there.

The odd thing is that they display on the keyboard fine.. and the same value is being added to the cheat string as is being displayed. So I'm pretty puzzled as to why this is happening. I'm not sure if it is a problem caused by the Russification mod on my computer or whether all installations will suffer a similar problem; the wrong hex values are being added?

Anyway, feel free to try it out by pressing Jump+Crouch. I'm using a keyboard, so I'm not sure how well this works with joypads anyway... I just thought it was a good idea to enable joypad users to type cheats and use cheat-activated mods. and such.

Offline

#2 18-09-2010 15:21

Alien
Registered: 12-10-2008
Posts: 564

Re: On-Screen Keyboard - Help

Nice idea. And here's fully working script. The source code is for this compiler (which is not in public access for a while).

[Opcode=0x00E1]
static bool PLAYER_PRESSED_KEY(int playerId, int key);
[Opcode=0x00E2]
static int GET_PLAYER_KEY_STATE(int playerId, int key);
[Opcode=0x0ADF]
static void ADD_GXT(auto, auto);
[Opcode=0x0256]
static bool PLAYER_DEFINED(int);
[Opcode=0x01B4]
static void SET_PLAYER_MOVABLE(int, int);
[Opcode=0x03F0]
static void ENABLE_DRAWING(int);
[Opcode=0x0ACA]
static void HELP_MESSAGE_INTERMEDIATE(auto);
[Opcode=0x038E]
static void DRAW_RECT(float x, float y, float w, float h, int r, int g, int b, int a);
[Opcode=0x0449]
static bool IS_CHAR_IN_A_CAR(int char);
[Opcode=0x0ACE]
static void HELP_MESSAGE_INTERMEDIATE_FORMAT(auto format, ...);
[Opcode=0x0340]
static void SET_DRAW_FOREGROUND_COLOR(int r, int g, int b, int a);
[Opcode=0x081C]
static void SET_OUTLINE(int type, int r, int g, int b, int a);
[Opcode=0x033E]
static void ADD_TEXT_DRAWER(float x, float y, gxt text);
[Opcode=0x0ADE]
static int GET_GXT_ENTRY_PTR(auto);


[FixedVarPosition=1000]
extern gxt KbdGxts[1];    /*    "1" ... "0"
                                "Q" ... "P"
                                "A" ... "L"
                                "Z" ... "M"  */

[FixedVarPosition=2]
extern int Player;

[FixedVarPosition=3]
extern int PlayerChar;

[FunctionPointer=0x438480]
native void AddCharToCheatString(int key);

int InitExtraVars(int base, int size, int elem_size)
{
    int address;
    if (ALLOCATE_MEMORY((size + 2) * elem_size, out address))
        return (address - base) / elem_size;
    else
        return 0;
}

void main()
{
    if (!IS_GAME_VERSION_ORIGINAL())
        return;
    WAIT(3000);
    int kbdGxt_base[4];
    int let_count[4];
    let_count[0] = 10;
    let_count[1] = 10;
    let_count[2] = 9;
    let_count[3] = 7;
    {
        int i;        
        for (i = 0; i < 4; i += 1)
        {
            kbdGxt_base[i] = InitExtraVars(&KbdGxts[0], let_count[i], sizeof(gxt));
            if (kbdGxt_base[i] == 0)
            {
                HELP_MESSAGE_INTERMEDIATE("MALLOC failed.");
                return;
            }
        }
        
        int off;
        off = kbdGxt_base[0];
        KbdGxts[off] = "VKBD_1"; ADD_GXT("VKBD_1", "1"); off += 1; 
        KbdGxts[off] = "VKBD_2"; ADD_GXT("VKBD_2", "2"); off += 1; 
        KbdGxts[off] = "VKBD_3"; ADD_GXT("VKBD_3", "3"); off += 1; 
        KbdGxts[off] = "VKBD_4"; ADD_GXT("VKBD_4", "4"); off += 1; 
        KbdGxts[off] = "VKBD_5"; ADD_GXT("VKBD_5", "5"); off += 1; 
        KbdGxts[off] = "VKBD_6"; ADD_GXT("VKBD_6", "6"); off += 1; 
        KbdGxts[off] = "VKBD_7"; ADD_GXT("VKBD_7", "7"); off += 1; 
        KbdGxts[off] = "VKBD_8"; ADD_GXT("VKBD_8", "8"); off += 1; 
        KbdGxts[off] = "VKBD_9"; ADD_GXT("VKBD_9", "9"); off += 1; 
        KbdGxts[off] = "VKBD_0"; ADD_GXT("VKBD_0", "0");
        
        off = kbdGxt_base[1];
        KbdGxts[off] = "VKBD_Q"; ADD_GXT("VKBD_Q", "Q"); off += 1;
        KbdGxts[off] = "VKBD_W"; ADD_GXT("VKBD_W", "W"); off += 1;
        KbdGxts[off] = "VKBD_E"; ADD_GXT("VKBD_E", "E"); off += 1;
        KbdGxts[off] = "VKBD_R"; ADD_GXT("VKBD_R", "R"); off += 1;
        KbdGxts[off] = "VKBD_T"; ADD_GXT("VKBD_T", "T"); off += 1;
        KbdGxts[off] = "VKBD_Y"; ADD_GXT("VKBD_Y", "Y"); off += 1;
        KbdGxts[off] = "VKBD_U"; ADD_GXT("VKBD_U", "U"); off += 1;
        KbdGxts[off] = "VKBD_I"; ADD_GXT("VKBD_I", "I"); off += 1;
        KbdGxts[off] = "VKBD_O"; ADD_GXT("VKBD_O", "O"); off += 1;
        KbdGxts[off] = "VKBD_P"; ADD_GXT("VKBD_P", "P");
        
        off = kbdGxt_base[2];
        KbdGxts[off] = "VKBD_A"; ADD_GXT("VKBD_A", "A"); off += 1;
        KbdGxts[off] = "VKBD_S"; ADD_GXT("VKBD_S", "S"); off += 1;
        KbdGxts[off] = "VKBD_D"; ADD_GXT("VKBD_D", "D"); off += 1;
        KbdGxts[off] = "VKBD_F"; ADD_GXT("VKBD_F", "F"); off += 1;
        KbdGxts[off] = "VKBD_G"; ADD_GXT("VKBD_G", "G"); off += 1;
        KbdGxts[off] = "VKBD_H"; ADD_GXT("VKBD_H", "H"); off += 1;
        KbdGxts[off] = "VKBD_J"; ADD_GXT("VKBD_J", "J"); off += 1;
        KbdGxts[off] = "VKBD_K"; ADD_GXT("VKBD_K", "K"); off += 1;
        KbdGxts[off] = "VKBD_L"; ADD_GXT("VKBD_L", "L");

        off = kbdGxt_base[3];
        KbdGxts[off] = "VKBD_Z"; ADD_GXT("VKBD_Z", "Z"); off += 1;
        KbdGxts[off] = "VKBD_X"; ADD_GXT("VKBD_X", "X"); off += 1;
        KbdGxts[off] = "VKBD_C"; ADD_GXT("VKBD_C", "C"); off += 1;
        KbdGxts[off] = "VKBD_V"; ADD_GXT("VKBD_V", "V"); off += 1;
        KbdGxts[off] = "VKBD_B"; ADD_GXT("VKBD_B", "B"); off += 1;
        KbdGxts[off] = "VKBD_N"; ADD_GXT("VKBD_N", "N"); off += 1;
        KbdGxts[off] = "VKBD_M"; ADD_GXT("VKBD_M", "M");
    }
    while (true)
    {
        do WAIT(0);
        while (!PLAYER_DEFINED(0) || IS_CHAR_IN_A_CAR(PlayerChar) 
               || !PLAYER_PRESSED_KEY(0, 14) || !PLAYER_PRESSED_KEY(0, 18));
        
        SET_PLAYER_MOVABLE(0, 0);
        WRITE_MEMORY(0x439B0A, 4, 0x90909090, 1);    // NOP: .text:00439B0A 008                 call    AddCharToCheatString
        WRITE_MEMORY(0x439B0E, 1, 0x90, 1);
        WRITE_MEMORY(0x969110, 1, 0, 0);
        timer1 = 0;
        int selected_x, selected_y;
        
        selected_x = selected_y = 0;
        while (true)
        {
            if (timer1 >= 150)        // input rest-time
            {
                if (PLAYER_PRESSED_KEY(0, 15))    // ENTER VEHICLE
                    break;
                else if (PLAYER_PRESSED_KEY(0, 16))    // SPRINT
                {
                    int char;
                    int entry_ptr;
                    entry_ptr = GET_GXT_ENTRY_PTR(KbdGxts[kbdGxt_base[selected_y] + selected_x]);
                    if (entry_ptr != null)
                    {
                        // read first character from gxt
                        READ_MEMORY(entry_ptr, 1, 0, out char);
                        AddCharToCheatString(char);
                    }
                    else
                        HELP_MESSAGE_INTERMEDIATE_FORMAT("~r~GXT \'%s\' not found", KbdGxts[kbdGxt_base[selected_y] + selected_x]);
                    timer1 = 0;
                        
                }
                else if (GET_PLAYER_KEY_STATE(0, 0) > 100)        // GO_RIGHT
                {
                    selected_x += 1;
                    if (selected_x >= let_count[selected_y])
                    {
                        selected_x = 0;
                        selected_y += 1;
                        selected_y %= 4;
                    }
                    timer1 = 0;
                }
                else if (GET_PLAYER_KEY_STATE(0, 0) < -100)        // GO_LEFT
                {
                    selected_x -= 1;
                    if (selected_x < 0)
                    {
                        selected_y -= 1;
                        if (selected_y < 0)
                            selected_y = 3;
                        selected_x = let_count[selected_y] - 1;
                    }
                    timer1 = 0;
                }
                else if (GET_PLAYER_KEY_STATE(0, 1) > 100)        // GO_FORWARD
                {
                    selected_y += 1;
                    selected_y %= 4;
                    if (selected_x >= let_count[selected_y])
                        selected_x = let_count[selected_y] - 1;
                    timer1 = 0;
                }
                else if (GET_PLAYER_KEY_STATE(0, 1) < -100)        // GO_BACK
                {
                    selected_y -= 1;
                    if (selected_y < 0)
                        selected_y = 3;
                    if (selected_x >= let_count[selected_y])
                        selected_x = let_count[selected_y] - 1;
                    timer1 = 0;
                }
            }
            ADD_GXT("VKBD_CS", 0x969110);
            ENABLE_DRAWING(1);
            ADD_TEXT_DRAWER(80, 40, "VKBD_CS");
            DRAW_RECT(175, 75, 250, 80, 0, 0, 10, 200);
            SET_DRAW_FOREGROUND_COLOR(200, 200, 200, 255);
            SET_OUTLINE(1, 0, 0, 0, 255);
            
            float start_x, start_y;
            int i, j;
            start_x = start_y = 60;
            
            // draw kbd buttons
            for (j = 0; j < 4; j += 1)
            {
                float x, y;
                x = start_x;
                y = start_y;
                for (i = 0; i < let_count[j]; i += 1)
                {                
                    if (selected_y == j && selected_x == i)
                    {
                        SET_DRAW_FOREGROUND_COLOR(255, 255, 100, 255);
                        ADD_TEXT_DRAWER(x, y, KbdGxts[kbdGxt_base[j] + i]);
                        SET_DRAW_FOREGROUND_COLOR(200, 200, 200, 255);
                    }
                    else
                        ADD_TEXT_DRAWER(x, y, KbdGxts[kbdGxt_base[j] + i]);
                    x += 24;
                }
                start_x += 6;
                start_y += 14;
            }
            
            WAIT(0);
        }
        WRITE_MEMORY(0x439B0A, 4, 0xFFE971E8, 1);    // RESTORE: .text:00439B0A 008                 call    AddCharToCheatString
        WRITE_MEMORY(0x439B0E, 1, 0xFF, 1);

        SET_PLAYER_MOVABLE(0, 1);
        
    }
}

The decompiled SB code:

// This file was decompiled using sascm.ini published by Seemann (http://sannybuilder.com/files/SASCM.rar) on 13.10.2007

{$VERSION 3.1.0027}
{$CLEO .cs}

//-------------MAIN---------------
0AB1: call_scm_func @Noname_56 0 
0A93: end_custom_thread 

:Noname_C
0A8E: 4@ = 1@ + 2 // int 
0012: 4@ *= 2@  // Note: the incorrect math opcode was used here
0AC8: 3@ = allocate_memory_size 4@ 
else_jump @Noname_4F 
0A8F: 4@ = 3@ - 0@ // int 
0016: 4@ /= 2@  // Note: the incorrect math opcode was used here
0AB2: ret 1 4@ 
jump @Noname_56 

:Noname_4F
0AB2: ret 1 0 

:Noname_56
0AA9:   is_game_version_original 
else_jump @Noname_66 
jump @Noname_6B 

:Noname_66
0AB2: ret 0 

:Noname_6B
wait 3000 
4@ = 10 
5@ = 10 
6@ = 9 
7@ = 7 
8@ = 0 

:Noname_93
   not 8@ >= 4 
else_jump @Noname_FD 
0AC7: 9@ = var s$1000[0] offset 
0AB1: call_scm_func @Noname_C 3 9@ 4@(8@,4i) 8 0@(8@,4i) 
  0@(8@,4i) == 0 
else_jump @Noname_EF 
0ACA: show_text_box "MALLOC failed." 
0AB2: ret 0 

:Noname_EF
8@ += 1 
jump @Noname_93 

:Noname_FD
0006: 9@ = 0@  // Note: the incorrect math opcode was used here
05AA: $1000(9@,1s) = "VKBD_1" 
0ADF: add_dynamic_GXT_entry "VKBD_1" text "1" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_2" 
0ADF: add_dynamic_GXT_entry "VKBD_2" text "2" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_3" 
0ADF: add_dynamic_GXT_entry "VKBD_3" text "3" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_4" 
0ADF: add_dynamic_GXT_entry "VKBD_4" text "4" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_5" 
0ADF: add_dynamic_GXT_entry "VKBD_5" text "5" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_6" 
0ADF: add_dynamic_GXT_entry "VKBD_6" text "6" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_7" 
0ADF: add_dynamic_GXT_entry "VKBD_7" text "7" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_8" 
0ADF: add_dynamic_GXT_entry "VKBD_8" text "8" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_9" 
0ADF: add_dynamic_GXT_entry "VKBD_9" text "9" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_0" 
0ADF: add_dynamic_GXT_entry "VKBD_0" text "0" 
0006: 9@ = 1@  // Note: the incorrect math opcode was used here
05AA: $1000(9@,1s) = "VKBD_Q" 
0ADF: add_dynamic_GXT_entry "VKBD_Q" text "Q" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_W" 
0ADF: add_dynamic_GXT_entry "VKBD_W" text "W" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_E" 
0ADF: add_dynamic_GXT_entry "VKBD_E" text "E" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_R" 
0ADF: add_dynamic_GXT_entry "VKBD_R" text "R" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_T" 
0ADF: add_dynamic_GXT_entry "VKBD_T" text "T" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_Y" 
0ADF: add_dynamic_GXT_entry "VKBD_Y" text "Y" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_U" 
0ADF: add_dynamic_GXT_entry "VKBD_U" text "U" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_I" 
0ADF: add_dynamic_GXT_entry "VKBD_I" text "I" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_O" 
0ADF: add_dynamic_GXT_entry "VKBD_O" text "O" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_P" 
0ADF: add_dynamic_GXT_entry "VKBD_P" text "P" 
0006: 9@ = 2@  // Note: the incorrect math opcode was used here
05AA: $1000(9@,1s) = "VKBD_A" 
0ADF: add_dynamic_GXT_entry "VKBD_A" text "A" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_S" 
0ADF: add_dynamic_GXT_entry "VKBD_S" text "S" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_D" 
0ADF: add_dynamic_GXT_entry "VKBD_D" text "D" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_F" 
0ADF: add_dynamic_GXT_entry "VKBD_F" text "F" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_G" 
0ADF: add_dynamic_GXT_entry "VKBD_G" text "G" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_H" 
0ADF: add_dynamic_GXT_entry "VKBD_H" text "H" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_J" 
0ADF: add_dynamic_GXT_entry "VKBD_J" text "J" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_K" 
0ADF: add_dynamic_GXT_entry "VKBD_K" text "K" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_L" 
0ADF: add_dynamic_GXT_entry "VKBD_L" text "L" 
0006: 9@ = 3@  // Note: the incorrect math opcode was used here
05AA: $1000(9@,1s) = "VKBD_Z" 
0ADF: add_dynamic_GXT_entry "VKBD_Z" text "Z" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_X" 
0ADF: add_dynamic_GXT_entry "VKBD_X" text "X" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_C" 
0ADF: add_dynamic_GXT_entry "VKBD_C" text "C" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_V" 
0ADF: add_dynamic_GXT_entry "VKBD_V" text "V" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_B" 
0ADF: add_dynamic_GXT_entry "VKBD_B" text "B" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_N" 
0ADF: add_dynamic_GXT_entry "VKBD_N" text "N" 
9@ += 1 
05AA: $1000(9@,1s) = "VKBD_M" 
0ADF: add_dynamic_GXT_entry "VKBD_M" text "M" 

:Noname_635
wait 0 
   Player.Defined(0)
else_jump @Noname_635 
0449:   actor $PLAYER_ACTOR in_a_car 
else_jump @Noname_657 
jump @Noname_635 

:Noname_657
00E1:   player 0 pressed_key 14 
else_jump @Noname_635 
00E1:   player 0 pressed_key 18 
else_jump @Noname_635 
Player.CanMove(0) = False
0A8C: write_memory 4430602 size 4 value -1869574000 virtual_protect 1 
0A8C: write_memory 4430606 size 1 value 144 virtual_protect 1 
0A8C: write_memory 9867536 size 1 value 0 virtual_protect 0 
32@ = 0 
9@ = 0 
0006: 8@ = 9@  // Note: the incorrect math opcode was used here

:Noname_6B8
  32@ >= 150 
else_jump @Noname_8E5 
00E1:   player 0 pressed_key 15 
else_jump @Noname_6E2 
jump @Noname_A5A 
jump @Noname_8E5 

:Noname_6E2
00E1:   player 0 pressed_key 16 
else_jump @Noname_778 
0A8E: 12@ = 0@(9@,4i) + 8@ // int 
0ADE: 11@ = text_by_GXT_entry $1000(12@,1s) 
   not 11@ == 0 
else_jump @Noname_73A 
0A8D: 10@ = read_memory 11@ size 1 virtual_protect 0 
0AA5: call 4424832 1 pop 1 10@ 
jump @Noname_76A 

:Noname_73A
0A8E: 12@ = 0@(9@,4i) + 8@ // int 
0ACE: show_formatted_text_box "~r~GXT '%s' not found" $1000(12@,1s)  

:Noname_76A
32@ = 0 
jump @Noname_8E5 

:Noname_778
00E2: get_player 0 key 0 state_to 10@ 
  10@ > 100 
else_jump @Noname_7CF 
8@ += 1 
002D:   8@ >= 4@(9@,4i) // (int) 
else_jump @Noname_7C1 
8@ = 0 
9@ += 1 
0B14: 9@ = 9@ MOD 4 

:Noname_7C1
32@ = 0 
jump @Noname_8E5 

:Noname_7CF
00E2: get_player 0 key 0 state_to 10@ 
   not 10@ >= -100 
else_jump @Noname_833 
8@ -= 1 
   not 8@ >= 0 
else_jump @Noname_825 
9@ -= 1 
   not 9@ >= 0 
else_jump @Noname_817 
9@ = 3 

:Noname_817
0A8F: 8@ = 4@(9@,4i) - 1 // int 

:Noname_825
32@ = 0 
jump @Noname_8E5 

:Noname_833
00E2: get_player 0 key 1 state_to 10@ 
  10@ > 100 
else_jump @Noname_88A 
9@ += 1 
0B14: 9@ = 9@ MOD 4 
002D:   8@ >= 4@(9@,4i) // (int) 
else_jump @Noname_87C 
0A8F: 8@ = 4@(9@,4i) - 1 // int 

:Noname_87C
32@ = 0 
jump @Noname_8E5 

:Noname_88A
00E2: get_player 0 key 1 state_to 10@ 
   not 10@ >= -100 
else_jump @Noname_8E5 
9@ -= 1 
   not 9@ >= 0 
else_jump @Noname_8BD 
9@ = 3 

:Noname_8BD
002D:   8@ >= 4@(9@,4i) // (int) 
else_jump @Noname_8DE 
0A8F: 8@ = 4@(9@,4i) - 1 // int 

:Noname_8DE
32@ = 0 

:Noname_8E5
0ADF: add_dynamic_GXT_entry 'VKBD_CS' text 9867536 
03F0: enable_text_draw 1 
033E: set_draw_text_position 80.0 40.0 GXT 'VKBD_CS' 
038E: draw_box_position 175.0 75.0 size 250.0 80.0 RGBA 0 0 10 200 
0340: set_text_draw_RGBA 200 200 200 255 
081C: draw_text_outline 1 RGBA 0 0 0 255 
11@ = 60.0 
0007: 10@ = 11@  // Note: the incorrect math opcode was used here
13@ = 0 

:Noname_961
   not 13@ >= 4 
else_jump @Noname_A4F 
0007: 14@ = 10@  // Note: the incorrect math opcode was used here
0007: 15@ = 11@  // Note: the incorrect math opcode was used here
12@ = 0 

:Noname_986
802D:   not  12@ >= 4@(13@,4i) // (int) 
else_jump @Noname_A2D 
003B:   9@ == 13@ // (int) 
else_jump @Noname_9F7 
003B:   8@ == 12@ // (int) 
else_jump @Noname_9F7 
0340: set_text_draw_RGBA 255 255 100 255 
0A8E: 16@ = 0@(13@,4i) + 12@ // int 
033E: set_draw_text_position 14@ 15@ GXT $1000(16@,1s) 
0340: set_text_draw_RGBA 200 200 200 255 
jump @Noname_A15 

:Noname_9F7
0A8E: 16@ = 0@(13@,4i) + 12@ // int 
033E: set_draw_text_position 14@ 15@ GXT $1000(16@,1s) 

:Noname_A15
14@ += 24.0 
12@ += 1 
jump @Noname_986 

:Noname_A2D
10@ += 6.0 
11@ += 14.0 
13@ += 1 
jump @Noname_961 

:Noname_A4F
wait 0 
jump @Noname_6B8 

:Noname_A5A
0A8C: write_memory 4430602 size 4 value -1478168 virtual_protect 1 
0A8C: write_memory 4430606 size 1 value 255 virtual_protect 1 
Player.CanMove(0) = True
jump @Noname_635

Pay attention on this lines:
1) it is necessary to NOP function AddCharToCheatString call

        WRITE_MEMORY(0x439B0A, 4, 0x90909090, 1);    // NOP: .text:00439B0A 008                 call    AddCharToCheatString
        WRITE_MEMORY(0x439B0E, 1, 0x90, 1);

and restore it after the virtual keyboard is closed:

        WRITE_MEMORY(0x439B0A, 4, 0xFFE971E8, 1);    // RESTORE: .text:00439B0A 008                 call    AddCharToCheatString
        WRITE_MEMORY(0x439B0E, 1, 0xFF, 1);

2) when the user presses SPRINT, we are putting the current character to cheat queue:

[FunctionPointer=0x438480]
native void AddCharToCheatString(int key);
...
				else if (PLAYER_PRESSED_KEY(0, 16))	// SPRINT
				{
					int char;
					int entry_ptr;
					entry_ptr = GET_GXT_ENTRY_PTR(KbdGxts[kbdGxt_base[selected_y] + selected_x]);
					if (entry_ptr != null)
					{
						// read the first character from gxt entry
						READ_MEMORY(entry_ptr, 1, 0, out char);
						AddCharToCheatString(char);
					}
					else
						HELP_MESSAGE_INTERMEDIATE_FORMAT("~r~GXT \'%s\' not found", KbdGxts[kbdGxt_base[selected_y] + selected_x]);
					timer1 = 0;
						
				}

Like this... Hope, it will help ya.=)

Last edited by Alien (18-09-2010 18:06)

Offline

#3 18-09-2010 16:48

Deji
From: UK
Registered: 09-11-2008
Posts: 189
Website

Re: On-Screen Keyboard - Help

I still don't fully understand the compiler, but after the Opcode Database upgrade, a lot of GTA IV Native Function Names will be linked to the opcodes. Most opcodes already have pretty decent descriptions and parameter information linked to them, so I'd be willing to enable the database to export a file for this project.

Thanks for the help. I assume since the compiler is not yet publicly available, the source will not be compilable for me? I'm interested in using this syntax as it may prepare me for coding in C++ - And the decompiled version is pretty confusing.


Hmm.. the keyboard selects the character to the left indefinitely... I assume the wrong value was used for checking whether the joystick was pressed to the left.


EDIT

                else if (GET_PLAYER_KEY_STATE(0, 0) > 100)        // GO_RIGHT
                {
                    selected_x += 1;
                    if (selected_x >= let_count[selected_y])
                    {
                        selected_x = 0;
                        selected_y += 1;
                        selected_y %= 4;
                    }
                    timer1 = 0;
                }
                else if (GET_PLAYER_KEY_STATE(0, 0) < -100)        // GO_LEFT
                {
                    selected_x -= 1;
                    if (selected_x < 0)
                    {
                        selected_y -= 1;
                        if (selected_y < 0)
                            selected_y = 3;
                        selected_x = let_count[selected_y] - 1;
                    }
                    timer1 = 0;
                }
                else if (GET_PLAYER_KEY_STATE(0, 1) > 100)        // GO_FORWARD
                {
                    selected_y += 1;
                    selected_y %= 4;
                    if (selected_x >= let_count[selected_y])
                        selected_x = let_count[selected_y] - 1;
                    timer1 = 0;
                }
                else if (GET_PLAYER_KEY_STATE(0, 1) < -100)        // GO_BACK
                {
                    selected_y -= 1;
                    if (selected_y < 0)
                        selected_y = 3;
                    if (selected_x >= let_count[selected_y])
                        selected_x = let_count[selected_y] - 1;
                    timer1 = 0;
                }

I can't compile though smile

.. Or will a C compiler do the job in some way? I'm a bit confused.

Last edited by Deji (18-09-2010 16:54)

Offline

#4 18-09-2010 17:56

Alien
Registered: 12-10-2008
Posts: 564

Re: On-Screen Keyboard - Help

Deji wrote:

Hmm.. the keyboard selects the character to the left indefinitely... I assume the wrong value was used for checking whether the joystick was pressed to the left.

Ah yes. Earlier in this place stood zero

 if (GET_PLAYER_KEY_STATE(0, 0) < 0)        // GO_LEFT

But then I have thought that on joypad these values will be analog, instead of discrete (+128,-128 as on the keypad), and sensitivity needs to be reduced... I have set 100, and minuses have got lost.

Deji wrote:

I'm interested in using this syntax as it may prepare me for coding in C++

C++ coding is much more compilcated. Scripting C-like language is as much as possible simplified. If to undertake a C ++ imho it is better to undertake at once from the correct end. There's many theoretical concepts which should be studied such as: classes, polymorphism, inheritance, templates etc. Take a book 'The C++ Programming Language' by Bjarne Stroustrup (I studied under this book) and start to read.

Deji wrote:

I still don't fully understand the compiler, but after the Opcode Database upgrade, a lot of GTA IV Native Function Names will be linked to the opcodes. Most opcodes already have pretty decent descriptions and parameter information linked to them, so I'd be willing to enable the database to export a file for this project.

It is pleasant to hear. Association of opcodes and IV-natives would take away from me too much time. I hoped that there will be someone who could be engaged in it, but till now interested persons weren't.

Deji wrote:

I can't compile though

Use decompiled code as a source. The C-like code has been shown only as the pseudocode, for the best digestibility. If there is some compilation problems with SB, i've attached compiled script.

I assume since the compiler is not yet publicly available, the source will not be compilable for me?

It is not up to the end written yet IDE for the compiler. So, the source will not be compilable for anybody (except me).

Last edited by Alien (18-09-2010 17:58)

Offline

#5 18-09-2010 21:37

Deji
From: UK
Registered: 09-11-2008
Posts: 189
Website

Re: On-Screen Keyboard - Help

I'll take a look at that, thanks. I've been going through multiple online tutorials on C++, C++/CLI and C#... Trying to decide which one to focus on more. I've nearly gone through one whole tutorial on C++ and still have no clue on how to do anything. Learning C# seems more effective, but maybe it'd help to look around for some C++ source codes on simple programs to understand how to put stuff to use.

I'll try and make more sense of the decompiled code tommorrow and release.

Offline

#6 19-09-2010 19:17

TheSiggi
Registered: 23-06-2010
Posts: 3

Re: On-Screen Keyboard - Help

Deji wrote:

I'll take a look at that, thanks. I've been going through multiple online tutorials on C++, C++/CLI and C#... Trying to decide which one to focus on more. I've nearly gone through one whole tutorial on C++ and still have no clue on how to do anything. Learning C# seems more effective, but maybe it'd help to look around for some C++ source codes on simple programs to understand how to put stuff to use.

I'll try and make more sense of the decompiled code tommorrow and release.

I know this is offtopic but it might help you to make a decision concerning your question on which language to focus on:

C++ is still the standard language favoured by most Software devolpers and nearly all game developers because its faster ( concerning the runtime compiler speed).
C# uses a clearer structure than C++/CLI does and the latest update minimized the speed advantage of CLI to C# on only 20% and the C# compiler is improved [hangover]everyday, every fuckin day! [/hangover] and so it will take a couple of years until C++ has little advantages

I have a friend who works as programmer and software developer and he told me theres a change going on in the applied informatics scene... an increasing number of software developers are changing their requirements:
They appoint more and more C# programmers or even switch completly to C#.

So, although its not the most popular language it soon will turn into the most used (or a better language gets released :S)

cheers

Offline

#7 20-09-2010 10:52

Alien
Registered: 12-10-2008
Posts: 564

Re: On-Screen Keyboard - Help

On the subject. It is possible also to check, if the cheat code have been applied, and to close the keyboard, when it happens:

                else if (PLAYER_PRESSED_KEY(0, 16))    // SPRINT
                {
                    int char;
                    int entry_ptr;
                    entry_ptr = GET_GXT_ENTRY_PTR(KbdGxts[kbdGxt_base[selected_y] + selected_x]);
                    if (entry_ptr != null)
                    {
                        // read first character from gxt
                        READ_MEMORY(entry_ptr, 1, 0, out char);
                        AddCharToCheatString(char);

                        READ_MEMORY(0x969110, 1, 0, out char);
                        // the cheat code is applied
                        if (char == 0)
                            break;
                    }
                    else
                        HELP_MESSAGE_INTERMEDIATE_FORMAT("~r~GXT \'%s\' not found", KbdGxts[kbdGxt_base[selected_y] + selected_x]);
                    timer1 = 0;
                        
                }

@TheSiggi - Well, in GTA-modding native (non-managed) C/C++ occupes also niche of ASI libraries. It has that advantage that is compiled in the same code which is used by game (x86 code). It allows to replace some parts of a code of game with your own code. But these tricks concern a category of dirty hacks and no normal programmer will train in these tricks of students. And there's needs also a base knowledge of x86 asm.

but maybe it'd help to look around for some C++ source codes on simple programs to understand how to put stuff to use.

You can learn the language first, and then, when you will feel the skills of language the sufficient, take a look at source codes of some ASI libraries.

C# is focused first of all on convenience of working out of a normal software (instead of ASI libraries). I do love this language. The cleo script compiler (to which I generally yet haven't thought up the name) is written under this language. Now I think over creation of the personal site based on ASP.NET and here is used C# again. Actually, the width of applicability of C# and .NET at all amazes.

GTAG v2 (all about modding) - Coming Soon.

Any terms on when it will happen?

Offline

#8 20-09-2010 16:10

Silent
Registered: 08-05-2010
Posts: 29

Re: On-Screen Keyboard - Help

Alien wrote:

GTAG v2 (all about modding) - Coming Soon.

Any terms on when it will happen?

I believe that Deji will open v2 when he'll finish some things and additional languages translations. However v1 has many modding infos also tongue

Offline

#9 02-10-2010 12:32

vellis4frankli
From: 1905 Willow Ave, Weehawken.
Registered: 02-10-2010
Posts: 1

Re: On-Screen Keyboard - Help

The goal of this site is to have all GTA modding related knowledge in one convenient place. At the moment this will consist of guides and tutorials for modding as well as modding related documentation. All GTANet members can contribute their knowledge and are invited to write articles for the site

Offline

#10 02-10-2010 15:37

Deji
From: UK
Registered: 09-11-2008
Posts: 189
Website

Re: On-Screen Keyboard - Help

...

Are you a META dumping bot or something? I'm ultimately confused. Too confused to think of a response rolleyes

Offline

Board footer

Powered by FluxBB