diff --git a/HISTORY b/HISTORY index a48d91f..9ac74d4 100644 --- a/HISTORY +++ b/HISTORY @@ -1,3 +1,14 @@ +2000/10/4(水) + +wonx-a06 公開 + +WWDisplay_DrawScreen() のアルゴリズムを大幅に修正. +たいして高速にならなかった.X サーバの描画がホットスポットになっていると +思われるので,描画量を減らす努力が必要. + + + + 2000/10/3(火) wonx-a05 公開 diff --git a/Makefile b/Makefile index bdd232c..dfdd62d 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,8 @@ XINCLUDEDIR = /usr/X11R6/include INCLUDEDIR = . XLIBDIR = /usr/X11R6/lib -VERSION = Wonx-a05 -PKGNAME = wonx-a05 +VERSION = Wonx-a06 +PKGNAME = wonx-a06 OBJS = WWCharacter.o WWColorMap.o WWDisplay.o WWLCDPanel.o WWPalette.o WWScreen.o WWSprite.o WonxDisplay.o XDisplay.o bank.o comm.o disp.o text.o key.o sound.o system.o timer.o etc.o wonx.o diff --git a/WWDisplay.c b/WWDisplay.c index 5791fc4..b552641 100644 --- a/WWDisplay.c +++ b/WWDisplay.c @@ -195,22 +195,14 @@ WWDisplay WWDisplay_Destroy(WWDisplay display) /* LCDパネルの描画 */ /*===========================================================================*/ -static int WWDisplay_DrawScreen(WWDisplay display, WWScreen screen) +static int WWDisplay_DrawScreen(WWDisplay display, WWScreen screen, + int lcd_x, int lcd_y) { - WWLCDPanel lcd_panel; - int lcd_panel_width; - int lcd_panel_height; - int pixel; - int x, y, px, py; + int px, py; int sx, sy, ex, ey; - int mode; - if (!WWScreen_GetEnable(screen)) return (0); - - lcd_panel = WWDisplay_GetLCDPanel(display); - lcd_panel_width = WWLCDPanel_GetWidth( lcd_panel); - lcd_panel_height = WWLCDPanel_GetHeight(lcd_panel); + if (!WWScreen_GetEnable(screen)) return (-1); if ( (WWScreen_GetMode(screen) == WWSCREEN_INSIDE_ONLY) || (WWScreen_GetMode(screen) == WWSCREEN_OUTSIDE_ONLY) ) { @@ -237,50 +229,35 @@ static int WWDisplay_DrawScreen(WWDisplay display, WWScreen screen) #endif } - mode = WWScreen_GetMode(screen); - - /* 以下はホットスポットになるので,そのうちループアンローリング */ - /* したほうがいいかも */ - - for (y = 0; y < lcd_panel_height; y++) { - - if (mode == WWSCREEN_INSIDE_ONLY) { - if (y > ey) { break; } - if (y < sy) { y = sy - 1; continue; } - } - - py = y + WWScreen_GetRollY(screen); - - for (x = 0; x < lcd_panel_width; x++) { - - if (mode == WWSCREEN_INSIDE_ONLY) { - if (x > ex) { x = lcd_panel_width - 1; continue; } - if (x < sx) { x = sx - 1; continue; } - } else if (mode == WWSCREEN_OUTSIDE_ONLY) { - if ( (x >= sx) && (x <= ex) && (y >= sy) && (y <= ey) ) { - x = ex; - continue; - } - } - - px = x + WWScreen_GetRollX(screen); - - pixel = WWScreen_GetPixel(screen, px, py); - - /* 透明色の場合 */ - if (pixel == -1) continue; - - pixel = WWColorMap_GetLCDColor(WWDisplay_GetColorMap(display), pixel); - WWLCDPanel_SetPixel(lcd_panel, x, y, pixel); - } + switch (WWScreen_GetMode(screen)) { + case WWSCREEN_INSIDE_ONLY: + if ( (lcd_x < sx) || (lcd_x > ex) || (lcd_y < sy) || (lcd_y > ey) ) + return (-1); + break; + case WWSCREEN_OUTSIDE_ONLY: + if ( !( (lcd_x < sx) || (lcd_x > ex) || (lcd_y < sy) || (lcd_y > ey) ) ) + return (-1); + break; } - return (0); + px = lcd_x + WWScreen_GetRollX(screen); + py = lcd_y + WWScreen_GetRollY(screen); + + pixel = WWScreen_GetPixel(screen, px, py); + + /* 透明色の場合 */ + if (pixel == -1) return (-1); + + pixel = WWColorMap_GetLCDColor(WWDisplay_GetColorMap(display), pixel); + WWLCDPanel_SetPixel(WWDisplay_GetLCDPanel(display), lcd_x, lcd_y, pixel); + + return (pixel); } -static int WWDisplay_DrawSprite(WWDisplay display, WWSprite sprite) +static int WWDisplay_DrawSprite(WWDisplay display, WWSprite sprite, + int lcd_x, int lcd_y) { - int x, y, lcd_x, lcd_y; + int x, y, sprite_x, sprite_y; int sx, sy, ex, ey; int pixel, outside; @@ -296,35 +273,38 @@ static int WWDisplay_DrawSprite(WWDisplay display, WWSprite sprite) ey = sy + WWDisplay_GetSpriteWindowHeight(display); #endif - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x++) { - pixel = WWSprite_GetPixel(sprite, x, y); + sprite_x = WWSprite_GetX(sprite); + sprite_y = WWSprite_GetY(sprite); - /* 透明色の場合 */ - if (pixel == -1) continue; + if ( (lcd_x < sprite_x) || (lcd_x > sprite_x + 7) || + (lcd_y < sprite_y) || (lcd_y > sprite_y + 7) ) + return (-1); - lcd_x = WWSprite_GetX(sprite) + x; - lcd_y = WWSprite_GetY(sprite) + y; + x = lcd_x - sprite_x; + y = lcd_y - sprite_y; - if (WWDisplay_GetSpriteWindowEnable(display)) { - if ( (lcd_x < sx) || (lcd_y < sy) || (lcd_x > ex) || (lcd_y > ey) ) - outside = 1; - else - outside = 0; + pixel = WWSprite_GetPixel(sprite, x, y); - if (WWSprite_GetClipping(sprite)) { /* ウインドウの外側部分を表示 */ - if (!outside) continue; - } else { /* ウインドウの内側部分を表示 */ - if (outside) continue; - } - } + /* 透明色の場合 */ + if (pixel == -1) return (-1); - pixel = WWColorMap_GetLCDColor(WWDisplay_GetColorMap(display), pixel); - WWLCDPanel_SetPixel(WWDisplay_GetLCDPanel(display), lcd_x, lcd_y, pixel); + if (WWDisplay_GetSpriteWindowEnable(display)) { + if ( (lcd_x < sx) || (lcd_y < sy) || (lcd_x > ex) || (lcd_y > ey) ) + outside = 1; + else + outside = 0; + + if (WWSprite_GetClipping(sprite)) { /* ウインドウの外側部分を表示 */ + if (!outside) return (-1); + } else { /* ウインドウの内側部分を表示 */ + if (outside) return (-1); } } - return (0); + pixel = WWColorMap_GetLCDColor(WWDisplay_GetColorMap(display), pixel); + WWLCDPanel_SetPixel(WWDisplay_GetLCDPanel(display), lcd_x, lcd_y, pixel); + + return (pixel); } int WWDisplay_DrawLCDPanel(WWDisplay display) @@ -337,6 +317,7 @@ int WWDisplay_DrawLCDPanel(WWDisplay display) WWColorMap color_map; int border; WWSprite sprite; + int ret; lcd_panel = WWDisplay_GetLCDPanel(display); lcd_panel_width = WWLCDPanel_GetWidth( lcd_panel); @@ -344,44 +325,55 @@ int WWDisplay_DrawLCDPanel(WWDisplay display) color_map = WWDisplay_GetColorMap(display); border = WWDisplay_GetBorder(display); - /* ボーダーカラーで埋める */ for (x = 0; x < lcd_panel_width; x++) { for (y = 0; y < lcd_panel_height; y++) { + + /* スクリーン2より優先のスプライトの描画 */ + /* 重なった場合は,番号の若いものが手前に表示される */ + ret = -1; + if (WWDisplay_GetSpriteEnable(display)) { + for (i = 0; i < WWDisplay_GetSpriteCount(display); i++) { + sprite = WWDisplay_GetSprite(display, + i + WWDisplay_GetSpriteStart(display)); + if (WWSprite_GetPriority(sprite)) { + ret = WWDisplay_DrawSprite(display, sprite, x, y); + if (ret != -1) break; + } + } + } + if (ret != -1) continue; + + /* スクリーン2の描画 */ + ret = WWDisplay_DrawScreen(display, WWDisplay_GetScreen(display, 1), + x, y); + if (ret != -1) continue; + + /* スクリーン2より優先でないスプライトの描画 */ + /* 重なった場合は,番号の若いものが手前に表示される */ + ret = -1; + if (WWDisplay_GetSpriteEnable(display)) { + for (i = 0; i < WWDisplay_GetSpriteCount(display); i++) { + sprite = WWDisplay_GetSprite(display, + i + WWDisplay_GetSpriteStart(display)); + if (!WWSprite_GetPriority(sprite)) { + ret = WWDisplay_DrawSprite(display, sprite, x, y); + if (ret != -1) break; + } + } + } + if (ret != -1) continue; + + /* スクリーン1の描画 */ + ret = WWDisplay_DrawScreen(display, WWDisplay_GetScreen(display, 0), + x, y); + if (ret != -1) continue; + + /* ボーダーカラーの描画 */ WWLCDPanel_SetPixel(lcd_panel, x, y, WWColorMap_GetLCDColor(color_map, border)); } } - /* スクリーン1描画 */ - WWDisplay_DrawScreen(display, WWDisplay_GetScreen(display, 0)); - - /* スプライト描画(スクリーン2より優先でないもの) */ - /* 重なった場合は,番号の若いものが手前に表示される */ - if (WWDisplay_GetSpriteEnable(display)) { - for (i = WWDisplay_GetSpriteCount(display) - 1; i >= 0; i--) { - sprite = WWDisplay_GetSprite(display, - i + WWDisplay_GetSpriteStart(display)); - if (!WWSprite_GetPriority(sprite)) { - WWDisplay_DrawSprite(display, sprite); - } - } - } - - /* スクリーン2描画 */ - WWDisplay_DrawScreen(display, WWDisplay_GetScreen(display, 1)); - - /* スプライト描画(スクリーン2より優先なもの) */ - /* 重なった場合は,番号の若いものが手前に表示される */ - if (WWDisplay_GetSpriteEnable(display)) { - for (i = WWDisplay_GetSpriteCount(display) - 1; i >= 0; i--) { - sprite = WWDisplay_GetSprite(display, - i + WWDisplay_GetSpriteStart(display)); - if (WWSprite_GetPriority(sprite)) { - WWDisplay_DrawSprite(display, sprite); - } - } - } - return (0); }