/*
	ARTemis (Graphic Editor for FM-TOWNS)
	(c) MATSUUCHI Ryosuke 1992

	goshi.c

	摩筆のシミュレート
*/

#include <stdio.h>
#include <egb.h>
#include <stdlib.h>
#include <msdos.cf>
#include <fnt.h>
#include <ctype.h>

#include "ge.h"
#include "dispman.h"
#include "imageman.h"


typedef struct {
	char b,r,g;
	char dmy;
} pencol_t;

#define	subst_pencol(obj, r,g,b)	\
	*(int*)&(obj) = ((int)(g) << 16) | ((int)(r) << 8) | (int)(b)

// static int pencol_r[16][16], pencol_g[16][16], pencol_b[16][16];
static pencol_t penc[32][32];

#define	XL	32
#define	YL	32
#define	CX	15
#define	CY	15

void get_pencol(int x, int y, pen_t *pen)
/*
	ペン先に色をコピーする
*/
{
	int c;
	if (mode != MODE32K)
		return;
	if (pen_isdottype(pen))
		c = EIMpoint(x,y), subst_pencol(penc[CY][CX], getR(c), getG(c), getB(c));
	else
	{
		int maxx,maxy;
		maxx = EIMgetxsize();
		maxy = EIMgetysize();
		void get_pencol_hline(int x0,int y0,int dx,int xlen,int dy,
							  short *graymap)
		{
			int i; short *ep;
			ep = (short*)EIMadrs(x0+dx,_lim(y0+dy,0,maxy));
			for (i=0; i<xlen; i++)
			{
				int ix = _lim(x0+dx+i,0,maxx) - (x0+dx);
				c = *(ep + ix);
				subst_pencol(penc[CY+dy][CX+dx+i],getR(c),getG(c),getB(c));
			}
		}
		pen_fill(pen, get_pencol_hline, x,y, NO);
	}
#if 0
		x1 = _max(x - 7 + 0,  0) - (x - 7);
		y1 = _max(y - 7 + 0,  0) - (y - 7);
		x2 = _min(x - 7 + 15,  maxx) - (x - 7);
		y2 = _min(y - 7 + 15,  maxy) - (y - 7);
		//
		// 16×16の領域のうち、画面の上にはみ出した部分の処理
		if (0 < y1)
		{
			for (j=0; j<=15; j++)
			{
				int tx = (j < x1 ? 0 : x2 < j ? maxx : x - 7 + j);
				c = EIMpoint(tx, 0);
				for (i=0; i<y1; i++)
					if (pen->pat[i*16+j] > 0)
						subst_pencol(penc[i][j], getR(c), getG(c), getB(c));
			}
		}
		for (i=y1; i<=y2; i++)
		{
			int pi;
			//
			// 16×16の領域で、画面の上端・下端の間にある部分のうち、
			// 画面の左にはみ出した部分の処理
			if (0 < x1)
			{
				c = EIMpoint(0, y-7+i);
				for (j=0; j<x1; j++)
					if (pen->pat[i*16+j] > 0)
						subst_pencol(penc[i][j], getR(c), getG(c), getB(c));
			}
			//
			// 16×16の領域で、完全に画面内にある部分の処理
			short *ep;
			ep = (short*)EIMadrs(x-7+x1,y-7+i);
			pi = i*16+x1;
			for (j=x1; j<=x2; j++,ep++,pi++)
				if (pen->pat[pi] > 0)
					c = *ep, subst_pencol(penc[i][j], getR(c), getG(c), getB(c));
			//
			// 16×16の領域で、画面の上端・下端の間にある部分のうち、
			// 画面の右にはみ出した部分の処理
			if (x2 < 15)
			{
				c = EIMpoint(maxx, y-7+i);
				for (j=x2+1; j<=15; j++)
					if (pen->pat[i*16+j])
						subst_pencol(penc[i][j], getR(c), getG(c), getB(c));
			}
		}
		//
		// 16×16の領域のうち、画面の下にはみ出した部分の処理
		if (y2 < 15)
		{
			for (j=0; j<=15; j++)
			{
				int tx = (j < x1 ? 0 : x2 < j ? maxx : x - 7 + j);
				c = EIMpoint(tx, maxy);
				for (i=y2+1; i<=15; i++)
					if (pen->pat[i*16+j] > 0)
						subst_pencol(penc[i][j], getR(c), getG(c), getB(c));
			}
		}
	}
