PC6001V for IS01 その7

osdSDL.cpp(1/2)

#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <SDL.h>
#include <SDL_syswm.h>
#include <SDL_endian.h>

#include "../log.h"
#include "../osd.h"
#include "../common.h"
#include "../vsurface.h"
#include "../p6el.h"

#include <android/log.h>
#include <jni.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <android/log.h>

bool gFlip=false;
extern "C" void Android_JNI_SwapWindow();
////////////////////////////////////////////////////////////////
// キャプション設定
//
// 引数:    wh            ウィンドウハンドル
//            str            キャプション文字列へのポインタ
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_SetWindowCaption( HWINDOW wh, const char *str )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_SetWindowCaption]");
    Android_JNI_SwapWindow();
    gFlip=false;
///    #if SDL_VERSION_ATLEAST(2,0,0)
///    if( wh && str ) SDL_SetWindowTitle( (SDL_Window*)wh, str );
///    #else
///    if( str ) SDL_WM_SetCaption( str, "" );
///    #endif
}

GLuint textures;
unsigned char gBuffer[512][512][2];
///static GLfloat vertices[] = {
///        -1.0f, -1.0f, 0.0f,
///        1.0f, -1.0f, 0.0f,
///        -1.0f, 1.0f, 0.0f,
///        1.0f,  1.0f, 0.0f};
///
///static GLfloat texcoord[] = {
///         0.0f, 1.0f,
///         1.0f, 1.0f,
///         0.0f, 0.0f,
///         1.0f, 0.0f,
///};

extern "C" jint Java_org_libsdl_app_SDLActivity_NativeRender
  (JNIEnv * env, jclass cls)
{
	static int initialized = 0;
	if ( initialized == 0 ) {
		__android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][Java_org_libsdl_app_SDLActivity_NativeRender]");
		memset(gBuffer, 0, 512*512*2);
	    glMatrixMode( GL_PROJECTION );
		glLoadIdentity();
		glGenTextures( 1, &textures );
		glBindTexture( GL_TEXTURE_2D, textures );
		glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
		glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	    initialized = 1;
	}
///    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
///    glMatrixMode( GL_PROJECTION );
///    glLoadIdentity();
	glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, gBuffer );
///    glViewport( 0, 0, 1024, 1024 );
///    glMatrixMode(GL_MODELVIEW);
///    glLoadIdentity();
///    glEnable( GL_TEXTURE_2D );
///    glVertexPointer( 3,GL_FLOAT,0,vertices );
///    glTexCoordPointer( 2, GL_FLOAT, 0, texcoord );
///    glTranslatef(0.0f, -1.0f, 0.0f);
///    glDrawArrays( GL_TRIANGLE_STRIP,0,4 );

	return 1;
}

///////////////////////////////////////////////////////////
// SDL関連
///////////////////////////////////////////////////////////
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
#define AUDIOFORMAT AUDIO_S16MSB // 16ビット符号あり
#else
#define AUDIOFORMAT AUDIO_S16    // 16ビット符号あり
#endif

// SDLサーフェス用オプション
#define SDLOP_SCREEN (SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_HWACCEL)

// ユーザー定義イベント
#define UEV_FPSUPDATE   (SDL_USEREVENT+0)
#define UEV_RESTART     (SDL_USEREVENT+1)
#define UEV_DOKOLOAD    (SDL_USEREVENT+2)
#define UEV_REPLAY      (SDL_USEREVENT+3)
#ifndef NOMONITOR    // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //
#define UEV_DEBUGMODEBP (SDL_USEREVENT+4)
#endif               // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //

#define USESDLTIMER   // SDLのタイマ使用




#ifndef USESDLTIMER
#define TIMERRES 10   // タイマ解像度
// タイマ情報
struct TINFO {
    UINT id;          // タイマID
    DWORD interval;   // 割込み間隔(ms)
    CBF_TMR callback; // コールバック関数
    void *param;      // コールバック関数に渡す引数
    TINFO *next;      // 次のタイマ情報へのポインタ
    
    TINFO() : id(0), callback(NULL), param(NULL), next(NULL) {}
};
#endif


///////////////////////////////////////////////////////////
// ローカル関数定義
///////////////////////////////////////////////////////////
/// OSD_FolderDiaog()で使用するコールバックプロシージャ
/// static int CALLBACK OsdBrowseCallbackProc( HWND, UINT, LPARAM, LPARAM );
#ifndef USESDLTIMER
// OSD_AddTimer()で使用するコールバックプロシージャ
static void CALLBACK OsdTimerCallbackProc( UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR );
#endif

///////////////////////////////////////////////////////////
// スタティック変数
///////////////////////////////////////////////////////////
///static HANDLE hMutex;                    // 多重起動チェック用のミューテックス
///static BROWSEINFO OBI;                   // OSD_FolderDiaog()で使用する情報を格納する構造体

#if SDL_VERSION_ATLEAST(2,0,0)
static PCKEYsym VKTable[SDL_NUM_SCANCODES]; // SDLスキャンコード  -> 仮想キーコード 変換テーブル
#else
/// static PCKEYsym VKTable[SDLK_LAST];     // SDLキーコード  -> 仮想キーコード 変換テーブル
static PCKEYsym VKTable[SDL_NUM_SCANCODES]; // SDLスキャンコード  -> 仮想キーコード 変換テーブル
#endif



