Put all player-related information in one place

Issue #20 resolved
Tygre repo owner created an issue

Put all player-related information in one place, using a struct, including to record the file formats accepted by the players rather than hard-coding these formats in the common controls.

Comments (3)

  1. Tygre reporter

    Use Matt's skeleton implementation that is very, very cool!

    typedef enum player_id {
        P_AMIGAAMP = 0,
        P_DELITRACKER,
        P_EAGLEPLAYER,
        P_HIPPOPLAYER,
        P_MULTIPLAYER,
        P_MAX
    } player_id_t;
    
    enum type_id {
        T_CUST = 0,
        T_DIGI,
        T_MED,
        T_MOD,
        T_MP3,
        T_MPG,
        T_S3M,
        T_XM,
        T_MAX
    };
    
    #define TB_CUST (1 << T_CUST)
    #define TB_DIGI (1 << T_DIGI)
    #define TB_MED  (1 << T_MED)
    #define TB_MOD  (1 << T_MOD)
    #define TB_MP3  (1 << T_MP3)
    #define TB_MPG  (1 << T_MPG)
    #define TB_S3M  (1 << T_S3M)
    #define TB_XM   (1 << T_XM)
    
    const char *const type_str[T_MAX] = {
        "cust",
        "digi",
        "med",
        "mod",
        "mp3",
        "mpg",
        "s3m",
        "xm"
    };
    
    struct player_info
    {
        player_id_t id;
        const char  *portname;
        unsigned int    supported;
        /* XXX
         * Could have other interesting fields for player name string,
         * control info or whatever
         */
    };
    
    static const struct player_info players[P_MAX] = {
        { P_AMIGAAMP, "AMIGAAMP",
            TB_MP3 | TB_MPG },
        { P_DELITRACKER, "DELITRACKER",
            TB_MED | TB_XM | TB_CUST | /*TB_DIGI |*/ TB_MOD | TB_S3M },
        { P_EAGLEPLAYER, "rexx_EP",
            TB_MED | TB_CUST | TB_MP3 | TB_MOD | TB_MPG },
        { P_HIPPOPLAYER, "HIPPOPLAYER",
            TB_XM | TB_MP3 | /* TB_DIGI |*/ TB_MOD | TB_S3M },
        { P_MULTIPLAYER, "RXTRACKER",
            /*TB_DIGI |*/ TB_MOD }
    };
    
    
    static player_id_t  player = -1;
    
  2. Tygre reporter
    static const char   *hypothetical_findport(const char *);
    static player_id_t  player_find(void);
    static bool     player_supported(const char *);
    
    int         main(void);
    
    
    int
    main(void)
    {
    
        if ((player = player_find()) == -1) {
            /* XXX No supported player found, report error */
            exit(EXIT_FAILURE);
        }
    
        printf("Player ID: %d\n", player);
        printf("Player supports type: %d\n",
               (int)player_supported("mod")); /* XXX "mod" would normally
                             be filename */
    
        /* Examples of faster and cleaner if/case than with strcmp(3) */
    
        if (player == P_DELITRACKER)
            printf("Player is Delitracker\n");
    
        switch (player) {
        case P_DELITRACKER:
            printf("Indeed Delitracker\n");
            break;
        case P_AMIGAAMP: /* FALLTHROUGH */
        case P_EAGLEPLAYER: /* FALLTHROUGH */
        case P_HIPPOPLAYER: /* FALLTHROUGH */
        case P_MULTIPLAYER: /* FALLTHROUGH */
            printf("Definitely something else\n");
            break;
        }
    
        exit(EXIT_SUCCESS);
    }
    
    /* XXX Cheap test simulation :) */
    static const char *
    hypothetical_findport(const char *port)
    {
    
        return (strcmp(port, "DELITRACKER") == 0 ? "DELITRACKER" : NULL);
    }
    
    /* Type support lookup example */
    bool
    player_supported(const char *filename)
    {
        int     i;
        unsigned int    sup;
    
        assert(player != -1);
        sup = players[player].supported;
    
        for (i = 0; i < T_MAX; i++) {
            if ((sup & (1 << i)) != 0) {
                const char *str = type_str[i];
                /* XXX
                if (str_startswith(filename, str) ||
                    str_endswith(filename, str))
                    return true;
                */
                if (strcasecmp(filename, str) == 0)
                    return true;
            }
        }
    
        return false;
    }
    
    /* Player lookup example */
    static player_id_t
    player_find(void)
    {
        int i;
    
        for (i = 0; i < P_MAX; i++) {
            const struct player_info *p = &players[i];
    
            if (hypothetical_findport(p->portname) != NULL)
                return p->id;
        }
    
        return -1;
    }
    
  3. Log in to comment