wonx/XDisplay.c
Hiroaki Sakai d1cde9116a Added dump of RGB value when dumping palette data.
Fixed a part of the data dump part.

Changed the line of perl script from / usr / bin / perl to / usr / local / bin / perl.
(On FreeBSD, Japanese perl is in / usr / local / bin)

For disp.c, libwwc.c, a function for reading and acquiring bitmap data of characters,
The type of bitmap data is not unsigned char *, but instead of short int *, long int *
It was modified to an appropriate type.
Let the bitmap of the WWCharacter class be union of uchar, ushort, ulong,
By accessing with an appropriate type in WWCharacter_GetPixel ()
The endian dependence of bitmap data is eliminated.  (i386, confirmed by SPARC)

Fixed how to get the value of WWCharacter_GetPixel () in 16 PACKED color mode.
(The bug that the character was displayed inverted horizontally was resolved)

Stop for 10 seconds at F11, forcibly end with Ctrl-c or F12,
Added iconization with Ctrl-i.  (It was a function that was originally, but I forgot that,
We modified it somewhat to make it formal support)

Move display / non-display change key from p to F10.  Manual correction.

XDisplay.c: generated with XColorGC_CreateFromRGB () with XDisplay_DrawLCDWindow ()
Since we did not Destroy () the XColorGC object, we made a bug that caused memory flow
Fix.  (XColorGC_Destroy (x_color_gc) addition)

Add wonx_include / fcntl.h.  The contents are / usr / include / fcntl.h,
Just include /usr/include/sys/fcntl.h.