#ifndef USESDLTIMER
static TINFO *tif;
#endif
///////////////////////////////////////////////////////////
// 定数
///////////////////////////////////////////////////////////
#if SDL_VERSION_ATLEAST(2,0,0)
static const struct {    // SDLスキャンコード -> 仮想キーコード定義
    SDL_Scancode InKey;  // SDLのスキャンコード
    PCKEYsym VKey;       // 仮想キーコード
} VKeyDef[] = {
    { SDL_SCANCODE_UNKNOWN,          KVC_UNKNOWN },
    
    { SDL_SCANCODE_1,                KVC_1 },            // 1    !
    { SDL_SCANCODE_2,                KVC_2 },            // 2    "
    { SDL_SCANCODE_3,                KVC_3 },            // 3    #
    { SDL_SCANCODE_4,                KVC_4 },            // 4    $
    { SDL_SCANCODE_5,                KVC_5 },            // 5    %
    { SDL_SCANCODE_6,                KVC_6 },            // 6    &
    { SDL_SCANCODE_7,                KVC_7 },            // 7    '
    { SDL_SCANCODE_8,                KVC_8 },            // 8    (
    { SDL_SCANCODE_9,                KVC_9 },            // 9    )
    { SDL_SCANCODE_0,                KVC_0 },            // 0
    
    { SDL_SCANCODE_A,                KVC_A },            // a    A
    { SDL_SCANCODE_B,                KVC_B },            // b    B
    { SDL_SCANCODE_C,                KVC_C },            // c    C
    { SDL_SCANCODE_D,                KVC_D },            // d    D
    { SDL_SCANCODE_E,                KVC_E },            // e    E
    { SDL_SCANCODE_F,                KVC_F },            // f    F
    { SDL_SCANCODE_G,                KVC_G },            // g    G
    { SDL_SCANCODE_H,                KVC_H },            // h    H
    { SDL_SCANCODE_I,                KVC_I },            // i    I
    { SDL_SCANCODE_J,                KVC_J },            // j    J
    { SDL_SCANCODE_K,                KVC_K },            // k    K
    { SDL_SCANCODE_L,                KVC_L },            // l    L
    { SDL_SCANCODE_M,                KVC_M },            // m    M
    { SDL_SCANCODE_N,                KVC_N },            // n    N
    { SDL_SCANCODE_O,                KVC_O },            // o    O
    { SDL_SCANCODE_P,                KVC_P },            // p    P
    { SDL_SCANCODE_Q,                KVC_Q },            // q    Q
    { SDL_SCANCODE_R,                KVC_R },            // r    R
    { SDL_SCANCODE_S,                KVC_S },            // s    S
    { SDL_SCANCODE_T,                KVC_T },            // t    T
    { SDL_SCANCODE_U,                KVC_U },            // u    U
    { SDL_SCANCODE_V,                KVC_V },            // v    V
    { SDL_SCANCODE_W,                KVC_W },            // w    W
    { SDL_SCANCODE_X,                KVC_X },            // x    X
    { SDL_SCANCODE_Y,                KVC_Y },            // y    Y
    { SDL_SCANCODE_Z,                KVC_Z },            // z    Z
    
    { SDL_SCANCODE_F1,               KVC_F1 },           // F1
    { SDL_SCANCODE_F2,               KVC_F2 },           // F2
    { SDL_SCANCODE_F3,               KVC_F3 },           // F3
    { SDL_SCANCODE_F4,               KVC_F4 },           // F4
    { SDL_SCANCODE_F5,               KVC_F5 },           // F5
    { SDL_SCANCODE_F6,               KVC_F6 },           // F6
    { SDL_SCANCODE_F7,               KVC_F7 },           // F7
    { SDL_SCANCODE_F8,               KVC_F8 },           // F8
    { SDL_SCANCODE_F9,               KVC_F9 },           // F9
    { SDL_SCANCODE_F10,              KVC_F10 },          // F10
    { SDL_SCANCODE_F11,              KVC_F11 },          // F11
    { SDL_SCANCODE_F12,              KVC_F12 },          // F12
    
    { SDL_SCANCODE_MINUS,            KVC_MINUS },        // -    =
    { SDL_SCANCODE_APOSTROPHE,       KVC_CARET },        // ^    ~
    { SDL_SCANCODE_BACKSPACE,        KVC_BACKSPACE },    // BackSpace
    { SDL_SCANCODE_GRAVE,            KVC_AT },           // @    `
    { SDL_SCANCODE_LEFTBRACKET,      KVC_LBRACKET },     // [    {
    { SDL_SCANCODE_EQUALS,           KVC_SEMICOLON },    // ;    +
    { SDL_SCANCODE_SEMICOLON,        KVC_COLON },        // :    *
    { SDL_SCANCODE_COMMA,            KVC_COMMA },        // ,    <
    { SDL_SCANCODE_PERIOD,           KVC_PERIOD },       // .    >
    { SDL_SCANCODE_SLASH,            KVC_SLASH },        // /    ?
    { SDL_SCANCODE_SPACE,            KVC_SPACE },        // Space
    
    { SDL_SCANCODE_ESCAPE,           KVC_ESC },          // ESC
    { SDL_SCANCODE_TAB,              KVC_TAB },          // Tab
    { SDL_SCANCODE_CAPSLOCK,         KVC_CAPSLOCK },     // CapsLock
    { SDL_SCANCODE_RETURN,           KVC_ENTER },        // Enter
    { SDL_SCANCODE_LCTRL,            KVC_LCTRL },        // L-Ctrl
    { SDL_SCANCODE_RCTRL,            KVC_RCTRL },        // R-Ctrl
    { SDL_SCANCODE_LSHIFT,           KVC_LSHIFT },       // L-Shift
    { SDL_SCANCODE_RSHIFT,           KVC_RSHIFT },       // R-Shift
    { SDL_SCANCODE_LALT,             KVC_LALT },         // L-Alt
    { SDL_SCANCODE_RALT,             KVC_RALT },         // R-Alt
    { SDL_SCANCODE_PRINTSCREEN,      KVC_PRINT },        // PrintScreen
    { SDL_SCANCODE_PRINTSCREEN,      KVC_SCROLLLOCK },   // ScrollLock
    { SDL_SCANCODE_PAUSE,            KVC_PAUSE },        // Pause
    { SDL_SCANCODE_INSERT,           KVC_INSERT },       // Insert
    { SDL_SCANCODE_DELETE,           KVC_DELETE },       // Delete
    { SDL_SCANCODE_END,              KVC_END },          // End
    { SDL_SCANCODE_HOME,             KVC_HOME },         // Home
    { SDL_SCANCODE_PAGEUP,           KVC_PAGEUP },       // PageUp
    { SDL_SCANCODE_PAGEDOWN,         KVC_PAGEDOWN },     // PageDown
    
    { SDL_SCANCODE_UP,               KVC_UP },           // ↑
    { SDL_SCANCODE_DOWN,             KVC_DOWN },         // ↓
    { SDL_SCANCODE_LEFT,             KVC_LEFT },         // ←
    { SDL_SCANCODE_RIGHT,            KVC_RIGHT },        // →
    
    { SDL_SCANCODE_KP_0,             KVC_P0 },           // [0]
    { SDL_SCANCODE_KP_1,             KVC_P1 },           // [1]
    { SDL_SCANCODE_KP_2,             KVC_P2 },           // [2]
    { SDL_SCANCODE_KP_3,             KVC_P3 },           // [3]
    { SDL_SCANCODE_KP_4,             KVC_P4 },           // [4]
    { SDL_SCANCODE_KP_5,             KVC_P5 },           // [5]
    { SDL_SCANCODE_KP_6,             KVC_P6 },           // [6]
    { SDL_SCANCODE_KP_7,             KVC_P7 },           // [7]
    { SDL_SCANCODE_KP_8,             KVC_P8 },           // [8]
    { SDL_SCANCODE_KP_9,             KVC_P9 },           // [9]
    { SDL_SCANCODE_NUMLOCKCLEAR,     KVC_NUMLOCK },      // NumLock
    { SDL_SCANCODE_KP_PLUS,          KVC_P_PLUS },       // [+]
    { SDL_SCANCODE_KP_MINUS,         KVC_P_MINUS },      // [-]
    { SDL_SCANCODE_KP_MULTIPLY,      KVC_P_MULTIPLY },   // [*]
    { SDL_SCANCODE_KP_DIVIDE,        KVC_P_DIVIDE },     // [/]
    { SDL_SCANCODE_KP_PERIOD,        KVC_P_PERIOD },     // [.]
    { SDL_SCANCODE_KP_ENTER,         KVC_P_ENTER },      // [Enter]

    // 日本語キーボードのみ
    { SDL_SCANCODE_BACKSLASH,        KVC_YEN },          // ¥   |
    { SDL_SCANCODE_RIGHTBRACKET,     KVC_RBRACKET },     // ]    }
    { SDL_SCANCODE_NONUSBACKSLASH,   KVC_UNDERSCORE },   // ¥   _
//    {                 ,                KVC_HANZEN },   // 半角/全角
//    {                 ,                KVC_MUHENKAN }, // 無変換
//    {                 ,                KVC_HENKAN },   // 変換
//    {                 ,                KVC_HIRAGANA }, // ひらがな

    // 追加キー
    { SDL_SCANCODE_LGUI,            KVX_LMETA },         // L-Meta
    { SDL_SCANCODE_RGUI,            KVX_RMETA },         // R-Meta
    { SDL_SCANCODE_MENU,            KVX_MENU }           // Menu
};
#else
static const struct {    // SDLキーコード -> 仮想キーコード定義
    int InKey;           // SDLのキーコード
    PCKEYsym VKey;       // 仮想キーコード
} VKeyDef[] = {
    { SDLK_UNKNOWN,            KVC_UNKNOWN },
    
    { SDLK_1,                KVC_1 },            // 1    !
    { SDLK_2,                KVC_2 },            // 2    "
    { SDLK_3,                KVC_3 },            // 3    #
    { SDLK_4,                KVC_4 },            // 4    $
    { SDLK_5,                KVC_5 },            // 5    %
    { SDLK_6,                KVC_6 },            // 6    &
    { SDLK_7,                KVC_7 },            // 7    '
    { SDLK_8,                KVC_8 },            // 8    (
    { SDLK_9,                KVC_9 },            // 9    )
    { SDLK_0,                KVC_0 },            // 0
    
    { SDLK_a,                KVC_A },            // a    A
    { SDLK_b,                KVC_B },            // b    B
    { SDLK_c,                KVC_C },            // c    C
    { SDLK_d,                KVC_D },            // d    D
    { SDLK_e,                KVC_E },            // e    E
    { SDLK_f,                KVC_F },            // f    F
    { SDLK_g,                KVC_G },            // g    G
    { SDLK_h,                KVC_H },            // h    H
    { SDLK_i,                KVC_I },            // i    I
    { SDLK_j,                KVC_J },            // j    J
    { SDLK_k,                KVC_K },            // k    K
    { SDLK_l,                KVC_L },            // l    L
    { SDLK_m,                KVC_M },            // m    M
    { SDLK_n,                KVC_N },            // n    N
    { SDLK_o,                KVC_O },            // o    O
    { SDLK_p,                KVC_P },            // p    P
    { SDLK_q,                KVC_Q },            // q    Q
    { SDLK_r,                KVC_R },            // r    R
    { SDLK_s,                KVC_S },            // s    S
    { SDLK_t,                KVC_T },            // t    T
    { SDLK_u,                KVC_U },            // u    U
    { SDLK_v,                KVC_V },            // v    V
    { SDLK_w,                KVC_W },            // w    W
    { SDLK_x,                KVC_X },            // x    X
    { SDLK_y,                KVC_Y },            // y    Y
    { SDLK_z,                KVC_Z },            // z    Z
    
    { SDLK_F1,               KVC_F1 },           // F1
    { SDLK_F2,               KVC_F2 },           // F2
    { SDLK_F3,               KVC_F3 },           // F3
    { SDLK_F4,               KVC_F4 },           // F4
    { SDLK_F5,               KVC_F5 },           // F5
    { SDLK_F6,               KVC_F6 },           // F6
    { SDLK_F7,               KVC_F7 },           // F7
    { SDLK_F8,               KVC_F8 },           // F8
    { SDLK_F9,               KVC_F9 },           // F9
    { SDLK_F10,              KVC_F10 },          // F10
    { SDLK_F11,              KVC_F11 },          // F11
    { SDLK_F12,              KVC_F12 },          // F12
    
    { SDLK_MINUS,            KVC_MINUS },        // -    =
    { SDLK_CARET,            KVC_CARET },        // ^    ~
    { SDLK_BACKSPACE,        KVC_BACKSPACE },    // BackSpace
    { SDLK_AT,               KVC_AT },           // @    `
    { SDLK_LEFTBRACKET,      KVC_LBRACKET },     // [    {
    { SDLK_SEMICOLON,        KVC_SEMICOLON },    // ;    +
    { SDLK_COLON,            KVC_COLON },        // :    *
    { SDLK_COMMA,            KVC_COMMA },        // ,    <
    { SDLK_PERIOD,           KVC_PERIOD },       // .    >
    { SDLK_SLASH,            KVC_SLASH },        // /    ?
    { SDLK_SPACE,            KVC_SPACE },        // Space
    
    { SDLK_ESCAPE,           KVC_ESC },          // ESC
    { SDLK_BACKQUOTE,        KVC_HANZEN },       // 半角/全角
    { SDLK_TAB,              KVC_TAB },          // Tab
    { SDLK_CAPSLOCK,         KVC_CAPSLOCK },     // CapsLock
    { SDLK_RETURN,           KVC_ENTER },        // Enter
    { SDLK_LCTRL,            KVC_LCTRL },        // L-Ctrl
    { SDLK_RCTRL,            KVC_RCTRL },        // R-Ctrl
    { SDLK_LSHIFT,           KVC_LSHIFT },       // L-Shift
    { SDLK_RSHIFT,           KVC_RSHIFT },       // R-Shift
    { SDLK_LALT,             KVC_LALT },         // L-Alt
    { SDLK_RALT,             KVC_RALT },         // R-Alt
    { SDLK_PRINT,            KVC_PRINT },        // PrintScreen
    { SDLK_SCROLLOCK,        KVC_SCROLLLOCK },   // ScrollLock
    { SDLK_PAUSE,            KVC_PAUSE },        // Pause
    { SDLK_INSERT,           KVC_INSERT },       // Insert
    { SDLK_DELETE,           KVC_DELETE },       // Delete
    { SDLK_END,              KVC_END },          // End
    { SDLK_HOME,             KVC_HOME },         // Home
    { SDLK_PAGEUP,           KVC_PAGEUP },       // PageUp
    { SDLK_PAGEDOWN,         KVC_PAGEDOWN },     // PageDown
    
    { SDLK_UP,               KVC_UP },           // ↑
    { SDLK_DOWN,             KVC_DOWN },         // ↓
    { SDLK_LEFT,             KVC_LEFT },         // ←
    { SDLK_RIGHT,            KVC_RIGHT },        // →
    
    { SDLK_KP0,              KVC_P0 },           // [0]
    { SDLK_KP1,              KVC_P1 },           // [1]
    { SDLK_KP2,              KVC_P2 },           // [2]
    { SDLK_KP3,              KVC_P3 },           // [3]
    { SDLK_KP4,              KVC_P4 },           // [4]
    { SDLK_KP5,              KVC_P5 },           // [5]
    { SDLK_KP6,              KVC_P6 },           // [6]
    { SDLK_KP7,              KVC_P7 },           // [7]
    { SDLK_KP8,              KVC_P8 },           // [8]
    { SDLK_KP9,              KVC_P9 },           // [9]
    { SDLK_NUMLOCK,          KVC_NUMLOCK },      // NumLock
    { SDLK_KP_PLUS,          KVC_P_PLUS },       // [+]
    { SDLK_KP_MINUS,         KVC_P_MINUS },      // [-]
    { SDLK_KP_MULTIPLY,      KVC_P_MULTIPLY },   // [*]
    { SDLK_KP_DIVIDE,        KVC_P_DIVIDE },     // [/]
    { SDLK_KP_PERIOD,        KVC_P_PERIOD },     // [.]
    { SDLK_KP_ENTER,         KVC_P_ENTER },      // [Enter]
    
    // 日本語キーボードのみ
    { SDLK_BACKSLASH,        KVC_YEN },          // ¥    |
    { SDLK_RIGHTBRACKET,     KVC_RBRACKET },     // ]    }
    { SDLK_LESS,             KVC_UNDERSCORE },   // ¥    _
//    {                 ,        KVC_MUHENKAN }, // 無変換
//    {                 ,        KVC_HENKAN },   // 変換
//    {                 ,        KVC_HIRAGANA }, // ひらがな
    
    // 追加キー
    { SDLK_LMETA,            KVX_LMETA },        // L-Meta
    { SDLK_RMETA,            KVX_RMETA },        // R-Meta
    { SDLK_MENU,             KVX_MENU }          // Menu
};
#endif


