MSX Village forum

La Place des Développeurs Do The Same - MSX

Ricco59 Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 02/01/2021 à 11h22

Messages: 248

Le 30/04/2021 à 00h17
Salut la compagnie

Voilà, à peine "Where Is It ?" inscrit au MSXDEV'21, je me remets en route avec le portage d'un jeu qui est pratiquement fini sur Coleco.
Son nom... il le signe à la poin-teu de l'épée.... mais naannn "Do The Same"

Il s'agit d'un jeu créé lors d'une convention AC ou RGC par Matmook sur Atari Jaguar en full assembleur

Aimant ce jeu, lors de la dernière RGC, je lui ai demandé si je pouvais faire une conversion de DTS sur coleco. Il m'a dit qu'il n'y avait aucun souci.
DTS a été entièrement codé from scratch en C sur Coleco/Msx. La seule chose que j'ai récupérée est l'ensemble des niveaux de la version Jag' (112 )

La version coleco a été mise en standby (pratiquement terminée : il me reste le sfx et les graphs d'un background) parce que je me suis mis au MSX et de fait, j'ai fini Wii ? :)

J'ai donc commencé hier soir la version MSX
Toute l'intro et le menu fonctionnent.
Voici quelques images (il reste des modifs à faire)







N'hésitez pas à me dire ce que vous en pensez
Pour voir le jeu en action (version coleco), c'est ici

Bonne nuit/journée les potos :) Edité par Ricco59 Le 01/05/2021 à 17h50


Tous mes travaux sont centralisés sur mon piti blog : https://ricco59.blogspot.com/
E-mail    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2743

Le 30/04/2021 à 10h21
Les T sont biens lisibles ; c'est bon, je valide ! :lol

Plus sérieusement, ça à l'air bien cool. :top

J'ai regardé que 5 premières mins de la vidéo et je me demande juste comment tu vas apporté de la difficulté ?
On arrive très vite à l'écran remplis.


On est toujours ignorant avant de savoir.
Github    
Jipe Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 02/10/2009 à 19h41

Messages: 10420

Le 30/04/2021 à 10h50
Super tu as le droit de proposer plusieurs jeux au MSXdev et l'échéance est Aout ;)


:noel
Site web    
TurboSEB Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 08/08/2010 à 20h57

Messages: 5816

Le 30/04/2021 à 15h43
Tout est dans le titre :tea
Original comme jeu :) Edité par TurboSEB Le 30/04/2021 à 17h50



MSX 1&2 + Moniteurs+divers (environ 0.70Tonnes)
   
Ricco59 Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 02/01/2021 à 11h22

Messages: 248

Le 01/05/2021 à 12h27
Salut les Potos

Voici une chtite video du menu en action :)
Video DTS

@Guillaume, je savais que les fonts te feraient plaisirs :lol

Pour ce qui est de la difficulté, j'ai eu les niveaux comme ça. Ensuite zone remplie ou pas, tout dépend des mélanges : nbre de fois à droite / à gauche et le temps aussi qui vient jouer le trouble fêtes

Ce soir je m'y remets ;)

Belle journée à tous et bon 1er Mai


Tous mes travaux sont centralisés sur mon piti blog : https://ricco59.blogspot.com/
E-mail    
Ricco59 Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 02/01/2021 à 11h22

Messages: 248

Le 03/05/2021 à 23h47
Hello,

Le jeu fonctionne :tchin
Mais ce fut un combat acharné avec un bug stupide de ma part. En effet, dans ma routine de comparaison des figures (en ASM), j'ai "commenté" le RET alors que cette routine était __naked !!!

Donc dès que le test se faisait, la routine s'exécutait ainsi que celle qui était juste en dessous !!
Cette routine 'Affiche_level(Lvl)' était appelée dans le jeu.
J'ai commenté cette routine partout où elle se trouvait et la valeur s'affichait qd meme !!?? esprit es-tu lo ?? :fou
Je pensais que c'est 'Affiche_level()' qui merdouillait.... eh bien non, c'etait le RET que j'avais oublié de décommenter...

Pffiiiooouuu
C'est résolu

ma todolist

+ mettre les diagonales dans la partie jeu

