Permalink
Browse files

Multi-color pattern support

  • Loading branch information...
1 parent b4c3eb4 commit a408f96909b9220110701918328f54ad10eea29b @stg committed Jun 14, 2012
View
Binary file not shown.
View
Binary file not shown.
View
Binary file not shown.
View
Binary file not shown.
View
Binary file not shown.
@@ -138,11 +138,15 @@ static void cmd_track() {
// print image to screen
static void image_print(uint8_t *p_img,uint16_t w,uint16_t h) {
uint16_t x,y;
+ uint8_t sample,memo;
for(y=0;y<h;y++) {
+ memo=0;
for(x=0;x<w;x++) {
- putchar(image_sample(p_img,w,x,y)?'X':'-');
+ sample=image_sample(p_img,w,x,y);
+ if(memo==0&&sample!=0xFF) memo=sample&0xF;
+ putchar(sample!=0xFF?'X':'-');
}
- printf("\n");
+ printf(" %01X\n",memo);
}
}
@@ -5,20 +5,32 @@ All values are big-endian where appropriate.
Offset Bytes Content
0x0000 2 Width in pixels/stitches
0x0002 2 Height in pixels/rows
-0x0008 width*height Greyscale pixel data - top-down, left-right
+0x0008 width*height Pixel data - top-down, left-right
Pixels will output as a stitch when < 50% brightness (0x80).
Example, letter P, 6x9 pixels, 58 bytes, hexadecimal:
-00 06
-00 09
-FF FF FF FF FF FF
-FF 00 00 00 FF FF
-FF 00 FF FF 00 FF
-FF 00 FF FF 00 FF
-FF 00 00 00 FF FF
-FF 00 FF FF FF FF
-FF 00 FF FF FF FF
-FF 00 FF FF FF FF
-FF FF FF FF FF FF
+ 00 06
+ 00 09
+ FF FF FF FF FF FF
+ FF 00 00 00 FF FF
+ FF 00 FF FF 00 FF
+ FF 00 FF FF 00 FF
+ FF 00 00 00 FF FF
+ FF 00 FF FF FF FF
+ FF 00 FF FF FF FF
+ FF 00 FF FF FF FF
+ FF FF FF FF FF FF
+
+Pixel values for single color patterns:
+
+ 00 contrast yarn
+ FF main yarn
+
+Pixel values for multi-color patterns:
+
+ 01 contrast yarn 1
+ 02 contrast yarn 2
+ 03 contrast yarn 3
+ FF main yarn
View
@@ -3,13 +3,47 @@
#include <stdbool.h>
#include <FreeImage.h>
#include "loader.h"
+#include <stdio.h> // todo remove
+#include <string.h> // todo remove
+
+#define ABS(n) (((n)<0)?(-(n)):((n)))
+
+// byte order access fixes bug in FreeImage
+#define RED(q) (q->rgbBlue)
+#define GREEN(q) (q->rgbGreen)
+#define BLUE(q) (q->rgbRed)
static FIBITMAP *dib=NULL;
static uint16_t w,h;
+static RGBQUAD colors[16] = {
+ {.rgbRed=0x00,.rgbGreen=0x00,.rgbBlue=0x00}, // 0 black
+ {.rgbRed=0x00,.rgbGreen=0x00,.rgbBlue=0x7F}, // 1 dark blue
+ {.rgbRed=0x00,.rgbGreen=0x7F,.rgbBlue=0x00}, // 2 dark green
+ {.rgbRed=0x7F,.rgbGreen=0x00,.rgbBlue=0x00}, // 3 dark red
+ {.rgbRed=0x00,.rgbGreen=0x00,.rgbBlue=0x00},
+ {.rgbRed=0x00,.rgbGreen=0x00,.rgbBlue=0x00},
+ {.rgbRed=0x00,.rgbGreen=0x00,.rgbBlue=0x00},
+ {.rgbRed=0x00,.rgbGreen=0x00,.rgbBlue=0x00},
+ {.rgbRed=0x00,.rgbGreen=0x00,.rgbBlue=0x00},
+ {.rgbRed=0x00,.rgbGreen=0x00,.rgbBlue=0x00},
+ {.rgbRed=0x00,.rgbGreen=0x00,.rgbBlue=0x00},
+ {.rgbRed=0x00,.rgbGreen=0x00,.rgbBlue=0x00},
+ {.rgbRed=0x00,.rgbGreen=0x00,.rgbBlue=0x00},
+ {.rgbRed=0x00,.rgbGreen=0x00,.rgbBlue=0x00},
+ {.rgbRed=0x00,.rgbGreen=0x00,.rgbBlue=0x00},
+ {.rgbRed=0xFF,.rgbGreen=0xFF,.rgbBlue=0xFF} // F white
+};
bool image_loadpicture(const char* filename) {
FREE_IMAGE_FORMAT fif=FIF_UNKNOWN;
int flag=0;
+/*
+ int n;
+ for(n=0;n<strlen(filename);n++) {
+ printf("%02X ",filename[n]);
+ }
+ printf("\n");
+*/
fif=FreeImage_GetFileType(filename,0);
if(fif==FIF_UNKNOWN) {
fif=FreeImage_GetFIFFromFilename(filename);
@@ -38,15 +72,48 @@ uint16_t image_height() {
return h;
}
+static uint8_t match_color(RGBQUAD *p_quad) {
+ uint16_t diff,best=0xFFFF;
+ uint8_t n,i=0x0F;
+// printf("%02X%02X%02X ",p_quad->rgbRed,p_quad->rgbGreen,p_quad->rgbBlue);
+ for(n=0;n<16;n++) {
+ diff = ABS((RED(p_quad)) -((int16_t)colors[n].rgbRed ))
+ + ABS((GREEN(p_quad))-((int16_t)colors[n].rgbGreen))
+ + ABS((BLUE(p_quad)) -((int16_t)colors[n].rgbBlue ));
+ if(diff<best) {
+ best=diff;
+ i=n;
+ }
+ }
+// printf("%02X ",i);
+ return i==0x0F?0xFF:i;
+}
+
+static void image_print(uint8_t *p_img,uint16_t w,uint16_t h) {
+ uint16_t x,y;
+ uint8_t sample,memo;
+ for(y=0;y<h;y++) {
+ memo=0;
+ for(x=0;x<w;x++) {
+ sample=image_sample(p_img,w,x,y);
+ if(memo==0&&sample!=0xFF) memo=sample&0xF;
+// printf("%c",sample!=0xFF?'X':'-');
+ }
+// printf(" %01X\n",memo);
+ }
+}
+
void image_convert(uint8_t *p_data) {
uint16_t x,y;
RGBQUAD quad;
for(y=0;y<h;y++) {
for(x=0;x<w;x++) {
FreeImage_GetPixelColor(dib,x,y,&quad);
- p_data[y*w+x]=((uint16_t)quad.rgbRed+(uint16_t)quad.rgbGreen+(uint16_t)quad.rgbBlue)/3;
+ p_data[y*w+x]=match_color(&quad);
}
- }
+// printf("\n");
+ }
+ image_print(p_data,w,h);
}
void image_free() {
View
@@ -210,6 +210,7 @@ void r_init( SDL_Surface *scr ) {
void r_draw() {
unsigned char x, y;
unsigned char i, j;
+ Uint32 SDL_color;
SDL_BlitSurface(bg,NULL,screen,NULL);
write_index = 0;
SDL_Rect srcrect;
@@ -231,7 +232,20 @@ void r_draw() {
srcrect.x = TERM( x, y ).cchar << 4;
srcrect.y = ( TERM( x, y ).tick >= 0 ? TERM( x, y ).tick << 4 : 240 ) + TERM( x, y ).cfont * 256;
if( TERM( x, y ).bgc ) {
- SDL_FillRect( screen, &dstrect, 0 );
+
+ switch(0xF-TERM( x, y ).bgc) {
+ case 0x0: SDL_color = SDL_MapRGB(screen->format,0x00,0x00,0x00);
+ break;
+ case 0x1: SDL_color = SDL_MapRGB(screen->format,0x00,0x00,0x7F);
+ break;
+ case 0x2: SDL_color = SDL_MapRGB(screen->format,0x00,0x7F,0x00);
+ break;
+ case 0x3: SDL_color = SDL_MapRGB(screen->format,0x7F,0x00,0x00);
+ break;
+ default : SDL_color = SDL_MapRGB(screen->format,0x7F,0x7F,0x7F);
+ }
+
+ SDL_FillRect( screen, &dstrect, SDL_color );
}
SDL_BlitSurface( font, &srcrect, screen, &dstrect );
}
View
@@ -138,12 +138,6 @@ static bool grid_cset(uiobj_t *p_ui,int16_t x,int16_t y,char c,uint8_t bg) {
}
static void grid_focus(uiobj_t *p_ui) {
-/* grid_t *p_grid=p_ui->obj;
- view_t *p_view=p_ui->view;
- if(p_grid->data) {
- r_cins(p_ui->x+p_view->x-p_grid->l+p_grid->x*3+2,p_ui->y+p_view->y-p_grid->t+p_grid->y*3+2);
- }
-*/
grid_t *p_grid=p_ui->obj;
view_t *p_view=p_ui->view;
if(p_grid->data) {
@@ -153,77 +147,6 @@ static void grid_focus(uiobj_t *p_ui) {
}
static void grid_draw(uiobj_t *p_ui) {
-/* grid_t *p_grid=p_ui->obj;
- view_t *p_view=p_ui->view;
- uint16_t x,y;
- uint8_t bg;
- if(p_ui->state&9) {
- r_white(p_ui->x+p_view->x-1,p_ui->y+p_view->y-1,p_ui->w+2,p_ui->h+2);
- if(p_grid->data) {
- for(y=1;y<3*p_grid->h+1;y++) {
- grid_cset(p_ui,0,y,'h',0);
- grid_cset(p_ui,p_grid->w*3+1,y,'g',0);
- if(((y-1)%15)==0) {
- grid_cset(p_ui,-1,y ,'0'+(((y-1)/300)%10),0);
- grid_cset(p_ui,-1,y+1,'0'+(((y-1)/ 30)%10),0);
- grid_cset(p_ui,-1,y+2,'0'+(((y-1)/ 3)%10),0);
- grid_cset(p_ui,-2,y ,'0'+(((y-1)/300)%10),0);
- grid_cset(p_ui,-2,y+1,'0'+(((y-1)/ 30)%10),0);
- grid_cset(p_ui,-2,y+2,'0'+(((y-1)/ 3)%10),0);
- }
- }
- for(x=1;x<3*p_grid->w+1;x++) {
- grid_cset(p_ui,x,0,'b',0);
- grid_cset(p_ui,x,p_grid->h*3+1,'y',0);
- if(((x-1)%15)==0) {
- grid_cset(p_ui,x ,-1,'0'+(((x-1)/300)%10),0);
- grid_cset(p_ui,x+1,-1,'0'+(((x-1)/ 30)%10),0);
- grid_cset(p_ui,x+2,-1,'0'+(((x-1)/ 3)%10),0);
- grid_cset(p_ui,x ,-2,'0'+(((x-1)/300)%10),0);
- grid_cset(p_ui,x+1,-2,'0'+(((x-1)/ 30)%10),0);
- grid_cset(p_ui,x+2,-2,'0'+(((x-1)/ 3)%10),0);
- }
- }
- grid_cset(p_ui,0,0,'m',0);
- grid_cset(p_ui,p_grid->w*3+1,0,'c',0);
- grid_cset(p_ui,0,p_grid->h*3+1,'r',0);
- grid_cset(p_ui,p_grid->w*3+1,p_grid->h*3+1,'i',0);
- for(y=0;y<p_grid->h;y++) {
- for(x=0;x<p_grid->w;x++) {
- bg=(p_grid->data[x+y*p_grid->w]<0x80)?1:0;
- grid_cset(p_ui,x*3+1,y*3+1,'t',bg);
- grid_cset(p_ui,x*3+2,y*3+1,'y',bg);
- grid_cset(p_ui,x*3+3,y*3+1,'u',bg);
- grid_cset(p_ui,x*3+1,y*3+2,'g',bg);
- grid_cset(p_ui,x*3+2,y*3+2,'ñ',bg);
- grid_cset(p_ui,x*3+3,y*3+2,'h',bg);
- grid_cset(p_ui,x*3+1,y*3+3,'v',bg);
- grid_cset(p_ui,x*3+2,y*3+3,'b',bg);
- grid_cset(p_ui,x*3+3,y*3+3,'n',bg);
- }
- }
- if(p_grid->l) for(y=0;y<p_ui->h-0;y++) {
- r_char(p_ui->x+p_view->x,p_ui->y+p_view->y+y,'a',0,0);
- }
- if(p_grid->w*3+2-p_grid->l>p_ui->w) for(y=0;y<p_ui->h-0;y++) {
- r_char(p_ui->x+p_view->x+p_ui->w-1,p_ui->y+p_view->y+y,'d',0,0);
- }
- if(p_grid->t) for(x=0;x<p_ui->w-0;x++) {
- r_char(p_ui->x+p_view->x+x,p_ui->y+p_view->y,'w',0,0);
- }
- if(p_grid->h*3+2-p_grid->t>p_ui->h) for(x=0;x<p_ui->w-0;x++) {
- r_char(p_ui->x+p_view->x+x,p_ui->y+p_view->y+p_ui->h-1,'s',0,0);
- }
- if(p_ui->state&8) {
- r_done(p_ui->x+p_view->x-1,p_ui->y+p_view->y-1,p_ui->w+2,p_ui->h+2);
- }
- }
- }
- if(p_ui->state&4) {
- grid_focus(p_ui);
- }
- p_ui->state=0;
-*/
grid_t *p_grid=p_ui->obj;
view_t *p_view=p_ui->view;
uint16_t x,y;
@@ -261,7 +184,7 @@ static void grid_draw(uiobj_t *p_ui) {
grid_cset(p_ui,p_grid->w*2+1,p_grid->h*2+1,'i',0);
for(y=0;y<p_grid->h;y++) {
for(x=0;x<p_grid->w;x++) {
- bg=(p_grid->data[x+y*p_grid->w]<0x80)?1:0;
+ bg=0xF-(p_grid->data[x+y*p_grid->w]&0xF);
grid_cset(p_ui,x*2+1,y*2+1,'t',bg);
grid_cset(p_ui,x*2+2,y*2+1,'u',bg);
grid_cset(p_ui,x*2+1,y*2+2,'v',bg);
@@ -292,60 +215,17 @@ static void grid_draw(uiobj_t *p_ui) {
}
static bool grid_key(uiobj_t *p_ui,SDL_Keycode sym) {
-/*
- grid_t *p_grid=p_ui->obj;
- switch(sym) {
- case SDLK_LEFT:
- if(p_grid->x>0) {
- p_grid->x--;
- p_ui->state|=4;
- }
- break;
- case SDLK_RIGHT:
- if(p_grid->x<p_grid->w-1) {
- p_grid->x++;
- p_ui->state|=4;
- }
- break;
- case SDLK_UP:
- if(p_grid->y>0) {
- p_grid->y--;
- p_ui->state|=4;
- }
- break;
- case SDLK_DOWN:
- if(p_grid->y<p_grid->h-1) {
- p_grid->y++;
- p_ui->state|=4;
- }
- break;
- case SDLK_SPACE:
- p_grid->data[p_grid->x+p_grid->y*p_grid->w]=p_grid->data[p_grid->x+p_grid->y*p_grid->w]<0x80?0xFF:0x00;
- p_ui->state|=8;
- return true;
- }
-
- if((p_grid->x*3+2)-2<p_grid->l) {
- p_grid->l=(p_grid->x*3+2)-2;
- p_ui->state|=8;
- } else if( (p_grid->x*3+2)+3>p_grid->l+p_ui->w ) {
- p_grid->l=(p_grid->x*3+2)+3-p_ui->w;
- p_ui->state|=8;
- }
-
- if((p_grid->y*3+2)-2<p_grid->t) {
- p_grid->t=(p_grid->y*3+2)-2;
- p_ui->state|=8;
- } else if( (p_grid->y*3+2)+3>p_grid->t+p_ui->h ) {
- p_grid->t=(p_grid->y*3+2)+3-p_ui->h;
- p_ui->state|=8;
- }
-
-
- return false;
-*/
grid_t *p_grid=p_ui->obj;
- switch(sym) {
+ uint16_t x;
+ uint8_t sample=0;
+ if((sym>=SDLK_0&&sym<=SDLK_3)) {
+ for(x=0;x<p_grid->w;x++) {
+ if(p_grid->data[x+p_grid->y*p_grid->w]<0xF) {
+ p_grid->data[x+p_grid->y*p_grid->w]=sym-SDLK_0;
+ p_ui->state|=8;
+ }
+ }
+ } else switch(sym) {
case SDLK_LEFT:
if(p_grid->x>0) {
p_grid->x--;
@@ -371,7 +251,13 @@ static bool grid_key(uiobj_t *p_ui,SDL_Keycode sym) {
}
break;
case SDLK_SPACE:
- p_grid->data[p_grid->x+p_grid->y*p_grid->w]=p_grid->data[p_grid->x+p_grid->y*p_grid->w]<0x80?0xFF:0x00;
+ for(x=0;x<p_grid->w;x++) {
+ if(p_grid->data[x+p_grid->y*p_grid->w]<0xF) {
+ sample=p_grid->data[x+p_grid->y*p_grid->w];
+ break;
+ }
+ }
+ p_grid->data[p_grid->x+p_grid->y*p_grid->w]=p_grid->data[p_grid->x+p_grid->y*p_grid->w]<0x0F?0xFF:sample;
p_ui->state|=8;
break;
default:
View
@@ -14,10 +14,10 @@ extern "C" {
uint8_t *image_alloc(uint16_t width,uint16_t height);
// get pixel from image
-bool image_sample(uint8_t *p_image,uint16_t width,uint16_t x,uint16_t y);
+uint8_t image_sample(uint8_t *p_image,uint16_t width,uint16_t x,uint16_t y);
// set pixel in image
-void image_pset(uint8_t *p_image,uint16_t width,uint16_t x,uint16_t y,bool pixel);
+void image_pset(uint8_t *p_image,uint16_t width,uint16_t x,uint16_t y,uint8_t pixel);
// read image file
uint8_t *image_read(FILE *f,uint16_t *width,uint16_t *height);
Oops, something went wrong. Retry.

0 comments on commit a408f96

Please sign in to comment.