///////////////////////////////////////////////////////////
// メッセージ配列
///////////////////////////////////////////////////////////
// 一般メッセージ
const char *MsgStr[] = {
    "終了してよろしいですか?",
    "終了確認",
    "再起動してよろしいですか?",
    "変更は再起動後に有効となります。\n今すぐ再起動しますか?",
    "再起動確認",
    "拡張ROMを挿入してリセットします。",
    "拡張ROMを排出してリセットします。",
    "リセット確認"
};

// メニュー用メッセージ ------
const char *MsgMen[] = {
    "ビデオキャプチャ...",
    "ビデオキャプチャ停止",
    "記録...",    // (リプレイ)
    "記録停止",   // (リプレイ)
    "再生...",    // (リプレイ)
    "再生停止"    // (リプレイ)
};

// INIファイル用メッセージ ------
const char *MsgIni[] = {
    // [CONFIG]
    "; === PC6001V 初期設定ファイル ===\n\n",
    // "機種 60:PC-6001 62:PC-6001mk2 66:PC-6601 64:PC-6001mk2SR 68:PC-6601SR",
    "機種 60:PC-6001 62:PC-6001mk2 66:PC-6601",
    "FDD接続台数 (0-2)",
    "拡張RAM使用",
    "Turbo TAPE Yes:有効 No:無効",
    "BoostUp Yes:有効 No:無効",
    "BoostUp 最大倍率(N60モード)",
    "BoostUp 最大倍率(N60m/N66モード)",
    "オーバークロック率 (1-1000)%",
    "CRCチェック Yes:有効 No:無効",
    "ROMパッチ Yes:あてる No:あてない",
    // [DISPLAY]
    "カラーモード 8:8bit 16:16bit 24:24bit",
    "MODE4カラーモード 0:モノクロ 1:赤/青 2:青/赤 3:ピンク/緑 4:緑/ピンク",
    "スキャンライン Yes:あり No:なし",
    "スキャンライン輝度 (0-100)%",
    "4:3表示 Yes:有効 No:無効",
    "フルスクリーンモード Yes:有効 No:無効",
    "ステータスバー Yes:表示 No:非表示",
    "フレームスキップ",
    // [SOUND]
    "サンプリングレート (44100/22050/11025)Hz",
    "サウンドバッファサイズ",
    "マスター音量 (0-100)",
    "PSG音量 (0-100)",
    "音声合成音量 (0-100)",
    "TAPEモニタ音量 (0-100)",
    "PSG LPFカットオフ周波数(0で無効)",
    // [MOVIE]
    "RLEフラグ Yes:RLE有効 No:ベタ",
    // [FILES]
    "拡張ROMファイル名",
    "TAPE(LODE)ファイル名(起動時に自動マウント)",
    "TAPE(SAVE)ファイル名(SAVE時に自動マウント)",
    "DISK1ファイル名(起動時に自動マウント)",
    "DISK2ファイル名(起動時に自動マウント)",
    "プリンタ出力ファイル名",
    "全角フォントファイル名",
    "半角フォントファイル名",
    // [PATH]
    "ROMイメージ格納パス",
    "TAPEイメージ格納パス",
    "DISKイメージ格納パス",
    "拡張ROMイメージ格納パス",
    "スナップショット格納パス",
    "WAVEファイル格納パス",
    "FONT格納パス",
    // [CHECK]
    "終了時確認 Yes:する No:しない",
    "終了時INIファイルを保存 Yes:する No:しない",
    // [KEY]
    "キーリピートの間隔(単位:ms 0で無効)",
    "PS/2キーボード使う? Yes:PS/2 No:USB",
    // [OPTION]
    "戦士のカートリッジ Yes:有効 No:無効"
    
};

