622 lines
18 KiB
C
622 lines
18 KiB
C
/*
|
|
* TilEm II
|
|
*
|
|
* Copyright (c) 2010-2011 Thibault Duponchelle
|
|
* Copyright (c) 2010-2012 Benjamin Moody
|
|
*
|
|
* This program is free software: you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <gtk/gtk.h>
|
|
#include <glib/gstdio.h>
|
|
#include <ticalcs.h>
|
|
#include <tilem.h>
|
|
|
|
#include "gui.h"
|
|
#include "files.h"
|
|
#include "msgbox.h"
|
|
|
|
/* Set size hints for the toplevel window */
|
|
static void set_size_hints(GtkWidget *widget, gpointer data)
|
|
{
|
|
TilemEmulatorWindow *ewin = data;
|
|
|
|
/* Don't use gtk_window_set_geometry_hints() (which would
|
|
appear to do what we want) because, in addition to setting
|
|
the hints we want, that function causes GTK+ to argue with
|
|
the window manager.
|
|
|
|
Instead, we call this function after the check-resize
|
|
signal (which is when GTK+ itself would normally set the
|
|
hints.)
|
|
|
|
FIXME: check that this works as desired on Win32/Quartz. */
|
|
|
|
if (gtk_widget_get_window(widget))
|
|
gdk_window_set_geometry_hints(gtk_widget_get_window(widget),
|
|
&ewin->geomhints,
|
|
ewin->geomhintmask);
|
|
}
|
|
|
|
static void window_state_changed(G_GNUC_UNUSED GtkWidget *w,
|
|
GdkEventWindowState *event, gpointer data)
|
|
{
|
|
TilemEmulatorWindow *ewin = data;
|
|
ewin->window_state = event->new_window_state;
|
|
}
|
|
|
|
static gboolean window_maximized(TilemEmulatorWindow *ewin)
|
|
{
|
|
return (ewin->window_state & (GDK_WINDOW_STATE_MAXIMIZED
|
|
| GDK_WINDOW_STATE_FULLSCREEN));
|
|
}
|
|
|
|
static gboolean screen_repaint(GtkWidget *w, GdkEventExpose *ev G_GNUC_UNUSED,
|
|
TilemEmulatorWindow *ewin)
|
|
{
|
|
GtkAllocation alloc;
|
|
GdkWindow *win;
|
|
GtkStyle *style;
|
|
|
|
gtk_widget_get_allocation(w, &alloc);
|
|
|
|
/* If image buffer is not the correct size, allocate a new one */
|
|
|
|
if (!ewin->lcd_image_buf
|
|
|| alloc.width != ewin->lcd_image_width
|
|
|| alloc.height != ewin->lcd_image_height) {
|
|
ewin->lcd_image_width = alloc.width;
|
|
ewin->lcd_image_height = alloc.height;
|
|
g_free(ewin->lcd_image_buf);
|
|
ewin->lcd_image_buf = g_new(byte, alloc.width * alloc.height);
|
|
}
|
|
|
|
/* Draw LCD contents into the image buffer */
|
|
|
|
g_mutex_lock(ewin->emu->lcd_mutex);
|
|
ewin->emu->lcd_update_pending = FALSE;
|
|
tilem_draw_lcd_image_indexed(ewin->emu->lcd_buffer,
|
|
ewin->lcd_image_buf,
|
|
alloc.width, alloc.height, alloc.width,
|
|
(ewin->lcd_smooth_scale
|
|
? TILEM_SCALE_SMOOTH
|
|
: TILEM_SCALE_FAST));
|
|
g_mutex_unlock(ewin->emu->lcd_mutex);
|
|
|
|
/* Render buffer to the screen */
|
|
|
|
win = gtk_widget_get_window(w);
|
|
style = gtk_widget_get_style(w);
|
|
gdk_draw_indexed_image(win, style->fg_gc[GTK_STATE_NORMAL], 0, 0,
|
|
alloc.width, alloc.height, GDK_RGB_DITHER_NONE,
|
|
ewin->lcd_image_buf, alloc.width,
|
|
ewin->lcd_cmap);
|
|
return TRUE;
|
|
}
|
|
|
|
/* Set the color palette for drawing the emulated LCD. */
|
|
static void screen_restyle(GtkWidget* w, GtkStyle* oldstyle G_GNUC_UNUSED,
|
|
TilemEmulatorWindow* ewin)
|
|
{
|
|
dword* palette;
|
|
GtkStyle *style;
|
|
int r_dark, g_dark, b_dark;
|
|
int r_light, g_light, b_light;
|
|
double gamma = 2.2;
|
|
|
|
if (!ewin->skin) {
|
|
/* no skin -> use standard GTK colors */
|
|
|
|
style = gtk_widget_get_style(w);
|
|
|
|
r_dark = style->text[GTK_STATE_NORMAL].red / 257;
|
|
g_dark = style->text[GTK_STATE_NORMAL].green / 257;
|
|
b_dark = style->text[GTK_STATE_NORMAL].blue / 257;
|
|
|
|
r_light = style->base[GTK_STATE_NORMAL].red / 257;
|
|
g_light = style->base[GTK_STATE_NORMAL].green / 257;
|
|
b_light = style->base[GTK_STATE_NORMAL].blue / 257;
|
|
}
|
|
else {
|
|
/* use skin colors */
|
|
|
|
r_dark = ((ewin->skin->lcd_black >> 16) & 0xff);
|
|
g_dark = ((ewin->skin->lcd_black >> 8) & 0xff);
|
|
b_dark = (ewin->skin->lcd_black & 0xff);
|
|
|
|
r_light = ((ewin->skin->lcd_white >> 16) & 0xff);
|
|
g_light = ((ewin->skin->lcd_white >> 8) & 0xff);
|
|
b_light = (ewin->skin->lcd_white & 0xff);
|
|
}
|
|
|
|
/* Generate a new palette, and convert it into GDK format */
|
|
|
|
if (ewin->lcd_cmap)
|
|
gdk_rgb_cmap_free(ewin->lcd_cmap);
|
|
|
|
palette = tilem_color_palette_new(r_light, g_light, b_light,
|
|
r_dark, g_dark, b_dark, gamma);
|
|
ewin->lcd_cmap = gdk_rgb_cmap_new(palette, 256);
|
|
tilem_free(palette);
|
|
|
|
gtk_widget_queue_draw(ewin->lcd);
|
|
}
|
|
|
|
static void skin_size_allocate(GtkWidget *widget, GtkAllocation *alloc,
|
|
gpointer data)
|
|
{
|
|
TilemEmulatorWindow *ewin = data;
|
|
int rawwidth, rawheight, scaledwidth, scaledheight;
|
|
int lcdleft, lcdright, lcdtop, lcdbottom;
|
|
double rx, ry, r;
|
|
|
|
g_return_if_fail(ewin->skin != NULL);
|
|
|
|
rawwidth = gdk_pixbuf_get_width(ewin->skin->raw);
|
|
rawheight = gdk_pixbuf_get_height(ewin->skin->raw);
|
|
|
|
rx = (double) alloc->width / rawwidth;
|
|
ry = (double) alloc->height / rawheight;
|
|
r = MIN(rx, ry);
|
|
|
|
scaledwidth = rawwidth * r;
|
|
scaledheight = rawheight * r;
|
|
|
|
if (ewin->skin->width == scaledwidth
|
|
&& ewin->skin->height == scaledheight)
|
|
return;
|
|
|
|
ewin->skin->width = scaledwidth;
|
|
ewin->skin->height = scaledheight;
|
|
ewin->skin->sx = ewin->skin->sy = 1.0 / r;
|
|
|
|
if (ewin->skin->image)
|
|
g_object_unref(ewin->skin->image);
|
|
ewin->skin->image = gdk_pixbuf_scale_simple(ewin->skin->raw,
|
|
scaledwidth,
|
|
scaledheight,
|
|
GDK_INTERP_BILINEAR);
|
|
|
|
gtk_image_set_from_pixbuf(GTK_IMAGE(ewin->background),
|
|
ewin->skin->image);
|
|
|
|
lcdleft = ewin->skin->lcd_pos.left * r + 0.5;
|
|
lcdright = ewin->skin->lcd_pos.right * r + 0.5;
|
|
lcdtop = ewin->skin->lcd_pos.top * r + 0.5;
|
|
lcdbottom = ewin->skin->lcd_pos.bottom * r + 0.5;
|
|
|
|
gtk_widget_set_size_request(ewin->lcd,
|
|
MAX(lcdright - lcdleft, 1),
|
|
MAX(lcdbottom - lcdtop, 1));
|
|
|
|
gtk_layout_move(GTK_LAYOUT(widget), ewin->lcd,
|
|
lcdleft, lcdtop);
|
|
|
|
ewin->zoom_factor = r / ewin->base_zoom;
|
|
|
|
if (ewin->zoom_factor <= 1.0)
|
|
ewin->zoom_factor = 1.0;
|
|
}
|
|
|
|
static void noskin_size_allocate(G_GNUC_UNUSED GtkWidget *widget,
|
|
GtkAllocation *alloc, gpointer data)
|
|
{
|
|
TilemEmulatorWindow *ewin = data;
|
|
int lcdwidth, lcdheight;
|
|
|
|
g_return_if_fail(ewin->emu->calc != NULL);
|
|
|
|
lcdwidth = ewin->emu->calc->hw.lcdwidth;
|
|
lcdheight = ewin->emu->calc->hw.lcdheight;
|
|
|
|
if (alloc->width > alloc->height)
|
|
ewin->zoom_factor = (gdouble) alloc->width / lcdwidth;
|
|
else
|
|
ewin->zoom_factor = (gdouble) alloc->height / lcdheight;
|
|
|
|
if (ewin->zoom_factor <= 1.0)
|
|
ewin->zoom_factor = 1.0;
|
|
}
|
|
|
|
/* Used when you load another skin */
|
|
void redraw_screen(TilemEmulatorWindow *ewin)
|
|
{
|
|
GtkWidget *pImage;
|
|
GtkWidget *emuwin;
|
|
int lcdwidth, lcdheight;
|
|
int screenwidth, screenheight;
|
|
int minwidth, minheight, defwidth, defheight,
|
|
curwidth, curheight;
|
|
double sx, sy, s, a1, a2;
|
|
GError *err = NULL;
|
|
|
|
if (ewin->skin) {
|
|
skin_unload(ewin->skin);
|
|
g_free(ewin->skin);
|
|
}
|
|
|
|
if (ewin->skin_disabled || !ewin->skin_file_name) {
|
|
ewin->skin = NULL;
|
|
}
|
|
else {
|
|
ewin->skin = g_new0(SKIN_INFOS, 1);
|
|
if (skin_load(ewin->skin, ewin->skin_file_name, &err)) {
|
|
skin_unload(ewin->skin);
|
|
ewin->skin = NULL;
|
|
}
|
|
}
|
|
|
|
if (ewin->emu->calc) {
|
|
lcdwidth = ewin->emu->calc->hw.lcdwidth;
|
|
lcdheight = ewin->emu->calc->hw.lcdheight;
|
|
}
|
|
else {
|
|
lcdwidth = lcdheight = 1;
|
|
}
|
|
|
|
if (ewin->lcd)
|
|
gtk_widget_destroy(ewin->lcd);
|
|
if (ewin->background)
|
|
gtk_widget_destroy(ewin->background);
|
|
if (ewin->layout)
|
|
gtk_widget_destroy(ewin->layout);
|
|
|
|
/* create LCD widget */
|
|
ewin->lcd = gtk_drawing_area_new();
|
|
gtk_widget_set_double_buffered(ewin->lcd, FALSE);
|
|
|
|
/* create background image and layout */
|
|
if (ewin->skin) {
|
|
ewin->layout = gtk_layout_new(NULL, NULL);
|
|
|
|
pImage = gtk_image_new();
|
|
gtk_layout_put(GTK_LAYOUT(ewin->layout), pImage, 0, 0);
|
|
ewin->background = pImage;
|
|
|
|
screenwidth = (ewin->skin->lcd_pos.right
|
|
- ewin->skin->lcd_pos.left);
|
|
screenheight = (ewin->skin->lcd_pos.bottom
|
|
- ewin->skin->lcd_pos.top);
|
|
|
|
gtk_widget_set_size_request(ewin->lcd,
|
|
screenwidth, screenheight);
|
|
gtk_layout_put(GTK_LAYOUT(ewin->layout), ewin->lcd,
|
|
ewin->skin->lcd_pos.left,
|
|
ewin->skin->lcd_pos.top);
|
|
|
|
g_signal_connect(ewin->layout, "size-allocate",
|
|
G_CALLBACK(skin_size_allocate), ewin);
|
|
|
|
emuwin = ewin->layout;
|
|
|
|
defwidth = ewin->skin->width;
|
|
defheight = ewin->skin->height;
|
|
|
|
sx = (double) lcdwidth / screenwidth;
|
|
sy = (double) lcdheight / screenheight;
|
|
s = MAX(sx, sy);
|
|
minwidth = defwidth * s + 0.5;
|
|
minheight = defheight * s + 0.5;
|
|
ewin->base_zoom = s;
|
|
}
|
|
else {
|
|
ewin->layout = NULL;
|
|
ewin->background = NULL;
|
|
|
|
emuwin = ewin->lcd;
|
|
|
|
g_signal_connect(ewin->lcd, "size-allocate",
|
|
G_CALLBACK(noskin_size_allocate), ewin);
|
|
|
|
defwidth = minwidth = lcdwidth;
|
|
defheight = minheight = lcdheight;
|
|
ewin->base_zoom = 1.0;
|
|
}
|
|
|
|
curwidth = defwidth * ewin->base_zoom * ewin->zoom_factor + 0.5;
|
|
curheight = defheight * ewin->base_zoom * ewin->zoom_factor + 0.5;
|
|
|
|
gtk_widget_set_can_focus(emuwin, TRUE);
|
|
|
|
gtk_widget_add_events(emuwin, (GDK_BUTTON_PRESS_MASK
|
|
| GDK_BUTTON_RELEASE_MASK
|
|
| GDK_BUTTON1_MOTION_MASK
|
|
| GDK_POINTER_MOTION_HINT_MASK
|
|
| GDK_DROP_FINISHED
|
|
| GDK_DRAG_MOTION));
|
|
|
|
g_signal_connect(ewin->lcd, "expose-event",
|
|
G_CALLBACK(screen_repaint), ewin);
|
|
g_signal_connect(ewin->lcd, "style-set",
|
|
G_CALLBACK(screen_restyle), ewin);
|
|
|
|
g_signal_connect(emuwin, "button-press-event",
|
|
G_CALLBACK(mouse_press_event), ewin);
|
|
g_signal_connect(emuwin, "motion-notify-event",
|
|
G_CALLBACK(pointer_motion_event), ewin);
|
|
g_signal_connect(emuwin, "button-release-event",
|
|
G_CALLBACK(mouse_release_event), ewin);
|
|
g_signal_connect(emuwin, "popup-menu",
|
|
G_CALLBACK(popup_menu_event), ewin);
|
|
|
|
/* FIXME: this is rather broken; GTK_DEST_DEFAULT_ALL sends a
|
|
successful "finished" message to any drop that matches the
|
|
list of targets. Files/URIs we can't accept should be
|
|
rejected, and we shouldn't send the "finished" message
|
|
until it's actually finished. */
|
|
gtk_drag_dest_set(emuwin, GTK_DEST_DEFAULT_ALL,
|
|
NULL, 0, GDK_ACTION_COPY);
|
|
gtk_drag_dest_add_uri_targets(emuwin);
|
|
g_signal_connect(emuwin, "drag-data-received",
|
|
G_CALLBACK(drag_data_received), ewin);
|
|
|
|
|
|
/* Hint calculation assumes the emulator is the only thing in
|
|
the window; if other widgets are added, this will have to
|
|
change accordingly
|
|
*/
|
|
ewin->geomhints.min_width = minwidth;
|
|
ewin->geomhints.min_height = minheight;
|
|
a1 = (double) minwidth / minheight;
|
|
a2 = (double) defwidth / defheight;
|
|
ewin->geomhints.min_aspect = MIN(a1, a2) - 0.0001;
|
|
ewin->geomhints.max_aspect = MAX(a1, a2) + 0.0001;
|
|
ewin->geomhintmask = (GDK_HINT_MIN_SIZE | GDK_HINT_ASPECT);
|
|
|
|
/* If the window is already realized, set the hints now, so
|
|
that the WM will see the new hints before we try to resize
|
|
the window */
|
|
set_size_hints(ewin->window, ewin);
|
|
|
|
gtk_widget_set_size_request(emuwin, minwidth, minheight);
|
|
gtk_container_add(GTK_CONTAINER(ewin->window), emuwin);
|
|
|
|
if (!window_maximized(ewin))
|
|
gtk_window_resize(GTK_WINDOW(ewin->window),
|
|
curwidth, curheight);
|
|
|
|
gtk_widget_show_all(emuwin);
|
|
|
|
if (err) {
|
|
messagebox01(GTK_WINDOW(ewin->window), GTK_MESSAGE_ERROR,
|
|
"Unable to load skin", "%s", err->message);
|
|
g_error_free(err);
|
|
}
|
|
}
|
|
|
|
static void window_destroy(G_GNUC_UNUSED GtkWidget *w, gpointer data)
|
|
{
|
|
TilemEmulatorWindow *ewin = data;
|
|
|
|
if (!window_maximized(ewin))
|
|
tilem_config_set("settings",
|
|
"zoom/r", ewin->zoom_factor,
|
|
NULL);
|
|
|
|
ewin->window = ewin->layout = ewin->lcd = ewin->background = NULL;
|
|
}
|
|
|
|
TilemEmulatorWindow *tilem_emulator_window_new(TilemCalcEmulator *emu)
|
|
{
|
|
TilemEmulatorWindow *ewin;
|
|
|
|
g_return_val_if_fail(emu != NULL, NULL);
|
|
|
|
ewin = g_slice_new0(TilemEmulatorWindow);
|
|
ewin->emu = emu;
|
|
|
|
tilem_config_get("settings",
|
|
"skin_disabled/b", &ewin->skin_disabled,
|
|
"smooth_scaling/b=1", &ewin->lcd_smooth_scale,
|
|
"zoom/r=2.0", &ewin->zoom_factor,
|
|
NULL);
|
|
|
|
if (ewin->zoom_factor <= 1.0)
|
|
ewin->zoom_factor = 1.0;
|
|
|
|
/* Create the window */
|
|
ewin->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
|
|
|
g_signal_connect(ewin->window, "window-state-event",
|
|
G_CALLBACK(window_state_changed), ewin);
|
|
g_signal_connect(ewin->window, "destroy",
|
|
G_CALLBACK(window_destroy), ewin);
|
|
|
|
g_signal_connect_after(ewin->window, "check-resize",
|
|
G_CALLBACK(set_size_hints), ewin);
|
|
|
|
gtk_widget_add_events(ewin->window, (GDK_KEY_PRESS_MASK
|
|
| GDK_KEY_RELEASE_MASK));
|
|
|
|
g_signal_connect(ewin->window, "key-press-event",
|
|
G_CALLBACK(key_press_event), ewin);
|
|
g_signal_connect(ewin->window, "key-release-event",
|
|
G_CALLBACK(key_release_event), ewin);
|
|
|
|
build_menu(ewin);
|
|
|
|
tilem_emulator_window_calc_changed(ewin);
|
|
|
|
return ewin;
|
|
}
|
|
|
|
void tilem_emulator_window_free(TilemEmulatorWindow *ewin)
|
|
{
|
|
g_return_if_fail(ewin != NULL);
|
|
|
|
if (ewin->lcd)
|
|
gtk_widget_destroy(ewin->lcd);
|
|
if (ewin->background)
|
|
gtk_widget_destroy(ewin->background);
|
|
if (ewin->layout)
|
|
gtk_widget_destroy(ewin->layout);
|
|
if (ewin->window)
|
|
gtk_widget_destroy(ewin->window);
|
|
if (ewin->popup_menu)
|
|
gtk_widget_destroy(ewin->popup_menu);
|
|
if (ewin->actions)
|
|
g_object_unref(ewin->actions);
|
|
|
|
g_free(ewin->lcd_image_buf);
|
|
|
|
g_free(ewin->skin_file_name);
|
|
if (ewin->skin) {
|
|
skin_unload(ewin->skin);
|
|
g_free(ewin->skin);
|
|
}
|
|
|
|
if (ewin->lcd_cmap)
|
|
gdk_rgb_cmap_free(ewin->lcd_cmap);
|
|
|
|
g_slice_free(TilemEmulatorWindow, ewin);
|
|
}
|
|
|
|
void tilem_emulator_window_set_skin(TilemEmulatorWindow *ewin,
|
|
const char *filename)
|
|
{
|
|
g_return_if_fail(ewin != NULL);
|
|
|
|
g_free(ewin->skin_file_name);
|
|
if (filename)
|
|
ewin->skin_file_name = g_strdup(filename);
|
|
else
|
|
ewin->skin_file_name = NULL;
|
|
redraw_screen(ewin);
|
|
}
|
|
|
|
/* Switch between skin and LCD-only mode */
|
|
void tilem_emulator_window_set_skin_disabled(TilemEmulatorWindow *ewin,
|
|
gboolean disabled)
|
|
{
|
|
g_return_if_fail(ewin != NULL);
|
|
|
|
if (ewin->skin_disabled != !!disabled) {
|
|
ewin->skin_disabled = !!disabled;
|
|
redraw_screen(ewin);
|
|
}
|
|
}
|
|
|
|
void tilem_emulator_window_calc_changed(TilemEmulatorWindow *ewin)
|
|
{
|
|
const char *model;
|
|
char *name = NULL, *path;
|
|
|
|
g_return_if_fail(ewin != NULL);
|
|
g_return_if_fail(ewin->emu != NULL);
|
|
|
|
g_free(ewin->skin_file_name);
|
|
ewin->skin_file_name = NULL;
|
|
|
|
if (!ewin->emu->calc)
|
|
return;
|
|
|
|
model = ewin->emu->calc->hw.name;
|
|
|
|
tilem_config_get(model,
|
|
"skin/f", &name,
|
|
NULL);
|
|
|
|
if (!name)
|
|
name = g_strdup_printf("%s.skn", model);
|
|
|
|
if (!g_path_is_absolute(name)) {
|
|
path = get_shared_file_path("skins", name, NULL);
|
|
tilem_emulator_window_set_skin(ewin, path);
|
|
g_free(path);
|
|
}
|
|
else {
|
|
tilem_emulator_window_set_skin(ewin, name);
|
|
}
|
|
|
|
g_free(name);
|
|
}
|
|
|
|
void tilem_emulator_window_refresh_lcd(TilemEmulatorWindow *ewin)
|
|
{
|
|
g_return_if_fail(ewin != NULL);
|
|
if (ewin->lcd)
|
|
gtk_widget_queue_draw(ewin->lcd);
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Display the lcd image into the terminal */
|
|
void display_lcdimage_into_terminal(TilemEmulatorWindow *ewin)
|
|
{
|
|
|
|
int width, height;
|
|
guchar* lcddata;
|
|
int x, y;
|
|
char c;
|
|
width = ewin->emu->calc->hw.lcdwidth;
|
|
height = ewin->emu->calc->hw.lcdheight;
|
|
FILE* lcd_content_file;
|
|
/* Alloc mmem */
|
|
lcddata = g_new(guchar, (width / 8) * height);
|
|
|
|
/* Get the lcd content using the function 's pointer from Benjamin's core */
|
|
(*ewin->emu->calc->hw.get_lcd)(ewin->emu->calc, lcddata);
|
|
|
|
/* Print a little demo just for fun;) */
|
|
printf("\n\n\n");
|
|
printf(" r rr r rrrrr rrr r rrrrr r r rr r rr r \n");
|
|
printf(" r r r r r r r r rr rr r r r r r r r \n");
|
|
printf(" r r r r r r r r r r r r r r r r r r \n");
|
|
printf("rrrrr r r r r r r rrrr r r r r r r r rrrrr rrrrr rrrrr \n");
|
|
printf(" r r r r r r r r r r rrr r r r r r r \n");
|
|
printf(" r r r r r r r r r r r r r r r r \n");
|
|
printf(" r rr r r rrr rrrrr rrrrr r r r rr r \n");
|
|
printf("\n(Here is just a sample...)\n\n");
|
|
|
|
/* Request user to know which char user wants */
|
|
|
|
printf("Which char to display FOR BLACK?\n");
|
|
scanf("%c", &c); /* Choose wich char for the black */
|
|
|
|
//printf("Which char to display FOR GRAY ?\n");
|
|
//scanf("%c", &b); /* Choose wich char for the black */
|
|
|
|
lcd_content_file = g_fopen("lcd_content.txt", "w");
|
|
|
|
printf("\n\n\n### LCD CONTENT ###\n\n\n\n");
|
|
for (y = 0; y < height; y++) {
|
|
for (x = 0; x < width; x++) {
|
|
/*printf("%d ", lcddata[y * width + x]); */
|
|
if (lcddata[(y * width + x) / 8] & (0x80 >> (x % 8))) {
|
|
printf("%c", c);
|
|
if(lcd_content_file != NULL)
|
|
fprintf(lcd_content_file,"%c", c);
|
|
} else {
|
|
printf("%c", ' ');
|
|
if(lcd_content_file != NULL)
|
|
fprintf(lcd_content_file,"%c", ' ');
|
|
}
|
|
}
|
|
printf("\n");
|
|
if(lcd_content_file != NULL)
|
|
fprintf(lcd_content_file,"%c", '\n');
|
|
}
|
|
if(lcd_content_file != NULL) {
|
|
fclose(lcd_content_file);
|
|
printf("\n### END ###\n\nSaved into lcd_content.txt\n");
|
|
}
|
|
|
|
}
|