Enero 10, 2013, 09:21:20 AM Ultima modificación: Enero 20, 2013, 02:05:05 PM por Wadk
  • Nombre del creador: Wadk
  • Breve descripción de su función: Comprueba si un archivo dado es una partida guardada que corresponde al juego actual. Nótese que el script puede fallar si, por alguna casualidad estratosférica, un archivo cualquiera llega a tener el game_id del juego en cuestión en los bytes del 4 al 7. Creo que es más probable que te caiga un rayo en un día soleado, y después otro.
  • Versión GM utilizada: :GM8: , posiblemente funcione en otras.
  • Código del Script:[gml]// file_is_savegame(file);
    // Return whether the given file is a valid savegame of the current game.

    var f, i, value;
    f = file_bin_open(argument0, 0);

    value = 0;
    for (i = 0; i < 4; i += 1) {
        file_bin_seek(f, 4 + i);
        value += file_bin_read_byte(f) << (i << 3);
    }

    file_bin_close(f);
    return (value == game_id);[/gml]
    El único argumento es la localización del archivo a verificar.

Es un script que creé hace un par de años para una pregunta: http://www.comunidadgm.org/index.php?topic=11653

Pensé que ya lo había puesto en esta sección, pero lo busqué y no lo encontré, así que bueno, acá está.
Esta versión es un poco distinta (más optimizada) pero no está probada. Cualquier problema lo reportan acá.

Saludos.
Vim.

sabía que el Game_id se guardaba en alguna parte del savegame pero no sabía dónde... pero... lo más interesante que puedo extraer de este script es la linea de:
[gml]
value += file_bin_read_byte(f) * power(256, i);
[/gml]
Osea, no se me hubiera ocurrido que poniendole power a la i y sumandolo se podía convertir a decimal el valor... jaja... muy util...
Cita de: CGM 2008CGM: Un poco mas serios, mejores Juegos.
Bienvenid@ a CGM. Recomenzamos desde cero, con un reglamento mas estricto, mejor definido y con mas ganas que nunca de hacer juegos con calidad comercial. El que avisa no es traidor: Leete las reglas si no quieres llevarte un capon makero.
Mercilessly!!
Plug-In para animaciones: http://ciberman.net/tweenline/

Cita de: Ciberman en Enero 14, 2013, 08:18:24 PM
sabía que el Game_id se guardaba en alguna parte del savegame pero no sabía dónde... pero... lo más interesante que puedo extraer de este script es la linea de:
[gml]
value += file_bin_read_byte(f) * power(256, i);
[/gml]
Osea, no se me hubiera ocurrido que poniendole power a la i y sumandolo se podía convertir a decimal el valor... jaja... muy util...
Claro :P. Es porque esencialmente se lee en base 256. Si se leyera en binario (base 2), sería power(2, i), octal (base 8) sería power(8, i)... en fin, que es un cambio de base común y corriente.
Vim.

Cita de: Wadk en Enero 14, 2013, 09:01:44 PM
Cita de: Ciberman en Enero 14, 2013, 08:18:24 PM
sabía que el Game_id se guardaba en alguna parte del savegame pero no sabía dónde... pero... lo más interesante que puedo extraer de este script es la linea de:
[gml]
value += file_bin_read_byte(f) * power(256, i);
[/gml]
Osea, no se me hubiera ocurrido que poniendole power a la i y sumandolo se podía convertir a decimal el valor... jaja... muy util...
Claro :P. Es porque esencialmente se lee en base 256. Si se leyera en binario (base 2), sería power(2, i), octal (base 8) sería power(8, i)... en fin, que es un cambio de base común y corriente.
Y como casi todo lo que es potencia de dos en las computadoras puede ser usado a nivel de bits.

256<<(i-1<<3);

El código anterior da el mismo resultado que usando power excepto en la potencia 0 que da un numero enorme. aunque no seria muy útil en el script de wadk tal vez para ciertos bucles enormes podría llegar a ser útil.

#4 Enero 16, 2013, 03:55:06 AM Ultima modificación: Enero 16, 2013, 03:58:30 AM por Wadk
Opaa, no la tenía esa. Debe ser muchísimo más rápido. A ver, versión experimental potencialmente mucho más rápida:
[gml]// file_is_savegame(file);
// Return whether the given file is a valid savegame of the current game.

var f, i, value;
f = file_bin_open(argument0, 0);

file_bin_seek(f, 4);
value = file_bin_read_byte(f);
for (i = 0; i < 3; i += 1) {
    file_bin_seek(f, 5 + i);
    value += file_bin_read_byte(f) * (256 << (i << 3));
}

file_bin_close(f);
return (value == game_id);[/gml]
¿Así sería? Los paréntesis los puse por las dudas porque ni idea de si << tiene prioridad o no sobre *.
Vim.

#5 Enero 16, 2013, 05:47:18 AM Ultima modificación: Enero 16, 2013, 10:26:38 PM por brunoxzx
Cita de: Wadk en Enero 16, 2013, 03:55:06 AM
Opaa, no la tenía esa. Debe ser muchísimo más rápido. A ver, versión experimental potencialmente mucho más rápida:
[gml]// file_is_savegame(file);
// Return whether the given file is a valid savegame of the current game.

var f, i, value;
f = file_bin_open(argument0, 0);

file_bin_seek(f, 4);
value = file_bin_read_byte(f);
for (i = 0; i < 3; i += 1) {
    file_bin_seek(f, 5 + i);
    value += file_bin_read_byte(f) * (256 << (i << 3));
}

file_bin_close(f);
return (value == game_id);[/gml]
¿Así sería? Los paréntesis los puse por las dudas porque ni idea de si << tiene prioridad o no sobre *.
Sí, si sería así pero corroborando me acabo de dar cuenta de que:
[gml]
n<<(i <<3)=n*power(i, 256);
[/gml]
Y funciona con el 0 xD.

así que solo se remplazaría el power y es probable que elevar a la 256 (y tal vez cualquier potencia de 2 positiva) sea aun mas rápido que una multiplicación.
[gml]value += file_bin_read_byte(f)<<(i <<3);[/gml]

P.D: En realidad esto de elevar a potencias de 2 no lo supe hasta ayer xD.
P.D2:Yo tampoco tengo idea de como sea la jerarquía de operaciones a nivel de bits pero en el código que puse ayer había una resta y cuando lo probé se ejecutaba antes que las "<<".

OK, OTRA versión experimental potencialmente MÁS rápida todavía:
[gml]// file_is_savegame(file);
// Return whether the given file is a valid savegame of the current game.

var f, i, value;
f = file_bin_open(argument0, 0);

value = 0;
for (i = 0; i < 4; i += 1) {
    file_bin_seek(f, 4 + i);
    value += file_bin_read_byte(f) << (i << 3);
}

file_bin_close(f);
return (value == game_id);[/gml]
Vim.