// どこでもSAVE用メッセージ ------
const char *MsgDok[] = {
    "; === PC6001V どこでもSAVEファイル ===\n\n"
};

// Error用メッセージ ------
const char *MsgErr[] = {
    "Error",
    "エラーはありません",
    "原因不明のエラーが発生しました",
    "メモリの確保に失敗しました",
    "指定された機種のROMイメージが見つからないため機種を変更しました\n設定を確認してください",
    "ROMイメージが見つかりません\n設定とファイル名を確認してください",
    "ROMイメージのサイズが不正です",
    "ROMイメージのCRCが不正です",
    "ライブラリの初期化に失敗しました",
    "初期化に失敗しました\n設定を確認してください",
    "フォントの読込みに失敗しました",
    "フォントファイルの作成に失敗しました",
    "INIファイルの読込みに失敗しました\nデフォルト設定で起動します",
    "INIファイルの読込みに失敗しました",
    "INIファイルの保存に失敗しました",
    "TAPEイメージのマウントに失敗しました",
    "DISKイメージのマウントに失敗しました",
    "拡張ROMイメージのマウントに失敗しました",
    "どこでもLOADに失敗しました",
    "どこでもSAVEに失敗しました",
    "どこでもLOADに失敗しました\n保存時とPC6001Vのバージョンが異なります",
    "リプレイ再生に失敗しました",
    "リプレイ記録に失敗しました",
    "リプレイデータがありません"
};


////////////////////////////////////////////////////////////////
// 小文字による文字列比較
//
// 引数:    s1            比較する文字列へのポインタ1
//            s2            比較する文字列へのポインタ2
// 返値:    int            0:等しい 正数:s1>s2 負数:s1<s2
////////////////////////////////////////////////////////////////
int stricmp ( const char *s1, const char *s2 )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][stricmp]");
    const char *ps1 = s1, *ps2 = s2;
    
    if( !s1 ) return -1;
    if( !s2 ) return  1;

    // 先頭の文字
    char c1 = *ps1++;
    char c2 = *ps2++;

    // どちらかの文字列終端まで繰り返し
    while( c1 && c2 ){
        // 小文字に変換
        if( c1 >= 'A' && c1 <= 'Z' ) c1 += 'a' - 'A';
        if( c2 >= 'A' && c2 <= 'Z' ) c2 += 'a' - 'A';

        // 等しくなかったら比較終了
        if( c1 != c2 ) break;

        // 次の文字取得
        c1 = *ps1++;
        c2 = *ps2++;
    }

    return (int)c1 - (int)c2;
}

////////////////////////////////////////////////////////////////
// モジュールパス取得
//
// 引数:    なし
// 返値:    char *        取得した文字列へのポインタ
////////////////////////////////////////////////////////////////
const char *OSD_GetModulePath( void )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_GetModulePath]");

    static char mpath[MAX_PATH] = "/sdcard/pc6001v/";
    return mpath;
}


////////////////////////////////////////////////////////////////
// パスのデリミタを'/'に変換
//
// 引数:    path        パス格納バッファポインタ
// 返値:    なし
////////////////////////////////////////////////////////////////
void Delimiter( char *path )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][Delimiter]");
    while( char *c = strchr( path, '\\') )
        *c = '/';
}


////////////////////////////////////////////////////////////////
// パスのデリミタを'\'に変換
//
// 引数:    path        パス格納バッファポインタ
// 返値:    なし
////////////////////////////////////////////////////////////////
void UnDelimiter( char *path )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][UnDelimiter]");
    while( char *c = strchr( path, '/') )
        *c = '\\';
}


////////////////////////////////////////////////////////////////
// パスの末尾にデリミタを追加
//
// 引数:    path        パス格納バッファポインタ
// 返値:    なし
////////////////////////////////////////////////////////////////
void AddDelimiter( char *path )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][AddDelimiter]");
    if( !strlen( path ) )
        strncpy( path, "/", PATH_MAX );
    else if( (path[strlen(path)-1] != '/' ) && ( path[strlen(path)-1] != '\\') )
        strncat( path, "/", PATH_MAX );
}


////////////////////////////////////////////////////////////////
// パスの末尾のデリミタを削除
//
// 引数:    path        パス格納バッファポインタ
// 返値:    なし
////////////////////////////////////////////////////////////////
void DelDelimiter( char *path )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][DelDelimiter]");
    if( strlen( path ) > 1 )
        while( ( path[strlen(path)-1] == '/' ) || ( path[strlen(path)-1] == '\\' ) )
            path[strlen(path)-1] = '\0';
}

////////////////////////////////////////////////////////////////
// 初期化
//
// 引数:    なし
// 返値:    bool        true:成功 false:失敗
////////////////////////////////////////////////////////////////
bool OSD_Init( void )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_Init]");
    if( SDL_Init( SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK ) )
        return false;

    // SDLキーコード  -> 仮想キーコード 変換テーブル初期化
    ZeroMemory( &VKTable, sizeof(VKTable) );
    for( int i=0; i < COUNTOF(VKeyDef); i++ ) VKTable[VKeyDef[i].InKey] = VKeyDef[i].VKey;
    #if SDL_VERSION_ATLEAST(2,0,0)
    // SDL2.0はキーシンボルがUnicodeに対応しているらしい
    #else
    // Unicode有効 オーバーヘッドは気にしないことにする
    SDL_EnableUNICODE( 1 );
    #endif

    #ifndef USESDLTIMER
    tif = NULL;
    #endif

    return true;
}


////////////////////////////////////////////////////////////////
// 終了処理
//
// 引数:    なし
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_Quit( void )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_Quit]");
    #ifndef USESDLTIMER
    // タイマ全削除
    TINFO *ti    = tif;
    TINFO *tip   = NULL;
    while( ti ){
        timeKillEvent( ti->id );
        timeEndPeriod( TIMERRES );
        tip = ti;
        ti = ti->next;
        delete tip;
    }
    tif = NULL;
    #endif

    // Mutex を開放する
///    ReleaseMutex( hMutex );

    SDL_Quit();
}

////////////////////////////////////////////////////////////////
// 多重起動チェック
//
// 引数:    なし
// 返値:    bool        true:起動済み false:未起動
////////////////////////////////////////////////////////////////
bool OSD_IsWorking( void )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_IsWorking]");
///    SDL_Delay(10000);
    return false;
}

////////////////////////////////////////////////////////////////
// フルパスからファイル名を取得
//
// 引数:    path        フルパス格納バッファポインタ
// 返値:    char *        ファイル名の開始ポインタ
////////////////////////////////////////////////////////////////
const char *OSD_GetFileNamePart( const char *path )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_GetFileNamePart]");

    const char *p = strrchr(path, '/');
    if (p == NULL) return path;
    else if (p == path) return (p + 1);
}


////////////////////////////////////////////////////////////////
// ファイルの存在チェック
//
// 引数:    path        フルパス格納バッファポインタ
// 返値:    bool        true:存在する false:存在しない
////////////////////////////////////////////////////////////////
bool OSD_FileExist( const char *fullpath )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_FileExist] %s", fullpath);
    struct stat st;
    if (NULL != strrchr(fullpath, '*') || 0==stat(fullpath, &st)) return true;

    return false;
}


////////////////////////////////////////////////////////////////
// ファイルの読取り専用チェック
//
// 引数:    path        フルパス格納バッファポインタ
// 返値:    bool        true:読取り専用 false:読み書き
///////////////////////////////////////////////////////////////
bool OSD_FileReadOnly( const char *fullpath )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_FileReadOnly] %s", fullpath);
    FILE *fp;
    if ( NULL != (fp=fopen(fullpath, "r+b")) ){
        fclose( fp );
        return false;
    }
    
    if ( NULL != (fp=fopen(fullpath, "rb")) ){
        fclose( fp );
        return true;
    }
    
    return false;
}