#endif
}



void put_pencol(int x, int y, pen_t *pen)
/*
	ペン先の色と画面の色の間で平均をとる
*/
{
	int para = goshi_para;
	pencol_t *pc;
	if (mode != MODE32K)
		return;
	int i,j;
	if (pen_isdottype(pen))
	{
		int c,cr,cg,cb,r,g,b;
		c = EIMpoint(x,y);
		cr = getR(c), cg = getG(c), cb = getB(c);
		pc = &penc[CY][CX];
		r = (cr*(256-para) + pc->r*para + 128) >>8;
		g = (cg*(256-para) + pc->g*para + 128) >>8;
		b = (cb*(256-para) + pc->b*para + 128) >>8;
		pc->r -= (pc->r - r);
		pc->g -= (pc->g - g);
		pc->b -= (pc->b - b);
		EIMpset(x,y, r*32+g*1024+b, DrawNORMAL);
	}
	else
	{
		void put_pencol_hline(int x0,int y0,int dx,int xlen,int dy,
							  short *graymap)
		{
			int i; short *ep,*ep0;
			ep0 = ep = (short*)EIMadrs(x0+dx,y0+dy);
			for (i=0; i<xlen; i++,ep++)
			{
				int c = *ep, cr = getR(c), cg = getG(c), cb = getB(c);
				pc = &penc[CY+dy][CX+dx+i];
				int r,g,b;
				r = (cr*(256-para)+pc->r*para+(my_rand() & 255)) >>8;
				g = (cg*(256-para)+pc->g*para+(my_rand() & 255)) >>8;
				b = (cb*(256-para)+pc->b*para+(my_rand() & 255)) >>8;
				pc->r -= (pc->r - r);
				pc->g -= (pc->g - g);
				pc->b -= (pc->b - b);
				*ep = r*32+g*1024+b;
			}
			DMimage_hline_map(x0+dx,x0+dx+xlen-1,y0+dy,(char*)ep0);
		}
		pen_fill(pen, put_pencol_hline, x,y, YES);
	}
#if 0
		int x1,y1,x2,y2,maxx,maxy;
		maxx = EIMgetxsize()-1;
		maxy = EIMgetysize()-1;
		x1 = _max(x - 7 +  0,     0);
		y1 = _max(y - 7 +  0,     0);
		x2 = _min(x - 7 + 15,  maxx);
		y2 = _min(y - 7 + 15,  maxy);
		for (i=y1; i<=y2; i++)
		{
			short *ep0 = (short *)EIMadrs(x1,i);
			void hline(int _x1, int _x2, int _y)
			{
				int pi = (_y-(y-7)) * 16 + (_x1-(x-7));
				short *ep = ep0 + _x1 - x1;
				for (int ii=_x1; ii<=_x2; ii++,ep++,pi++)
				{
					if (pen->pat[pi] <= 0)
						continue;
					int c = *ep, cr = getR(c), cg = getG(c), cb = getB(c);
					pc = &penc[_y-(y-7)][ii-(x-7)];
					int r,g,b;
					r = (cr*(256-para)+pc->r*para+(my_rand() & 255)) >>8;
					g = (cg*(256-para)+pc->g*para+(my_rand() & 255)) >>8;
					b = (cb*(256-para)+pc->b*para+(my_rand() & 255)) >>8;
					pc->r -= (pc->r - r);
					pc->g -= (pc->g - g);
					pc->b -= (pc->b - b);
					*ep = r*32+g*1024+b;
				}
			}
			hline_func(x1,x2,i, hline);
			DMimage_hline_map(x1,x2,i,(char*)ep0);
		}
	}
#endif
}


/* end of goshi.c */
