Usage:
Functions to copy+paste somewhere at the end of your code:
Full working example:
Tested with:
- Cleo 4.1
- Samp 0.3.7 R1
- Sampfuncs 5.4.1-final
Code:
alloc 2@ 100
format 2@ "CLEO/audio/*.mp3"
call @load_file_names 2 max_filenames 1000 wildcard 2@ _name_array 0@ _index_of_highest_loaded_name 1@
for 31@ = 0 to 1@
call @get_nth_file_name 2 name_array 0@ n 31@ _returned_name 30@
chatmsg "%d. %s" -1 31@ 30@
end
Functions to copy+paste somewhere at the end of your code:
Code:
:get_nth_file_name
{
Input params:
0@ = pointer to array of pointers, each leading to filename
1@ = n (starting with 0)
Usage:
call @get_nth_file_name 2 name_array 0@ n 0 _returned_name 30@
}
1@ *= 4 // each pointer has 4 bytes
005A: 0@ += 1@ // (int)
0A8D: 31@ = read_memory 0@ size 4 virtual_protect 0
ret 1 31@
:load_file_names
{
Input params:
0@ = filenames limit
1@ = wildcard (e.g. "CLEO/audio/*.mp3")
Usage:
call @load_file_names 2 max_filenames 1000 wildcard 2@ _name_array 0@ _index_of_highest_loaded_name 1@
}
0085: 24@ = 0@ // copy of max_filenames
24@ *= 4
24@ += 4
alloc 26@ 24@ // pointer to pointers (4000 will allow to store 1000 pointers, so if there is 1001 files found then the code will possibly crash)
//chatmsg "base addr = %X" -1 26@
0085: 25@ = 26@ // 25@ is a copy to manipulate (26@, the begining of array, will be returned)
31@ = 0 // loaded file count
alloc 30@ 400 // max length of a single file name (if larger is encountered the code will possibly crash)
if 0AE6: 29@ = find_first_file 1@ get_filename_to 30@
then
repeat
wait 0
0C17: 28@ = strlen 30@
alloc 27@ 28@ // additional byte to end the string is not required because we will not store the ".mp3"
0AA5: call 0x8220AD num_params 3 pop 3 27@ "%[^.]" 30@ // just so the title doesn't contain ".mp3" at the end
31@ += 1
//chatmsg "string addr = %X at %X" -1 27@ 25@
0A8C: write_memory 25@ size 4 value 27@ virtual_protect 0 // save the pointer in our array of pointers
25@ += 4
if 003B: 31@ == 0@
then
printf "Max number (%d) of files was reached. Rest is ignored." 5000 0@
break
end
until 8AE7: 30@ = find_next_file 29@
0AE8: find_close 29@
0A8C: write_memory 25@ size 4 value 0 virtual_protect 0
else
printf "No files found at all using: %s" 10000 1@
end
free 30@
31@ -= 1
ret 2 26@ 31@
:release_file_names
{
If you use @load_file_names function consecutively without releasing the memory, then it will take too much of it.
Input params:
0@ = name_array (pointer to array of pointers to allocated memory)
Usage:
call @release_file_names 1 name_array 0@
}
0A8D: 31@ = read_memory 0@ size 4 virtual_protect 0
repeat
wait 0
free 31@
0@ += 4
0A8D: 31@ = read_memory 0@ size 4 virtual_protect 0
until 31@ == 0
ret 0
Full working example:
Code:
{$CLEO .cs}
0000: NOP
repeat
wait 50
until 0AFA: is_samp_structures_available
0B34: samp register_client_command "show_names" to_label @cmd_show_names
0B34: samp register_client_command "reload_names" to_label @cmd_reload_names
alloc 2@ 100
format 2@ "CLEO/audio/*.mp3"
call @load_file_names 2 max_filenames 1000 wildcard 2@ _name_array 0@ _index_of_highest_loaded_name 1@ //(_index_of_highest_loaded_name = how_many_loaded - 1)
while true
wait 1000
end
:cmd_show_names
if 1@ > -1
then
chatmsg "{00FF00}File names:" -1
for 31@ = 0 to 1@
call @get_nth_file_name 2 name_array 0@ n 31@ _returned_name 30@
chatmsg "%d. %s" -1 31@ 30@
//chatmsg "%d. %s {AAAAAA} - addr = %X" -1 31@ 30@ 30@
end
else
chatmsg "{FF0000}ERROR: {FFFFFF}No names were loaded..." -1
end
samp.CmdRet()
:cmd_reload_names
call @release_file_names 1 _name_array 0@
call @load_file_names 2 max_filenames 1000 wildcard 2@ _name_array 0@ _index_of_highest_loaded_name 1@
samp.CmdRet()
:get_nth_file_name
{
Input params:
0@ = pointer to array of pointers, each leading to filename
1@ = n (starting with 0)
Usage:
call @get_nth_file_name 2 name_array 0@ n 0 _returned_name 30@
}
1@ *= 4 // each pointer has 4 bytes
005A: 0@ += 1@ // (int)
0A8D: 31@ = read_memory 0@ size 4 virtual_protect 0
ret 1 31@
:load_file_names
{
Input params:
0@ = filenames limit
1@ = wildcard (e.g. "CLEO/audio/*.mp3")
Usage:
call @load_file_names 2 max_filenames 1000 wildcard 2@ _name_array 0@ _index_of_highest_loaded_name 1@
}
0085: 24@ = 0@ // copy of max_filenames
24@ *= 4
24@ += 4
alloc 26@ 24@ // pointer to pointers (4000 will allow to store 1000 pointers, so if there is 1001 files found then the code will possibly crash)
//chatmsg "base addr = %X" -1 26@
0085: 25@ = 26@ // 25@ is a copy to manipulate (26@, the begining of array, will be returned)
31@ = 0 // loaded file count
alloc 30@ 400 // max length of a single file name (if larger is encountered the code will possibly crash)
if 0AE6: 29@ = find_first_file 1@ get_filename_to 30@
then
repeat
wait 0
0C17: 28@ = strlen 30@
alloc 27@ 28@ // additional byte to end the string is not required because we will not store the ".mp3"
0AA5: call 0x8220AD num_params 3 pop 3 27@ "%[^.]" 30@ // just so the title doesn't contain ".mp3" at the end
31@ += 1
//chatmsg "string addr = %X at %X" -1 27@ 25@
0A8C: write_memory 25@ size 4 value 27@ virtual_protect 0 // save the pointer in our array of pointers
25@ += 4
if 003B: 31@ == 0@
then
printf "Max number (%d) of files was reached. Rest is ignored." 5000 0@
break
end
until 8AE7: 30@ = find_next_file 29@
0AE8: find_close 29@
0A8C: write_memory 25@ size 4 value 0 virtual_protect 0
else
printf "No files found at all using: %s" 10000 1@
end
free 30@
31@ -= 1
ret 2 26@ 31@
:release_file_names
{
If you use @load_file_names function consecutively without releasing the memory, then it will take too much of it.
Input params:
0@ = name_array (pointer to array of pointers to allocated memory)
Usage:
call @release_file_names 1 name_array 0@
}
0A8D: 31@ = read_memory 0@ size 4 virtual_protect 0
repeat
wait 0
free 31@
0@ += 4
0A8D: 31@ = read_memory 0@ size 4 virtual_protect 0
until 31@ == 0
ret 0
Tested with:
- Cleo 4.1
- Samp 0.3.7 R1
- Sampfuncs 5.4.1-final