////////////////////////////////////////////////////////////////
// メッセージ表示
//
// 引数:    mes            メッセージ文字列へのポインタ
//            cap            ウィンドウキャプション文字列へのポインタ
//            type        表示形式指示のフラグ
// 返値:    int            押されたボタンの種類
//                            OSDR_OK:     OKボタン
//                            OSDR_CANCEL: CANCELボタン
//                            OSDR_YES:    YESボタン
//                            OSDR_NO:     NOボタン
////////////////////////////////////////////////////////////////
int OSD_Message( const char *mes, const char *cap, int type )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_Message] %s", mes);
    return OSDR_CANCEL;
}




////////////////////////////////////////////////////////////////
// キーリピート設定
//
// 引数:    repeat    キーリピートの間隔(ms) 0で無効
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_SetKeyRepeat( int repeat )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_SetKeyRepeat]");
    #if SDL_VERSION_ATLEAST(2,0,0)
    // SDL2.0にはキーリピートの設定がないらしい
    #else
    SDL_EnableKeyRepeat( 500, repeat );
    #endif
}


////////////////////////////////////////////////////////////////
// OSDキーコード -> 仮想キーコード変換
//
// 引数:    scode        環境依存のキーコード
// 返値:    PCKEYsym    仮想キーコード
////////////////////////////////////////////////////////////////
PCKEYsym OSD_ConvertKeyCode( int scode )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_ConvertKeyCode]");
    return VKTable[scode];
}


////////////////////////////////////////////////////////////////
// 利用可能なジョイスティック数取得
//
// 引数:    なし
// 返値:    int            利用可能なジョイスティック数
////////////////////////////////////////////////////////////////
int OSD_GetJoyNum( void )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_GetJoyNum]");
    return SDL_NumJoysticks();
}


////////////////////////////////////////////////////////////////
// ジョイスティック名取得
//
// 引数:    int            インデックス
// 返値:    char *        ジョイスティック名文字列へのポインタ
////////////////////////////////////////////////////////////////
const char *OSD_GetJoyName( int index )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_GetJoyName]");
    return SDL_JoystickName( index );
}


////////////////////////////////////////////////////////////////
// ジョイスティックオープンされてる?
//
// 引数:    int            インデックス
// 返値:    bool        true:OPEN false:CLOSE
////////////////////////////////////////////////////////////////
bool OSD_OpenedJoy( int index )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_OpenedJoy]");
    return SDL_JoystickOpened( index ) ? true : false;
}


////////////////////////////////////////////////////////////////
// ジョイスティックオープン
//
// 引数:    int            インデックス
// 返値:    HJOYINFO    ジョイスティック情報へのポインタ
////////////////////////////////////////////////////////////////
HJOYINFO OSD_OpenJoy( int index )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_OpenJoy]");
    return (HJOYINFO)SDL_JoystickOpen( index );
}


////////////////////////////////////////////////////////////////
// ジョイスティッククローズ
//
// 引数:    int            インデックス
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_CloseJoy( HJOYINFO jinfo )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_CloseJoy]");
    SDL_JoystickClose( (SDL_Joystick *)jinfo );
}


////////////////////////////////////////////////////////////////
// ジョイスティックの軸の数取得
//
// 引数:    HJOYINFO    ジョイスティック情報へのポインタ
// 返値:    int            軸の数
////////////////////////////////////////////////////////////////
int OSD_GetJoyNumAxes( HJOYINFO jinfo )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_GetJoyNumAxes]");
    return SDL_JoystickNumAxes( (SDL_Joystick *)jinfo );
}


////////////////////////////////////////////////////////////////
// ジョイスティックのボタンの数取得
//
// 引数:    HJOYINFO    ジョイスティック情報へのポインタ
// 返値:    int            ボタンの数
////////////////////////////////////////////////////////////////
int OSD_GetJoyNumButtons( HJOYINFO jinfo )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_GetJoyButtons]");
    return SDL_JoystickNumButtons( (SDL_Joystick *)jinfo );
}


////////////////////////////////////////////////////////////////
// ジョイスティックの軸の状態取得
//
// 引数:    HJOYINFO    ジョイスティック情報へのポインタ
//            int            軸の番号
// 返値:    int            軸の状態(-32768~32767)
////////////////////////////////////////////////////////////////
int OSD_GetJoyAxis( HJOYINFO jinfo, int num )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_GetJoyAxis]");
    return SDL_JoystickGetAxis( (SDL_Joystick *)jinfo, num );
}


////////////////////////////////////////////////////////////////
// ジョイスティックのボタンの状態取得
//
// 引数:    HJOYINFO    ジョイスティック情報へのポインタ
//            int            ボタンの番号
// 返値:    bool        ボタンの状態 true:ON false:OFF
////////////////////////////////////////////////////////////////
bool OSD_GetJoyButton( HJOYINFO jinfo, int num )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_GetJoyButton]");
    return SDL_JoystickGetButton( (SDL_Joystick *)jinfo, num ) ? true : false;
}


////////////////////////////////////////////////////////////////
// オーディオデバイスオープン
//
// 引数:    obj            自分自身へのオブジェクトポインタ
//            callback    コールバック関数へのポインタ
//            rate        サンプリングレート
//            sample        バッファサイズ(サンプル数)
// 返値:    bool        true:成功 false:失敗
////////////////////////////////////////////////////////////////
bool OSD_OpenAudio( void *obj, CBF_SND callback, int rate, int samples )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_OpenAudio]");
    SDL_AudioSpec ASpec;                // オーディオスペック
    
    ASpec.freq     = rate;                // サンプリングレート
    ASpec.format   = AUDIOFORMAT;        // フォーマット
    ASpec.channels = 1;                    // モノラル
    ASpec.samples  = samples;            // バッファサイズ(サンプル数)
    ASpec.callback = callback;            // コールバック関数の指定
    ASpec.userdata = obj;                // コールバック関数に自分自身のオブジェクトポインタを渡す
    
    // オーディオデバイスを開く
    if( SDL_OpenAudio( &ASpec, NULL ) < 0 ) return false;
    
    return true;
}


////////////////////////////////////////////////////////////////
// オーディオデバイスクローズ
//
// 引数:    なし
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_CloseAudio( void )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_CloseAudio]");
    SDL_CloseAudio();
}


////////////////////////////////////////////////////////////////
// 再生開始
//
// 引数:    なし
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_StartAudio( void )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_PauseAudio]");
    SDL_PauseAudio( 0 );
}


////////////////////////////////////////////////////////////////
// 再生停止
//
// 引数:    なし
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_StopAudio( void )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_StopAudio]");
    SDL_PauseAudio( 1 );
}


////////////////////////////////////////////////////////////////
// 再生状態取得
//
// 引数:    なし
// 返値:    bool        true:再生中 false:停止中
////////////////////////////////////////////////////////////////
bool OSD_AudioPlaying( void )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_AudioPlaying]");
    return SDL_GetAudioStatus() == SDL_AUDIO_PLAYING ? true : false;
}


////////////////////////////////////////////////////////////////
// Waveファイル読込み
//  対応形式は 22050Hz以上,符号付き16bit,1ch
//
// 引数:    filepath    ファイルパス
//            buf            バッファポインタ格納ポインタ
//            len            ファイル長さ格納ポインタ
//            freq        サンプリングレート格納ポインタ
// 返値:    bool        true:成功 false:失敗
////////////////////////////////////////////////////////////////
bool OSD_LoadWAV( const char *filepath, BYTE **buf, DWORD *len, int *freq )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_LoadWAV]");
    SDL_AudioSpec ws;
    
    if( !SDL_LoadWAV( filepath, &ws, buf, (Uint32 *)len ) ) return false;
    
    if( ws.freq < 22050 || ws.format != AUDIO_S16 || ws.channels != 1 ){
        SDL_FreeWAV( *buf );
        return false;
    }
    
    *freq    = ws.freq;
    
    return true;
}


////////////////////////////////////////////////////////////////
// Waveファイル開放
//
// 引数:    buf            バッファへのポインタ
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_FreeWAV( BYTE *buf )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_FreeWAV]");
    SDL_FreeWAV( buf );
}


////////////////////////////////////////////////////////////////
// オーディオをロックする
//
// 引数:    なし
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_LockAudio( void )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_LockAudio]");
    SDL_LockAudio();
}


////////////////////////////////////////////////////////////////
// オーディオをアンロックする
//
// 引数:    なし
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_UnlockAudio( void )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_UnLockAudio]");
    SDL_UnlockAudio();
}


////////////////////////////////////////////////////////////////
// 指定時間待機
//
// 引数:    tms            待機時間(ms)
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_Delay( DWORD tms )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_Delay]");
    #ifdef USESDLTIMER
    SDL_Delay( tms );
    #else
    Sleep( tms );
    #endif
}


