//--------------------------------------------------------------------------// // iq / rgba . tiny codes . 2008 // //--------------------------------------------------------------------------// #define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #include //#include #include #include #include //#include //#include //#include #include "../intro.h" #include "../4klang.h" #include "../intro.h" #include "../config.h" #include ISpVoice *pVoice; //SAPI voice bool speechflag = false; //============================================================================================== typedef struct { //--------------- HINSTANCE hInstance; HDC hDC; HGLRC hRC; HWND hWnd; //--------------- int full; //--------------- char wndclass[4]; // window class and title :) //--------------- }WININFO; static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, // accum 32, // zbuffer 0, // stencil! 0, // aux PFD_MAIN_PLANE, 0, 0, 0, 0 }; static WININFO wininfo = { 0,0,0,0,0, {'J','F','K',0} }; //============================================================================================== static LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { // salvapantallas if( uMsg==WM_SYSCOMMAND && (wParam==SC_SCREENSAVE || wParam==SC_MONITORPOWER) ) return( 0 ); // boton x o pulsacion de escape if( uMsg==WM_CLOSE || uMsg==WM_DESTROY || (uMsg==WM_KEYDOWN && wParam==VK_ESCAPE) ) { PostQuitMessage(0); return( 0 ); } if( uMsg==WM_SIZE ) { glViewport( 0, 0, lParam&65535, lParam>>16 ); } if( uMsg==WM_CHAR || uMsg==WM_KEYDOWN) { if( wParam==VK_ESCAPE ) { PostQuitMessage(0); return( 0 ); } } return( DefWindowProc(hWnd,uMsg,wParam,lParam) ); } static void window_end( WININFO *info ) { if( info->hRC ) { wglMakeCurrent( 0, 0 ); wglDeleteContext( info->hRC ); } if( info->hDC ) ReleaseDC( info->hWnd, info->hDC ); if( info->hWnd ) DestroyWindow( info->hWnd ); UnregisterClass( info->wndclass, info->hInstance ); if( info->full ) { ChangeDisplaySettings( 0, 0 ); while( ShowCursor( 1 )<0 ); // show cursor } } static int window_init( WININFO *info ) { unsigned int PixelFormat; DWORD dwExStyle, dwStyle; DEVMODE dmScreenSettings; RECT rec; WNDCLASS wc; ZeroMemory( &wc, sizeof(WNDCLASS) ); wc.style = CS_OWNDC|CS_HREDRAW|CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.hInstance = info->hInstance; wc.lpszClassName = info->wndclass; wc.hbrBackground =(HBRUSH)CreateSolidBrush(0x00102030); if( !RegisterClass(&wc) ) return( 0 ); if( info->full ) { dmScreenSettings.dmSize = sizeof(DEVMODE); dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; dmScreenSettings.dmBitsPerPel = 32; dmScreenSettings.dmPelsWidth = XRES; dmScreenSettings.dmPelsHeight = YRES; if( ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) return( 0 ); dwExStyle = WS_EX_APPWINDOW; dwStyle = WS_VISIBLE | WS_POPUP; while( ShowCursor( 0 )>=0 ); // hide cursor } else { dwExStyle = 0; dwStyle = WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_OVERLAPPED; dwStyle = WS_VISIBLE | WS_OVERLAPPEDWINDOW|WS_POPUP; } rec.left = 0; rec.top = 0; rec.right = XRES; rec.bottom = YRES; AdjustWindowRect( &rec, dwStyle, 0 ); info->hWnd = CreateWindowEx( dwExStyle, wc.lpszClassName, "Machmalala", dwStyle, (GetSystemMetrics(SM_CXSCREEN)-rec.right+rec.left)>>1, (GetSystemMetrics(SM_CYSCREEN)-rec.bottom+rec.top)>>1, rec.right-rec.left, rec.bottom-rec.top, 0, 0, info->hInstance, 0 ); if( !info->hWnd ) return( 0 ); if( !(info->hDC=GetDC(info->hWnd)) ) return( 0 ); if( !(PixelFormat=ChoosePixelFormat(info->hDC,&pfd)) ) return( 0 ); if( !SetPixelFormat(info->hDC,PixelFormat,&pfd) ) return( 0 ); if( !(info->hRC=wglCreateContext(info->hDC)) ) return( 0 ); if( !wglMakeCurrent(info->hDC,info->hRC) ) return( 0 ); return( 1 ); } //============================================================================================== // MAX_SAMPLES gives you the number of samples for the whole song. we always produce stereo samples, so times 2 for the buffer SAMPLE_TYPE lpSoundBuffer[MAX_SAMPLES*2]; HWAVEOUT hWaveOut; #pragma data_seg(".wavefmt") WAVEFORMATEX WaveFMT = { #ifdef FLOAT_32BIT WAVE_FORMAT_IEEE_FLOAT, #else WAVE_FORMAT_PCM, #endif 2, // channels SAMPLE_RATE, // samples per sec SAMPLE_RATE*sizeof(SAMPLE_TYPE)*2, // bytes per sec sizeof(SAMPLE_TYPE)*2, // block alignment; sizeof(SAMPLE_TYPE)*8, // bits per sample 0 // extension not needed }; #pragma data_seg(".wavehdr") WAVEHDR WaveHDR = { (LPSTR)lpSoundBuffer, MAX_SAMPLES*sizeof(SAMPLE_TYPE)*2, // MAX_SAMPLES*sizeof(float)*2(stereo) 0, 0, 0, 0, 0, 0 }; MMTIME MMTime = { TIME_SAMPLES, 0 }; //============================================================================================== int WINAPI WinMain( HINSTANCE instance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { MSG msg; int done=0; WININFO *info = &wininfo; info->hInstance = GetModuleHandle( 0 ); //if( MessageBox( 0, "fullscreen?", info->wndclass, MB_YESNO|MB_ICONQUESTION)==IDYES ) info->full++; if( !window_init(info) ) { window_end( info ); MessageBox( 0, "window_init()!","error",MB_OK|MB_ICONEXCLAMATION ); return( 0 ); } /* if( !intro_init() ) { window_end( info ); MessageBox( 0, "intro_init()!","error",MB_OK|MB_ICONEXCLAMATION ); return( 0 ); } */ intro_init(); BuildFont(info->hDC); //============================================================================================== #ifdef USE_SOUND_THREAD // thx to xTr1m/blu-flame for providing a smarter and smaller way to create the thread :) CreateThread(0, 0, (LPTHREAD_START_ROUTINE)_4klang_render, lpSoundBuffer, 0, 0); #else _4klang_render(lpSoundBuffer); #endif waveOutOpen ( &hWaveOut, WAVE_MAPPER, &WaveFMT, NULL, 0, CALLBACK_NULL ); waveOutPrepareHeader( hWaveOut, &WaveHDR, sizeof(WaveHDR) ); waveOutWrite ( hWaveOut, &WaveHDR, sizeof(WaveHDR) ); long to=timeGetTime(); while( !done ) { // get sample position for timing waveOutGetPosition(hWaveOut, &MMTime, sizeof(MMTIME)); // access to envelope buffer for sync. only works when the song was exported with that option // envelopes are recorded for each voice (max 2) in each instrument (max 16) every 256 samples. range [0..1] // so, e.g. to get envelope of instrument 5, voice 0 do: //float aha = (&_4klang_envelope_buffer)[((MMTime.u.sample >> 8) << 5) + 2*5+0]; // so, e.g. to get envelope of instrument 3, voice 1 do: //float oho = (&_4klang_envelope_buffer)[((MMTime.u.sample >> 8) << 5) + 2*3+1]; float aha = (&_4klang_envelope_buffer+512)[((MMTime.u.sample >> 8) << 5) + 2*10+0]; // 12=pling? 11=basedrum 10=bass 9=melo 8=slidemelo 7=hihat 6=chord 5=? long t = timeGetTime() - to; while( PeekMessage(&msg,0,0,0,PM_REMOVE) ) { if( msg.message==WM_QUIT ) done=1; TranslateMessage( &msg ); DispatchMessage( &msg ); } intro_do( t, aha ); if( MMTime.u.sample >= MAX_SAMPLES || (t*0.000992) >= 247.0) done = 1; SwapBuffers( info->hDC ); /* if( t >= 8300.0f && speechflag == false) { speechflag = true; if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) return( 0 ); HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice); hr = pVoice->SetVolume(90); hr = pVoice->SetRate(-1); hr = pVoice->Speak(L"Galvanize! ", SPF_ASYNC, NULL); hr = pVoice->WaitUntilDone(14000); pVoice->Release(); pVoice = NULL; CoUninitialize(); } */ } //============================================================================================== window_end( info ); return( 0 ); }