Пример #1
0
/* Update LCD screen part */
int hid_update_lcd(void)
{
	int i, j, k, l;
	uint8_t *lcd_bitmap = &tihw.ram[tihw.lcd_adr];	
	uint8_t *lcd_buf = (uint8_t *)lcd_bytmap;	
	GdkRect src;
	guchar *p;

	tihw.lcd_ptr = (char *) &tihw.ram[tihw.lcd_adr];	

    if(!pixmap || !lcd_mem || !tihw.lcd_ptr)
        return 0;

	// Check for LCD state change (from TI HW)
	if(lcd_state != tihw.on_off)
	{
		lcd_state = tihw.on_off;
		lcd_changed = 1;

		if(!lcd_state)
			redraw_lcd();	// to clear LCD
	}

	// Check for contrast change (from TI HW)
	if(contrast != tihw.contrast)
	{
		gint c = contrast = tihw.contrast;

		new_contrast = (c + old_contrast) / 2;
  		old_contrast = c;

		compute_grayscale();

		lcd_changed = 1;
	}

	// Check for gray plane change (menu/hw)
    if(max_plane != ngc) 
    {
		max_plane = ngc;
		compute_grayscale();
    }

	// LCD off or unchanged: don't refresh !
	if(!lcd_state || !lcd_changed)
		return 0;

	// Reset LCD changed flag.
	lcd_changed = 0;

	// Convert the bitmap screen to a bytemap screen and grayscalize
	memset(lcd_bytmap, 0, LCDMEM_H*LCDMEM_W);	
	for(l = 0; l < 8; l++)
	{
		int pp = gp_seq[ngc][l];
		if(pp == -1) break;

		lcd_bitmap = lcd_planebufs[pp];

		for(j = 0, k = 0; k < LCDMEM_H; k++)
		{
			for(i = 0; i < LCDMEM_W/8; i++, lcd_bitmap++) 
			{
				lcd_bytmap[j++] += convtab[(*lcd_bitmap << 1)  ];
				lcd_bytmap[j++] += convtab[(*lcd_bitmap << 1)+1];
			}
		}
    }

    if(1)
	{
		// Copy LCD from buffer to pixbuf
		for(j = 0; j < LCDMEM_H; j++)
		{
			for (i = 0; i < LCDMEM_W; i++) 
			{
				p = li.pixels + j * li.rowstride + i * li.n_channels;
				
				p[0] = grayscales[*lcd_buf].r;
				p[1] = grayscales[*lcd_buf].g;
				p[2] = grayscales[*lcd_buf].b;
				lcd_buf++;
			}
		}

        // Set region to update
        src.x = src.y = 0;
		src.w = (tihw.log_w > tihw.lcd_w) ? tihw.lcd_w : tihw.log_w;
		src.h = (tihw.log_h > tihw.lcd_h) ? tihw.lcd_h : tihw.log_h;

		// Copy surface into window
		if(sf)
		{
			src.w = (int)(sf * src.w);
			src.h = (int)(sf * src.h);

			// scale image
			g_object_unref(skin_infos.image);
			skin_infos.image = gdk_pixbuf_scale_simple(lcd, lr.w, lr.h, GDK_INTERP_NEAREST);

			// and draw image into pixmap (next, into window on expose event)
			gdk_draw_pixbuf(pixmap, main_wnd->style->fg_gc[GTK_WIDGET_STATE(main_wnd)],
			 skin_infos.image, src.x, src.y, lr.x, lr.y, src.w, src.h,
			  GDK_RGB_DITHER_NONE, 0, 0);
			gtk_widget_queue_draw_area(area, lr.x, lr.y, src.w, src.h);
		}
		else
		{
			// and draw image into pixmap (next, into window on expose event)
			gdk_draw_pixbuf(pixmap, main_wnd->style->fg_gc[GTK_WIDGET_STATE(main_wnd)],
			  lcd_mem, src.x, src.y, lr.x, lr.y, src.w, src.h,
			  GDK_RGB_DITHER_NONE, 0, 0);
			gtk_widget_queue_draw_area(area, lr.x, lr.y, src.w, src.h);
		}
    }

	// Screen shot
	if(!--skip_cnt && shot_cnt > 0)
	{
		skip_cnt = options2.skips;

		hid_screenshot_single();
		shot_cnt--;
	}

    return -1;
}
Пример #2
0
int  hid_init(void)
{
    // Found a PC keyboard keymap
    match_keymap(tihw.calc_type);

    // Load kbd keymap
    if(keymap_load(options.keys_file) == -1)
    {
	    gchar *s = g_strdup_printf("unable to load this keymap: <%s>\n", options.keys_file);
	    tiemu_error(0, s);
	    g_free(s);
	    return -1;
    }

    // Found a skin
	match_skin(tihw.calc_type);

    // Load skin (2 parts)
    if(skin_load(&skin_infos, options.skin_file) == -1) 
    {
	    gchar *s = g_strdup_printf("unable to load this skin: <%s>\n", options.skin_file);
	    tiemu_error(0, s);
	    g_free(s);
	    return -1;
    }

	// Allocate the skn pixbuf (if needed)
	skn = skin_infos.image;
  
	// Set skin keymap depending on calculator type
    switch(tihw.calc_type)
    {
    case TI92:
    case TI92p:
    case V200:
        skn_keymap = sknKey92;
        break;
    case TI89:
    case TI89t:
      	skn_keymap = sknKey89;
        break;
    default:
        {
	  	gchar *s = g_strdup_printf("no skin found for this calc\n");
	  	tiemu_error(0, s);
	  	g_free(s);
	  	return -1;
        }
	}

	// Set window/LCD sizes
	set_scale(options.view);
	set_infos();

    // Allocate the TI screen buffer
	lcd_bytmap = (uint32_t *)malloc(LCDMEM_W * LCDMEM_H);

    // Allocate the lcd pixbuf
    lcd = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, si.t * LCDMEM_W, si.t * LCDMEM_H);
    if(lcd == NULL)
    {
        gchar *s = g_strdup_printf("unable to create LCD pixbuf.\n");
	    tiemu_error(0, s);
	    g_free(s);
	    return -1;
    }

	// Used by TI89 (the LCD view is clipped from memory view)
	si.l = gdk_pixbuf_new_subpixbuf(lcd, 0, 0, tihw.lcd_w, tihw.lcd_h);
    
	// Constants for LCD update (speed-up)
    li.n_channels = gdk_pixbuf_get_n_channels (lcd);
	li.width = gdk_pixbuf_get_width (lcd);
	li.height = gdk_pixbuf_get_height (lcd);
	li.rowstride = gdk_pixbuf_get_rowstride (lcd);
	li.pixels = gdk_pixbuf_get_pixels (lcd);

	// Create main window
	display_main_wnd();

    // Allocate the backing pixmap (used for drawing and refresh)
    pixmap = gdk_pixmap_new(main_wnd->window, wr.w, wr.h, -1);
    if(pixmap == NULL)
    {
        gchar *s = g_strdup_printf("unable to create backing pixbuf.\n");
	    tiemu_error(0, s);
	    g_free(s);
	    return -1;
    }
    
    // Draw the skin and compute grayscale palette
	redraw_skin();
  	compute_grayscale();

    // Init the planar/chunky conversion table for LCD
  	compute_convtable();

    // Install LCD refresh: 100 FPS (10 ms)
    tid = g_timeout_add((params.lcd_rate == -1) ? 50 : params.lcd_rate, 
		(GtkFunction)hid_refresh, NULL);

	gtk_widget_show(main_wnd);	// show wnd here

	if(options.view == VIEW_FULL)
		gdk_window_fullscreen(main_wnd->window);
	
    return 0;
}