////////////////////////////////////////////////////////////////
// プロセス開始からの経過時間取得
//
// 引数:    なし
// 返値:    DWORD        経過時間(ms)
////////////////////////////////////////////////////////////////
DWORD OSD_GetTicks( void )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_GetTicks]");
    #ifdef USESDLTIMER
    return SDL_GetTicks();
    #else
    return GetTickCount();
    #endif
}


////////////////////////////////////////////////////////////////
// タイマ追加
//
// 引数:    interval    割込み間隔(ms)
//            callback    コールバック関数
//            param        コールバック関数に渡す引数
// 返値:    HTIMERID    タイマID(失敗したらNULL)
////////////////////////////////////////////////////////////////
HTIMERID OSD_AddTimer( DWORD interval, CBF_TMR callback, void *param )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_AddTimer]");
    #ifdef USESDLTIMER
    #if SDL_VERSION_ATLEAST(2,0,0)
    SDL_TimerID *pid = NULL;
    SDL_TimerID tid = SDL_AddTimer( interval, (SDL_TimerCallback)callback, param );
    if( tid ){
        pid = new SDL_TimerID;
        if( pid ) *pid = tid;
    }
    return (HTIMERID)pid;
    #else
///    return (HTIMERID)SDL_AddTimer( interval, (SDL_NewTimerCallback)callback, param );
    return (HTIMERID)SDL_AddTimer( interval, (SDL_TimerCallback)callback, param );
    #endif
    #else
    TINFO *tinfo = new TINFO;
    if( !tinfo ) return NULL;
    
    timeBeginPeriod( TIMERRES );
    tinfo->interval = interval;
    tinfo->callback = callback;
    tinfo->param    = param;
    tinfo->id       = timeSetEvent( interval, 1, OsdTimerCallbackProc, 0, TIME_PERIODIC );
    if( !tinfo->id ){
        delete tinfo;
        timeEndPeriod( TIMERRES );
        return NULL;
    }
    
    TINFO *ti = tif;
    if( !ti ) tif = tinfo;
    else{
        while( ti->next ) ti = ti->next;
        ti->next = tinfo;
    }
    
    return (HTIMERID)tinfo;
    #endif
}

#ifndef USESDLTIMER
// OSD_AddTimer()で使用するコールバックプロシージャ
static void CALLBACK OsdTimerCallbackProc( UINT id,  UINT, DWORD_PTR data, DWORD_PTR, DWORD_PTR )
{
    TINFO *ti = tif;
    
    while( ti && (ti->id != id) ) ti = ti->next;
    if( ti ) ti->callback( ti->interval, ti->param );
}
#endif


////////////////////////////////////////////////////////////////
// タイマ削除
//
// 引数:    id            タイマID
// 返値:    bool        true:成功 false:失敗
////////////////////////////////////////////////////////////////
bool OSD_DelTimer( HTIMERID id )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_DelTimer]");
    #ifdef USESDLTIMER
    #if SDL_VERSION_ATLEAST(2,0,0)
    if( SDL_RemoveTimer( *((SDL_TimerID *)id) ) ){
        delete (SDL_TimerID *)id;
        return true;
    }else
        return false;
    #else
    return (bool)SDL_RemoveTimer( (SDL_TimerID)id );
    #endif
    #else
    if( !id ) return false;
    
    TINFO *tinfo = (TINFO *)id;
    TINFO *ti    = tif;
    TINFO *tip   = NULL;
    
    while( ti && (ti->id != tinfo->id) ){
        tip = ti;
        ti  = ti->next;
    }
    if( !ti ) return false;
    
    if( timeKillEvent( ti->id ) != TIMERR_NOERROR )
        return false;
    timeEndPeriod( TIMERRES );
    
    delete ti;
    if( tip ) tip->next = NULL;
    else      tif = NULL;
    
    return true;
    #endif
}



////////////////////////////////////////////////////////////////
// マウスカーソル表示/非表示
//
// 引数:    disp        true:表示 false:非表示
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_ShowCursor( bool disp )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_ShowCursor]");
    SDL_ShowCursor( disp ? SDL_ENABLE : SDL_DISABLE );
}


////////////////////////////////////////////////////////////////
// ウィンドウ作成
//
// 引数:    pwh            ウィンドウハンドルへのポインタ
//            w            幅
//            h            高さ
//            bpp            色深度
//            fsflag        true:フルスクリーン false:ウィンドウ
// 返値:    bool        true:成功 false:失敗
////////////////////////////////////////////////////////////////
bool OSD_CreateWindow( HWINDOW *pwh, int w, int h, int bpp, bool fsflag )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_CreateWindow]");
    #if SDL_VERSION_ATLEAST(2,0,0)
    if( !*pwh ){
        *pwh = (HWINDOW)SDL_CreateWindow( "", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h,
                                            SDL_WINDOW_SHOWN );
        if( !*pwh ) return false;
    }
    
    SDL_Renderer *rend = SDL_GetRenderer( (SDL_Window *)*pwh );
    if( rend ) SDL_DestroyRenderer( rend );
    
    if( fsflag ){
        SDL_DisplayMode mode;
        
        mode.format = bpp ==  8 ? SDL_PIXELFORMAT_INDEX8 :
                      bpp == 16 ? SDL_PIXELFORMAT_RGB555 :
                                  SDL_PIXELFORMAT_RGB24;
        mode.w = w;
        mode.h = h;
        mode.refresh_rate = 0;
        mode.driverdata   = 0;
        SDL_SetWindowDisplayMode( (SDL_Window *)*pwh, &mode );
        SDL_SetWindowFullscreen( (SDL_Window *)*pwh, SDL_TRUE );
    }else{
        SDL_SetWindowFullscreen( (SDL_Window *)*pwh, SDL_FALSE );
        SDL_SetWindowSize( (SDL_Window *)*pwh, w, h );
    }
    
    rend = SDL_CreateRenderer( (SDL_Window *)*pwh, -1, SDL_RENDERER_ACCELERATED );
    #else
    *pwh = (HWINDOW)SDL_SetVideoMode( w, h, bpp, SDLOP_SCREEN | (fsflag ? SDL_FULLSCREEN : 0) );
    #endif
    return *pwh ? true : false;
}


////////////////////////////////////////////////////////////////
// ウィンドウ破棄
//
// 引数:    wh            ウィンドウハンドル
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_DestroyWindow( HWINDOW wh )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_DestroyWindow]");
    #if SDL_VERSION_ATLEAST(2,0,0)
    if( wh ){
        SDL_Renderer *rend = SDL_GetRenderer( (SDL_Window *)wh );
        if( rend ) SDL_DestroyRenderer( rend );
        SDL_DestroyWindow( (SDL_Window *)wh );
    }
    #else
    // SDL1.2は無視
    #endif
}


////////////////////////////////////////////////////////////////
// ウィンドウの幅を取得
//
// 引数:    wh            ウィンドウハンドル
// 返値:    int            幅
////////////////////////////////////////////////////////////////
int OSD_GetWindowWidth( HWINDOW wh )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_GetWindowWidth]");
    int res = 0;
    #if SDL_VERSION_ATLEAST(2,0,0)
    if( wh ) SDL_GetWindowSize( (SDL_Window *)wh, &res, NULL );
    #else
    if( wh ) res = ((SDL_Surface *)wh)->w;
    #endif
    return res;
}


////////////////////////////////////////////////////////////////
// ウィンドウの高さを取得
//
// 引数:    wh            ウィンドウハンドル
// 返値:    int            高さ
////////////////////////////////////////////////////////////////
int OSD_GetWindowHeight( HWINDOW wh )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_GetWindowHeight]");
    int res = 0;
    #if SDL_VERSION_ATLEAST(2,0,0)
    if( wh ) SDL_GetWindowSize( (SDL_Window *)wh, NULL, &res );
    #else
    if( wh ) res = ((SDL_Surface *)wh)->h;
    #endif
    return res;
}


////////////////////////////////////////////////////////////////
// ウィンドウの色深度を取得
//
// 引数:    wh            ウィンドウハンドル
// 返値:    int            色深度
////////////////////////////////////////////////////////////////
int OSD_GetWindowBPP( HWINDOW wh )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_GetWindowBPP]");
    int res = 0;
    #if SDL_VERSION_ATLEAST(2,0,0)
    if( wh ) res = (SDL_GetWindowSurface( (SDL_Window *)wh ))->format->BitsPerPixel;
    #else
    if( wh ) res = ((SDL_Surface *)wh)->format->BitsPerPixel;
    #endif
    return res;
}


