1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
|
#include "../globals.h"
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PLUGIN_NAME "Smooth"
glob_statics my_g_stat;
glob_variables my_g_var;
// global variables
colour_hex col[256][16]; // Star, Source, Trigger, 13 targets
int glob_idx = 0;
/*****************************************************************************/
// NO CHANGES TO MAKE HERE
Uint8 my_getpixel(SDL_Surface* surface, int x, int y) {
int bpp = surface->format->BytesPerPixel;
Uint8* p = (Uint8*)surface->pixels + y * surface->pitch + x * bpp;
/* Here p is the address to the pixel we want to retrieve */
switch (bpp) {
case 1:
return *p;
default:
return 0; /* shouldn't happen, but avoids warnings */
}
}
void init_plugin(glob_statics* g_stat) {
// required since it is called specifically at load time
// update the local glob_statics so that other functions can access it as
// well.
my_g_stat.debug = g_stat->debug;
my_g_stat.filein = g_stat->filein;
my_g_stat.fileout = g_stat->fileout;
my_g_stat.config_file = g_stat->config_file;
my_g_stat.image_in = g_stat->image_in;
if (my_g_stat.debug) {
printf("Loading %s\n", PLUGIN_NAME);
}
if (my_g_stat.debug > 3) {
printf("Checking the global stats for %s\n", PLUGIN_NAME);
printf("\tdebug = %d\n", my_g_stat.debug);
printf("\tfilein = %s\n", my_g_stat.filein);
printf("\tfileout = %s\n", my_g_stat.fileout);
printf("\tconfig_file = %s\n", my_g_stat.config_file);
}
}
void deinit_plugin(void) {
// required since it is called specifically at unload time
if (my_g_stat.debug) {
printf("Unloading %s\n", PLUGIN_NAME);
}
}
int plugin_parse(char* line) {
// required
// will prepare the plugin to know what to send back when receiving a
// colour_hex in plugin_apply
const int size = strlen(line);
int newrec = 1;
int let = 0;
unsigned int idx = 0;
char color[7] = {0};
colour_hex r = 0;
colour_hex g = 0;
colour_hex b = 0;
// in this case we know we should receive 18 parameters
// 1 for slave, 1 for master and 13 for the resulting colour
if (my_g_stat.debug > 3) {
printf("Parsing %s\n", line);
}
col[glob_idx][0] = 0;
for (int i = 0; i <= size; i++) {
char c = (i == size ? '\n' : line[i]);
if (c != ' ' && c != '\t' && c != '\n' && c != '\r') {
if (newrec) {
newrec = 0;
idx++;
}
if (let < 6) {
color[let] = c;
}
let++;
} else {
if (newrec == 0) {
color[let] = '\0';
if (idx == 2 && let > 0 && color[0] == '*') {
col[glob_idx][0] = 1;
col[glob_idx][idx] = 0;
} else {
sscanf(color, "%02x%02x%02x", &r, &g, &b);
col[glob_idx][idx] = ((r << 16) | (g << 8) | (b));
}
}
newrec = 1;
let = 0;
}
}
glob_idx++;
return 0;
}
int calculate(Uint8 col_num, unsigned int my_x, unsigned int my_y) {
// this function helps to identify which colour to return
// it returns either 1 or 0 based on whether the pixel at (x,y) is of colour
// col_num it also checks boundaries and return 0 if out of boundaries
if (my_x > 191 || my_y > 191) {
// printf("out of bounds\n");
return 0;
} else {
int ret = my_getpixel(my_g_stat.image_in, my_x, my_y);
return ret == col_num;
}
}
int has_around(colour_hex col_name) {
// this checks if there is a chunk around (i,j) of colour col_name
// we check the 8 directions
// used to find a trigger colour around the chunk we are transforming
long int a0 = my_getpixel(
my_g_stat.image_in, (192 + my_g_var.global_x - 1) % 192,
(192 + my_g_var.global_y - 1) % 192);
long int a = my_g_stat.image_in->format->palette->colors[a0].r * 256 * 256
+ my_g_stat.image_in->format->palette->colors[a0].g * 256
+ my_g_stat.image_in->format->palette->colors[a0].b;
long int b0 = my_getpixel(
my_g_stat.image_in, (192 + my_g_var.global_x) % 192,
(192 + my_g_var.global_y - 1) % 192);
long int b = my_g_stat.image_in->format->palette->colors[b0].r * 256 * 256
+ my_g_stat.image_in->format->palette->colors[b0].g * 256
+ my_g_stat.image_in->format->palette->colors[b0].b;
long int c0 = my_getpixel(
my_g_stat.image_in, (192 + my_g_var.global_x + 1) % 192,
(192 + my_g_var.global_y - 1) % 192);
long int c = my_g_stat.image_in->format->palette->colors[c0].r * 256 * 256
+ my_g_stat.image_in->format->palette->colors[c0].g * 256
+ my_g_stat.image_in->format->palette->colors[c0].b;
long int d0 = my_getpixel(
my_g_stat.image_in, (192 + my_g_var.global_x - 1) % 192,
(192 + my_g_var.global_y) % 192);
long int d = my_g_stat.image_in->format->palette->colors[d0].r * 256 * 256
+ my_g_stat.image_in->format->palette->colors[d0].g * 256
+ my_g_stat.image_in->format->palette->colors[d0].b;
long int e0 = my_getpixel(
my_g_stat.image_in, (192 + my_g_var.global_x + 1) % 192,
(192 + my_g_var.global_y) % 192);
long int e = my_g_stat.image_in->format->palette->colors[e0].r * 256 * 256
+ my_g_stat.image_in->format->palette->colors[e0].g * 256
+ my_g_stat.image_in->format->palette->colors[e0].b;
long int f0 = my_getpixel(
my_g_stat.image_in, (192 + my_g_var.global_x - 1) % 192,
(192 + my_g_var.global_y + 1) % 192);
long int f = my_g_stat.image_in->format->palette->colors[f0].r * 256 * 256
+ my_g_stat.image_in->format->palette->colors[f0].g * 256
+ my_g_stat.image_in->format->palette->colors[f0].b;
long int g0 = my_getpixel(
my_g_stat.image_in, (192 + my_g_var.global_x) % 192,
(192 + my_g_var.global_y + 1) % 192);
long int g = my_g_stat.image_in->format->palette->colors[g0].r * 256 * 256
+ my_g_stat.image_in->format->palette->colors[g0].g * 256
+ my_g_stat.image_in->format->palette->colors[g0].b;
long int h0 = my_getpixel(
my_g_stat.image_in, (192 + my_g_var.global_x + 1) % 192,
(192 + my_g_var.global_y + 1) % 192);
long int h = my_g_stat.image_in->format->palette->colors[h0].r * 256 * 256
+ my_g_stat.image_in->format->palette->colors[h0].g * 256
+ my_g_stat.image_in->format->palette->colors[h0].b;
long int val = col_name;
return a == val || b == val || c == val || d == val || e == val || f == val
|| g == val || h == val;
}
// UP TO HERE
/*****************************************************************************/
colour_hex plugin_apply(colour_hex colour, glob_variables* g_var) {
// required
// function called to transform a colour_hex into another one. plugin_parse
// must have been called previously to know what to return. the
// implementation is left to the plugin writer both plugin_parse and
// plugin_apply are obviously plugin-specific colour is the colour at point
// (i,j) -- (i,j) are external variables from smooth
my_g_var.global_x = g_var->global_x;
my_g_var.global_y = g_var->global_y;
my_g_var.image_out = g_var->image_out;
Uint8 col_num = my_getpixel(
my_g_stat.image_in, my_g_var.global_x, my_g_var.global_y);
// find the colour in big table
int loc_idx = 0;
while (loc_idx < glob_idx && col[loc_idx][1] != colour) {
loc_idx++;
}
if (loc_idx >= glob_idx) {
fprintf(stderr,
"WARNING: loc_idx >= glob_idx. This should never happen\n");
return colour; // colour is not in table, so we don't treat it. This
// should never happen.
}
if (col[loc_idx][0] == 1 || has_around(col[loc_idx][2])) {
// printf("trig is around!\n");
// this is the main part. Trigger is * or trigger is around the chunk to
// change.
unsigned short int a
= calculate(col_num, my_g_var.global_x - 1, my_g_var.global_y);
unsigned short int b
= calculate(col_num, my_g_var.global_x, my_g_var.global_y + 1);
unsigned short int c
= calculate(col_num, my_g_var.global_x + 1, my_g_var.global_y);
unsigned short int d
= calculate(col_num, my_g_var.global_x, my_g_var.global_y - 1);
if (!((a || c) && (b || d))) {
// this combinaison is not authorised for modifying.
// we must have at least one on North or South or both AND one on
// East or West or both
if (my_g_stat.debug > 3) {
printf("trigger present but not authorised combinaison a=%d "
"b=%d c=%d d=%d\n",
a, b, c, d);
}
return colour;
}
unsigned int calc_value = lround(
1 + (2.4 * a) + (-2.1 * b) + (1.1 * c) + (3.1 * d) + 0.5);
if (my_g_stat.debug > 3) {
printf("calc_value is %u at (%d,%d) -- a=%d b=%d c=%d d=%d\n",
calc_value, my_g_var.global_x, my_g_var.global_y, a, b, c,
d);
}
if (calc_value != 6) {
// not the center chunk with a trigger on one of the corners
return col[loc_idx][calc_value + 3]; // the first 3 cells are
// star, slave and trigger
} else {
// in this case, the chunk is a center chunk with a trigger on one
// corner need to know trigger's index.
// Uint8 idx_trigger =
// SDL_MapRGB(
// my_g_stat.image_in->format,
// 16*(int)col[loc_idx][1][0]+(int)col[loc_idx][1][1],
// 16*(int)col[loc_idx][1][2]+(int)col[loc_idx][1][3],
// 16*(int)col[loc_idx][1][4]+(int)col[loc_idx][1][5]);
Uint8 idx_trigger = 0;
unsigned short int i = calculate(
idx_trigger, my_g_var.global_x - 1,
my_g_var.global_y - 1); // NW corner
unsigned short int j = calculate(
idx_trigger, my_g_var.global_x + 1,
my_g_var.global_y - 1); // NE corner
unsigned short int k = calculate(
idx_trigger, my_g_var.global_x + 1,
my_g_var.global_y + 1); // SE corner
unsigned short int l = calculate(
idx_trigger, my_g_var.global_x - 1,
my_g_var.global_y + 1); // SW corner
if (i + j + k + l != 1) {
// Not exactly one trigger at the corners. This is not allowed
return colour;
} else {
calc_value = 8 + 1 * i + 2 * j + 3 * k + 4 * l;
return col[loc_idx][calc_value + 3];
}
}
} else {
// No trigger aroung this chunk
return colour;
}
}
|