/*
 * MultiPlayer
 * Copyright (C) 1992 Bryan Ford
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * I (the author of MultiPlayer) can be contacted on the Internet at
 * "bryan.ford@m.cc.utah.edu".  See "Player.doc" for other addresses.
 *
 * $Id: player.h,v 3.1 92/05/25 07:54:02 BAF Exp $
 * Global header for C modules
 *
 * $Log:	player.h,v $
 * Revision 3.1  92/05/25  07:54:02  BAF
 * GNU-ized.
 * 
 *
 */

#ifndef DOS_DOS_H
#include <dos/dos.h>
#endif

#define CLOCK 3579545

#define callvec(name) { extern void (*name)(void); if(name) (*name)(); }

#define FFperF 3

struct ModNode
  {
    struct MinNode node;
    short size;
    char *nameptr;
    BPTR dir;
    char volume;
    char balance;
    unsigned char speed;
    char filter;
    long endtime;
    char flags;
    char pad;
    char name[1];
  };
#define MNF_ENDFADE           0x02      // Fade out on ending
#define MNF_PTTEMPO           0x04      // Enable Protracker tempo commands
#define MNF_NOTPROTRACKER     0x08      // This is not a Protracker module

/* Program arguments */
extern struct PlayerArgs
  {
    char *dir;
    char **mods;
    char *prog;
    char *screen;
    int noreq;
    int nowin;
    int norexx;
    int nodetach;
  } argarray;

/* One of MultiPlayer's windows (or some other thread) */
struct MPWin
  {
    void *spec;
    short *snappos;
    void (*initfunc)(void);
    struct CallNode snapnode;
    struct CallNode checknode;
    struct CallNode closenode;
    void *userdata;
    struct Window *win;
    long sigmask;
    long ovhan;
  };

/* All of the following variables, except the arbitrated globals, are
   declared (and explained more fully) in main.c.  */

/* System flags */
extern char sysflags, sysflags2;
#define SF_KILL         0x01    // Kill MultiPlayer ASAP
#define SF_TIMERUP      0x04    // Timer/sequence needs updating
#define SF_WINDOWUP     0x08    // Windows need updating
#define SF_REPEAT       0x10    // Song is repeating
#define SF_SECOND       0x20    // One second has gone by
#define SF_FADEDONE     0x40    // We're finished fading
#define SF_FADEPAUSE    0x80    // We're fading out for a pause

/* Play mode */
extern char playmode;
#define PM_SEQUENCE     0       // Play in sequence
#define PM_RANDOM       1       // Random order
#define PM_ONCE         2       // Play once then unload
#define PM_OVEROVER     3       // Play same module over and over
#define PM_SEQUENCEONCE 4       // Through sequence once

/* Show mode */
extern char showmode;
#define SM_NOTHING      0       // Don't mess with the title bar
#define SM_CLOCK        1       // Minute/second music timer
#define SM_SEQUENCE0    2       // Sequence starting from 0
#define SM_SEQUENCE1    3       // Sequence starting from 1

/* Flash mode */
extern char flashflags;
#define FF_SPECTRUM     0x01    // Spectrum analyzer
#define FF_SCOPE        0x02    // Stereo Scope
#define FF_QSCOPE       0x04    // Quadrascope
#define FF_NOTES        0x08    // Note scroller
#define FF_CHANNELS     0x10    // Channel meter
#define FF_INFO         0x20    // Info display (not really "flashy", but handled the same way...)

/* Module type */
extern char modtype;
#define MTF_MODSPEED    0x01    // Supports modspeed
#define MTF_SEQUENCE    0x02    // Supports sequence display
#define MTF_REPEAT      0x04    // Supports repeat detection
#define MTF_MODIFIED    0x08    // Mod prefs have been changed
#define MTF_PROTRACKER  0x10    // This is the Protracker player
#define MTF_FILTER      0x20    // Filter can be controlled
#define MTF_JUMP        0x40    // Module can jump to other positions

/* Help contexts */
#define MAINCONTEXT     0
#define PANELCONTEXT    1
#define PROGWINCONTEXT  2
#define PREFSWINCONTEXT 3
#define FLASHYWINCONTEXT 4

/* Other globals */
extern struct Screen *playerscreen;
extern struct MsgPort *wbappport;

extern struct CallList dolist;
extern struct CallList checklist;
extern struct CallList updatelist;
extern struct CallList timerlist;
extern struct CallList snaplist;
extern struct CallList closelist;
extern struct CallList endlist;

extern char playmode, showmode;

/* Arbitrated globals */
extern struct MinList modlist;
extern struct ModNode *curmod, *selmod;

#define adddo(node) AddCallNode(&dolist,node)

/* Main prototypes */
char *winerr(char *mes);
char *setdir(BPTR newdir);
char *setdirname(char *name);
char *progadd(BPTR dir,char *name);
char *progaddargs(int args,struct WBArg *arg);
char *progstart(void);
char *prognext(void);
char *progprev(void);
char *progact(struct ModNode *node);
void progdel(struct ModNode *node);
void progclear(void);
char *progsave(char *filename);
char *progload(char *filename,int start);

void addcalls(
  struct CallNode *check,
  struct CallNode *update,
  struct CallNode *timernode,
  struct CallNode *end);
void addsigs(long newsigs);
void remsigs(long oldsigs);

char *reqmod(int clear);
char *openfilerequest(void (*donecall)(struct WBArg *args,int count),
  void *frspec,void *userstruct);
void closefilerequest(void (*donecall)(struct WBArg *args,int count));
void windowkey(int rawcode,int context);
void windowclick(int rawcode);
void standardcallback(struct GuidMessage *gm);

char *openmpwin(struct MPWin *win,long ov);
void closempwin(struct MPWin *win);
void setfinmpwin(struct MPWin *win);

/* Player prototypes */
void setsong(int song);
char *loadmod(char *name);
char *playmod(int song);
char *startmod(char *name,int song);
char *contmod(void);
char *contplaymod(void);
void stopmod(void);
void endmod(void);
int iscantcont(char *errmes);

/* Globals prototypes */
void GlobSetByte(char *var,char value,void *(*notroutine)(void));
void GlobSetWord(short *var,short value,void *(*notroutine)(void));
void GlobSetLong(long *var,long value,void *(*notroutine)(void));
void GlobPreMod(void *var,void *(*notroutine)(void));
void GlobPostMod(void *var,void *(*notroutine)(void));