////////////////////////////////////////////////////////////////
// パレット設定
//
// 引数:    wh            ウィンドウハンドル
//            pal            パレットへのポインタ
// 返値:    bool        true:成功 false:失敗
////////////////////////////////////////////////////////////////
bool OSD_SetPalette( HWINDOW wh, VPalette *pal )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_SetPalette]");
    #if SDL_VERSION_ATLEAST(2,0,0)
//    return SDL_SetSurfacePalette( SDL_GetWindowSurface( (SDL_Window *)wh ), (SDL_Palette *)pal ) ? false : true;
    return true;
    #else
    return SDL_SetPalette( (SDL_Surface *)wh, SDL_LOGPAL|SDL_PHYSPAL, (SDL_Color *)pal->colors, 0, pal->ncols ) ? false : true;
    #endif
}


////////////////////////////////////////////////////////////////
// ウィンドウクリア
//  色は0(黒)で決め打ち
//
// 引数:    wh            ウィンドウハンドル
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_ClearWindow( HWINDOW wh )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_ClearWindow]");
    #if SDL_VERSION_ATLEAST(2,0,0)
    SDL_Renderer *rend = SDL_GetRenderer( (SDL_Window *)wh );
    SDL_SetRenderDrawColor( rend, 0, 0, 0, 0xff );
    SDL_RenderClear( rend );
    #else
    SDL_FillRect( (SDL_Surface *)wh, NULL, 0 );
    #endif
}


////////////////////////////////////////////////////////////////
// ウィンドウ反映
//
// 引数:    wh            ウィンドウハンドル
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_RenderWindow( HWINDOW wh )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_RenderWindow]");
    #if SDL_VERSION_ATLEAST(2,0,0)
    SDL_Renderer *rend = SDL_GetRenderer( (SDL_Window *)wh );
    SDL_RenderPresent( rend );
    #else
///    SDL_Flip( (SDL_Surface *)wh );
    #endif

}


////////////////////////////////////////////////////////////////
// ウィンドウに転送
//
// 引数:    wh            ウィンドウハンドル
//            src            転送元サーフェス
//            pal            パレットへのポインタ
//            x,y            転送先座標
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_BlitToWindow( HWINDOW wh, VSurface *src, int x, int y, VPalette *pal )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_BlitToWindow]");
///    VRect src1,drc1;
    
    if( !src || !wh ) return;
/*    #if SDL_VERSION_ATLEAST(2,0,0)
    SDL_Surface *dst  = SDL_GetWindowSurface( (SDL_Window *)wh );
    #else
    SDL_Surface *dst  = SDL_GetVideoSurface();
    #endif
    
    // 転送元範囲設定
    src1.x = max( 0, -x );
    src1.y = max( 0, -y );
    src1.w = min( src->Width()  - src1.x, dst->w );
    src1.h = min( src->Height() - src1.y, dst->h );
    
    if( src1.w <= 0 || src1.h <= 0 ) return;
    
    // 転送先範囲設定
    drc1.x = max( 0, x );
    drc1.y = max( 0, y );
    
    
    if( SDL_MUSTLOCK( dst ) ) SDL_LockSurface( dst );
    
    BYTE *psrc = (BYTE *)src->GetPixels() + src->Pitch() * src1.y + src1.x * src->Bpp() / 8;
    BYTE *pdst = (BYTE *)dst->pixels      + dst->pitch   * drc1.y + drc1.x * dst->format->BytesPerPixel;
    
    if( src->Bpp() == dst->format->BitsPerPixel ){
        for( int i=0; i < src1.h; i++ ){
            memcpy( pdst, psrc, src1.w * dst->format->BytesPerPixel );
            psrc += src->Pitch();
            pdst += dst->pitch;
        }
    }else if( src->Bpp() == 8 && dst->format->BitsPerPixel == 16 ){    // 8 -> 16 bpp (5:6:5)
        for( int i=0; i < src1.h; i++ ){
            for( int j=0; j < src1.w; j++ ){
                WORD wdat = (WORD)(pal->colors[*psrc].r & 0xf8) << 8
                          | (WORD)(pal->colors[*psrc].g & 0xfc) << 3
                          | (WORD)(pal->colors[*psrc].b & 0xf8) >> 3;
                *pdst++ = (BYTE)( wdat       & 0xff);
                *pdst++ = (BYTE)((wdat >> 8) & 0xff);
                psrc++;
            }
            psrc += src->Pitch() - src1.w;
            pdst += dst->pitch   - src1.w * 2;
        }
    }else if( src->Bpp() == 8 && dst->format->BitsPerPixel == 24 ){    // 8 -> 24 bpp
        for( int i=0; i < src1.h; i++ ){
            for( int j=0; j < src1.w; j++ ){
                *pdst++ = pal->colors[*psrc].b;
                *pdst++ = pal->colors[*psrc].g;
                *pdst++ = pal->colors[*psrc].r;
                psrc++;
            }
            psrc += src->Pitch() - src1.w;
            pdst += dst->pitch   - src1.w * 3;
        }
    }
    
    if( SDL_MUSTLOCK( dst ) ) SDL_UnlockSurface( dst ); */
	if (src->Width()>=640 && src->Height()>=460 && src->Bpp()==16) {
		int i, j;
		unsigned char *tsrc = (unsigned char *)(src->GetPixels());
		for( i=0 ; i<512 ; i++ ){
			for( j=0 ; j<512 ; j++){
				if (j<(src->Width()/2) && i<(src->Height()/2)) {
					gBuffer[ i ][ j ][ 0 ] = *(tsrc+0);
					gBuffer[ i ][ j ][ 1 ] = *(tsrc+1);
					tsrc+=4;
				}
			}
			tsrc+=(src->Width()*2);
		}
	} else if (src->Width()==360 && src->Height()>=230 && src->Bpp()==16) {
		int i, j;
		unsigned char *tsrc = (unsigned char *)(src->GetPixels());
		for( i=0 ; i<512 ; i++ ){
			for( j=0 ; j<512 ; j++){
				if (j<src->Width() && i<src->Height()) {
					gBuffer[ i ][ j ][ 0 ] = *(tsrc+0);
					gBuffer[ i ][ j ][ 1 ] = *(tsrc+1);
					tsrc+=2;
				}
			}
		}
	}
	gFlip=true;
}


////////////////////////////////////////////////////////////////
// ウィンドウに転送(2倍)
//
// 引数:    wh            ウィンドウハンドル
//            src            転送元サーフェス
//            x,y            転送先座標
// 返値:    なし
////////////////////////////////////////////////////////////////
void OSD_BlitToWindow2( HWINDOW wh, VSurface *src, int x, int y )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_BlitToWindow2]");
    VRect src1,drc1;
    
    if( !src || !wh ) return;
    #if SDL_VERSION_ATLEAST(2,0,0)
    SDL_Surface *dst  = SDL_GetWindowSurface( (SDL_Window *)wh );
    #else
    SDL_Surface *dst  = SDL_GetVideoSurface();
    #endif
    
    // 転送元範囲設定
    src1.x = max( 0, -x/2 );
    src1.y = max( 0, -y/2 );
    src1.w = min( src->Width()  - src1.x, dst->w / 2 );
    src1.h = min( src->Height() - src1.y, dst->h / 2 );
    
    if( src1.w <= 0 || src1.h <= 0 ) return;
    
    // 転送先範囲設定
    drc1.x = max( 0, x );
    drc1.y = max( 0, y );
    
    
    if( SDL_MUSTLOCK( dst ) ) SDL_LockSurface( dst );
    
    BYTE *psrc = (BYTE *)src->GetPixels() + src->Pitch() * src1.y + src1.x * src->Bpp() / 8;
    BYTE *pdst = (BYTE *)dst->pixels      + dst->pitch   * drc1.y + drc1.x * dst->format->BytesPerPixel;
    
    if( src->Bpp() == dst->format->BitsPerPixel ){
        switch( src->Bpp() ){
        case 8:
            for( int i=0; i < src1.h; i++ ){
                for( int j=0; j < src1.w; j++ ){
                    *pdst++ = *psrc;
                    *pdst++ = *psrc++;
                }
                psrc += src->Pitch()   - src1.w;
                pdst += dst->pitch * 2 - src1.w * 2;
            }
            break;
            
        case 16:
            for( int i=0; i < src1.h; i++ ){
                for( int j=0; j < src1.w; j++ ){
                    WORD d1 = *(WORD *)psrc++;
                    psrc++;
                    *((WORD *)pdst++) = d1;
                    pdst++;
                    *((WORD *)pdst++) = d1;
                    pdst++;
                }
                psrc += src->Pitch()   - src1.w * 2;
                pdst += dst->pitch * 2 - src1.w * 4;
            }
            break;
            
        case 24:
            for( int i=0; i < src1.h; i++ ){
                for( int j=0; j < src1.w; j++ ){
                    BYTE b = *psrc++;
                    BYTE g = *psrc++;
                    BYTE r = *psrc++;
                    *pdst++ = b;
                    *pdst++ = g;
                    *pdst++ = r;
                    *pdst++ = b;
                    *pdst++ = g;
                    *pdst++ = r;
                }
                psrc += src->Pitch()   - src1.w * 3;
                pdst += dst->pitch * 2 - src1.w * 6;
            }
        }
        
        pdst = (BYTE *)dst->pixels + dst->pitch * drc1.y + drc1.x * dst->format->BytesPerPixel;
        for( int i=0; i < src1.h; i++ ){
            memcpy( pdst + dst->pitch, pdst, src1.w * 2 * dst->format->BytesPerPixel );
            pdst += dst->pitch * 2;
        }
    }
    
    if( SDL_MUSTLOCK( dst ) ) SDL_UnlockSurface( dst );
}