Format change of serial output message (output to serial port:).
(I tried to enclose it with "".)
etc.c: wonx_print_character () Fixed.  (Add \ ", \ \ and others)
Fix sout2str.pl.  (Add \ ", \ \ etc .... The above message for serial output
It was modified according to format change)

Added int2sint.pl, filters.pl, challsrc.sh.
Change sys2wonx.pl.

in wonx_include / types.h
typedef unsigned short WORD;
typedef unsigned long DWORD;
To
typedef unsigned short int WORD;
typedef unsigned long int DWORD;
change to.

Fixed README.

Version 2.1 - from wonx-2.1.tar.gz
2018-03-07 23:07:23 +00:00

594 lines
19 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*****************************************************************************/
/* ここから */
/*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include "XDisplayP.h"
#include "WonX.h"
#include "etc.h"
/*****************************************************************************/
/* メンバ関数の定義 */
/*****************************************************************************/
Display * XDisplay_GetDisplay(XDisplay d) { return (d->display); }
Colormap XDisplay_GetColormap(XDisplay d) { return (d->colormap); }
XColorGCDatabase XDisplay_GetColorGCDatabase(XDisplay x_display)
{ return (x_display->color_gc_database); }
unsigned int XDisplay_GetKeyPress(XDisplay d) { return (d->key_press); }
int XDisplay_GetLCDDraw(XDisplay d) { return (d->lcd_draw); }
int XDisplay_GetColorMapPrint(XDisplay d) {return (d->color_map_print); }
int XDisplay_GetPalettePrint(XDisplay d) {return (d->palette_print); }
int XDisplay_GetCharacterPrint(XDisplay d) {return (d->character_print); }
int XDisplay_GetSpritePrint(XDisplay d) {return (d->sprite_print); }
int XDisplay_SetColorMapPrint(XDisplay d, int f)
{ return (d->color_map_print = f); }
int XDisplay_SetPalettePrint(XDisplay d, int f)
{ return (d->palette_print = f); }
int XDisplay_SetCharacterPrint(XDisplay d, int f)
{ return(d->character_print = f); }
int XDisplay_SetSpritePrint(XDisplay d, int f)
{ return (d->sprite_print = f); }
/*****************************************************************************/
/* 内部で使用する関数などの定義 */
/*****************************************************************************/
#if 0
static XrmOptionDescRec options[] = {};
#endif
static Atom wm_delete_window;
static void die(Widget w)
{
kill(getpid(), SIGINT);
}
static void quit(Widget w, XEvent * event, String * params, Cardinal * num)
{
die(w);
}
static void wm_protocols_proc(Widget w, XEvent * event, String * params,
Cardinal * num)
{
if ((event->type == ClientMessage) &&
(event->xclient.data.l[0] != wm_delete_window)) {
XBell(XtDisplay(w), 0);
} else {
die(w);
}
}
static void iconify(Widget w, XEvent * event, String * params, Cardinal * num)
{
XIconifyWindow(XtDisplay(w), XtWindow(w), DefaultScreen(XtDisplay(w)));
}
static void sleep_10(Widget w, XEvent * event, String * params, Cardinal * num)
{
time_t old_t;
time_t t;
int i;
/* UNIXTimer.c 内部で SIGALRM を使用しているのでsleep() は使用できない */
#if 0
sleep(10);
#else
for (i = 0; i < 10; i++) {
time(&t);
old_t = t;
while (t == old_t)
time(&t);
}
#endif
}
static XtActionsRec actions[] = {
{"quit", quit},
{"wm_protocols_proc", wm_protocols_proc},
{"iconify", iconify},
{"pause", sleep_10}
};
static char * translations =
"<Message>WM_PROTOCOLS: wm_protocols_proc()\n"
"None<Key>F11: pause()\n"
"Ctrl<Key>i: iconify()\n"
"Ctrl<Key>c: quit()\n"
"None<Key>F12: quit()\n"
"None<Key>q: quit()";
/*===========================================================================*/
/* 色名からピクセル値を取得する */
/*===========================================================================*/
static unsigned long XDisplay_GetPixelFromColorName(XDisplay x_display,
char * color_name)
{
XColor c0, c1;
XAllocNamedColor(x_display->display, x_display->colormap, color_name,
&c0, &c1);
return (c0.pixel);
}
/*===========================================================================*/
/* イベントハンドラ */
/*===========================================================================*/
/*---------------------------------------------------------------------------*/
/* イクスポーズ */
/*---------------------------------------------------------------------------*/
static void ExposeHandler(Widget w, XtPointer p, XEvent * event,
Boolean * dispatch)
{
XDisplay x_display = (XDisplay)p;
XCopyArea(x_display->display, x_display->lcd_pixmap,
x_display->lcd_window, x_display->copy_gc,
0, 0, x_display->width, x_display->height, 0, 0);
return;
}
/*---------------------------------------------------------------------------*/
/* キーの押下 */
/*---------------------------------------------------------------------------*/
static void KeyHandler(Widget w, XtPointer p, XEvent * event,
Boolean * dispatch)
{
XDisplay x_display = (XDisplay)p;
KeySym key_sym;
int press = 0;
if ((event->type == KeyPress) || (event->type == KeyRelease)) {
key_sym = XKeycodeToKeysym(x_display->display, event->xkey.keycode, 0);
switch (key_sym) {
/* WonderSwan用 */
case XK_Up : press = KEY_UP1; break;
case XK_Right : press = KEY_RIGHT1; break;
case XK_Down : press = KEY_DOWN1; break;
case XK_Left : press = KEY_LEFT1; break;
case XK_i : press = KEY_UP2; break;
case XK_l : press = KEY_RIGHT2; break;
case XK_k : press = KEY_DOWN2; break;
case XK_j : press = KEY_LEFT2; break;
case XK_s : press = KEY_START; break;
case XK_space : press = KEY_A; break;
case XK_Shift_L : press = KEY_B; break;
default : press = 0; break;
}
/* WonX 操作用 */
if (event->type == KeyPress) {
switch (key_sym) {
/* 表示モード変更 */
case XK_F10 :
x_display->lcd_draw = !(x_display->lcd_draw);
if (x_display->lcd_draw) {
#if 1
WonXDisplay_Flush(WonX_GetWonXDisplay());
#else
ExposeHandler(w, p, event, dispatch);
#endif
}
break;
/* データのダンプ操作 */
case XK_F1 : x_display->color_map_print = 1; break;
case XK_F2 : x_display->palette_print = 1; break;
case XK_F3 : x_display->character_print = 1; break;
case XK_F4 : x_display->sprite_print = 1; break;
}
}
if (press) {
if (event->type == KeyPress) x_display->key_press |= press;
else x_display->key_press &= ~press;
}
}
return;
}
/*---------------------------------------------------------------------------*/
/* マウスがウインドウを離れたら,キーを初期化する */
/*---------------------------------------------------------------------------*/
static void LeaveWindowHandler(Widget w, XtPointer p, XEvent * event,
Boolean * dispatch)
{
XDisplay x_display = (XDisplay)p;
x_display->key_press = 0;
return;
}
/*===========================================================================*/
/* オブジェクトの生成と消去 */
/*===========================================================================*/
/*---------------------------------------------------------------------------*/
/* オブジェクトの生成 */
/*---------------------------------------------------------------------------*/
XDisplay XDisplay_Create(int width, int height)
{
XDisplay x_display;
int argc = 0;
char ** argv = NULL;
XColor color;
char * color_name[] = {"white", "gray84", "gray78", "gray72",
"gray66", "gray60", "gray54", "gray48",
"gray42", "gray36", "gray30", "gray24",
"gray18", "gray12", "gray6", "black"};
int i;
x_display = (XDisplay)malloc(sizeof(_XDisplay));
if (x_display == NULL)
WonX_Error("XDisplay_Create", "Cannot allocate memory.");
x_display->width = width;
x_display->height = height;
x_display->toplevel = XtAppInitialize(&(x_display->app_context),
"WonX",
NULL, 0, &argc, argv, NULL, NULL, 0);
XtVaSetValues(x_display->toplevel, XtNinput, True, NULL);
XtVaSetValues(x_display->toplevel, XtNtitle, "WonX", NULL);
XtVaSetValues(x_display->toplevel, XtNwidth , x_display->width , NULL);
XtVaSetValues(x_display->toplevel, XtNminWidth , x_display->width , NULL);
XtVaSetValues(x_display->toplevel, XtNmaxWidth , x_display->width , NULL);
XtVaSetValues(x_display->toplevel, XtNheight , x_display->height, NULL);
XtVaSetValues(x_display->toplevel, XtNminHeight, x_display->height, NULL);
XtVaSetValues(x_display->toplevel, XtNmaxHeight, x_display->height, NULL);
x_display->key_press = 0;
x_display->lcd_draw = 1;
XtRealizeWidget(x_display->toplevel);
while (!XtIsRealized(x_display->toplevel)) { /* None */ }
x_display->display = XtDisplay(x_display->toplevel);
x_display->root_window = DefaultRootWindow(x_display->display);
x_display->lcd_window = XtWindow(x_display->toplevel);
x_display->colormap = DefaultColormap(x_display->display,
DefaultScreen(x_display->display));
x_display->depth = DefaultDepth(x_display->display,
DefaultScreen(x_display->display));
x_display->lcd_pixmap = XCreatePixmap(x_display->display,
x_display->lcd_window,
x_display->width,
x_display->height,
x_display->depth);
x_display->copy_gc = XCreateGC(x_display->display, x_display->lcd_window,
0, 0);
XSetFunction(x_display->display, x_display->copy_gc, GXcopy);
for (i = 0; i < 16; i++) {
XParseColor(x_display->display, x_display->colormap,
color_name[i], &color); /* 色の名前 → RGB値*/
XAllocColor(x_display->display, x_display->colormap,
&color); /* 色を確保し,ピクセル値を得る */
x_display->color_gc[i] = XCreateGC(x_display->display,
x_display->lcd_window, 0, 0);
XSetForeground(x_display->display, x_display->color_gc[i], color.pixel);
XSetFunction(x_display->display, x_display->color_gc[i], GXcopy);
}
/* GCのデータベース初期化 */
x_display->color_gc_database =
XColorGCDatabase_Create(x_display,
0, /* studying_flag */
1, /* cache_flag */
3, /* cache_size */
256, /* hash_number */
"black", /* background_color */
16 /* gradation */);
/* フォントの確保 */
x_display->font = XLoadFont(x_display->display, "8x16");
x_display->font_gc = XCreateGC(x_display->display,
x_display->lcd_window, 0, 0);
XSetFont(x_display->display, x_display->font_gc, x_display->font);
XSetFunction(x_display->display, x_display->font_gc, GXcopy);
XSetForeground(x_display->display, x_display->font_gc,
XDisplay_GetPixelFromColorName(x_display, "white"));
XSetBackground(x_display->display, x_display->font_gc,
XDisplay_GetPixelFromColorName(x_display, "black"));
XFillRectangle(x_display->display, x_display->lcd_window,
x_display->color_gc[0],
0, 0, x_display->width, x_display->height);
/* イベントハンドラの登録 */
XtAddEventHandler(x_display->toplevel, KeyPressMask | KeyReleaseMask,
False, KeyHandler, x_display);
XtAddEventHandler(x_display->toplevel, ExposureMask,
False, ExposeHandler, x_display);
XtAddEventHandler(x_display->toplevel, LeaveWindowMask | FocusChangeMask,
False, LeaveWindowHandler, x_display);
/* アイコンの設定 */
#if 0
XtVaSetValues(x_display->toplevel, XtNiconPixmap,
x_display->icon_pixmap, NULL);
XtVaSetValues(x_display->toplevel, XtNiconMask ,
x_display->icon_mask , NULL);
#endif
/* アクションの設定 */
XtAppAddActions(x_display->app_context, actions, XtNumber(actions));
/* トランスレーションの設定 */
XtOverrideTranslations(x_display->toplevel,
XtParseTranslationTable(translations));
/* ウィンドウマネージャからの f.delete への対応 */
wm_delete_window = XInternAtom(x_display->display,
"WM_DELETE_WINDOW", False);
XSetWMProtocols(x_display->display, x_display->lcd_window,
&wm_delete_window, 1);
/* Xサーバと同期をとる */
/* True だと,イベントキュー内のイベントを廃棄する */
XSync(x_display->display, True);
return (x_display);
}
/*---------------------------------------------------------------------------*/
/* オブジェクトの消去 */
/*---------------------------------------------------------------------------*/
XDisplay XDisplay_Destroy(XDisplay x_display)
{
int i;
if (x_display == NULL) return (NULL);
/* あとでリソースの解放を追加すること */
if (x_display->color_gc != NULL) {
for (i = 0; i < 16; i++) {
if (x_display->color_gc[i])
XFreeGC(x_display->display, x_display->color_gc[i]);
x_display->color_gc[i] = 0;
}
}
free(x_display);
return (NULL);
}
/*---------------------------------------------------------------------------*/
/* Xサーバとの同期 */
/*---------------------------------------------------------------------------*/
int XDisplay_Sync(XDisplay x_display)
{
XEvent event;
XFlush(x_display->display);
/* Xサーバと同期をとる */
/* False だと,イベントキュー内のイベントを廃棄しない */
XSync(x_display->display, False);
/* イベントの処理 */
while (XtAppPending(x_display->app_context)) {
XtAppNextEvent(x_display->app_context, &event);
XtDispatchEvent(&event);
}
return (0);
}
/*---------------------------------------------------------------------------*/
/* 描画 */
/*---------------------------------------------------------------------------*/
int XDisplay_DrawLCDWindow(XDisplay x_display, WWDisplay ww_display,
WWLCDPanel ww_lcd_panel)
{
int x, y;
int px, py, ph;
int num;
int n[16];
XRectangle rectangle;
XRectangle * rectangles[16];
unsigned short int pixel;
int ww_lcd_width, ww_lcd_height;
int red, green, blue;
XColorGCDatabase database;
XColorGC x_color_gc;
GC gc;
ww_lcd_width = WWLCDPanel_GetWidth( ww_lcd_panel);
ww_lcd_height = WWLCDPanel_GetHeight(ww_lcd_panel);
switch (WWDisplay_GetColorMode(ww_display)) {
case COLOR_MODE_GRAYSCALE:
/* 隣接しているピクセルはまとめて描画するので,ピクセル数の最大値は */
/* 最悪の場合(縞々模様のとき)でwidth * height / 2 になる. */
num =
WWLCDPanel_GetHeight(ww_lcd_panel) *
WWLCDPanel_GetWidth(ww_lcd_panel) / 2;
/*
* この malloc() は,実際にはメモリはほとんど使用されていないので,
* そのうちなんとかする必要がある
*/
for (pixel = 0; pixel < 16; pixel++) {
n[pixel] = 0;
rectangles[pixel] = (XRectangle *)malloc(sizeof(XRectangle) * num);
}
if (rectangles == NULL)
WonX_Error("XDisplay_DrawLCDWindow", "Cannot allocate memory.");
/* ここの処理はホットスポットになるので,のちのちにチューニングすること */
for (y = 0; y < ww_lcd_height; y++) {
py = (y * x_display->height) / ww_lcd_height;
ph = (y+1) * x_display->height / ww_lcd_height- py;
for (x = 0; x < ww_lcd_width; x++) {
if (!WWLCDPanel_IsPixelChanged(ww_lcd_panel, x, y)) {
continue;
}
pixel = WWLCDPanel_GetPixel(ww_lcd_panel, x, y);
px = (x * x_display->width ) / ww_lcd_width;
rectangles[pixel][n[pixel]].x = px;
rectangles[pixel][n[pixel]].y = py;
rectangles[pixel][n[pixel]].width =
(x+1) * x_display->width / ww_lcd_width - px;
rectangles[pixel][n[pixel]].height = ph;
/* 隣接してる同色のピクセルは,極力いっしょに描画する */
x++;
while ( (x < ww_lcd_width) &&
(pixel == WWLCDPanel_GetPixel(ww_lcd_panel, x, y)) &&
(WWLCDPanel_IsPixelChanged(ww_lcd_panel, x, y)) ) {
rectangles[pixel][n[pixel]].width =
(x+1) * x_display->width / ww_lcd_width - px;
x++;
}
x--;
n[pixel]++;
}
}
for (pixel = 0; pixel < 16; pixel++) {
if (n[pixel] > 0) {
XFillRectangles(x_display->display,
x_display->lcd_pixmap,
x_display->color_gc[pixel],
rectangles[pixel], n[pixel]);
}
}
for (pixel = 0; pixel < 16; pixel++) {
free(rectangles[pixel]);
}
break;
case COLOR_MODE_4COLOR:
case COLOR_MODE_16COLOR:
case COLOR_MODE_16PACKED:
database = XDisplay_GetColorGCDatabase(x_display);
for (y = 0; y < ww_lcd_height; y++) {
py = (y * x_display->height) / ww_lcd_height;
ph = (y+1) * x_display->height / ww_lcd_height- py;
for (x = 0; x < ww_lcd_width; x++) {
if (!WWLCDPanel_IsPixelChanged(ww_lcd_panel, x, y)) {
continue;
}
pixel = WWLCDPanel_GetPixel(ww_lcd_panel, x, y);
px = (x * x_display->width ) / ww_lcd_width;
rectangle.x = px;
rectangle.y = py;
rectangle.width = (x+1) * x_display->width / ww_lcd_width - px;
rectangle.height = ph;
/* 隣接してる同色のピクセルは,極力いっしょに描画する */
x++;
while ( (x < ww_lcd_width) &&
(pixel == WWLCDPanel_GetPixel(ww_lcd_panel, x, y)) &&
(WWLCDPanel_IsPixelChanged(ww_lcd_panel, x, y)) ) {
rectangle.width =
(x+1) * x_display->width / ww_lcd_width - px;
x++;
}
x--;
red = (pixel >> 8) & 0xf;
green = (pixel >> 4) & 0xf;
blue = (pixel >> 0) & 0xf;
red = (red == 15) ? 65535 : red * 4096;
green = (green == 15) ? 65535 : green * 4096;
blue = (blue == 15) ? 65535 : blue * 4096;
x_color_gc = XColorGC_CreateFromRGB(database, red, green, blue);
gc = XColorGC_GetGC(x_color_gc);
XFillRectangle(x_display->display,
x_display->lcd_pixmap,
gc,
rectangle.x,
rectangle.y,
rectangle.width,
rectangle.height);
XColorGC_Destroy(x_color_gc);
}
}
break;
default:
WonX_Error("XDisplay_DrawLCDWindow", "Unknown color mode.");
}
XCopyArea(x_display->display, x_display->lcd_pixmap,
x_display->lcd_window, x_display->copy_gc,
0, 0, x_display->width, x_display->height, 0, 0);
WWLCDPanel_ResetAllDraw(ww_lcd_panel);
WWLCDPanel_ReverseCurrent(ww_lcd_panel);
XDisplay_Sync(x_display);
return (0);
}
/*---------------------------------------------------------------------------*/
/* GC の作成 */
/*---------------------------------------------------------------------------*/
GC XDisplay_CreateGC(XDisplay x_display)
{
GC gc;
gc = XCreateGC(x_display->display, x_display->root_window, 0, 0);
return (gc);
}
/*---------------------------------------------------------------------------*/
/* GC の解放 */
/*---------------------------------------------------------------------------*/
int XDisplay_DestroyGC(XDisplay x_display, GC gc)
{
XFreeGC(x_display->display, gc);
return (0);
}
/*****************************************************************************/
/* ここまで */
/*****************************************************************************/
/*****************************************************************************/
/* End of File. */
/*****************************************************************************/