import com.nttdocomo.ui.Canvas;
import com.nttdocomo.ui.Dialog;
import com.nttdocomo.ui.Display;
import com.nttdocomo.ui.Font;
import com.nttdocomo.ui.Graphics;
import com.nttdocomo.ui.IApplication;
import com.nttdocomo.ui.Image;
import com.nttdocomo.ui.MediaImage;
import com.nttdocomo.ui.MediaManager;
import com.nttdocomo.ui.PhoneSystem;
/**
* @author mieki256 レジューム処理のテスト用アプリ
*/
public class ResumeTest extends IApplication {
Main l_main = new Main();
public void start() {
Display.setCurrent(l_main);
l_main.exec();
}
public void resume() {
// 実処理クラスが復帰して、リジューム用処理が呼び出せるようになるまで繰り返す
while (l_main == null) {
Thread.yield();
}
l_main.resumeJobEnable = true;
l_main.mcResume();
}
}
/**
* 実処理
*
*/
final class Main extends Canvas {
/**
* リジューム処理実行中フラグ
*/
public boolean resumeJobEnable;
/**
* ProcessEvent実行中フラグ
*/
boolean processEventJobEnable;
/**
* FPS。1秒間に何回画面を書き換えるか
*/
static final int FPS = 25;
/**
* 1ループのwait時間。FPSから算出。
*/
static final int SLEEP_VALUE = 1000 / FPS;
/**
* アプリ画面横幅
*/
static final int SCREEN_W = 240;
/**
* アプリ画面縦幅
*/
static final int SCREEN_H = 240;
/**
* リピートボタン情報
*/
private int c_repbtn;
/**
* トリガボタン情報
*/
private int trgBtn;
/**
* 割り込みにより記録されたボタン情報
*/
private int keyBtnInterrupt;
/**
* 一意の値(同時押しを無効)にしたトリガボタン情報
*/
private int trgBtnUniq;
/**
* キー情報取得をしない状態を指定するための時間カウンタ
*/
private int keyNoCheckEnableCount;
/**
* キートリガチェック時の待ちフレーム数。
*
* 各シーンの切り替わり時などで、念のために、多少なりともwaitを入れてからトリガをチェックしている。
*
*/
static final int KEY_CHK_WAITFRAME = 4;
// キーのビット情報
static final int KB_UP = (1 << Display.KEY_UP) | (1 << Display.KEY_2);
static final int KB_DOWN = (1 << Display.KEY_DOWN) | (1 << Display.KEY_8);
static final int KB_LEFT = (1 << Display.KEY_LEFT) | (1 << Display.KEY_4);
static final int KB_RIGHT = (1 << Display.KEY_RIGHT) | (1 << Display.KEY_6);
static final int KB_SELECT = (1 << Display.KEY_SELECT) | (1 << Display.KEY_5);
static final int KB_SOFT1 = (1 << Display.KEY_SOFT1);
static final int KB_SOFT2 = (1 << Display.KEY_SOFT2);
/**
* 画面描画に使う Graphics オブジェクト
*/
private Graphics g = getGraphics();
private interface IG {
public int NUMBERIMG = 0;
public int STATUS = 1;
public int ICON = 2;
public int BTNMARK = 3;
/**
* 画像ファイル総数
*/
public int IMAGE_MAX = 4;
}
/**
* 画像イメージ格納用
*/
private Image[] img = new Image[IG.IMAGE_MAX];
/**
* 画面描画に使う Font オブジェクト(システムフォント)
*/
private Font m_font;
/**
* システムフォント描画位置調整用(単位はドット)
*/
private int stringH;
/**
* システムフォント文字サイズ(単位はドット)
*/
private int fontSize;
/**
* メインループ用記録カウンタ:ループ処理開始時間
*/
private long mainLoopStartTime;
/**
* メインループ記録カウンタ:待ち時間
*/
private int mainLoopWaitTime;
/**
* フレームカウンタ
*/
private int frameCounter = 0;
/**
* リジューム時に待つ時間
*/
static final int RESUME_WAIT_TIME = FPS;
/**
* リジューム時の処理キャンセルタイマー
*/
private int resumeWaitTimer;
/**
* メインステップ変数
*/
private int mainStep;
/**
* シーンカウンタ変数
*/
private int sceneStep;
// ----------------------------------------
/**
* キー入力用ワークを全消去
*/
private void clearAllKeyWork() {
clearKeyWork();
keyNoCheckEnableCount = FPS / 4;
}
/**
* キー入力用ワークを消去(キー入力キャンセルタイマーはセットしない)
*/
private void clearKeyWork() {
c_repbtn = 0;
keyBtnInterrupt = 0;
trgBtn = 0;
trgBtnUniq = 0;
}
/**
* キー入力用ワークの内容を設定
*/
private void setKeyWork(int key) {
int oldkey = c_repbtn;
key |= keyBtnInterrupt;
keyBtnInterrupt = 0;
c_repbtn = key;
trgBtn = (oldkey ^ c_repbtn) & c_repbtn;
trgBtnUniq = getKeyUniqBit(trgBtn);
}
/**
* リジューム関係のwaitカウンタを初期化
*/
public void initResumeWaitWork() {
clearKeyWork();
keyNoCheckEnableCount = RESUME_WAIT_TIME;
resumeWaitTimer = RESUME_WAIT_TIME;
}
/**
* リジューム処理。
*
* - キーワークをクリアする。
* - サウンドを再開再生する。
*
*/
public void mcResume() {
resumeJobEnable = true;
saveProcessHistory(ProcessKind.RESUME);
initResumeWaitWork();
// 本来ここにサウンド再開処理
// ログ描画
drawLogInterrupt();
// キー入力がなくなるまで待つ
do {
try {
Thread.sleep(SLEEP_VALUE);
} catch (InterruptedException e) {
}
setKeyWork(getKeypadState());
} while (c_repbtn != 0 || trgBtn != 0);
resumeJobEnable = false;
}
// イベント通知処理
public void processEvent(int a_type, int a_param) {
if (processEventJobEnable) return;
processEventJobEnable = true;
if (a_type == Display.RESUME_VM_EVENT) {
// リジューム時はワークをクリア
saveProcessHistory(ProcessKind.EVENT);
initResumeWaitWork();
}
if (a_type == Display.KEY_PRESSED_EVENT) {
// キーが押された
if (keyNoCheckEnableCount <= 0) keyBtnInterrupt |= (0x01 << a_param);
}
processEventJobEnable = false;
}
// ----------------------------------------
/**
* コンストラクタ
*/
public Main() {
resumeJobEnable = true;
// 念のためにキーワークだけでもクリアしておく
clearAllKeyWork();
keyNoCheckEnableCount = RESUME_WAIT_TIME;
}
// ----------------------------------------
/**
* メイン処理担当
*/
public void exec() {
// ----------------------------------------
// ワーク初期化
resumeJobEnable = true;
processEventJobEnable = false;
System.gc();
// バックライトON
PhoneSystem.setAttribute(PhoneSystem.DEV_BACKLIGHT, PhoneSystem.ATTR_BACKLIGHT_ON);
g = getGraphics(); // グラフィック生成
// 画面全体クリア
g.lock();
g.setClip(0, 0, SCREEN_W, SCREEN_H);
g.setColor(Graphics.getColorOfName(Graphics.WHITE));
g.fillRect(0, 0, SCREEN_W, SCREEN_H);
g.unlock(true);
// フォント設定
m_font = Font.getFont(Font.SIZE_TINY); // フォントをTINYにする
g.setFont(m_font); // フォントを設定
stringH = m_font.getAscent() - m_font.getHeight();
fontSize = m_font.getHeight();
// ボタン情報初期化
clearAllKeyWork();
keyNoCheckEnableCount = FPS / 2;
System.gc();
loadImage();
System.gc();
// カウンター初期化
mainLoopWaitTime = SLEEP_VALUE; // フレーム間隔
resumeWaitTimer = 0;
frameCounter = 0;
sceneStep = 0;
mainStep = 0;
initLogWork();
resumeJobEnable = false;
// ----------------------------------------
// メインループ
while (true) {
saveProcessHistory(ProcessKind.LOOPSTART);
mainLoopStartTime = System.currentTimeMillis();
if (resumeJobEnable) {
// リジューム中なら待つ
try {
Thread.sleep(SLEEP_VALUE);
} catch (InterruptedException e) {
}
continue;
}
// キーワーク設定
if (keyNoCheckEnableCount > 0 || resumeJobEnable) {
// キー情報を取得しない処理
int key = getKeypadState();
key |= keyBtnInterrupt;
clearKeyWork();
if (!resumeJobEnable) {
if (key == 0) keyNoCheckEnableCount--;
}
} else {
// キー情報取得処理
saveProcessHistory(ProcessKind.KEYSET);
setKeyWork(getKeypadState());
}
try {
if (!resumeJobEnable) {
// リジューム処理終了待ちではないので、メイン処理を実行
if (resumeWaitTimer > 0) {
// リジューム直後なので待つ
resumeWaitTimer--;
} else {
// メイン処理
saveProcessHistory(ProcessKind.MAIN);
switch (mainStep) {
case 0:
// 起動時の入力待ち
// 描画
saveProcessHistory(ProcessKind.DRAWSTART);
g.lock();
g.setColor(Graphics.getColorOfName(Graphics.WHITE));
g.fillRect(0, 0, SCREEN_W, SCREEN_H);
g.setColor(Graphics.getColorOfName(Graphics.BLACK));
printCenter("START [OK]", SCREEN_H / 2);
g.unlock(true);
saveProcessHistory(ProcessKind.KEYCHECK);
if (trgBtnUniq == KB_SELECT) {
mainStep++;
}
break;
case 1:
setSoftKeyText("休止", "終了");
setLogSaveEnable();
mainStep++;
break;
case 2:
// 処理経過を描画
{
saveProcessHistory(ProcessKind.KEYCHECK);
if (trgBtnUniq == KB_SOFT1) {
// 一時停止
mainStep++;
}
if (trgBtnUniq == KB_SOFT2) {
// アプリ終了
IApplication.getCurrentApp().terminate();
}
if (trgBtnUniq == KB_SELECT) {
sceneStep++;
}
// 描画
{
saveProcessHistory(ProcessKind.DRAWSTART);
g.lock();
g.setColor(Graphics.getColorOfName(Graphics.WHITE));
g.fillRect(0, 0, SCREEN_W, SCREEN_H);
int x, y;
// アイコン描画
x = SCREEN_W - 10;
y = SCREEN_H - 10;
int idx = frameCounter % 5;
drawIcon(g, x, y, idx);
// ログを描画
drawLog(g);
g.unlock(true);
}
}
break;
case 3:
setSoftKeyText("再開", "");
saveProcessHistory(ProcessKind.PAUSESTART);
setLogSaveDisable();
mainStep++;
case 4:
{
// 描画
{
saveProcessHistory(ProcessKind.DRAWSTART);
g.lock();
g.setColor(Graphics.getColorOfName(Graphics.WHITE));
g.fillRect(0, 0, SCREEN_W, SCREEN_H);
// ログを描画
drawLogHistory(g);
g.unlock(true);
}
saveProcessHistory(ProcessKind.KEYCHECK);
if ((c_repbtn & (1 << Display.KEY_UP)) != 0) {
decrementLogReadPointer();
}
if ((c_repbtn & (1 << Display.KEY_DOWN)) != 0) {
incrementLogReadPointer();
}
if (trgBtnUniq == KB_SOFT1) {
setSoftKeyText("休止", "終了");
setLogSaveEnable();
saveProcessHistory(ProcessKind.PAUSEEND);
mainStep -= 2;
}
}
break;
}
}
}
// キューに溜まったサウンド再生・停止要求をこなす
if (!resumeJobEnable) {
// 本来ここでサウンド再生 or 停止処理
}
saveProcessHistory(ProcessKind.MAIN_END);
if (!resumeJobEnable) {
// リジューム中ではない
// バックライト操作
if ((frameCounter % (3 * FPS)) == 0) {
PhoneSystem.setAttribute(PhoneSystem.DEV_BACKLIGHT, PhoneSystem.ATTR_BACKLIGHT_ON);
}
}
if (resumeJobEnable) mainLoopStartTime = System.currentTimeMillis();
System.gc();
while (System.currentTimeMillis() < mainLoopStartTime + mainLoopWaitTime)
Thread.yield();
frameCounter++;
} catch (Exception e) {
String s = "情報:" + e + "\nmStep=" + mainStep;
displayDialogMessage("エラー発生", s);
IApplication.getCurrentApp().terminate();
}
saveProcessHistory(ProcessKind.LOOPEND);
}
}
// 画面描画
public void paint(Graphics g) {
}
/**
* ダイアログメッセージを表示する
*
* @param titleStr
* ダイアログタイトル文字列
* @param message
* ダイアログメッセージ文字列
*/
private void displayDialogMessage(String titleStr, String message) {
Dialog d = new Dialog(Dialog.DIALOG_ERROR, titleStr);
d.setText(message);
d.show();
}
/**
* キーの同時入力を避けるために一意の値にする
*
* @param keystatus
* キー情報
* @return 一意にしたキー情報
*/
int getKeyUniqBit(int keystatus) {
int key = 0;
if ((keystatus & KB_UP) != 0) {
key = KB_UP;
} else if ((keystatus & KB_DOWN) != 0) {
key = KB_DOWN;
} else if ((keystatus & KB_LEFT) != 0) {
key = KB_LEFT;
} else if ((keystatus & KB_RIGHT) != 0) {
key = KB_RIGHT;
} else if ((keystatus & KB_SELECT) != 0) {
key = KB_SELECT;
} else if ((keystatus & KB_SOFT1) != 0) {
key = KB_SOFT1;
} else if ((keystatus & KB_SOFT2) != 0) {
key = KB_SOFT2;
}
return key;
}
/**
* 割り込み時のログ描画
*/
void drawLogInterrupt() {
g.lock();
g.setColor(Graphics.getColorOfRGB(255, 227, 227));
g.fillRect(0, 0, SCREEN_W, SCREEN_H);
// ログを描画
drawLog(g);
g.unlock(true);
}
// ----------------------------------------
// 以降文字列描画系
/**
* ベースライン調整を考慮した座標で文字列描画する
*
* @param s
* 文字列
* @param x
* 描画位置 x
* @param y
* 描画位置 y
*/
public void _drawString(String s, int x, int y) {
g.drawString(s, x, y + fontSize + stringH);
}
/**
* 文字列をセンタリング描画する。
*
* @param str
* 文字列
* @param y
* 描画位置 y
* @return 描画開始位置 x
*/
int printCenter(String str, int y) {
int x = (SCREEN_W - m_font.stringWidth(str)) / 2;
g.drawString(str, x, y + fontSize + stringH);
return x;
}
/**
* 影つき文字列をセンタリング描画する。
*
* - fgcolor、shadowcolor には、Graphics.getColorOfName() か Graphics.getColorOfRGB() で値を渡す
*
*
* @param str
* 文字列
* @param y
* 描画位置 y
* @param fgcolor
* 前景色
* @param shadowcolor
* 背景色
*/
void printCenterWithShadow(String str, int y, int fgcolor, int shadowcolor) {
int x = (SCREEN_W - m_font.stringWidth(str)) / 2;
printWithShadow(str, x, y, fgcolor, shadowcolor);
}
/**
* 影つき文字列を xy座標を指定して描画する。
*
* - fgcolor、bgcolor には、Graphics.getColorOfName() か Graphics.getColorOfRGB() で値を渡す
*
*
* @param str
* 文字列
* @param x
* 描画位置 x
* @param y
* 描画位置 y
* @param fgcolor
* 前景色
* @param shadowcolor
* 影色
*/
void printWithShadow(String str, int x, int y, int fgcolor, int shadowcolor) {
y += fontSize + stringH;
g.setColor(shadowcolor);
g.drawString(str, x + 1, y + 1);
g.setColor(fgcolor);
g.drawString(str, x, y);
}
/**
* 画像に基づく文字列表示メソッド処理指定用・ゼロの桁表示有効
*/
static final boolean ZERO_DISP_ENABLE = true;
/**
* 画像に基づく文字列表示メソッド処理指定用・ゼロの桁表示無効
*/
static final boolean ZERO_DISP_DISABLE = false;
/**
* 画像に基づく文字列表示メソッド処理指定用・数字の左詰め表示
*/
static final boolean ALIGN_LEFT = true;
/**
* 画像に基づく文字列表示メソッド処理指定用・数字の右詰め表示
*/
static final boolean ALIGN_RIGHT = false;
/**
* 画像に基づく文字列表示メソッド処理指定用・描画有効
*/
static final boolean DRAW_ENABLE = true;
/**
* 画像に基づく文字列表示メソッド処理指定用・描画をせずに横幅だけを取得する
*/
static final boolean DRAW_DISABLE = false;
/**
* フォント種類
*/
private interface FontKind {
/**
* 数字(小サイズ)
*/
public int MICRO = 0;
}
/**
* フォント種類に割り当てる、画像ナンバー、横幅、縦幅、スペーシングを列挙したテーブル
*/
static final short[] ASCII_WH = {
// Img_No, W, H, spacing
IG.NUMBERIMG, 4, 6, 0, // 小
};
static final int ASCII_WH_OFFSET = 4;
/**
* 数値を描画
*
* @param g
* Graphics クラス
* @param num
* 表示したい数値
* @param keta
* 桁
* @param x
* 表示位置 x
* @param y
* 表示位置 y
* @param zerodisp
* ZERO_DISP_ENABLE = ゼロで埋める / ZERO_DISP_DISABLE = ゼロで埋めない
* @param alignleft
* ALIGN_LEFT = 左詰 / ALIGN_RIGHT = 右詰
* @param drawEnable
* DRAW_ENABLE = 描画する / DRAW_DISABLE = 描画しない(横幅のみ取得)
* @param kind
* フォント種類 (FontKind を参照)
* @return 描画されるであろう横幅
*/
int drawNumberXSmall(Graphics g, long num, int keta, int x, int y, boolean zerodisp, boolean alignleft, boolean drawEnable, int kind) {
int string_w = 0; // 描画横幅記録用
int wadd = 0;
int n = kind * ASCII_WH_OFFSET;
int ign = ASCII_WH[n++]; // 画像ナンバー
int sw = ASCII_WH[n++]; // 1文字の横幅
int sh = ASCII_WH[n++]; // 1文字の縦幅
int xadd = ASCII_WH[n++]; // 1文字描くごとに補正する値
// 桁単位で計算するための値の初期値を求める
int a = 1;
int k = 1;
while (k < keta) {
a *= 10;
k++;
}
int w = sw;
w += wadd;
// 桁の数だけループ
for (int i = keta; i > 0; i--, a /= 10) {
long nokori = num % a;
// m に、その桁の値を取り出す
long m = num;
if (m != 0) {
m /= a;
}
if (zerodisp || (int) m != 0 || i == 1) {
// 以下の条件のどれかに合致した場合、処理をする。
// ・ゼロ表示が有効
// ・その桁が 0 ではない
// ・最後の桁
if (drawEnable) {
int sx = (int) (m * sw);
g.drawImage(img[ign], x, y, sx, 0, sw, sh);
}
if (((int) m != 0 && !zerodisp) || i == 1) {
// 以下の条件のどれかに合致した場合、それ以降はゼロ表示を有効にする。
// ・その桁が0ではなく、かつ、ゼロ表示が無効
// ・最後の桁
zerodisp = true;
}
}
if (zerodisp || !alignleft) {
x += (sw + xadd);
string_w += (sw + xadd);
}
num = nokori;
}
return string_w;
}
/**
* フォントの横幅を得る
*
* @param kind
* フォント種類。FontKind を参照のこと。
* @return 横幅ドット数
*/
int getFontW(int kind) {
return ASCII_WH[(kind * ASCII_WH_OFFSET) + 1];
}
/**
* フォントの縦幅を得る
*
* @param kind
* フォント種類。FontKind を参照のこと。
* @return 縦幅ドット数
*/
int getFontH(int kind) {
return ASCII_WH[(kind * ASCII_WH_OFFSET) + 2];
}
/**
* 画像読み込み(res/から)
*/
private void loadImage() {
for (int i = 0; i < IG.IMAGE_MAX; i++) {
String fn = Integer.toString(i) + ".gif";
MediaImage tempImg = MediaManager.getImage("resource:///" + fn);
try {
tempImg.use();
} catch (Exception e) {
}
img[i] = tempImg.getImage();
}
}
/**
* ステータス画像の縦幅
*/
private final static int STATUS_IMG_H = 6;
/**
* ステータス画像を描画
*
* @param g
* Graphics
* @param x
* 描画位置 x
* @param y
* 描画位置 y
* @param kind
* ステータス画像種類
* @return 描画した幅
*/
private int drawStatus(Graphics g, int x, int y, int kind) {
int imgLen = ProcessKind.LENGTH;
int ign = IG.STATUS;
int w = img[ign].getWidth();
int h = img[ign].getHeight();
h /= imgLen;
int sy = h * kind;
if (kind == ProcessKind.SCENE) {
w = 16;
}
if (kind == ProcessKind.STEP) {
w = 14;
}
g.drawImage(img[ign], x, y, 0, sy, w, h);
return w;
}
/**
* アイコン画像を描画
*
* @param g
* Graphics
* @param x
* 描画位置 x
* @param y
* 描画位置 y
* @param indexNumber
* パターンナンバー
*/
private void drawIcon(Graphics g, int x, int y, int indexNumber) {
final int imgLen = 5;
if (indexNumber >= imgLen) return;
int ign = IG.ICON;
int w = img[ign].getWidth();
int h = img[ign].getHeight();
w /= imgLen;
int sx = w * indexNumber;
g.drawImage(img[ign], x, y, sx, 0, w, h);
}
/**
* ビットパターンを画像で描画
*
* @param g
* Graphics
* @param x
* 描画位置 x
* @param y
* 描画位置 y
* @param bitPattern
* 描画したい値(32bit)
*/
private int drawBitPattern(Graphics g, int x, int y, int bitPattern) {
int ign = IG.BTNMARK;
int w = img[ign].getWidth();
int h = img[ign].getHeight();
w /= 2;
int dx = x + (w * (32 - 1));
int allw = 0;
for (int i = 0; i < 32; i++) {
int fg = bitPattern & 0x01;
int sx = w * fg;
g.drawImage(img[ign], dx, y, sx, 0, w, h);
dx -= w;
bitPattern >>= 1;
allw += w;
}
return allw;
}
/**
* ソフトキーのラベルを設定する
*
* @param labelStrLeft
* ソフトキー1ラベル
* @param labelStrRight
* ソフトキー2ラベル
*/
private void setSoftKeyText(String labelStrLeft, String labelStrRight) {
String l1;
String l2;
l1 = labelStrLeft;
if (l1 == null) l1 = "";
l2 = labelStrRight;
if (l2 == null) l2 = "";
setSoftLabel(SOFT_KEY_1, l1);
setSoftLabel(SOFT_KEY_2, l2);
}
/**
* ログを取る際の処理種類
*/
public interface ProcessKind {
public int LOOPSTART = 0;
public int LOOPEND = 1;
public int KEYSET = 2;
public int MAIN = 3;
public int MAIN_END = 4;
public int RESUME = 5;
public int EVENT = 6;
public int SCENE = 7;
public int PAUSESTART = 8;
public int PAUSEEND = 9;
public int KEYCHECK = 10;
public int DRAWSTART = 11;
public int STEP = 12;
public int LENGTH = 13;
}
/**
* ログワーク最大数
*/
private static final int LOG_MAX = 8192;
/**
* 処理種類ログワーク
*/
private int[] logStatus = new int[LOG_MAX];
/**
* キー情報ログワーク
*/
private int[] logBitPattern = new int[LOG_MAX];
/**
* シーンカウンタログワーク
*/
private int[] logScene = new int[LOG_MAX];
/**
* フレームカウンタログワーク
*/
private int[] logFrameCounter = new int[LOG_MAX];
/**
* ログワーク書き込み用ポインタ
*/
private int logWritePointer;
/**
* ログワーク読み込み用ポインタ
*/
private int logReadPointer;
/**
* ログを取るかどうかのフラグ
*/
private boolean logSaveEnable;
/**
* 1画面あたりに表示するログの行数
*/
private static final int LOG_LINE_PER_PAGE = SCREEN_H / STATUS_IMG_H;
/**
* ログワーク初期化
*/
private void initLogWork() {
for (int i = 0; i < LOG_MAX; i++) {
logStatus[i] = -1;
logBitPattern[i] = 0;
}
logWritePointer = 0;
logReadPointer = 0;
setLogSaveDisable();
}
/**
* ログ記録を有効化
*/
private void setLogSaveEnable() {
logSaveEnable = true;
}
/**
* ログ記録を無効化
*/
private void setLogSaveDisable() {
logSaveEnable = false;
}
/**
* ログを記録
*
* @param kind
* 記録する処理種類
*/
public void saveProcessHistory(int kind) {
if (!logSaveEnable) return;
logStatus[logWritePointer] = kind;
logBitPattern[logWritePointer] = trgBtnUniq;
logScene[logWritePointer] = (mainStep * 1000) + (sceneStep % 1000);
logFrameCounter[logWritePointer] = frameCounter;
logWritePointer++;
if (logWritePointer >= LOG_MAX) logWritePointer = 0;
}
/**
* ログを画面に描画
*
* @param g
* Graphics
*/
private void drawLog(Graphics g) {
int dx = 0;
int dy = SCREEN_H - STATUS_IMG_H;
int idx = logWritePointer;
for (int i = 0; i < LOG_LINE_PER_PAGE; i++) {
idx--;
if (idx < 0) idx += LOG_MAX;
int status = logStatus[idx];
int bitpat = logBitPattern[idx];
int scene = logScene[idx];
int fcount = logFrameCounter[idx];
if (status >= 0) {
drawLogOneLine(g, dx, dy, status, bitpat, scene, fcount);
dx = 0;
dy -= STATUS_IMG_H;
}
}
logReadPointer = idx;
}
/**
* ログを画面に描画(履歴表示時)
*
* @param g
* Graphics
*/
private void drawLogHistory(Graphics g) {
int dx = 0;
int dy = 0;
int idx = logReadPointer;
for (int i = 0; i < LOG_LINE_PER_PAGE; i++) {
int status = logStatus[idx];
int bitpat = logBitPattern[idx];
int scene = logScene[idx];
int fcount = logFrameCounter[idx];
if (status >= 0) {
drawLogOneLine(g, dx, dy, status, bitpat, scene, fcount);
}
dx = 0;
dy += STATUS_IMG_H;
idx++;
if (idx >= LOG_MAX) idx = 0;
}
}
/**
* ログ読み込みポインタを+1する
*/
private void incrementLogReadPointer() {
int checkIdx = logWritePointer - LOG_LINE_PER_PAGE + 1;
if (checkIdx < 0) checkIdx += LOG_MAX;
int idx = logReadPointer;
idx++;
if (idx >= LOG_MAX) idx = 0;
if (idx != checkIdx) {
logReadPointer = idx;
// System.out.println("WP="+logWritePointer+" RP="+logReadPointer);
}
}
/**
* ログ読み込みポインタを-1する
*/
private void decrementLogReadPointer() {
int checkIdx = logWritePointer - 1;
if (checkIdx < 0) checkIdx += LOG_MAX;
int idx = logReadPointer;
idx--;
if (idx < 0) idx += LOG_MAX;
if (idx != checkIdx) {
logReadPointer = idx;
// System.out.println("WP="+logWritePointer+" RP="+logReadPointer);
}
}
/**
* ログ一行分を画面に描画
*
* @param g
* Graphics
* @param x
* 描画位置 x
* @param y
* 描画位置 y
* @param status
* 描画する処理種類
* @param bitpat
* 描画するビットパターン値
* @param scene
* 描画するシーンカウンタ値
* @param fcount
* 描画するカウンタ値
*/
private void drawLogOneLine(Graphics g, int x, int y, int status, int bitpat, int scene, int fcount) {
int cnt_a = (scene != 0) ? (scene / 1000) : 0;
int cnt_b = (scene % 1000);
int w;
w = drawNumberXSmall(g, fcount, 8, x, y, ZERO_DISP_ENABLE, ALIGN_LEFT, DRAW_ENABLE, FontKind.MICRO);
x += w;
x += 2;
w = drawStatus(g, x, y, status);
x += w;
x += 2;
w = drawStatus(g, x, y, ProcessKind.SCENE);
x += w;
w = drawNumberXSmall(g, cnt_b, 3, x, y, ZERO_DISP_ENABLE, ALIGN_LEFT, DRAW_ENABLE, FontKind.MICRO);
x += w;
x += 2;
w = drawBitPattern(g, x, y, bitpat);
x += w;
w = drawStatus(g, x, y, ProcessKind.STEP);
x += w;
w = drawNumberXSmall(g, cnt_a, 1, x, y, ZERO_DISP_ENABLE, ALIGN_LEFT, DRAW_ENABLE, FontKind.MICRO);
x += w;
x += 2;
x = 0;
y -= STATUS_IMG_H;
}
}