You are not logged in.
Pages: 1
Here's the code for an on-screen keyboard I'm creating for joypad users...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | { $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 0x 969110 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 0x 969110 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
Nice idea. And here's fully working script. The source code is for this compiler (which is not in public access for a while).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | [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]); timer 1 = 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; } timer 1 = 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; } timer 1 = 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | // 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
1 2 | 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:
1 2 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | [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]); timer 1 = 0; } |
Like this... Hope, it will help ya.=)
Last edited by Alien (18-09-2010 18:06)
Offline
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 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; } timer 1 = 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; } timer 1 = 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
.. 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
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
1 | 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.
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.
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.
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
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
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
On the subject. It is possible also to check, if the cheat code have been applied, and to close the keyboard, when it happens:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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]); timer 1 = 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
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
Offline
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
...
Are you a META dumping bot or something? I'm ultimately confused. Too confused to think of a response
Offline
Pages: 1