///////////////////////////////////////////////////////////
// アイコン設定
//
// 引数:    wh            ウィンドウハンドル
//            model        機種 60,62,66
// 返値:    なし
///////////////////////////////////////////////////////////
void OSD_SetIcon( HWINDOW wh, int model )
{
    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][OSD_SetIcon]");
    return;
}





////////////////////////////////////////////////////////////////
// イベント取得(イベントが発生するまで待つ)
//
// 引数:    ev            イベント情報共用体へのポインタ
// 返値:    bool        true:成功 false:失敗
////////////////////////////////////////////////////////////////
bool OSD_GetEvent( Event *ev )
{
    SDL_Event event;
    PCKEYsym sym;
    
    if( !SDL_WaitEvent( &event ) ) {
        __android_log_print(ANDROID_LOG_INFO, "SDL", "!SDL_WaitEvent( &event )");
        return false;
    }
    switch( event.type ){
    case SDL_KEYDOWN:
        ev->type            = EV_KEYDOWN;
        ev->key.state        = true;
        #if SDL_VERSION_ATLEAST(2,0,0)
        ev->key.sym            = OSD_ConvertKeyCode( event.key.keysym.scancode );
        #else
        ev->key.sym            = OSD_ConvertKeyCode( event.key.keysym.sym );
        #endif
        ev->key.mod            = (PCKEYmod)(
                              ( event.key.keysym.mod & KMOD_LSHIFT ? KVM_LSHIFT : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_RSHIFT ? KVM_RSHIFT : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_LCTRL  ? KVM_LCTRL  : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_RCTRL  ? KVM_RCTRL  : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_LALT   ? KVM_LALT   : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_RALT   ? KVM_RALT   : KVM_NONE )
                            #if SDL_VERSION_ATLEAST(2,0,0)
                            | ( event.key.keysym.mod & KMOD_LGUI   ? KVM_LMETA  : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_RGUI   ? KVM_RMETA  : KVM_NONE )
                            #else
                            | ( event.key.keysym.mod & KMOD_LMETA  ? KVM_LMETA  : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_RMETA  ? KVM_RMETA  : KVM_NONE )
                            #endif
                            | ( event.key.keysym.mod & KMOD_NUM    ? KVM_NUM    : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_CAPS   ? KVM_CAPS   : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_MODE   ? KVM_MODE   : KVM_NONE ) );
        ev->key.unicode        = event.key.keysym.unicode;
        break;
        
    case SDL_KEYUP:
        ev->type            = EV_KEYUP;
        ev->key.state        = false;
        #if SDL_VERSION_ATLEAST(2,0,0)
        ev->key.sym            = OSD_ConvertKeyCode( event.key.keysym.scancode );
        #else
        ev->key.sym            = OSD_ConvertKeyCode( event.key.keysym.sym );
        #endif
        ev->key.mod            = (PCKEYmod)(
                              ( event.key.keysym.mod & KMOD_LSHIFT ? KVM_LSHIFT : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_RSHIFT ? KVM_RSHIFT : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_LCTRL  ? KVM_LCTRL  : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_RCTRL  ? KVM_RCTRL  : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_LALT   ? KVM_LALT   : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_RALT   ? KVM_RALT   : KVM_NONE )
                            #if SDL_VERSION_ATLEAST(2,0,0)
                            | ( event.key.keysym.mod & KMOD_LGUI   ? KVM_LMETA  : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_RGUI   ? KVM_RMETA  : KVM_NONE )
                            #else
                            | ( event.key.keysym.mod & KMOD_LMETA  ? KVM_LMETA  : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_RMETA  ? KVM_RMETA  : KVM_NONE )
                            #endif
                            | ( event.key.keysym.mod & KMOD_NUM    ? KVM_NUM    : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_CAPS   ? KVM_CAPS   : KVM_NONE )
                            | ( event.key.keysym.mod & KMOD_MODE   ? KVM_MODE   : KVM_NONE ) );
        ev->key.unicode        = event.key.keysym.unicode;
        break;
        
    case SDL_MOUSEBUTTONDOWN:
        ev->type            = EV_MOUSEBUTTONDOWN;
        ev->mousebt.button    = event.button.button == SDL_BUTTON_LEFT      ? MBT_LEFT      :
                              event.button.button == SDL_BUTTON_MIDDLE    ? MBT_MIDDLE    :
                              event.button.button == SDL_BUTTON_RIGHT     ? MBT_RIGHT     :
//                              event.button.button == SDL_BUTTON_WHEELUP   ? MBT_WHEELUP   :
//                              event.button.button == SDL_BUTTON_WHEELDOWN ? MBT_WHEELDOWN :
                              MBT_NONE;
        ev->mousebt.state    = true;
        ev->mousebt.x        = event.button.x;
        ev->mousebt.y        = event.button.y;
        break;
        
    case SDL_MOUSEBUTTONUP:
        ev->type            = EV_MOUSEBUTTONUP;
        ev->mousebt.button    = event.button.button == SDL_BUTTON_LEFT      ? MBT_LEFT      :
                              event.button.button == SDL_BUTTON_MIDDLE    ? MBT_MIDDLE    :
                              event.button.button == SDL_BUTTON_RIGHT     ? MBT_RIGHT     :
//                              event.button.button == SDL_BUTTON_WHEELUP   ? MBT_WHEELUP   :
//                              event.button.button == SDL_BUTTON_WHEELDOWN ? MBT_WHEELDOWN :
                              MBT_NONE;
        ev->mousebt.state    = false;
        ev->mousebt.x        = event.button.x;
        ev->mousebt.y        = event.button.y;
        break;
        
    case SDL_JOYAXISMOTION:
        ev->type            = EV_JOYAXISMOTION;
        ev->joyax.idx        = event.jaxis.which;
        ev->joyax.axis        = event.jaxis.axis;
        ev->joyax.value        = event.jaxis.value;
        break;
        
    case SDL_JOYBUTTONDOWN:
        ev->type            = EV_JOYBUTTONDOWN;
        ev->joybt.idx        = event.jbutton.which;
        ev->joybt.button    = event.jbutton.button;
        ev->joybt.state        = true;
        break;
        
    case SDL_JOYBUTTONUP:
        ev->type            = EV_JOYBUTTONUP;
        ev->joybt.idx        = event.jbutton.which;
        ev->joybt.button    = event.jbutton.button;
        ev->joybt.state        = false;
        break;
        
    case SDL_QUIT:
        ev->type            = EV_QUIT;
        break;
        
    case UEV_RESTART:
        ev->type            = EV_RESTART;
        break;
        
    case UEV_DOKOLOAD:
        ev->type            = EV_DOKOLOAD;
        break;
        
    case UEV_REPLAY:
        ev->type            = EV_REPLAY;
        break;
        
    case UEV_FPSUPDATE:
        ev->type            = EV_FPSUPDATE;
        ev->fps.fps            = event.user.code;
        break;
        
    #ifndef NOMONITOR    // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //
    case UEV_DEBUGMODEBP:
        ev->type            = EV_DEBUGMODEBP;
        ev->bp.addr            = event.user.code;
        break;
    #endif                // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //
        
    default:
    	if (gFlip) {
    		ev->type            = EV_FPSUPDATE;
    	} else {
    	    __android_log_print(ANDROID_LOG_INFO, "SDL", "[OSD][EV_NOEVENT]");
    		ev->type            = EV_NOEVENT;
    	}
    }
    
    return true;
}

つづきはその8に