/*
 * This file is part of roccat-tools.
 *
 * roccat-tools 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.
 *
 * roccat-tools 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 roccat-tools. If not, see <http://www.gnu.org/licenses/>.
 */

#include "roccat/ryos.h"

enum {
	KEY_WIDTH = 4,
	VOID = 0xff,
	ROWS = 30,
	COLS = 95,
	KEYS_NUM = 119,
};

typedef struct {
	guint8 hid;
	guint8 row;
	guint8 col;
} Position;

static Position light_position_table[KEYS_NUM] = {
	/* keys_macro */
	{0xaa,  7,  2},
	{0xab, 11,  2},
	{0xac, 15,  2},
	{0xad, 19,  2},
	{0xae, 23,  2},

	/* keys_function */
	{0x3a,  2, 15},
	{0x3b,  2, 19},
	{0x3c,  2, 23},
	{0x3d,  2, 27},
	{0x3e,  2, 33},
	{0x3f,  2, 37},
	{0x40,  2, 41},
	{0x41,  2, 45},
	{0x42,  2, 51},
	{0x43,  2, 55},
	{0x44,  2, 59},
	{0x45,  2, 63},
	{0x46,  2, 68},
	{0x47,  2, 72},
	{0x48,  2, 76},

	/* keys_thumbster */
	{0x90, 28, 28},
	{0x91, 28, 32},
	{0xf1, 28, 36},

	/* keys_easyzone */
	{0x35,  7,  7},
	{0x1e,  7, 11},
	{0x1f,  7, 15},
	{0x20,  7, 19},
	{0x21,  7, 23},
	{0x22,  7, 27},
	{0x23,  7, 31},
	{0x24,  7, 35},
	{0x25,  7, 39},
	{0x26,  7, 43},
	{0x27,  7, 47},
	{0x2d,  7, 51},
	{0x2e,  7, 55},
	{0x89,  7, 59},
	{0x2a,  7, 63},
	{0x49,  7, 68},
	{0x4a,  7, 72},
	{0x4b,  7, 76},
	{0x53,  7, 81},
	{0x54,  7, 85},
	{0x55,  7, 89},
	{0x56,  7, 93},
	{0x2b, 11,  8},
	{0x14, 11, 13},
	{0x1a, 11, 17},
	{0x08, 11, 21},
	{0x15, 11, 25},
	{0x17, 11, 29},
	{0x1c, 11, 33},
	{0x18, 11, 37},
	{0x0c, 11, 41},
	{0x12, 11, 45},
	{0x13, 11, 49},
	{0x2f, 11, 53},
	{0x30, 11, 57},
	{0x31, 11, 62},
	{0x4c, 11, 68},
	{0x4d, 11, 72},
	{0x4e, 11, 76},
	{0x5f, 11, 81},
	{0x60, 11, 85},
	{0x61, 11, 89},
	{0x57, 13, 93},
	{0x04, 15, 14},
	{0x16, 15, 18},
	{0x07, 15, 22},
	{0x09, 15, 26},
	{0x0a, 15, 30},
	{0x0b, 15, 34},
	{0x0d, 15, 38},
	{0x0e, 15, 42},
	{0x0f, 15, 46},
	{0x33, 15, 50},
	{0x34, 15, 54},
	{0x32, 15, 58},
	{0x28, 15, 62},
	{0x5c, 15, 81},
	{0x5d, 15, 85},
	{0x5e, 15, 89},
	{0xe1, 19,  8},
	{0x64, 19, 12},
	{0x1d, 19, 16},
	{0x1b, 19, 20},
	{0x06, 19, 24},
	{0x19, 19, 28},
	{0x05, 19, 32},
	{0x11, 19, 36},
	{0x10, 19, 40},
	{0x36, 19, 44},
	{0x37, 19, 48},
	{0x38, 19, 52},
	{0x87, 19, 56},
	{0xe5, 19, 61},
	{0x52, 19, 72},
	{0x59, 19, 81},
	{0x5a, 19, 85},
	{0x5b, 19, 89},
	{0x58, 21, 93},
	{0xe0, 23,  8},
	{0xe3, 23, 13},
	{0xe2, 23, 18},
	{0x8b, 23, 22},
	{0x2c, 23, 31},
	{0x8a, 23, 40},
	{0x88, 23, 44},
	{0xe6, 23, 49},
	{0x65, 23, 57},
	{0xe4, 23, 62},
	{0x50, 23, 68},
	{0x51, 23, 72},
	{0x4f, 23, 76},
	{0x62, 23, 83},
	{0x63, 23, 89},

	/* keys_extra */
	{0x39, 15,  9},
	{0xe7, 23, 53},
	{0x29,  2,  7},
};

gboolean ryos_ripple_get_center(guint8 hid, guint *row, guint *col) {
	guint i;

	for (i = 0; i < KEYS_NUM; ++i) {
		if (light_position_table[i].hid == hid) {
			*row = light_position_table[i].row;
			*col = light_position_table[i].col;
			return TRUE;
		}
	}

	return FALSE;
}

static guint8 light_index_table[ROWS][COLS] = {

	{ VOID, VOID, VOID, VOID, VOID, VOID, 0x01, 0x01, VOID, VOID, VOID, VOID, VOID, VOID, 0x02, 0x02, VOID, VOID, 0x0e, 0x0e, /* 0 */
	VOID, VOID, 0x03, 0x03, VOID, VOID, 0x0f, 0x0f, VOID, VOID, VOID, VOID, 0x04, 0x04, VOID, VOID, 0x10, 0x10, VOID, VOID,
	0x05, 0x05, VOID, VOID, 0x11, 0x11, VOID, VOID, VOID, VOID, 0x06, 0x06, VOID, VOID, 0x07, 0x07, VOID, VOID, 0x08, 0x08,
	VOID, VOID, 0x14, 0x14, VOID, VOID, VOID, 0x09, 0x09, VOID, VOID, 0x15, 0x15, VOID, VOID, 0x21, 0x21, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID },

	{ VOID, VOID, VOID, VOID, VOID, 0x01, 0x01, 0x01, 0x01, VOID, VOID, VOID, VOID, 0x02, 0x02, 0x02, 0x02, 0x0e, 0x0e, 0x0e,
	0x0e, 0x03, 0x03, 0x03, 0x03, 0x0f, 0x0f, 0x0f, 0x0f, VOID, VOID, 0x04, 0x04, 0x04, 0x04, 0x10, 0x10, 0x10, 0x10, 0x05,
	0x05, 0x05, 0x05, 0x11, 0x11, 0x11, 0x11, VOID, VOID, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08,
	0x08, 0x14, 0x14, 0x14, 0x14, VOID, 0x09, 0x09, 0x09, 0x09, 0x15, 0x15, 0x15, 0x15, 0x21, 0x21, 0x21, 0x21, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID },

	{ VOID, VOID, VOID, VOID, VOID, 0x01, 0x01, 0x01, 0x01, VOID, VOID, VOID, VOID, 0x02, 0x02, 0x02, 0x02, 0x0e, 0x0e, 0x0e,
	0x0e, 0x03, 0x03, 0x03, 0x03, 0x0f, 0x0f, 0x0f, 0x0f, VOID, VOID, 0x04, 0x04, 0x04, 0x04, 0x10, 0x10, 0x10, 0x10, 0x05,
	0x05, 0x05, 0x05, 0x11, 0x11, 0x11, 0x11, VOID, VOID, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08,
	0x08, 0x14, 0x14, 0x14, 0x14, VOID, 0x09, 0x09, 0x09, 0x09, 0x15, 0x15, 0x15, 0x15, 0x21, 0x21, 0x21, 0x21, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID },

	{ VOID, VOID, VOID, VOID, VOID, VOID, 0x01, 0x01, VOID, VOID, VOID, VOID, VOID, VOID, 0x02, 0x02, VOID, VOID, 0x0e, 0x0e,
	VOID, VOID, 0x03, 0x03, VOID, VOID, 0x0f, 0x0f, VOID, VOID, VOID, VOID, 0x04, 0x04, VOID, VOID, 0x10, 0x10, VOID, VOID,
	0x05, 0x05, VOID, VOID, 0x11, 0x11, VOID, VOID, VOID, VOID, 0x06, 0x06, VOID, VOID, 0x07, 0x07, VOID, VOID, 0x08, 0x08,
	VOID, VOID, 0x14, 0x14, VOID, VOID, VOID, 0x09, 0x09, VOID, VOID, 0x15, 0x15, VOID, VOID, 0x21, 0x21, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID },

	{ VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID },

	{ VOID, 0x00, 0x00, VOID, VOID, VOID, 0x0c, 0x0c, VOID, VOID, 0x0d, 0x0d, VOID, VOID, 0x19, 0x19, VOID, VOID, 0x1a, 0x1a, /* 5 */
	VOID, VOID, 0x1b, 0x1b, VOID, VOID, 0x27, 0x27, VOID, VOID, 0x1c, 0x1c, VOID, VOID, 0x28, 0x28, VOID, VOID, 0x1d, 0x1d,
	VOID, VOID, 0x29, 0x29, VOID, VOID, 0x12, 0x12, VOID, VOID, 0x1e, 0x1e, VOID, VOID, 0x13, 0x13, VOID, VOID, 0x20, 0x20,
	VOID, VOID, 0x2c, 0x2c, VOID, VOID, VOID, 0x2d, 0x2d, VOID, VOID, 0x39, 0x39, VOID, VOID, 0x45, 0x45, VOID, VOID, VOID,
	0x0a, 0x0a, VOID, VOID, 0x16, 0x16, VOID, VOID, 0x0b, 0x0b, VOID, VOID, 0x17, 0x17, VOID },

	{ 0x00, 0x00, 0x00, 0x00, VOID, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x19, 0x19, 0x19, 0x19, 0x1a, 0x1a, 0x1a,
	0x1a, 0x1b, 0x1b, 0x1b, 0x1b, 0x27, 0x27, 0x27, 0x27, 0x1c, 0x1c, 0x1c, 0x1c, 0x28, 0x28, 0x28, 0x28, 0x1d, 0x1d, 0x1d,
	0x1d, 0x29, 0x29, 0x29, 0x29, 0x12, 0x12, 0x12, 0x12, 0x1e, 0x1e, 0x1e, 0x1e, 0x13, 0x13, 0x13, 0x13, 0x20, 0x20, 0x20,
	0x20, 0x2c, 0x2c, 0x2c, 0x2c, VOID, 0x2d, 0x2d, 0x2d, 0x2d, 0x39, 0x39, 0x39, 0x39, 0x45, 0x45, 0x45, 0x45, VOID, 0x0a,
	0x0a, 0x0a, 0x0a, 0x16, 0x16, 0x16, 0x16, 0x0b, 0x0b, 0x0b, 0x0b, 0x17, 0x17, 0x17, 0x17 },

	{ 0x00, 0x00, 0x00, 0x00, VOID, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x19, 0x19, 0x19, 0x19, 0x1a, 0x1a, 0x1a,
	0x1a, 0x1b, 0x1b, 0x1b, 0x1b, 0x27, 0x27, 0x27, 0x27, 0x1c, 0x1c, 0x1c, 0x1c, 0x28, 0x28, 0x28, 0x28, 0x1d, 0x1d, 0x1d,
	0x1d, 0x29, 0x29, 0x29, 0x29, 0x12, 0x12, 0x12, 0x12, 0x1e, 0x1e, 0x1e, 0x1e, 0x13, 0x13, 0x13, 0x13, 0x20, 0x20, 0x20,
	0x20, 0x2c, 0x2c, 0x2c, 0x2c, VOID, 0x2d, 0x2d, 0x2d, 0x2d, 0x39, 0x39, 0x39, 0x39, 0x45, 0x45, 0x45, 0x45, VOID, 0x0a,
	0x0a, 0x0a, 0x0a, 0x16, 0x16, 0x16, 0x16, 0x0b, 0x0b, 0x0b, 0x0b, 0x17, 0x17, 0x17, 0x17 },

	{ VOID, 0x00, 0x00, VOID, VOID, VOID, 0x0c, 0x0c, VOID, VOID, 0x0d, 0x0d, VOID, VOID, 0x19, 0x19, VOID, VOID, 0x1a, 0x1a,
	VOID, VOID, 0x1b, 0x1b, VOID, VOID, 0x27, 0x27, VOID, VOID, 0x1c, 0x1c, VOID, VOID, 0x28, 0x28, VOID, VOID, 0x1d, 0x1d,
	VOID, VOID, 0x29, 0x29, VOID, VOID, 0x12, 0x12, VOID, VOID, 0x1e, 0x1e, VOID, VOID, 0x13, 0x13, VOID, VOID, 0x20, 0x20,
	VOID, VOID, 0x2c, 0x2c, VOID, VOID, VOID, 0x2d, 0x2d, VOID, VOID, 0x39, 0x39, VOID, VOID, 0x45, 0x45, VOID, VOID, VOID,
	0x0a, 0x0a, VOID, VOID, 0x16, 0x16, VOID, VOID, 0x0b, 0x0b, VOID, VOID, 0x17, 0x17, VOID },

	{ VOID, 0x18, 0x18, VOID, VOID, VOID, VOID, 0x24, 0x24, VOID, VOID, VOID, 0x25, 0x25, VOID, VOID, 0x31, 0x31, VOID, VOID, /* 9 */
	0x26, 0x26, VOID, VOID, 0x32, 0x32, VOID, VOID, 0x33, 0x33, VOID, VOID, 0x34, 0x34, VOID, VOID, 0x40, 0x40, VOID, VOID,
	0x35, 0x35, VOID, VOID, 0x2a, 0x2a, VOID, VOID, 0x36, 0x36, VOID, VOID, 0x1f, 0x1f, VOID, VOID, 0x2b, 0x2b, VOID, VOID,
	VOID, 0x38, 0x38, VOID, VOID, VOID, VOID, 0x51, 0x51, VOID, VOID, 0x5d, 0x5d, VOID, VOID, 0x69, 0x69, VOID, VOID, VOID,
	0x22, 0x22, VOID, VOID, 0x2e, 0x2e, VOID, VOID, 0x23, 0x23, VOID, VOID, VOID, VOID, VOID },

	{ 0x18, 0x18, 0x18, 0x18, VOID, VOID, 0x24, 0x24, 0x24, 0x24, VOID, 0x25, 0x25, 0x25, 0x25, 0x31, 0x31, 0x31, 0x31, 0x26,
	0x26, 0x26, 0x26, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33, 0x33, 0x34, 0x34, 0x34, 0x34, 0x40, 0x40, 0x40, 0x40, 0x35,
	0x35, 0x35, 0x35, 0x2a, 0x2a, 0x2a, 0x2a, 0x36, 0x36, 0x36, 0x36, 0x1f, 0x1f, 0x1f, 0x1f, 0x2b, 0x2b, 0x2b, 0x2b, VOID,
	0x38, 0x38, 0x38, 0x38, VOID, VOID, 0x51, 0x51, 0x51, 0x51, 0x5d, 0x5d, 0x5d, 0x5d, 0x69, 0x69, 0x69, 0x69, VOID, 0x22,
	0x22, 0x22, 0x22, 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x23, 0x23, 0x23, VOID, VOID, VOID, VOID },

	{ 0x18, 0x18, 0x18, 0x18, VOID, VOID, 0x24, 0x24, 0x24, 0x24, VOID, 0x25, 0x25, 0x25, 0x25, 0x31, 0x31, 0x31, 0x31, 0x26,
	0x26, 0x26, 0x26, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33, 0x33, 0x34, 0x34, 0x34, 0x34, 0x40, 0x40, 0x40, 0x40, 0x35,
	0x35, 0x35, 0x35, 0x2a, 0x2a, 0x2a, 0x2a, 0x36, 0x36, 0x36, 0x36, 0x1f, 0x1f, 0x1f, 0x1f, 0x2b, 0x2b, 0x2b, 0x2b, VOID,
	0x38, 0x38, 0x38, 0x38, VOID, VOID, 0x51, 0x51, 0x51, 0x51, 0x5d, 0x5d, 0x5d, 0x5d, 0x69, 0x69, 0x69, 0x69, VOID, 0x22,
	0x22, 0x22, 0x22, 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x23, 0x23, 0x23, VOID, 0x2f, 0x2f, VOID },

	{ VOID, 0x18, 0x18, VOID, VOID, VOID, VOID, 0x24, 0x24, VOID, VOID, VOID, 0x25, 0x25, VOID, VOID, 0x31, 0x31, VOID, VOID,
	0x26, 0x26, VOID, VOID, 0x32, 0x32, VOID, VOID, 0x33, 0x33, VOID, VOID, 0x34, 0x34, VOID, VOID, 0x40, 0x40, VOID, VOID,
	0x35, 0x35, VOID, VOID, 0x2a, 0x2a, VOID, VOID, 0x36, 0x36, VOID, VOID, 0x1f, 0x1f, VOID, VOID, 0x2b, 0x2b, VOID, VOID,
	VOID, 0x38, 0x38, VOID, VOID, VOID, VOID, 0x51, 0x51, VOID, VOID, 0x5d, 0x5d, VOID, VOID, 0x69, 0x69, VOID, VOID, VOID,
	0x22, 0x22, VOID, VOID, 0x2e, 0x2e, VOID, VOID, 0x23, 0x23, VOID, 0x2f, 0x2f, 0x2f, 0x2f },

	{ VOID, 0x30, 0x30, VOID, VOID, VOID, VOID, VOID, 0x3c, 0x3c, VOID, VOID, VOID, 0x3d, 0x3d, VOID, VOID, 0x49, 0x49, VOID, /* 13 */
	VOID, 0x3e, 0x3e, VOID, VOID, 0x4a, 0x4a, VOID, VOID, 0x3f, 0x3f, VOID, VOID, 0x4b, 0x4b, VOID, VOID, 0x4c, 0x4c, VOID,
	VOID, 0x41, 0x41, VOID, VOID, 0x42, 0x42, VOID, VOID, 0x4e, 0x4e, VOID, VOID, 0x37, 0x37, VOID, VOID, 0x43, 0x43, VOID,
	VOID, 0x44, 0x44, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	0x3a, 0x3a, VOID, VOID, 0x46, 0x46, VOID, VOID, 0x3b, 0x3b, VOID, 0x2f, 0x2f, 0x2f, 0x2f },

	{ 0x30, 0x30, 0x30, 0x30, VOID, VOID, VOID, 0x3c, 0x3c, 0x3c, 0x3c, VOID, 0x3d, 0x3d, 0x3d, 0x3d, 0x49, 0x49, 0x49, 0x49,
	0x3e, 0x3e, 0x3e, 0x3e, 0x4a, 0x4a, 0x4a, 0x4a, 0x3f, 0x3f, 0x3f, 0x3f, 0x4b, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c, 0x4c, 0x4c,
	0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42, 0x4e, 0x4e, 0x4e, 0x4e, 0x37, 0x37, 0x37, 0x37, 0x43, 0x43, 0x43, 0x43,
	0x44, 0x44, 0x44, 0x44, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, 0x3a,
	0x3a, 0x3a, 0x3a, 0x46, 0x46, 0x46, 0x46, 0x3b, 0x3b, 0x3b, 0x3b, VOID, 0x2f, 0x2f, VOID },

	{ 0x30, 0x30, 0x30, 0x30, VOID, VOID, VOID, 0x3c, 0x3c, 0x3c, 0x3c, VOID, 0x3d, 0x3d, 0x3d, 0x3d, 0x49, 0x49, 0x49, 0x49,
	0x3e, 0x3e, 0x3e, 0x3e, 0x4a, 0x4a, 0x4a, 0x4a, 0x3f, 0x3f, 0x3f, 0x3f, 0x4b, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c, 0x4c, 0x4c,
	0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42, 0x4e, 0x4e, 0x4e, 0x4e, 0x37, 0x37, 0x37, 0x37, 0x43, 0x43, 0x43, 0x43,
	0x44, 0x44, 0x44, 0x44, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, 0x3a,
	0x3a, 0x3a, 0x3a, 0x46, 0x46, 0x46, 0x46, 0x3b, 0x3b, 0x3b, 0x3b, VOID, VOID, VOID, VOID },

	{ VOID, 0x30, 0x30, VOID, VOID, VOID, VOID, VOID, 0x3c, 0x3c, VOID, VOID, VOID, 0x3d, 0x3d, VOID, VOID, 0x49, 0x49, VOID,
	VOID, 0x3e, 0x3e, VOID, VOID, 0x4a, 0x4a, VOID, VOID, 0x3f, 0x3f, VOID, VOID, 0x4b, 0x4b, VOID, VOID, 0x4c, 0x4c, VOID,
	VOID, 0x41, 0x41, VOID, VOID, 0x42, 0x42, VOID, VOID, 0x4e, 0x4e, VOID, VOID, 0x37, 0x37, VOID, VOID, 0x43, 0x43, VOID,
	VOID, 0x44, 0x44, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	0x3a, 0x3a, VOID, VOID, 0x46, 0x46, VOID, VOID, 0x3b, 0x3b, VOID, VOID, VOID, VOID, VOID },

	{ VOID, 0x48, 0x48, VOID, VOID, VOID, VOID, 0x54, 0x54, VOID, VOID, 0x55, 0x55, VOID, VOID, 0x61, 0x61, VOID, VOID, 0x56, /* 17 */
	0x56, VOID, VOID, 0x62, 0x62, VOID, VOID, 0x57, 0x57, VOID, VOID, 0x63, 0x63, VOID, VOID, 0x58, 0x58, VOID, VOID, 0x4d,
	0x4d, VOID, VOID, 0x59, 0x59, VOID, VOID, 0x5a, 0x5a, VOID, VOID, 0x4f, 0x4f, VOID, VOID, 0x5b, 0x5b, VOID, VOID, VOID,
	0x50, 0x50, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, 0x75, 0x75, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	0x52, 0x52, VOID, VOID, 0x5e, 0x5e, VOID, VOID, 0x53, 0x53, VOID, VOID, VOID, VOID, VOID },

	{ 0x48, 0x48, 0x48, 0x48, VOID, VOID, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x61, 0x61, 0x61, 0x61, 0x56, 0x56,
	0x56, 0x56, 0x62, 0x62, 0x62, 0x62, 0x57, 0x57, 0x57, 0x57, 0x63, 0x63, 0x63, 0x63, 0x58, 0x58, 0x58, 0x58, 0x4d, 0x4d,
	0x4d, 0x4d, 0x59, 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5a, 0x4f, 0x4f, 0x4f, 0x4f, 0x5b, 0x5b, 0x5b, 0x5b, VOID, 0x50,
	0x50, 0x50, 0x50, VOID, VOID, VOID, VOID, VOID, VOID, VOID, 0x75, 0x75, 0x75, 0x75, VOID, VOID, VOID, VOID, VOID, 0x52,
	0x52, 0x52, 0x52, 0x5e, 0x5e, 0x5e, 0x5e, 0x53, 0x53, 0x53, 0x53, VOID, VOID, VOID, VOID },

	{ 0x48, 0x48, 0x48, 0x48, VOID, VOID, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x61, 0x61, 0x61, 0x61, 0x56, 0x56,
	0x56, 0x56, 0x62, 0x62, 0x62, 0x62, 0x57, 0x57, 0x57, 0x57, 0x63, 0x63, 0x63, 0x63, 0x58, 0x58, 0x58, 0x58, 0x4d, 0x4d,
	0x4d, 0x4d, 0x59, 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5a, 0x4f, 0x4f, 0x4f, 0x4f, 0x5b, 0x5b, 0x5b, 0x5b, VOID, 0x50,
	0x50, 0x50, 0x50, VOID, VOID, VOID, VOID, VOID, VOID, VOID, 0x75, 0x75, 0x75, 0x75, VOID, VOID, VOID, VOID, VOID, 0x52,
	0x52, 0x52, 0x52, 0x5e, 0x5e, 0x5e, 0x5e, 0x53, 0x53, 0x53, 0x53, VOID, 0x5f, 0x5f, VOID },

	{ VOID, 0x48, 0x48, VOID, VOID, VOID, VOID, 0x54, 0x54, VOID, VOID, 0x55, 0x55, VOID, VOID, 0x61, 0x61, VOID, VOID, 0x56,
	0x56, VOID, VOID, 0x62, 0x62, VOID, VOID, 0x57, 0x57, VOID, VOID, 0x63, 0x63, VOID, VOID, 0x58, 0x58, VOID, VOID, 0x4d,
	0x4d, VOID, VOID, 0x59, 0x59, VOID, VOID, 0x5a, 0x5a, VOID, VOID, 0x4f, 0x4f, VOID, VOID, 0x5b, 0x5b, VOID, VOID, VOID,
	0x50, 0x50, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, 0x75, 0x75, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	0x52, 0x52, VOID, VOID, 0x5e, 0x5e, VOID, VOID, 0x53, 0x53, VOID, 0x5f, 0x5f, 0x5f, 0x5f },

	{ VOID, 0x60, 0x60, VOID, VOID, VOID, VOID, 0x6c, 0x6c, VOID, VOID, VOID, 0x6d, 0x6d, VOID, VOID, VOID, 0x6e, 0x6e, VOID, /* 21 */
	VOID, 0x64, 0x64, VOID, VOID, VOID, VOID, VOID, VOID, VOID, 0x70, 0x70, VOID, VOID, VOID, VOID, VOID, VOID, VOID, 0x65,
	0x65, VOID, VOID, 0x71, 0x71, VOID, VOID, VOID, 0x72, 0x72, VOID, VOID, 0x73, 0x73, VOID, VOID, 0x67, 0x67, VOID, VOID,
	VOID, 0x5c, 0x5c, VOID, VOID, VOID, VOID, 0x68, 0x68, VOID, VOID, 0x74, 0x74, VOID, VOID, 0x76, 0x76, VOID, VOID, VOID,
	VOID, VOID, 0x6a, 0x6a, VOID, VOID, VOID, VOID, 0x6b, 0x6b, VOID, 0x5f, 0x5f, 0x5f, 0x5f },

	{ 0x60, 0x60, 0x60, 0x60, VOID, VOID, 0x6c, 0x6c, 0x6c, 0x6c, VOID, 0x6d, 0x6d, 0x6d, 0x6d, VOID, 0x6e, 0x6e, 0x6e, 0x6e,
	0x64, 0x64, 0x64, 0x64, VOID, VOID, VOID, VOID, VOID, 0x70, 0x70, 0x70, 0x70, VOID, VOID, VOID, VOID, VOID, 0x65, 0x65,
	0x65, 0x65, 0x71, 0x71, 0x71, 0x71, VOID, 0x72, 0x72, 0x72, 0x72, 0x73, 0x73, 0x73, 0x73, 0x67, 0x67, 0x67, 0x67, VOID,
	0x5c, 0x5c, 0x5c, 0x5c, VOID, VOID, 0x68, 0x68, 0x68, 0x68, 0x74, 0x74, 0x74, 0x74, 0x76, 0x76, 0x76, 0x76, VOID, VOID,
	VOID, 0x6a, 0x6a, 0x6a, 0x6a, VOID, VOID, 0x6b, 0x6b, 0x6b, 0x6b, VOID, 0x5f, 0x5f, VOID },

	{ 0x60, 0x60, 0x60, 0x60, VOID, VOID, 0x6c, 0x6c, 0x6c, 0x6c, VOID, 0x6d, 0x6d, 0x6d, 0x6d, VOID, 0x6e, 0x6e, 0x6e, 0x6e,
	0x64, 0x64, 0x64, 0x64, VOID, VOID, VOID, VOID, VOID, 0x70, 0x70, 0x70, 0x70, VOID, VOID, VOID, VOID, VOID, 0x65, 0x65,
	0x65, 0x65, 0x71, 0x71, 0x71, 0x71, VOID, 0x72, 0x72, 0x72, 0x72, 0x73, 0x73, 0x73, 0x73, 0x67, 0x67, 0x67, 0x67, VOID,
	0x5c, 0x5c, 0x5c, 0x5c, VOID, VOID, 0x68, 0x68, 0x68, 0x68, 0x74, 0x74, 0x74, 0x74, 0x76, 0x76, 0x76, 0x76, VOID, VOID,
	VOID, 0x6a, 0x6a, 0x6a, 0x6a, VOID, VOID, 0x6b, 0x6b, 0x6b, 0x6b, VOID, VOID, VOID, VOID },

	{ VOID, 0x60, 0x60, VOID, VOID, VOID, VOID, 0x6c, 0x6c, VOID, VOID, VOID, 0x6d, 0x6d, VOID, VOID, VOID, 0x6e, 0x6e, VOID,
	VOID, 0x64, 0x64, VOID, VOID, VOID, VOID, VOID, VOID, VOID, 0x70, 0x70, VOID, VOID, VOID, VOID, VOID, VOID, VOID, 0x65,
	0x65, VOID, VOID, 0x71, 0x71, VOID, VOID, VOID, 0x72, 0x72, VOID, VOID, 0x73, 0x73, VOID, VOID, 0x67, 0x67, VOID, VOID,
	VOID, 0x5c, 0x5c, VOID, VOID, VOID, VOID, 0x68, 0x68, VOID, VOID, 0x74, 0x74, VOID, VOID, 0x76, 0x76, VOID, VOID, VOID,
	VOID, VOID, 0x6a, 0x6a, VOID, VOID, VOID, VOID, 0x6b, 0x6b, VOID, VOID, VOID, VOID, VOID },

	{ VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID },

	{ VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, /* 26 */
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, 0x78, 0x78, VOID, VOID, 0x79, 0x79, VOID, VOID, 0x7a, 0x7a, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID },

	{ VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID },

	{ VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID },

	{ VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, 0x78, 0x78, VOID, VOID, 0x79, 0x79, VOID, VOID, 0x7a, 0x7a, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID,
	VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID },
};

/* returns TRUE if position is in table range */
static gboolean set_led(RyosCustomLights *custom_lights, gint row, gint column, gboolean value) {
	guint8 bit;

	if (row >= ROWS || row < 0 || column >= COLS || column < 0)
		return FALSE;

	bit = light_index_table[row][column];
	if (bit != VOID)
		roccat_bitfield_set_bit(custom_lights->data, bit, value);

	return TRUE;
}

/*
 * QUOTE Midpoint circle algorithm copied from Perone's programming pad
 * http://willperone.net/Code/codecircle.php
 * Copyright (c) Will Perone
 */
gboolean ryos_ripple_draw_circle(RyosCustomLights *custom_lights, gint center_row, gint center_col, gint radius, gboolean value) {
	int x, y, d, delta_e, delta_se;
	gboolean go_on = FALSE;

	radius *= KEY_WIDTH,

	x = 0;
	y = radius;
	d = 1 - radius;
	delta_e = 3;
	delta_se = 5 - radius * 2;

	if (radius < 1)
		return TRUE;

	if (set_led(custom_lights, center_row - y, center_col, value)) go_on = TRUE;
	if (set_led(custom_lights, center_row + y, center_col, value)) go_on = TRUE;
	if (set_led(custom_lights, center_row, center_col - y, value)) go_on = TRUE;
	if (set_led(custom_lights, center_row, center_col + y, value)) go_on = TRUE;

	while (y > x) {
		if (d < 0) {
			d += delta_e;
			delta_se += 2;
		} else {
			d += delta_se;
			delta_se += 4;
			y--;
		}
		delta_e += 2;
		x++;

		if (set_led(custom_lights, center_row - y, center_col - x, value)) go_on = TRUE;
		if (set_led(custom_lights, center_row - x, center_col - y, value)) go_on = TRUE;
		if (set_led(custom_lights, center_row - x, center_col + y, value)) go_on = TRUE;
		if (set_led(custom_lights, center_row - y, center_col + x, value)) go_on = TRUE;
		if (set_led(custom_lights, center_row + y, center_col - x, value)) go_on = TRUE;
		if (set_led(custom_lights, center_row + x, center_col - y, value)) go_on = TRUE;
		if (set_led(custom_lights, center_row + x, center_col + y, value)) go_on = TRUE;
		if (set_led(custom_lights, center_row + y, center_col + x, value)) go_on = TRUE;
	}
	return go_on;
}