+ gerer les fires (fire1 clockwise, fire2 anticlockwise)
A ce sujet, évidemment c'est 'simple' avec un stick 2 bouttons, mais comment feriez-vous pour un systeme ClockWise/antiCW avec un stick UN boutton ?? stick + clavier pas très pratique ...
ou alors c'est soit clavier (fleches de direction + 2 touches) OU stick 2 bouttons et rien d'autres
Merci de me donner votre avis ;)

+ changer le system de password. Pour le moment, le passw permet de recommencer à un autre endroit
Je souhaite creer le password en fonction du temps mis pour trouver une figure
De ce fait le joueur va pourvoir, sur le NET, inserer son password et comparer avec les autres joueurs le temps qu'il a mis pour "résoudre une image" (Bondiouuu 112 niveaux... ca fait 112 tableau avec une 100aine de nom+time :fou
Il va pouvoir mettre aussi son password final (qd il aura terminé un niveau de difficulté) qui lui ne tiendra compte que du score
Et donc de m'assurer du dev php/mysql (chui rouillé :'( )

+ ajouter des SFX

+ modifier les graphs de fond

+ et surement d'autres choses

la p'tite video qui va bien



Tchao les potos


Edité par Ricco59 Le 04/05/2021 à 01h03


Tous mes travaux sont centralisés sur mon piti blog : https://ricco59.blogspot.com/
E-mail    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2743

Le 05/05/2021 à 08h58
A mon avis, il vaut mieux supporter les joysticks 1 bouton, même s'ils ne peuvent faire tourner que dans un sens.
Même si c'est pas idéal, c'est pas très gênant de devoir appuyer 1 fois pour tourner dans un sens et 3 fois pour tourner dans l'autre.
Tu peux préciser dans la doc que tu conseilles un joystick 2 boutons.

Pour le mot de passe, tu peux stocker le temps en seconde sur un uint16 : 0-65535, soit 1092 minutes ou 18h. ^^
Tu peux réduire le nombre de bits en fonction de la plus grande valeur que tu veux stocker.
Tu fais de même avec ton numéro de niveau (un uint8 devrait suffire), ensuite tu combines les bits de façon désordonnés puis tu les regroupes par 4 ou 5 pour former un caractère (4-bits: 0-F, 5-bits: 0-Z) et tu l'affiches au joueur.
Si tu veux que ton algo soit difficilement déchiffrable, tu peux ajouter quelques bits de contrôle qui sont générés aléatoirement et servent de clef pour le décodage.
Si ça t'intéresse, je peux t'expliquer la méthode en détail.

Et pour le PHP/mySQL c'est l'une de mes spécialités donc si tu as un soucis, tu sais ou me trouver. ;)

En tout cas bravo et bonne continuation !


On est toujours ignorant avant de savoir.
Github    
Ricco59 Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 02/01/2021 à 11h22

Messages: 248

Le 06/05/2021 à 23h37
Merci Guillaume pour ton retour

Je vais donc faire ca
- 1 fire > rotation CWise
- 2 fire > CW et ACW
- fleches de direction + 2 autres touches ;)

oui, je suis interessé par l'algo ;)

Et merci pour les encouragements et tout le reste ;)


Tous mes travaux sont centralisés sur mon piti blog : https://ricco59.blogspot.com/
E-mail    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2743

Le 07/05/2021 à 18h30
Alors, pour l'algo, voici d'abord l'approche naïve.


Tu as ton timer dans un uint16 dont on ne va utiliser que les 12 plus petits bits ; ce qui fait 4095 secondes max, soit un peu plus de 1h (on est large ^^).
Ton level est stocké dans un uint8 (256 possibilités).
L'aglo consiste simplement à ranger tes bits de façon désordonnée dans 4 entiers en les mettant par paquet de 5 pour obtenir des nombres en 0 et 31.
Ensuite, tu utilises un table de 32 entrées pour convertir ces valeurs en caractère.
Voici un exemple de table de conversion que tu peux utiliser :
Code C :
char ConversionTable = "D9XZLP8TE1N7A2YS6MB3RFW5CUGJ4QHK";

