123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- // wonbe Win32 text emulation
- /* First Created: Nov.4,2000 by Pie Dey Co.,Ltd. */
- /* This source code is distributed under GNU General Public License (GPL) */
- /* see http://www.gnu.org/ about GPL */
- #include <windows.h>
- #include <stdio.h>
- #include "win32text.h"
- #define SCREEN_SIZE_X (224/8)
- #define SCREEN_SIZE_Y (144/8)
- static WORD screen[SCREEN_SIZE_X][SCREEN_SIZE_Y];
- //static WORD lastChar;
- static UINT lastVKey;
- static HWND hwnd;
- static void wmPaint( HWND hWnd, HDC hdc )
- {
- int x,y;
- int xArea, yArea;
- RECT rect, rectDraw;
- TEXTMETRIC tm;
- GetClientRect( hWnd, &rect );
- SelectObject( hdc, GetStockObject( SYSTEM_FIXED_FONT ) );
- GetTextMetrics( hdc, &tm );
- xArea = SCREEN_SIZE_X * tm.tmMaxCharWidth;
- yArea = SCREEN_SIZE_Y * tm.tmHeight;
- rectDraw.left = (rect.right-rect.left)/2-xArea/2;
- rectDraw.top = (rect.bottom-rect.top)/2-yArea/2;
- rectDraw.right = (rect.right-rect.left)/2+xArea/2;
- rectDraw.bottom = (rect.bottom-rect.top)/2+yArea/2;
- FillRect( hdc, &rect, GetStockObject(GRAY_BRUSH) );
- FillRect( hdc, &rectDraw, GetStockObject(WHITE_BRUSH) );
- for( y=0; y<SCREEN_SIZE_Y; y++ ) {
- for( x=0; x<SCREEN_SIZE_X; x++ ) {
- WORD val;
- BYTE str[2];
- val = screen[x][y];
- if( val >= 0x100 ) {
- str[0] = (val >> 8);
- str[1] = (val & 0xff);
- TextOut( hdc,
- rectDraw.left+x*tm.tmMaxCharWidth,
- rectDraw.top+y*tm.tmHeight,
- str, 2 );
- } else {
- static char table[] = " !”#$%&’()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[¥]^_`abcdefghijklmnopqrstuvwxyz{|} ̄";
- if( val >= 0x20 && val <= 0x7e ) {
- TextOut( hdc,
- rectDraw.left+x*tm.tmMaxCharWidth,
- rectDraw.top+y*tm.tmHeight,
- &table[(val-0x20)*2], 2 );
- } else {
- str[0] = (BYTE)val;
- TextOut( hdc,
- rectDraw.left+x*tm.tmMaxCharWidth,
- rectDraw.top+y*tm.tmHeight,
- str, 1 );
- }
- }
- }
- }
- }
- LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- PAINTSTRUCT ps;
- HDC hdc;
- switch (message) {
- case WM_PAINT:
- hdc = BeginPaint(hWnd, &ps);
- wmPaint(hWnd,hdc);
- EndPaint(hWnd, &ps);
- break;
- case WM_KEYDOWN:
- lastVKey = (WORD)wParam;
- break;
- //case WM_CHAR:
- // lastChar = (WORD)wParam;
- // break;
- case WM_CLOSE:
- return 0; // 閉じちゃ駄目
- case WM_DESTROY:
- hwnd = NULL;
- PostQuitMessage(0);
- break;
- default:
- return (DefWindowProc(hWnd, message, wParam, lParam));
- }
- return (0);
- }
- static int createTextInThread()
- {
- WNDCLASS wc;
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = (WNDPROC)WndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = GetModuleHandle(NULL);
- wc.hIcon = NULL;
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = "wonbe_win32text";
- RegisterClass(&wc);
- hwnd = CreateWindow(wc.lpszClassName, "WONBE TEXT", WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, 0, SCREEN_SIZE_X*16+64, SCREEN_SIZE_Y*20+64,
- NULL, NULL, wc.hInstance, NULL);
- if( !hwnd ) return FALSE;
- clearText();
- ShowWindow( hwnd, SW_SHOW );
- UpdateWindow( hwnd );
- return TRUE;
- }
- void clearText()
- {
- int x,y;
- if( hwnd == NULL ) return;
- for( y=0; y<SCREEN_SIZE_Y; y++ ) {
- for( x=0; x<SCREEN_SIZE_X; x++ ) {
- screen[x][y] = ' ';
- }
- }
- InvalidateRect( hwnd, NULL, FALSE );
- }
- void drawChar( int x, int y, unsigned short ch )
- {
- if( x < 0 ) return;
- if( y < 0 ) return;
- if( x >= SCREEN_SIZE_X ) return;
- if( y >= SCREEN_SIZE_Y ) return;
- screen[x][y] = ch;
- InvalidateRect( hwnd, NULL, FALSE );
- }
- void updateText()
- {
- UpdateWindow( hwnd );
- }
- void deleteText()
- {
- if( hwnd == NULL ) return;
- DestroyWindow( hwnd );
- hwnd = NULL;
- }
- DWORD WINAPI ThreadFunc( LPVOID lpParam )
- {
- MSG msg;
- createTextInThread();
- while (GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return 0;
- }
- int createText()
- {
- DWORD dwThreadId, dwThrdParam = 1;
- HANDLE hThread;
- //lastChar = 0;
- lastVKey = 0;
- hThread = CreateThread(
- NULL, // no security attributes
- 0, // use default stack size
- ThreadFunc, // thread function
- &dwThrdParam, // argument to thread function
- 0, // use default creation flags
- &dwThreadId); // returns the thread identifier
- return TRUE;
- }
- unsigned short win32_wait()
- {
- UINT t;
- while( TRUE ) {
- // 以下の2行は本当はマルチスレッド的にNGなんだけど
- // テスト用環境だから大目に見る
- t = lastVKey;
- lastVKey = 0;
- switch( t ) {
- case 'P':
- return 0x02; // START BUTTON
- case VK_SPACE:
- return 0x04; //KEYWORD_SCAN_A;
- case VK_ESCAPE:
- return 0x08; //KEYWORD_SCAN_B;
- case VK_UP:
- case 'E':
- return 0x10; //KEYWORD_SCAN_X1;
- case VK_RIGHT:
- case 'D':
- return 0x20; //KEYWORD_SCAN_X2;
- case VK_DOWN:
- case 'X':
- return 0x40; //KEYWORD_SCAN_X3;
- case VK_LEFT:
- case 'S':
- return 0x80; //KEYWORD_SCAN_X4;
- case 'T':
- return 0x100; //KEYWORD_SCAN_Y1;
- case 'G':
- return 0x200; //KEYWORD_SCAN_Y2;
- case 'V':
- return 0x400; //KEYWORD_SCAN_Y3;
- case 'F':
- return 0x800; //KEYWORD_SCAN_Y4;
- }
- Sleep( 100 );
- }
- }
- unsigned short win32_scan()
- {
- WORD t;
- t = 0;
- if( GetAsyncKeyState('P') & 0x8000 ) {
- t |= 0x02; // START
- }
- if( GetAsyncKeyState(VK_SPACE) & 0x8000 ) {
- t |= 0x04; // A
- }
- if( GetAsyncKeyState(VK_ESCAPE) & 0x8000 ) {
- t |= 0x08; // B
- }
- if( GetAsyncKeyState('E') & 0x8000 ) {
- t |= 0x10; // X1
- }
- if( GetAsyncKeyState('D') & 0x8000 ) {
- t |= 0x20; // X2
- }
- if( GetAsyncKeyState('X') & 0x8000 ) {
- t |= 0x40; // X3
- }
- if( GetAsyncKeyState('S') & 0x8000 ) {
- t |= 0x80; // X4
- }
- if( GetAsyncKeyState('T') & 0x8000 ) {
- t |= 0x100; // Y1
- }
- if( GetAsyncKeyState('G') & 0x8000 ) {
- t |= 0x200; // Y2
- }
- if( GetAsyncKeyState('V') & 0x8000 ) {
- t |= 0x400; // Y3
- }
- if( GetAsyncKeyState('F') & 0x8000 ) {
- t |= 0x800; // Y4
- }
- return t;
- }
- unsigned int win32_get_tick_count()
- {
- return GetTickCount()/10;
- }
- void win32_sys_wait( unsigned int val )
- {
- Sleep( val*10 );
- }
- static BOOL bPlayingMIDI = FALSE;
- static UINT wDeviceID;
- DWORD stopMIDIFile(HWND hwnd)
- {
- if( bPlayingMIDI ) {
- mciSendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_WAIT, (DWORD)NULL);
- bPlayingMIDI = FALSE;
- }
- return 0;
- }
- DWORD playMIDIFile(HWND hWndNotify, LPSTR lpszMIDIFileName)
- {
- DWORD dwReturn;
- MCI_OPEN_PARMS mciOpenParms;
- MCI_PLAY_PARMS mciPlayParms;
- MCI_STATUS_PARMS mciStatusParms;
- //MCI_SEQ_SET_PARMS mciSeqSetParms;
- // Open the device by specifying the device and filename.
- // MCI will attempt to choose the MIDI mapper as the output port.
- mciOpenParms.lpstrDeviceType = "sequencer";
- mciOpenParms.lpstrElementName = lpszMIDIFileName;
- if (dwReturn = mciSendCommand((MCIDEVICEID)NULL, MCI_OPEN,
- MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,
- (DWORD)(LPVOID) &mciOpenParms))
- {
- // Failed to open device. Don't close it; just return error.
- return (dwReturn);
- }
- // The device opened successfully; get the device ID.
- wDeviceID = mciOpenParms.wDeviceID;
- bPlayingMIDI = TRUE;
- // Check if the output port is the MIDI mapper.
- mciStatusParms.dwItem = MCI_SEQ_STATUS_PORT;
- if (dwReturn = mciSendCommand(wDeviceID, MCI_STATUS,
- MCI_STATUS_ITEM, (DWORD)(LPVOID) &mciStatusParms))
- {
- mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD)NULL);
- return (dwReturn);
- }
- // The output port is not the MIDI mapper.
- // Ask if the user wants to continue.
- if (LOWORD(mciStatusParms.dwReturn) != MIDI_MAPPER)
- {
- //printf("Warning: The MIDI mapper is not available.\n");
- }
- // Begin playback. The window procedure function for the parent
- // window will be notified with an MM_MCINOTIFY message when
- // playback is complete. At this time, the window procedure closes
- // the device.
- mciPlayParms.dwCallback = (DWORD) hWndNotify;
- if (dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY,
- (DWORD)(LPVOID) &mciPlayParms))
- {
- mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD)NULL);
- return (dwReturn);
- }
- return (0L);
- }
- // "テキスト音楽「サクラ」"に含まれるdsakura.dllを用いてMMLを再生します
- // サクラは以下より入手できます http://www.text2music.com/
- // dsakura.dllが無ければ音が出ないだけで、エラーにはなりません。
- void win32_play_mml( const char * mml )
- {
- static BOOL initialized = FALSE;
- static HMODULE hmod = NULL;
- static FARPROC pMMLtoMIDI = NULL;
- if( !initialized ) {
- HMODULE hmod = LoadLibrary("dsakura");
- if( hmod != NULL ) {
- pMMLtoMIDI = GetProcAddress( hmod, "MMLtoMIDI" );
- } else {
- printf("LoadLibrary(\"dsakura\") failed\n");
- }
- initialized = TRUE;
- }
- if( pMMLtoMIDI != NULL ) {
- char errmsg[256];
- BOOL b;
- stopMIDIFile(hwnd);
- b = (*pMMLtoMIDI)(mml,"$$$.mid",errmsg);
- if( b == FALSE ) {
- printf("dsakura: %s\n",errmsg);
- }
- playMIDIFile(hwnd, "$$$.mid");
- } else {
- printf("play: %s\n", mml );
- }
- }
- // end of win32text.c
|