/**
 * TrueReality - dispatch.c
 * Copyright (C) 1998 Niki W. Waibel
 *
 * This program is free software; you can redistribute it and/
 * or modify it under the terms of the GNU General Public Li-
 * cence as published by the Free Software Foundation; either
 * version 2 of the Licence, or any later version.
 *
 * This program is distributed in the hope that it will be use-
 * ful, but WITHOUT ANY WARRANTY; without even the implied war-
 * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public Licence for more details.
 *
 * You should have received a copy of the GNU General Public
 * Licence along with this program; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
 * USA.
 *
 * Information about me (the author):
 *   Niki W. Waibel, Reichenau 20, 6890 Lustenau, Austria - EUROPE
 *   niki.waibel@gmx.net
**/



#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "config.h"

#include "n64/memory.h"
#include "parser_extern.h"
#include "romimage.h"
#include "romimage_extern.h"
#include "n64/cpu.h"
#include "n64/controller.h"
#include "n64/type_sizes.h"

#include "os/os.h"

#include "dispatch.h"



#ifdef DEBUG
#       include "debug.h"
#endif

#if DISPLAY_SUPPORT
#       include "Display/display.h"
#endif





#if DISPLAY_SUPPORT
static void display_close();
static void display_open();
static void display_refresh();
#endif
static WORD controller_get_status(WORD);









/*
 * the next 3 (display) routines are just compiled
 * if a display is specified in the Makefile
 *
 */

#if DISPLAY_SUPPORT





void display_open()
{
        char name[80];
        int  n = 80;
        int  i;



        switch(prefs.display)
        {
            case NO_DISPLAY:
                puts("Display:                                                             no display");
                break;


            case LOCAL_DISPLAY:
            case LOCAL_DISPLAY_PROCESS:
                if(OpenVisual() != -1)
                {
                        GetVisualName(name, &n);
            
                        printf("Connected to display:");
             
                        for(i = 21; i < (79-strlen(name)); i++)
                                putchar(' ');
                        puts(name); fflush(stdout);
                }
                else
                {
                        puts("Display connection failed, using display:                             no display");

                        prefs.display = NO_DISPLAY;
                }
                break;


            case REMOTE_DISPLAY:   /* far from complete */
                puts("REMOTE_DISPLAY is not implemented yet, using display:                 no display");
                prefs.display = NO_DISPLAY;
                break;
   
        } /* switch(prefs.display) */
   
} /* void display_open() */





void display_close()
{
        switch(prefs.display)
        {
            case NO_DISPLAY:
                break;

            case LOCAL_DISPLAY:
                CloseVisual();
                prefs.display = NO_DISPLAY;
                break;

            case LOCAL_DISPLAY_PROCESS:   /* far from complete */
            case REMOTE_DISPLAY:          /* far from complete */
                prefs.display = NO_DISPLAY;
                break;

        } /* switch(prefs.display) */
   
} /* void display_close() */





void display_refresh()
{
        switch(prefs.display)
        {
            case NO_DISPLAY:
            case LOCAL_DISPLAY_PROCESS:   /* far from complete */
            case REMOTE_DISPLAY:          /* far from complete */
                break;

            case LOCAL_DISPLAY:
                RefreshVisual();
                break;

        } /* switch(prefs.display) */
   
} /* void display_refresh() */





#endif /* #if DISPLAY_SUPPORT */





static WORD controller_get_status(WORD controller)
{
        WORD state;



        switch(prefs.display)
        {
            case NO_DISPLAY:
#if DISPLAY_SUPPORT & SUPPORT_LOCAL_DISPLAY_PROCESS
            case LOCAL_DISPLAY_PROCESS:
#endif
#if DISPLAY_SUPPORT & SUPPORT_REMOTE_DISPLAY
            case REMOTE_DISPLAY:
#endif
                fprintf(stdout,
                        "controller_get_status:\n"
                        "   input value of controller #%d\n"
                        "   (BBBBXXYY) ",
                        (int)controller);
                if(scanf("%lx", &state) == 1)
                        return(state);
                else
                        return(0);
                        
#if DISPLAY_SUPPORT & SUPPORT_LOCAL_DISPLAY
            case LOCAL_DISPLAY:
                return(CheckVisual());
#endif

        } /* switch(prefs.display) */
   

   
        return(0);   /* to make compiler happy */
   
} /* static unsigned long controller_get_status() */





int dispatch(int command, void *value)
{
        switch(command)
        {
            case SHUTDOWN:
#if DISPLAY_SUPPORT
                display_close();
#endif
                free_n64_mem();
                free(rom.image);
                exit(0);
                
            case MEMORY_ALLOC:
                return(alloc_n64_mem());
                
            case MEMORY_CLEAR:
                clear_n64_mem();
                return(0);
                
            case MEMORY_FREE:
                free_n64_mem();
                return(0);

#if DISPLAY_SUPPORT
            case DISPLAY_OPEN:
                display_open();
                return(0);

            case DISPLAY_REFRESH:
                display_refresh();
                return(0);
                
            case DISPLAY_CLOSE:
                display_close();
                return(0);
#endif

            case CONTROLLER_GET_STATUS:
                *((WORD *)value) = controller_get_status(*((WORD *)value));
                return(0);
                
            case CONTROLLER_INIT:
                InitController(*((WORD *)value));
                return(0);
        
            case CATCH_SIGNALS:
                CatchSignals();
                return(0);
        
            case CPU_RESET:
                rs4300i_Reset();
                return(0);
        
        } /* switch(command) */



        return(0);   /* to make compiler happy */

} /* int dispatch(int command, void *value) */

