Added palette.c/h and palette_init() call in main.c
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2014 rxi
|
* Copyright (c) 2014 rxi
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
* This library is free software; you can redistribute it and/or modify it
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "luaobj.h"
|
#include "luaobj.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
#include "palette.h"
|
||||||
|
|
||||||
|
|
||||||
static lua_State *L;
|
static lua_State *L;
|
||||||
@@ -43,6 +44,7 @@ int main(void) {
|
|||||||
/* Init everything */
|
/* Init everything */
|
||||||
atexit(deinit);
|
atexit(deinit);
|
||||||
vga_init();
|
vga_init();
|
||||||
|
palette_init();
|
||||||
keyboard_init();
|
keyboard_init();
|
||||||
|
|
||||||
/* Init lua */
|
/* Init lua */
|
||||||
@@ -99,4 +101,4 @@ int main(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
77
src/palette.c
Normal file
77
src/palette.c
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <pc.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
8
src/palette.h
Normal file
8
src/palette.h
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user