/*
 * Gamepad style buttons connected to IRQ/GPIO lines
 *
 * Copyright (c) 2007 CodeSourcery.
 * Written by Paul Brook
 *
 * This code is licenced under the GPL.
 */
#include "hw.h"
#include "devices.h"
#include "console.h"

typedef struct {
    qemu_irq irq;
    int keycode;
    int pressed;
} gamepad_button;

typedef struct {
    gamepad_button *buttons;
    int num_buttons;
    int extension;
} gamepad_state;

static void stellaris_gamepad_put_key(void * opaque, int keycode)
{
    gamepad_state *s = (gamepad_state *)opaque;
    int i;
    int down;

    if (keycode == 0xe0 && !s->extension) {
        s->extension = 0x80;
        return;
    }

    down = (keycode & 0x80) == 0;
    keycode = (keycode & 0x7f) | s->extension;

    for (i = 0; i < s->num_buttons; i++) {
        if (s->buttons[i].keycode == keycode
                && s->buttons[i].pressed != down) {
            s->buttons[i].pressed = down;
            qemu_set_irq(s->buttons[i].irq, down);
        }
    }

    s->extension = 0;
}

static void stellaris_gamepad_save(QEMUFile *f, void *opaque)
{
    gamepad_state *s = (gamepad_state *)opaque;
    int i;

    qemu_put_be32(f, s->extension);
    for (i = 0; i < s->num_buttons; i++)
        qemu_put_byte(f, s->buttons[i].pressed);
}

static int stellaris_gamepad_load(QEMUFile *f, void *opaque, int version_id)
{
    gamepad_state *s = (gamepad_state *)opaque;
    int i;

    if (version_id != 1)
        return -EINVAL;

    s->extension = qemu_get_be32(f);
    for (i = 0; i < s->num_buttons; i++)
        s->buttons[i].pressed = qemu_get_byte(f);

    return 0;
}

/* Returns an array 5 ouput slots.  */
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
{
    gamepad_state *s;
    int i;

    s = (gamepad_state *)qemu_mallocz(sizeof (gamepad_state));
    s->buttons = (gamepad_button *)qemu_mallocz(n * sizeof (gamepad_button));
    for (i = 0; i < n; i++) {
        s->buttons[i].irq = irq[i];
        s->buttons[i].keycode = keycode[i];
    }
    s->num_buttons = n;
    qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
    register_savevm("stellaris_gamepad", -1, 1,
                    stellaris_gamepad_save, stellaris_gamepad_load, s);
}