Note : Avec les 26 lettres et 10 chiffres, on a 4 caractères en trop. J'ai retiré '0' et 'O' pour éviter l'ambiguïté, et 'I' et 'V'... parce que. :)

Avec ça tu peux générer un code de 4 caractères comme "GH8M" ou "DSXA" qui code à la fois le numéro d'un niveau et à la fois le temps qu'on a mis à le terminer.
Ceci dit, si je parlais d'approche naïve, c'est qu'elle a un gros soucis : n'importe quel code est correct !
Une personne mal intentionnée peut donc essayer n'importe quelle combinaison et remplir ton Leaderboard avec des valeurs "valide" sans avoir joué au jeu.

Pour remédier à ce bug dans l'honnêteté humaine, y a un moyen simple : inclure des bits de contrôle.


Le principe est le même, sauf que cette fois, tu génères un code de contrôle (de 4-bits dans l'exemple).
Tu peux utiliser une fonction random si tu en as ou si tu as un compteur de frame (ce que tu devrais avoir ^^), tu peux juste prendre ses 4 plus petits bits.
Le but de ces bits de contrôles et qu'ils soient présents en plusieurs exemplaire chacun.
Au moment de lire un code, tu peux vérifier qu'un bit de contrôle à bien la même valeur à tous les endroits.
Tu invalides ainsi tous les codes qui ne respectent cette règle.
Dans l'ex. les bits de contrôle sont présents 2 ou 3 fois chacun ; plus tu dupliques ces bits et plus tu diminues le nombre de combinaison valide.
Tu pourrais par exemple répartir ton code sur 8 caractères au lieu de 6 et donc augmenter la duplication des bits de contrôle.

Pour la répartition des bits de ton Timer, fait attention au fait que les bits les plus hauts vont très souvent être à 0.
Il vaut donc mieux les repartir harmonieusement entre tes différents caractère.


On est toujours ignorant avant de savoir.
Github    
Ricco59 Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 02/01/2021 à 11h22

Messages: 248

Le 08/05/2021 à 00h27
Whaoooo perfecto Amigo

Je vais m'y interesser après quelques menues modifications sur DoTheSame ;)

Merci encore


Tous mes travaux sont centralisés sur mon piti blog : https://ricco59.blogspot.com/
E-mail    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2743

Le 08/05/2021 à 14h45
Pour m'amuser, j'ai implémenté une version de l'algo en PHP.
Tu peux la tester ici : http://aoineko.org/msx/tools/code.php

Je suis partis de la même table de conversion mais j'ai changé un peu le mapping des bits :
- J'ai gardé que 10-bits pour le temps (17 minutes max ça me semble déjà pas mal),
- Du coup, chacun des bits de control est maintenant présent 3 fois (ce qui diminue bien la probabilité de trouver un code au hasard).

Il y a 1 milliard de combinaison mais "seulement" 4 millions de valide (1 sur 250). Si tu veux encore faire baisser la proba, tu peux passer à 3 bits de control répété 4 fois.

Voici le mapping de bits que j'ai utilisé :


Voici le code PHP :

Code PHP :
<?php
 
$g_Log = "";
 
$g_Time = 0;
$g_Level = 0;
 
$g_CodeLen = 6;
$g_CodeCharacters = "D9XZLP8TE1N7A2YS6MB3RFW5CUGJ4QHK";
 
// Time variable bits mapping (chunk number, bit number)
$g_TimeBits = [
    [ 5, 1 ], // T0
    [ 3, 1 ], // T1
    [ 1, 2 ], // T2
    [ 2, 4 ], // T3
    [ 0, 0 ], // T4
    [ 5, 4 ], // T5
    [ 0, 2 ], // T6
    [ 2, 1 ], // T7
    [ 3, 2 ], // T8
    [ 4, 3 ], // T9
];
 
// Level variable bits mapping
$g_LevelBits = [
    [ 3, 4 ], // L0
    [ 4, 0 ], // L1
    [ 2, 3 ], // L2
    [ 5, 2 ], // L3
    [ 0, 4 ], // L4
    [ 4, 1 ], // L5
    [ 1, 1 ], // L6
    [ 1, 4 ]  // L7
];
 
// Control bits mapping
$g_ControlBits = [
    [ [ 0, 1 ], [ 1, 0 ], [ 4, 2 ], ], // C0
    [ [ 1, 3 ], [ 2, 0 ], [ 4, 4 ], ], // C1
    [ [ 2, 2 ], [ 3, 0 ], [ 5, 3 ], ], // C2
    [ [ 0, 3 ], [ 3, 3 ], [ 5, 0 ], ], // C3
];
 
// Check if all instances of a given control bit are equal
function CheckControlBits(&$CodeChunks)
{
    global $g_ControlBits, $g_Log;
 
    // For each control bit
    foreach ($g_ControlBits as $c => &$ctrlBits)
    {
        $first = 0;
        // For each instance of a given control bit
        foreach ($ctrlBits as $i => &$bits)
        {
            $val = ($CodeChunks[$bits[0]] & (1 << $bits[1])) ? 1 : 0;
            // $g_Log .= "bit[$c][$i] = $val<br/>";
            if($i == 0)
                $first = $val;
            else if($val != $first)
                return false;
        }
    }
 
    return true;
}
 
// Decode a variable given its bits mapping
function DecodeVariable(&$CodeChunks, &$Bits)
{
    $ret = 0;
    foreach ($Bits as $i => &$value)
        if($CodeChunks[$value[0]] & (1 << $value[1]))
            $ret += 1 << $i;
 
    return $ret;
}
 
// Decode time and level variables from code characters
function Decode($Code)
{
    global $g_Time, $g_Level, $g_CodeLen, $g_CodeCharacters, $g_TimeBits, $g_LevelBits, $g_Log;
 
    // Check code lenght
    if(strlen($Code) != $g_CodeLen)
    {
        $g_Log .= "Invalid code length!<br/>";
        return false;
    }
 
    // Decode characters into 5-bits chunks
    $chunks = array();
    for($i = 0; $i < $g_CodeLen; $i++)
    {
        $chr = $Code[$i];
        $chunks[$i] = stripos($g_CodeCharacters, $chr);
        if($chunks[$i] === false)
        {
            $g_Log .= "Invalid code character!<br/>";
            return false;
        }
        // $g_Log .= "chunk[$i] = $chunks[$i]<br/>";
    }
 
    // Check control bits
    if(!CheckControlBits($chunks))
    {
        $g_Log .= "Invalid control bits!<br/>";
        return false;
    }
 
    // Decode time variable
    $g_Time = DecodeVariable($chunks, $g_TimeBits);
 
    // Decode level variable
    $g_Level = DecodeVariable($chunks, $g_LevelBits);
 
    return true;
}
 
// Encode time and level variables into code characters
function Encode()
{
    global $g_Time, $g_Level, $g_CodeLen, $g_CodeCharacters, $g_TimeBits, $g_LevelBits, $g_Log, $g_ControlBits;
 
    // Prepare 5-bits chunks
    $chunks = array();
    for($i = 0; $i < $g_CodeLen; $i++)
        $chunks[$i] = 0;
 
    // Create control bits
    $ctrl = rand(0, 15);
    // $g_Log .= "control code = $ctrl<br/>";
 
    // Write control bits to chunks
    foreach ($g_ControlBits as $c => &$ctrlBits)
        if($ctrl & (1 << $c))
            foreach ($ctrlBits as &$bits)
                $chunks[$bits[0]] += 1 << $bits[1];
 
    // Encode time variable
    foreach ($g_TimeBits as $t => &$bits)
        if($g_Time & (1 << $t))
            $chunks[$bits[0]] += 1 << $bits[1];
 
    // Encode level variable
    foreach ($g_LevelBits as $t => &$bits)
        if($g_Level & (1 << $t))
            $chunks[$bits[0]] += 1 << $bits[1];
 
    // Convert chunk value to character
    $ret = "";
    for($i = 0; $i < $g_CodeLen; $i++)
        $ret .= $g_CodeCharacters[$chunks[$i]];
 
    return $ret;
}
 
// Get a system variables
function GetVar($param, $default = "")
{
    if(isset($_REQUEST[$param]))
        return $_REQUEST[$param];
    else
        return $default;
}
 
?>
<!DOCTYPE html>
<html>
    <head>
        <title>Do The Same</title>
        <meta charset="utf-8" />
        <script type="text/javascript" src="pub/main.js"></script>
    </head>
    <body>    
        <?php
            $action = GetVar('action');
            $code = GetVar('code', 'Y19NFP');
            $g_Time = GetVar('time', 0);
            $g_Level = GetVar('level', 0);
 
            if($action == "Decode")
            {
                Decode($code);
            }
            else if($action == "Encode")
            {
                $code = Encode();
            }
        ?>
        <form action="" method="get">
            <div style="flex-grow:1; display:flex; flex-flow:row;" >
                <div>
                    <label for="code">Code</label>
                    <input type="text" id="code" name="code" value="<?php print $code; ?>">
                </div>
 
                <div class="form-example" style="margin:0 1em 0 1em;">
                    »» <input type="submit" name="action" value="Decode"> »»
                    <br/>
                    «« <input type="submit" name="action" value="Encode"> ««
                </div>
 
                <div class="form-example">
                    <label for="time">Time </label>
                    <input type="number" id="time" name="time" value="<?php print $g_Time; ?>">
                    <?php print((int)($g_Time / 60) ."\"". $g_Time % 60 ."'"); ?>
                    <br/>
                    <label for="level">Level </label>
                    <input type="number" id="level" name="level" value="<?php print $g_Level; ?>">
                </div>
            </div>
        </form>
        <tt style="color:red;">
        <?php
            print($g_Log);
            // var_dump($GLOBALS);
        ?>
        </tt>
    </body>
</html>
 



Comme tu peux voir en tête du code, tu as des variables qui permettent de changer la mapping des bits ou la table de conversion des caractères sans toucher au code.
Enjoy! :tchin


On est toujours ignorant avant de savoir.
Github    
Ricco59 Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 02/01/2021 à 11h22

Messages: 248

Le 08/05/2021 à 16h58
T'es vraiment un Grand Malade : un CHEF ;)

Je te recontacte en mp très vite car je pense qu'il faudra ajouter le type de MAchine (Coleco/msx) et la freq (50/60)

tu as raison :tchin :tchin :tchin :tchin


Tous mes travaux sont centralisés sur mon piti blog : https://ricco59.blogspot.com/
E-mail    
Ricco59 Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 02/01/2021 à 11h22

Messages: 248

Le 09/05/2021 à 18h20
DoTheSame WIP03,

Hello, voici une nouvelle video de Do The Same intégrant de nouveaux gfx (par gfx hihihi)
N'hésitez pas à me (nous) faire un retour :)

Merci et bonne fin de journée les zamis

La video


Tous mes travaux sont centralisés sur mon piti blog : https://ricco59.blogspot.com/
E-mail    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2743

Le 09/05/2021 à 21h07
J'aime beaucoup le thème "nature" ! :top
C'est joli, écolo et puis ça permet d'avoir des images bien distinctes en jeu.

Pour chippoter, juste 2 remarques :
- L'écran d'accueil est très chargé (les insectes sont p'être de trop même s'ils sont mimi)
- Le fond en jeu (les feuilles vertes) attire trop l'œil (peut-être essayer des couleurs plus sombres)

En tout cas, bravo. :)


Ricco59 :
Je te recontacte en mp très vite car je pense qu'il faudra ajouter le type de MAchine (Coleco/msx) et la freq (50/60)


Si tu fais les choses proprement, 1 seconde en 50 ou 60 Hz, c'est la même chose. ;)

EDIT : En plus du temps, tu pourrais ajouter le nombre de "coups" qu'il a fallu au joueur pour finir le niveau. Je pense que ça peut être amusant d'essayer de résoudre les puzzles en le moins de coups possibles.


On est toujours ignorant avant de savoir.
Github    
igal Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++

Inscrit le : 29/07/2010 à 17h19

Messages: 5492

Le 09/05/2021 à 22h10
Il est très joli ton jeu :)


Tiens... voila du boudin, voila du boudin, voila du boudin... :siffle
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie