From 92511f0132cabe82e65cc1b3fc452562c09243f7 Mon Sep 17 00:00:00 2001 From: rxi Date: Thu, 22 Sep 2016 19:11:56 +0100 Subject: [PATCH] Added palette.c/h and palette_init() call in main.c --- src/main.c | 6 ++-- src/palette.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/palette.h | 8 ++++++ 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 src/palette.c create mode 100644 src/palette.h diff --git a/src/main.c b/src/main.c index 3ade310..9e34c48 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2014 rxi * * This library is free software; you can redistribute it and/or modify it @@ -16,6 +16,7 @@ #include "luaobj.h" #include "keyboard.h" #include "image.h" +#include "palette.h" static lua_State *L; @@ -43,6 +44,7 @@ int main(void) { /* Init everything */ atexit(deinit); vga_init(); + palette_init(); keyboard_init(); /* Init lua */ @@ -99,4 +101,4 @@ int main(void) { } return 0; -} +} diff --git a/src/palette.c b/src/palette.c new file mode 100644 index 0000000..af2a733 --- /dev/null +++ b/src/palette.c @@ -0,0 +1,77 @@ +#include +#include + +#include "palette.h" + +#define MAX_IDX 256 +#define MAP_SIZE 1024 +#define MAP_MASK (MAP_SIZE - 1) + +static struct { unsigned color; int idx; } map[MAP_SIZE]; +static int nextIdx; +static int inited; + + +void palette_init(void) { + if (inited) return; + palette_reset(); + inited = 1; +} + + +void palette_reset(void) { + /* Reset nextIdx -- start at idx 1 as 0 is used for transparency */ + nextIdx = 1; + /* Reset map */ + int i; + for (i = 0; i < MAP_SIZE; i++) { + map[i].idx = -1; + } +} + + +static unsigned hash(const void *data, int size) { + unsigned hash = 5381; + const unsigned char *p = data; + while (size--) { + hash = ((hash << 5) + hash) ^ *p++; + } + return hash; +} + + +int palette_colorIdx(int r, int g, int b) { + palette_init(); + + /* Make 18bit rgb color (6bits per-channel) from 8bit channels */ + unsigned color = ((r & 0xfc) << 10) | ((g & 0xfc) << 4) | ((b & 0xfc) >> 2); + + /* Hash color */ + unsigned h = hash(&color, sizeof(color)); + + /* Find color in hashmap */ + int i = h & MAP_MASK; + while (map[i].idx != -1) { + if (map[i].color == color) { + return map[i].idx; + } + i = (i + 1) & MAP_MASK; + } + + /* Color wasn't found in hashmap -- Add to system palette and map */ + if (nextIdx >= MAX_IDX) { + return -1; /* Return -1 for error if we've exceeded the palette capacity */ + } + int idx = nextIdx++; + + /* Update system palette */ + outp(0x03c8, idx); + outp(0x03c9, (color ) & 0x3f); /* r */ + outp(0x03c9, (color >> 6) & 0x3f); /* g */ + outp(0x03c9, (color >> 12) & 0x3f); /* b */ + + /* Add to hashmap and return idx */ + map[i].color = color; + map[i].idx = idx; + return idx; +} diff --git a/src/palette.h b/src/palette.h new file mode 100644 index 0000000..5fc7cbc --- /dev/null +++ b/src/palette.h @@ -0,0 +1,8 @@ +#ifndef PALETTE_H +#define PALETTE_H + +void palette_init(void); +void palette_reset(void); +int palette_colorIdx(int r, int g, int b); + +#endif