Пример #1
0
/*:::::*/
FBCALL void fb_GfxWindow(float x1, float y1, float x2, float y2, int screen)
{
	FB_GFXCTX *context = fb_hGetContext();
	float temp;
	
	if (!__fb_gfx)
		return;
	
	if (x1 || y1 || x2 || y2) {
		if (x2 < x1) {
			temp = x1;
			x1 = x2;
			x2 = temp;
		}
		if (y2 < y1) {
			temp = y1;
			y1 = y2;
			y2 = temp;
		}
		
		context->win_x = x1;
		context->win_w = x2 - x1;
		context->win_y = y1;
		context->win_h = y2 - y1;
		context->flags |= CTX_WINDOW_ACTIVE;
		if (screen)
			context->flags |= CTX_WINDOW_SCREEN;
	}
	else
		context->flags &= ~(CTX_WINDOW_ACTIVE | CTX_WINDOW_SCREEN);
}
Пример #2
0
/*:::::*/
static void fb_hPutPResetC(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param)
{
	int x;
	FB_GFXCTX *context = fb_hGetContext();
	
	w <<= (context->target_bpp >> 1);
	src_pitch -= w;
	dest_pitch -= w;
	for (; h; h--) {
		if (w & 1)
			*dest++ = 0xFF ^ *src++;
		if (w & 2) {
			*(unsigned short *)dest = 0xFFFF ^ *(unsigned short *)src;
			dest += 2;
			src += 2;
		}
		for (x = w >> 2; x; x--) {
			*(unsigned int *)dest = 0xFFFFFFFF ^ *(unsigned int *)src;
			dest += 4;
			src += 4;
		}
		src += src_pitch;
		dest += dest_pitch;
	}
}
Пример #3
0
/*:::::*/
FBCALL void fb_GfxView(int x1, int y1, int x2, int y2, unsigned int fill_color, unsigned int border_color, int flags)
{
	FB_GFXCTX *context = fb_hGetContext();
	unsigned int old_bg_color;

	if (!__fb_gfx)
		return;

	fb_hPrepareTarget(context, NULL);
	fb_hSetPixelTransfer(context, border_color);

	fb_hFixCoordsOrder(&x1, &y1, &x2, &y2);

    if ((x1 | y1 | x2 | y2) != 0xFFFF8000) {

        context->flags |= CTX_VIEWPORT_SET;

        if (flags & VIEW_SCREEN)
            context->flags |= CTX_VIEW_SCREEN;
        else
            context->flags &= ~CTX_VIEW_SCREEN;

        if (!(flags & DEFAULT_COLOR_2)) {
            border_color = fb_hFixColor(context->target_bpp, border_color);
            /* Temporarily set full screen area clipping to draw view border */
            context->view_x = 0;
            context->view_y = 0;
            context->view_w = __fb_gfx->w;
            context->view_h = __fb_gfx->h;
            fb_hGfxBox(x1 - 1, y1 - 1, x2 + 1, y2 + 1, border_color & __fb_gfx->color_mask, FALSE, 0xFFFF);
        }
        
        context->view_x = MID(0, x1, __fb_gfx->w);
        context->view_y = MID(0, y1, __fb_gfx->h);
        context->view_w = MIN(x2 - x1 + 1, __fb_gfx->w - x1);
        context->view_h = MIN(y2 - y1 + 1, __fb_gfx->h - y1);
        
        if (!(flags & DEFAULT_COLOR_1)) {
            old_bg_color = context->bg_color;
            context->bg_color = fb_hFixColor(context->target_bpp, fill_color);
            fb_GfxClear(1);
            context->bg_color = old_bg_color;
        }

    } else {

        context->flags &= ~CTX_VIEWPORT_SET;

        context->view_x = context->view_y = 0;
        context->view_w = __fb_gfx->w;
        context->view_h = __fb_gfx->h;
    }
}
Пример #4
0
/*:::::*/
FBCALL float fb_GfxCursor(int func)
{
	FB_GFXCTX *context = fb_hGetContext();
	
	if (!__fb_gfx)
		return 0.0;
	
	switch (func) {
		
		case 0: return fb_GfxPMap(context->last_x, 0);
		case 1: return fb_GfxPMap(context->last_y, 1);
		case 2: return context->last_x;
		case 3: return context->last_y;
	}
	return 0;
}
Пример #5
0
FBCALL void fb_GfxPset(void *target, float fx, float fy, unsigned int color, int flags, int ispreset)
{
	FB_GFXCTX *context;
	int x, y;

	FB_GRAPHICS_LOCK( );

	if (!__fb_gfx) {
		FB_GRAPHICS_UNLOCK( );
		return;
	}

	context = fb_hGetContext( );
	fb_hPrepareTarget(context, target);

	if (flags & DEFAULT_COLOR_1) {
		if (ispreset)
			color = context->bg_color;
		else
			color = context->fg_color;
	} else {
		color = fb_hFixColor(context->target_bpp, color);
	}

	fb_hSetPixelTransfer(context, color);
	fb_hFixRelative(context, flags, &fx, &fy, NULL, NULL);
	fb_hTranslateCoord(context, fx, fy, &x, &y);

	if ((x < context->view_x) || (y < context->view_y) ||
	    (x >= context->view_x + context->view_w) || (y >= context->view_y + context->view_h)) {
		FB_GRAPHICS_UNLOCK( );
		return;
	}

	DRIVER_LOCK();
	context->put_pixel(context, x, y, color);
	if (__fb_gfx->framebuffer == context->line[0])
		__fb_gfx->dirty[y] = TRUE;
	DRIVER_UNLOCK();

	FB_GRAPHICS_UNLOCK( );
}
Пример #6
0
/*:::::*/
FBCALL float fb_GfxPMap(float coord, int func)
{
	FB_GFXCTX *context = fb_hGetContext();

	if (!__fb_gfx)
		return 0.0;
	
	fb_hPrepareTarget(context, NULL);
	fb_hSetPixelTransfer(context, MASK_A_32);
	
	switch (func) {
		
		case 0:
			if (context->flags & CTX_WINDOW_ACTIVE)
				coord = ((coord - context->win_x) * context->view_w) / context->win_w;
			return coord;
		
		case 1:
			if (context->flags & CTX_WINDOW_ACTIVE) {
				coord = ((coord - context->win_y) * context->view_h) / context->win_h;
				if ((context->flags & CTX_WINDOW_SCREEN) == 0)
					coord = context->view_h - 1 - coord;
			}
			return coord;
		
		case 2:
			if (context->flags & CTX_WINDOW_ACTIVE)
				coord = ((coord * context->win_w) / context->view_w) + context->win_x;
			return coord;
		
		case 3:
			if (context->flags & CTX_WINDOW_ACTIVE) {
				if ((context->flags & CTX_WINDOW_SCREEN) == 0)
					coord = context->view_h - 1 - coord;
				coord = ((coord * context->win_h) / context->view_h) + context->win_y;
			}
			return coord;
	}
	return 0;
}
Пример #7
0
/*:::::*/
void fb_hPutPReset(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param)
{
	static PUTTER *all_putters[] = {
		fb_hPutPResetC, fb_hPutPResetC, NULL, fb_hPutPResetC,
#ifdef HOST_X86
		fb_hPutPResetMMX, fb_hPutPResetMMX, NULL, fb_hPutPResetMMX,
#endif
	};
	PUTTER *putter;
	FB_GFXCTX *context = fb_hGetContext();
	
	if (!context->putter[PUT_MODE_PRESET]) {
#ifdef HOST_X86
		if (__fb_gfx->flags & HAS_MMX)
			context->putter[PUT_MODE_PRESET] = &all_putters[4];
		else
#endif
			context->putter[PUT_MODE_PRESET] = &all_putters[0];
	}
	putter = context->putter[PUT_MODE_PRESET][context->target_bpp - 1];
	
	putter(src, dest, w, h, src_pitch, dest_pitch, alpha, blender, param);
}
Пример #8
0
FBCALL void fb_GfxDraw(void *target, FBSTRING *command)
{
	FB_GFXCTX *context;
	float x, y, dx, dy, ax, ay, x2, y2;
	int angle = 0, diagonal = FALSE;
	char *c;
	intptr_t value1, value2;
	int draw = TRUE, move = TRUE, length = 0, flags, rel;

	FB_GRAPHICS_LOCK( );

	if ((!__fb_gfx) || (!command) || (!command->data)) {
		if (command)
			fb_hStrDelTemp(command);
		FB_GRAPHICS_UNLOCK( );
		return;
	}

	context = fb_hGetContext( );
	fb_hPrepareTarget(context, target);
	fb_hSetPixelTransfer(context, MASK_A_32);

	x = context->last_x;
	y = context->last_y;

	DRIVER_LOCK();

	flags = context->flags;
	context->flags |= CTX_VIEW_SCREEN;

	for (c = command->data; *c;) {
		switch (toupper(*c)) {
			case 'B':
				c++;
				draw = FALSE;
				break;

			case 'N':
				c++;
				move = FALSE;
				break;

			case 'C':
				c++;
				if ((value1 = parse_number(&c)) == FB_NAN)
					goto error;
				context->fg_color = fb_hFixColor(context->target_bpp, value1);
				break;

			case 'S':
				c++;
				if ((value1 = parse_number(&c)) == FB_NAN)
					goto error;
				base_scale = (float)value1 / 4.0;
				break;

			case 'A':
				c++;
				if ((value1 = parse_number(&c)) == FB_NAN)
					goto error;
				base_angle = (value1 & 0x3) * 90;
				break;

			case 'T':
				c++;
				if (toupper(*c) != 'A')
					goto error;
				c++;
				if ((value1 = parse_number(&c)) == FB_NAN)
					goto error;
				base_angle = mod360( value1 );
				break;

			case 'X':
				c++;
				/* Here we could be more severe with checking, but it's unlikely our substring
				 * resides at location FB_NAN (0x80000000) */
				if ((value1 = parse_number(&c)) == FB_NAN)
					goto error;

				/* Store our current x/y for the recursive fb_GfxDraw() call */
				context->last_x = x;
				context->last_y = y;

				DRIVER_UNLOCK();
				fb_GfxDraw(target, (FBSTRING *)value1);
				DRIVER_LOCK();

				/* And update to x/y produced by the recursive fb_GfxDraw() call */
				x = context->last_x;
				y = context->last_y;

				break;

			case 'P':
				c++;
				if ((value1 = parse_number(&c)) == FB_NAN)
					goto error;
				value2 = value1;
				if (*c == ',') {
					c++;
					if ((value2 = parse_number(&c)) == FB_NAN)
						goto error;
				}
				DRIVER_UNLOCK();
				fb_GfxPaint(target, x, y, value1 & __fb_gfx->color_mask, value2 & __fb_gfx->color_mask, NULL, PAINT_TYPE_FILL, COORD_TYPE_A);
				DRIVER_LOCK();
				break;

			case 'M':
				c++;
				while ((*c == ' ') || (*c == '\t'))
					c++;
				rel = ((*c == '+') || (*c == '-'));
				if ((value1 = parse_number(&c)) == FB_NAN)
					goto error;
				if (*c++ != ',')
					goto error;
				if ((value2 = parse_number(&c)) == FB_NAN)
					goto error;
				x2 = (float)value1;
				y2 = (float)value2;
				if (rel) {
					ax = dcos(base_angle);
					ay = -dsin(base_angle);
					dx = x2;
					dy = y2;
					x2 = (((dx * ax) - (dy * ay)) * base_scale) + x;
					y2 = (((dy * ax) + (dx * ay)) * base_scale) + y;
				}
				if (draw) {
					DRIVER_UNLOCK();
					fb_GfxLine(target, (int)x, (int)y, (int)x2, (int)y2, 0, LINE_TYPE_LINE, 0xFFFF, COORD_TYPE_AA | DEFAULT_COLOR_1);
					DRIVER_LOCK();
				}
				if (move) {
					x = x2;
					y = y2;
				}
				move = draw = TRUE;
				break;

			case 'F': case 'D': angle += 90;
			case 'G': case 'L': angle += 90;
			case 'H': case 'U': angle += 90;
			case 'E': case 'R':
				diagonal = ((toupper(*c) >= 'E') && (toupper(*c) <= 'H'));
				c++;
				if ((value1 = parse_number(&c)) != FB_NAN)
					length = value1;
				else
					length = 1;

				angle = mod360( angle + base_angle );
				dx = (float)length * base_scale * dcos( angle );
				dy = (float)length * base_scale * -dsin( angle );

				if (diagonal) {
					x2 = x + (dx + dy);
					y2 = y + (dy - dx);
				}
				else {
					x2 = x + dx;
					y2 = y + dy;
				}
				if (draw) {
					fb_GfxDrawLine( context, CINT(x), CINT(y), CINT(x2), CINT(y2), context->fg_color, 0xffff );
				}
				if (move) {
					x = x2;
					y = y2;
				}

				angle = 0;
				move = draw = TRUE;
				break;

			default:
				c++;
				break;
		}
	}

	context->last_x = x;
	context->last_y = y;

error:
	context->flags = flags;

	DRIVER_UNLOCK();

	/* del if temp */
	fb_hStrDelTemp( command );

	FB_GRAPHICS_UNLOCK( );
}
Пример #9
0
FBCALL void fb_GfxEllipse(void *target, float fx, float fy, float radius, unsigned int color, float aspect, float start, float end, int fill, int flags)
{
	FB_GFXCTX *context;
	int x, y, x1, y1, top, bottom;
	unsigned int orig_color;
	float a, b, orig_x, orig_y, increment;

	FB_GRAPHICS_LOCK( );

	if (!__fb_gfx || radius <= 0.0) {
		FB_GRAPHICS_UNLOCK( );
		return;
	}

	context = fb_hGetContext();
	orig_x = fx;
	orig_y = fy;

	fb_hPrepareTarget(context, target);

	orig_color = color;
	if (flags & DEFAULT_COLOR_1)
		color = context->fg_color;
	else
		color = fb_hFixColor(context->target_bpp, color);
	
	fb_hSetPixelTransfer(context, color);

	fb_hFixRelative(context, flags, &fx, &fy, NULL, NULL);

	fb_hTranslateCoord(context, fx, fy, &x, &y);

	if (context->flags & CTX_WINDOW_ACTIVE) {
		/* radius gets multiplied by the VIEW/WINDOW width ratio (aspect is unchanged) */
		radius *= (context->view_w / context->win_w);
	}

	if (aspect == 0.0)
		aspect = __fb_gfx->aspect;

	if (aspect > 1.0) {
		a = (radius / aspect);
		b = radius;
	} else {
		a = radius;
		b = (radius * aspect);
	}

	if ((start != 0.0) || (end != 3.141593f * 2.0)) {
		if (start < 0) {
			start = -start;
			get_arc_point(start, a, b, &x1, &y1);
			x1 = orig_x + x1;
			y1 = orig_y - y1;
			fb_GfxLine(target, orig_x, orig_y, x1, y1, orig_color, LINE_TYPE_LINE, 0xFFFF, COORD_TYPE_AA | (flags & ~COORD_TYPE_MASK));
		}
		if (end < 0) {
			end = -end;
			get_arc_point(end, a, b, &x1, &y1);
			x1 = orig_x + x1;
			y1 = orig_y - y1;
			fb_GfxLine(target, orig_x, orig_y, x1, y1, orig_color, LINE_TYPE_LINE, 0xFFFF, COORD_TYPE_AA | (flags & ~COORD_TYPE_MASK));
		}
		
		while (end < start)
			end += 2 * PI;
		while (end - start > 2 * PI)
			start += 2 * PI;

		increment = 1 / (sqrt(a) * sqrt(b) * 1.5);

		DRIVER_LOCK();

		top = bottom = y;
		for (; start < end + (increment / 2); start += increment) {
			get_arc_point(start, a, b, &x1, &y1);
			x1 = x + x1;
			y1 = y - y1;
			if ((x1 < context->view_x) || (x1 >= context->view_x + context->view_w) ||
			    (y1 < context->view_y) || (y1 >= context->view_y + context->view_h))
				continue;
			context->put_pixel(context, x1, y1, color);
			if (y1 > bottom)
				bottom = y1;
			if (y1 < top)
				top = y1;
		}
	} else {
		DRIVER_LOCK();
		draw_ellipse(context, x, y, a, b, color, fill, &top, &bottom);
	}

	top = MID(context->view_y, top, context->view_y + context->view_h - 1);
	bottom = MID(context->view_y, bottom, context->view_y + context->view_h - 1);
	if( top > bottom )
		SWAP( top, bottom );

	SET_DIRTY(context, top, bottom - top + 1);

	DRIVER_UNLOCK();
	FB_GRAPHICS_UNLOCK( );
}
Пример #10
0
static int set_mode
	(
		int mode,
		int w, int h,
		int depth, int scanline_size,
		int num_pages, int refresh_rate,
		int palette, int font,
		int flags, float aspect,
		int text_w, int text_h
	)
{
    const GFXDRIVER *driver = NULL;
    FB_GFXCTX *context;
    int i, j, try_count;
    char *c, *driver_name;
    unsigned char *dest;

	/* normalize flags */
	if ((flags >= 0) && (flags & DRIVER_SHAPED_WINDOW))
		flags |= DRIVER_SHAPED_WINDOW | DRIVER_NO_FRAME | DRIVER_NO_SWITCH;

    release_gfx_mem();

	if( (mode == 0) || (w == 0) ) {
        memset(&__fb_ctx.hooks, 0, sizeof(__fb_ctx.hooks));

        if (flags != SCREEN_EXIT) {
            /* set and clear text screen mode or the width and line_len will be wrong */
            fb_Width( 80, 25 );
            fb_Cls( 0 );
        }
        /* reset viewport to console dimensions */
        fb_ConsoleSetTopBotRows(-1, -1);
	} else {
        __fb_ctx.hooks.inkeyproc = fb_GfxInkey;
        __fb_ctx.hooks.getkeyproc = fb_GfxGetkey;
        __fb_ctx.hooks.keyhitproc = fb_GfxKeyHit;
        __fb_ctx.hooks.clsproc = fb_GfxClear;
        __fb_ctx.hooks.colorproc = fb_GfxColor;
        __fb_ctx.hooks.locateproc = fb_GfxLocate;
        __fb_ctx.hooks.widthproc = fb_GfxWidth;
        __fb_ctx.hooks.getxproc = fb_GfxGetX;
        __fb_ctx.hooks.getyproc = fb_GfxGetY;
        __fb_ctx.hooks.getxyproc = fb_GfxGetXY;
        __fb_ctx.hooks.getsizeproc = fb_GfxGetSize;
        __fb_ctx.hooks.printbuffproc = fb_GfxPrintBufferEx;
        __fb_ctx.hooks.printbuffwproc = fb_GfxPrintBufferWstrEx;
        __fb_ctx.hooks.readstrproc = fb_GfxReadStr;
        __fb_ctx.hooks.multikeyproc = fb_GfxMultikey;
        __fb_ctx.hooks.getmouseproc = fb_GfxGetMouse;
        __fb_ctx.hooks.setmouseproc = fb_GfxSetMouse;
        __fb_ctx.hooks.inproc = fb_GfxIn;
        __fb_ctx.hooks.outproc = fb_GfxOut;
        __fb_ctx.hooks.viewupdateproc = fb_GfxViewUpdate;
        __fb_ctx.hooks.lineinputproc = fb_GfxLineInput;
        __fb_ctx.hooks.lineinputwproc = fb_GfxLineInputWstr;
        __fb_ctx.hooks.readxyproc = fb_GfxReadXY;
        __fb_ctx.hooks.sleepproc = fb_GfxSleep;
        __fb_ctx.hooks.isredirproc = fb_GfxIsRedir;
        __fb_ctx.hooks.pagecopyproc = fb_GfxPageCopy;
        __fb_ctx.hooks.pagesetproc = fb_GfxPageSet;
        __fb_gfx = (FBGFX *)calloc(1, sizeof(FBGFX));
    }

    if (__fb_gfx) {
    	__fb_gfx->id = screen_id++;
        __fb_gfx->mode_num = mode;
        __fb_gfx->w = w;
        __fb_gfx->h = h;
        __fb_gfx->depth = depth;
        if ((flags >= 0) && (flags & DRIVER_OPENGL))
            __fb_gfx->depth = MAX(16, __fb_gfx->depth);
        __fb_gfx->default_palette = (palette >= 0) ? &__fb_palette[palette] : NULL;
        __fb_gfx->scanline_size = scanline_size;
        __fb_gfx->font = (font >= 0) ? &__fb_font[font] : NULL;

		if( aspect != 0.0f )
			__fb_gfx->aspect = aspect;
		else
			__fb_gfx->aspect = (4.0 / 3.0) * ((float)__fb_gfx->h / (float)__fb_gfx->w);

        switch (__fb_gfx->depth) {
        case 15:
        case 16:	__fb_gfx->color_mask = 0xFFFF; __fb_gfx->depth = 16; break;
        case 24:
        case 32:	__fb_gfx->color_mask = 0xFFFFFFFF; __fb_gfx->depth = 32; break;
        default:	__fb_gfx->color_mask = (1 << __fb_gfx->depth) - 1;
        }

        __fb_gfx->bpp = BYTES_PER_PIXEL(__fb_gfx->depth);
        __fb_gfx->pitch = __fb_gfx->w * __fb_gfx->bpp;
        __fb_gfx->page = (unsigned char **)malloc(sizeof(unsigned char *) * num_pages);
        for (i = 0; i < num_pages; i++) {
		/* 0xF for the para alignment, p_size is sizeof(void *) rounded up to % 16 for the storage for the original pointer */
		int p_size = (sizeof(void *) + 0xF) & 0xF;
		void *tmp = malloc((__fb_gfx->pitch * __fb_gfx->h) + p_size + 0xF);
		__fb_gfx->page[i] = (unsigned char *)(((intptr_t)tmp + p_size + 0xF) & ~0xF);
		((void **)(__fb_gfx->page[i]))[-1] = tmp;
	}
        __fb_gfx->num_pages = num_pages;
        __fb_gfx->framebuffer = __fb_gfx->page[0];

        /* dirty lines array may be bigger than needed; this is to please the
         gfx driver which is not aware of the scanline size */
        __fb_gfx->dirty = (char *)calloc(1, __fb_gfx->h * __fb_gfx->scanline_size);
        __fb_gfx->device_palette = (unsigned int *)calloc(1, sizeof(int) * 256);
        __fb_gfx->palette = (unsigned int *)calloc(1, sizeof(int) * 256);
        __fb_gfx->color_association = (unsigned char *)malloc(16);
        __fb_gfx->key = (char *)calloc(1, 128);
        __fb_gfx->event_queue = (EVENT *)malloc(sizeof(EVENT) * MAX_EVENTS);
        __fb_gfx->event_mutex = fb_MutexCreate();
        __fb_color_conv_16to32 = (unsigned int *)malloc(sizeof(int) * 512);
        if (flags != DRIVER_NULL) {
			if (flags & DRIVER_ALPHA_PRIMITIVES)
	        	__fb_gfx->flags |= ALPHA_PRIMITIVES;
	        if (flags & DRIVER_OPENGL)
	        	__fb_gfx->flags |= OPENGL_SUPPORT;
	        if (flags & DRIVER_HIGH_PRIORITY)
	        	__fb_gfx->flags |= HIGH_PRIORITY;
	    }

        fb_hSetupFuncs(__fb_gfx->bpp);
        fb_hSetupData();

        if (!__fb_window_title)
        {
            __fb_window_title = fb_hGetExeName( window_title_buff, WINDOW_TITLE_SIZE - 1 );
            if ((c = strrchr(__fb_window_title, '.')))
                *c = '\0';
        }

		driver_name = __fb_gfx_driver_name;
		if (!driver_name)
	        driver_name = getenv("FBGFX");
        if ((flags == DRIVER_NULL) || ((driver_name) && (!strcasecmp(driver_name, "null"))))
            driver = &__fb_gfxDriverNull;
        else {
            for (try_count = (driver_name ? 4 : 2); try_count; try_count--) {
                for (i = 0; __fb_gfx_drivers_list[i >> 1]; i++) {
                    driver = __fb_gfx_drivers_list[i >> 1];
                    if ((driver_name) && !(try_count & 0x1) && (strcasecmp(driver_name, driver->name))) {
                        driver = NULL;
                        continue;
					}
                    if (!driver->init(__fb_window_title, __fb_gfx->w, __fb_gfx->h * __fb_gfx->scanline_size, __fb_gfx->depth, (i & 0x1) ? 0 : refresh_rate, flags))
                        break;
                    driver->exit();
                    driver = NULL;
                }
                if (driver)
                    break;
                if (driver_name) {
                    if (try_count == 3)
                        flags ^= DRIVER_FULLSCREEN;
                }
                else
                    flags ^= DRIVER_FULLSCREEN;
            }
        }

        if (!driver) {
            exit_proc();
            return fb_ErrorSetNum(FB_RTERROR_ILLEGALFUNCTIONCALL);
        }
        __fb_gfx->driver = driver;

        fb_GfxPalette(-1, 0, 0, 0);

        __fb_gfx->text_w = text_w;
        __fb_gfx->text_h = text_h;

        context = fb_hGetContext();

        fb_hResetCharCells(context, TRUE);
        for (i = 0; i < num_pages; i++) {
        	dest = __fb_gfx->page[i];
        	for (j = 0; j < __fb_gfx->h; j++) {
	        	context->pixel_set(dest, context->bg_color, context->view_w);
	        	dest += __fb_gfx->pitch;
	        }
		}

        if( !exit_proc_set ) {
            exit_proc_set = TRUE;
            atexit(exit_proc);
        }
    }

    if( flags!=SCREEN_EXIT ) {
        /* Reset VIEW PRINT
         *
         * Normally, resetting VIEW PRINT should also result in setting the cursor
         * position to Y,X = 1,1 but this doesn't seem to be suitable (at least
         * on Win32 platforms). I don't believe that this is a problem because
         * on DOS, the cursor position will automatically be reset when the screen
         * mode changes and not changing the console cursor position on Win32
         * and Linux seem to be more "natural". */
        fb_ConsoleViewEx( 0, 0, __fb_gfx!=NULL );
    }

    return fb_ErrorSetNum( FB_RTERROR_OK );
}
Пример #11
0
/*:::::*/
FBCALL void fb_GfxPaint(void *target, float fx, float fy, unsigned int color, unsigned int border_color, FBSTRING *pattern, int mode, int flags)
{
	FB_GFXCTX *context = fb_hGetContext();
	int size, x, y;
	unsigned char data[256], *dest, *src;
	SPAN **span, *s, *tail, *head;

	if (!__fb_gfx)
		return;

	fb_hPrepareTarget(context, target);

	if (flags & DEFAULT_COLOR_1)
		color = context->fg_color;
	else
		color = fb_hFixColor(context->target_bpp, color);
	if (flags & DEFAULT_COLOR_2)
		border_color = color;
	else
		border_color = fb_hFixColor(context->target_bpp, border_color);

	fb_hSetPixelTransfer(context,color);

	fb_hFixRelative(context, flags, &fx, &fy, NULL, NULL);

	fb_hTranslateCoord(context, fx, fy, &x, &y);

	fb_hMemSet(data, 0, sizeof(data));
	if ((mode == PAINT_TYPE_PATTERN) && (pattern)) {
		fb_hMemCpy(data, pattern->data, MIN(256, FB_STRSIZE(pattern)));
    }
    if (pattern) {
        /* del if temp */
        fb_hStrDelTemp( pattern );
    }

	if ((x < context->view_x) || (x >= context->view_x + context->view_w) ||
	    (y < context->view_y) || (y >= context->view_y + context->view_h))
		return;

	if (context->get_pixel(context, x, y) == border_color)
		return;

	size = sizeof(SPAN *) * (context->view_y + context->view_h);
	span = (SPAN **)malloc(size);
	fb_hMemSet(span, 0, size);

	tail = head = add_span(context, span, &x, y, border_color);

	/* Find all spans to paint */
	while (tail) {
		if (tail->y - 1 >= context->view_y) {
			for (x = tail->x1; x <= tail->x2; x++) {
				if (context->get_pixel(context, x, tail->y - 1) != border_color) {
					s = add_span(context, span, &x, tail->y - 1, border_color);
					if (s) {
						head->next = s;
						head = s;
					}
				}
			}
		}
		if (tail->y + 1 < context->view_y + context->view_h) {
			for (x = tail->x1; x <= tail->x2; x++) {
				if (context->get_pixel(context, x, tail->y + 1) != border_color) {
					s = add_span(context, span, &x, tail->y + 1, border_color);
					if (s) {
						head->next = s;
						head = s;
					}
				}
			}
		}
		tail = tail->next;
	}

	DRIVER_LOCK();

	/* Fill spans */
	for (y = context->view_y; y < context->view_y + context->view_h; y++) {
		for (s = tail = span[y]; s; s = s->row_next, free(tail), tail = s) {

			dest = context->line[s->y] + (s->x1 * context->target_bpp);

			if (mode == PAINT_TYPE_FILL)
				context->pixel_set(dest, color, s->x2 - s->x1 + 1);
			else {
				src = data + (((s->y & 0x7) << 3) * context->target_bpp);
				if (s->x1 & 0x7) {
					if ((s->x1 & ~0x7) == (s->x2 & ~0x7))
						size = s->x2 - s->x1 + 1;
					else
						size = 8 - (s->x1 & 0x7);
					fb_hPixelCpy(dest, src + ((s->x1 & 0x7) * context->target_bpp), size);
					dest += size * context->target_bpp;
				}
				s->x2++;
				for (x = (s->x1 + 7) >> 3; x < (s->x2 & ~0x7) >> 3; x++) {
					fb_hPixelCpy(dest, src, 8);
					dest += 8 * context->target_bpp;
				}
				if ((s->x2 & 0x7) && ((s->x1 & ~0x7) != (s->x2 & ~0x7)))
					fb_hPixelCpy(dest, src, s->x2 & 0x7);
			}

			if (__fb_gfx->framebuffer == context->line[0])
				__fb_gfx->dirty[context->view_y + y] = TRUE;
		}
	}
	free(span);

	DRIVER_UNLOCK();

}
Пример #12
0
void fb_GfxPrintBufferEx( const void *buffer, size_t len, int mask )
{
	FB_GFXCTX *context;
    const char *pachText = (const char *) buffer;
    int win_left, win_top, win_cols, win_rows;
    int view_top, view_bottom;
    fb_PrintInfo info;
    fb_ConHooks hooks;

	FB_GRAPHICS_LOCK( );

    /* Do we want to correct the console cursor position? */
    if( (mask & FB_PRINT_FORCE_ADJUST)==0 ) {
        /* No, we can check for the length to avoid unnecessary stuff ... */
        if( len==0 ) {
            FB_GRAPHICS_UNLOCK( );
            return;
        }
    }

	context = fb_hGetContext( );
	fb_hPrepareTarget(context, NULL);
	fb_hSetPixelTransfer(context, MASK_A_32);

	DRIVER_LOCK();

    fb_GetSize( &win_cols, &win_rows );
    fb_ConsoleGetView( &view_top, &view_bottom );
    win_left = win_top = 0;

    hooks.Opaque        = &info;
    hooks.Scroll        = fb_hHookConScroll;
    hooks.Write         = fb_hHookConWrite;
    hooks.Border.Left   = win_left;
    hooks.Border.Top    = win_top + view_top - 1;
    hooks.Border.Right  = win_left + win_cols - 1;
    hooks.Border.Bottom = win_top + view_bottom - 1;

	info.context = context;
    info.dirty_start = info.dirty_end = 0;

    {
        hooks.Coord.X = __fb_gfx->cursor_x;
        hooks.Coord.Y = __fb_gfx->cursor_y;

        if( __fb_gfx->flags & PRINT_SCROLL_WAS_OFF ) {
            __fb_gfx->flags &= ~PRINT_SCROLL_WAS_OFF;
            ++hooks.Coord.Y;
            hooks.Coord.X = hooks.Border.Left;
            fb_hConCheckScroll( &hooks );
        }

        fb_ConPrintTTY( &hooks,
                        pachText,
                        len,
                        TRUE );

        if( hooks.Coord.X != hooks.Border.Left
            || hooks.Coord.Y != (hooks.Border.Bottom+1) )
        {
            fb_hConCheckScroll( &hooks );
        } else {
            __fb_gfx->flags |= PRINT_SCROLL_WAS_OFF;
            hooks.Coord.X = hooks.Border.Right;
            hooks.Coord.Y = hooks.Border.Bottom;
        }
        fb_GfxLocateRaw( hooks.Coord.Y, hooks.Coord.X, -1 );
    }

    SET_DIRTY(context, info.dirty_start, info.dirty_end - info.dirty_start);

    DRIVER_UNLOCK();
	FB_GRAPHICS_UNLOCK( );
}
Пример #13
0
FBCALL void fb_GfxDraw(void *target, FBSTRING *command)
{
	FB_GFXCTX *context;
	float x, y, dx, dy, ax, ay, x2, y2, scale = 1.0, angle = 0.0;
	char *c;
	intptr_t value1, value2;
	int draw = TRUE, move = TRUE, length = 0, flags, rel, ix, iy;

	FB_GRAPHICS_LOCK( );

	if ((!__fb_gfx) || (!command) || (!command->data)) {
		if (command)
			fb_hStrDelTemp(command);
		FB_GRAPHICS_UNLOCK( );
		return;
	}

	context = fb_hGetContext( );
	fb_hPrepareTarget(context, target);
	fb_hSetPixelTransfer(context, MASK_A_32);

	x = context->last_x;
	y = context->last_y;

	DRIVER_LOCK();

	flags = context->flags;
	context->flags |= CTX_VIEW_SCREEN;

	for (c = command->data; *c;) {
		switch (toupper(*c)) {
			case 'B':
				c++;
				draw = FALSE;
				break;

			case 'N':
				c++;
				move = FALSE;
				break;

			case 'C':
				c++;
				if ((value1 = parse_number(&c)) == FB_NAN)
					goto error;
				context->fg_color = fb_hFixColor(context->target_bpp, value1);
				break;

			case 'S':
				c++;
				if ((value1 = parse_number(&c)) == FB_NAN)
					goto error;
				base_scale = (float)value1 / 4.0;
				break;

			case 'A':
				c++;
				if ((value1 = parse_number(&c)) == FB_NAN)
					goto error;
				base_angle = (float)(value1 & 0x3) * PI * 0.5;
				break;

			case 'T':
				c++;
				if (toupper(*c) != 'A')
					goto error;
				c++;
				if ((value1 = parse_number(&c)) == FB_NAN)
					goto error;
				base_angle = (float)value1 * PI / 180.0;
				break;

			case 'X':
				c++;
				/* Here we could be more severe with checking, but it's unlikely our substring
				 * resides at location FB_NAN (0x80000000) */
				if ((value1 = parse_number(&c)) == FB_NAN)
					goto error;

				/* Store our current x/y for the recursive fb_GfxDraw() call */
				context->last_x = x;
				context->last_y = y;

				DRIVER_UNLOCK();
				fb_GfxDraw(target, (FBSTRING *)value1);
				DRIVER_LOCK();

				/* And update to x/y produced by the recursive fb_GfxDraw() call */
				x = context->last_x;
				y = context->last_y;

				break;

			case 'P':
				c++;
				if ((value1 = parse_number(&c)) == FB_NAN)
					goto error;
				value2 = value1;
				if (*c == ',') {
					c++;
					if ((value2 = parse_number(&c)) == FB_NAN)
						goto error;
				}
				DRIVER_UNLOCK();
				fb_GfxPaint(target, x, y, value1 & __fb_gfx->color_mask, value2 & __fb_gfx->color_mask, NULL, PAINT_TYPE_FILL, COORD_TYPE_A);
				DRIVER_LOCK();
				break;

			case 'M':
				c++;
				rel = FALSE;
				while ((*c == ' ') || (*c == '\t'))
					c++;
				if ((*c == '+') || (*c == '-'))
				{
					rel = TRUE;
				}
				if ((value1 = parse_number(&c)) == FB_NAN)
					goto error;
				if (*c++ != ',')
					goto error;
				if ((value2 = parse_number(&c)) == FB_NAN)
					goto error;
				x2 = (float)value1;
				y2 = (float)value2;
				if (rel) {
					ax = cos(base_angle);
					ay = -sin(base_angle);
					dx = x2;
					dy = y2;
					x2 = (((dx * ax) - (dy * ay)) * base_scale) + x;
					y2 = (((dy * ax) + (dx * ay)) * base_scale) + y;
				}
				else {
					x2 += 0.5;
					y2 += 0.5;
				}
				if (draw) {
					DRIVER_UNLOCK();
					fb_GfxLine(target, (int)x, (int)y, (int)x2, (int)y2, 0, LINE_TYPE_LINE, 0xFFFF, COORD_TYPE_AA | DEFAULT_COLOR_1);
					DRIVER_LOCK();
				}
				if (move) {
					x = x2;
					y = y2;
				}
				move = draw = TRUE;
				break;

			case 'F': angle += PI * 0.25;
			case 'D': angle += PI * 0.25;
			case 'G': angle += PI * 0.25;
			case 'L': angle += PI * 0.25;
			case 'H': angle += PI * 0.25;
			case 'U': angle += PI * 0.25;
			case 'E': angle += PI * 0.25;
			case 'R':
				if ((toupper(*c) >= 'E') && (toupper(*c) <= 'H'))
					scale = SQRT_2;
				c++;
				if ((value1 = parse_number(&c)) != FB_NAN)
					length = value1;
				else
					length = 1;
				break;

			default:
				c++;
				break;
		}

		if (length) {
			length = (int)(((float)length * (base_scale * scale)) + 0.5);
			if (length < 0) {
				angle += PI;
				length = -length;
			}
			angle += base_angle;
			dx = x;
			dy = y;

			for (; length >= 0; length--) {
				if (draw) {
					ix = dx;
					iy = dy;
					if ((ix >= context->view_x) && (ix < context->view_x + context->view_w) &&
					    (iy >= context->view_y) && (iy < context->view_y + context->view_h)) {
					    	context->put_pixel(context, ix, iy, context->fg_color);
						if (__fb_gfx->framebuffer == context->line[0])
							__fb_gfx->dirty[iy] = TRUE;
					}
				}
				if (length) {
					dx += cos(angle);
					dy -= sin(angle);
				}
			}
			if (move) {
				x = dx;
				y = dy;
			}
			angle = 0.0;
			scale = 1.0;
			length = 0;
			move = draw = TRUE;
		}
	}

	context->last_x = x;
	context->last_y = y;

error:
	context->flags = flags;

	DRIVER_UNLOCK();

	/* del if temp */
	fb_hStrDelTemp( command );

	FB_GRAPHICS_UNLOCK( );
}
Пример #14
0
FBCALL void fb_GfxControl_i( int what, int *param1, int *param2, int *param3, int *param4 )
{
	FB_GFXCTX *context = fb_hGetContext();
	int res = 0;
	int res1 = 0, res2 = 0, res3 = 0, res4 = 0;
	int temp1, temp2, temp3, temp4;

	if (!param1) param1 = &temp1;
	if (!param2) param2 = &temp2;
	if (!param3) param3 = &temp3;
	if (!param4) param4 = &temp4;

	switch ( what ) {
	case GET_WINDOW_POS:
		if ((__fb_gfx) && (__fb_gfx->driver->set_window_pos))
			res = __fb_gfx->driver->set_window_pos(0x80000000, 0x80000000);
		res1 = (int)((short)(res & 0xFFFF));
		res2 = res >> 16;
		break;

	case GET_WINDOW_HANDLE:
		if (__fb_gfx)
			res1 = fb_hGetWindowHandle();
		break;

	case GET_DESKTOP_SIZE:
		fb_hScreenInfo(&res1, &res2, &temp3, &temp4);
		break;

	case GET_SCREEN_SIZE:
		if (__fb_gfx) {
			res1 = __fb_gfx->w;
			res2 = __fb_gfx->h;
		}
		break;

	case GET_SCREEN_DEPTH:
		if (__fb_gfx)
			res1 = __fb_gfx->depth;
		break;

	case GET_SCREEN_BPP:
		if (__fb_gfx)
			res1 = __fb_gfx->bpp;
		break;

	case GET_SCREEN_PITCH:
		if (__fb_gfx)
			res1 = __fb_gfx->pitch;
		break;

	case GET_SCREEN_REFRESH:
		if (__fb_gfx)
			res1 = __fb_gfx->refresh_rate;
		break;

	case GET_TRANSPARENT_COLOR:
		if ((__fb_gfx) && (__fb_gfx->bpp > 1))
			res1 = MASK_COLOR_32;
		break;

	case GET_VIEWPORT:
		if (__fb_gfx) {
			res1 = context->view_x;
			res2 = context->view_y;
			res3 = context->view_x + context->view_w - 1;
			res4 = context->view_y + context->view_h - 1;
		}
		break;

	case GET_PEN_POS:
		if (__fb_gfx) {
			res1 = context->last_x;
			res2 = context->last_y;
		}
		break;

	case GET_COLOR:
		if (__fb_gfx) {
			res1 = context->fg_color;
			res2 = context->bg_color;
		}
		break;

	case GET_ALPHA_PRIMITIVES:
		if (__fb_gfx)
			res1 = (__fb_gfx->flags & ALPHA_PRIMITIVES) ? FB_TRUE : FB_FALSE;
		break;

	case GET_HIGH_PRIORITY:
		if (__fb_gfx)
			res1 = (__fb_gfx->flags & HIGH_PRIORITY) ? FB_TRUE : FB_FALSE;
		break;

	case SET_WINDOW_POS:
		if ((__fb_gfx) && (__fb_gfx->driver->set_window_pos))
			__fb_gfx->driver->set_window_pos(*param1, *param2);
		break;

	case SET_PEN_POS:
		if (__fb_gfx) {
			if (*param1 != 0x80000000)
				context->last_x = *param1;
			if (*param2 != 0x80000000)
				context->last_y = *param2;
		}
		break;

	case SET_ALPHA_PRIMITIVES:
		if ((__fb_gfx) && (*param1 != 0x80000000)) {
			if (*param1)
				__fb_gfx->flags |= ALPHA_PRIMITIVES;
			else
				__fb_gfx->flags &= ~ALPHA_PRIMITIVES;
		}
		break;

#ifndef DISABLE_OPENGL
	case SET_GL_COLOR_BITS:
		__fb_gl_params.color_bits = *param1;
		break;

	case SET_GL_COLOR_RED_BITS:
		__fb_gl_params.color_red_bits = *param1;
		break;

	case SET_GL_COLOR_GREEN_BITS:
		__fb_gl_params.color_green_bits = *param1;
		break;

	case SET_GL_COLOR_BLUE_BITS:
		__fb_gl_params.color_blue_bits = *param1;
		break;

	case SET_GL_COLOR_ALPHA_BITS:
		__fb_gl_params.color_alpha_bits = *param1;
		break;

	case SET_GL_DEPTH_BITS:
		__fb_gl_params.depth_bits = *param1;
		break;

	case SET_GL_STENCIL_BITS:
		__fb_gl_params.stencil_bits = *param1;
		break;

	case SET_GL_ACCUM_BITS:
		__fb_gl_params.accum_bits = *param1;
		break;

	case SET_GL_ACCUM_RED_BITS:
		__fb_gl_params.accum_red_bits = *param1;
		break;

	case SET_GL_ACCUM_GREEN_BITS:
		__fb_gl_params.accum_green_bits = *param1;
		break;

	case SET_GL_ACCUM_BLUE_BITS:
		__fb_gl_params.accum_blue_bits = *param1;
		break;

	case SET_GL_ACCUM_ALPHA_BITS:
		__fb_gl_params.accum_alpha_bits = *param1;
		break;

	case SET_GL_NUM_SAMPLES:
		__fb_gl_params.num_samples = *param1;
		break;
#endif

	case POLL_EVENTS:
		if ((__fb_gfx) && (__fb_gfx->driver->poll_events))
			__fb_gfx->driver->poll_events();
		break;

	}

	if (what < SET_FIRST_SETTER) {
		*param1 = res1;
		*param2 = res2;
		*param3 = res3;
		*param4 = res4;
	}
}
Пример #15
0
/*:::::*/
static int gfx_get(void *target, float fx1, float fy1, float fx2, float fy2, unsigned char *dest, int coord_type, FBARRAY *array, int usenewheader )
{
	FB_GFXCTX *context = fb_hGetContext();
	PUT_HEADER *header;
	int x1, y1, x2, y2, w, h, pitch;

	if (!__fb_gfx)
		return fb_ErrorSetNum(FB_RTERROR_ILLEGALFUNCTIONCALL);

	fb_hPrepareTarget(context, target);
	fb_hSetPixelTransfer(context, MASK_A_32);

	fb_hFixRelative(context, coord_type, &fx1, &fy1, &fx2, &fy2);

	fb_hTranslateCoord(context, fx1, fy1, &x1, &y1);
	fb_hTranslateCoord(context, fx2, fy2, &x2, &y2);

	fb_hFixCoordsOrder(&x1, &y1, &x2, &y2);

	if ((x1 < context->view_x) || (y1 < context->view_y) ||
	    (x2 >= context->view_x + context->view_w) || (y2 >= context->view_y + context->view_h))
		return fb_ErrorSetNum(FB_RTERROR_ILLEGALFUNCTIONCALL);

	w = x2 - x1 + 1;
	h = y2 - y1 + 1;

	header = (PUT_HEADER *)dest;
	if (!usenewheader) {
		/* use old-style header for compatibility */
		header->old.bpp = context->target_bpp;
		header->old.width = w;
		header->old.height = h;
		pitch = w * context->target_bpp;
		dest += 4;
	}
	else {
		/* use new-style header */
		header->type = PUT_HEADER_NEW;
		header->width = w;
		header->height = h;
		header->bpp = context->target_bpp;
		pitch = header->pitch = ((w * context->target_bpp) + 0xF) & ~0xF;
		dest += sizeof(PUT_HEADER);
	}

	if( array != NULL ) {
		if ((array->size > 0) && ((intptr_t)dest + (pitch * h) > (intptr_t)array->data + array->size))
			return fb_ErrorSetNum(FB_RTERROR_ILLEGALFUNCTIONCALL);
	}

	DRIVER_LOCK();

	for (; y1 <= y2; y1++) {
		fb_hPixelCpy(dest, context->line[y1] + (x1 * context->target_bpp), w);
		dest += pitch;
	}

	DRIVER_UNLOCK();

	return fb_ErrorSetNum( FB_RTERROR_OK );
}