#define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #include "synth.h" #include #include "glext.h" #ifdef _DEBUG #include #include #include "Shaders.h" HANDLE gh_ShaderCompileEvent; static char** gs_LastShader_; static __time64_t gi_ShaderChangedDate; static unsigned int gi_ShaderProgram; static unsigned int gi_LastShaderProgram; static const char* gs_ShaderFile = "mark.fs"; DWORD WINAPI filemon(void* args) { while (true) { _finddata_t fdata; long hfile = _findfirst(gs_ShaderFile, &fdata); if (hfile != -1) { if (fdata.time_write != gi_ShaderChangedDate) { gi_ShaderChangedDate = fdata.time_write; ::SetEvent(gh_ShaderCompileEvent); std::cout << "Shader loaded." << std::endl; } _findclose(hfile); } ::Sleep(100); } return 0; } #else #pragma data_seg(".Shader0") #include "mark_small.h" #endif #ifndef SCREENWIDTH #define SCREENWIDTH 1280 #endif #ifndef SCREENHEIGHT #define SCREENHEIGHT 720 #endif #ifndef ASPECTOFFSET #define ASPECTOFFSET ((float(SCREENWIDTH) / float(SCREENHEIGHT) - 1.0f) * 0.5f) #endif #define WINDOWED struct FAKEPFD { WORD nSize; WORD nVersion; DWORD dwFlags; // Snip }; struct FAKEDEVMODE { BYTE dmDeviceName[CCHDEVICENAME]; WORD dmSpecVersion; WORD dmDriverVersion; WORD dmSize; WORD dmDriverExtra; DWORD dmFields; union { /* printer only fields */ struct { short dmOrientation; short dmPaperSize; short dmPaperLength; short dmPaperWidth; short dmScale; short dmCopies; short dmDefaultSource; short dmPrintQuality; }; FAKEPFD pfd; }; short dmColor; short dmDuplex; short dmYResolution; short dmTTOption; short dmCollate; BYTE dmFormName[CCHFORMNAME]; WORD dmLogPixels; DWORD dmBitsPerPel; DWORD dmPelsWidth; DWORD dmPelsHeight; union { DWORD dmDisplayFlags; DWORD dmNup; }; DWORD dmDisplayFrequency; }; #pragma bss_seg(".mainbss") static PFNGLCREATESHADERPROGRAMEXTPROC glCreateShaderProgramEXT; static PFNGLUSEPROGRAMPROC glUseProgram; static PFNGLUNIFORM4FPROC glUniform4f; #pragma data_seg(".devmode") static FAKEDEVMODE devmode = { "", 0, 0, sizeof(devmode), 0, DM_PELSWIDTH | DM_PELSHEIGHT, 0, 0, PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, 0, SCREENWIDTH, SCREENHEIGHT, 0, 0 }; #pragma data_seg(".fltused") int _fltused = 1; #pragma data_seg(".glCreateShaderProgramEXT") static const char* sglCreateShaderProgramEXT = "glCreateShaderProgramEXT"; #pragma data_seg(".glUseProgram") static const char* sglUseProgram = "glUseProgram"; #pragma data_seg(".glUniform4f") static const char* sglUniform4f = "glUniform4f"; #define shaderCountOffset 14 #define ATOM_EDIT 0xC018 #define ATOM_STATIC 0xC019 #define SCENE_LENGTH (SAMPLES_PER_TICK * 128) #pragma code_seg(".main") void _cdecl main() { InitSound(); #ifdef _DEBUG HDC hDC = GetDC(CreateWindowExA(0, (LPCSTR)ATOM_EDIT, 0, WS_OVERLAPPEDWINDOW | WS_SYSMENU | WS_VISIBLE, 0, 0, SCREENWIDTH, SCREENHEIGHT, 0, 0, 0, 0)); gh_ShaderCompileEvent = ::CreateEvent(NULL, FALSE, FALSE, TEXT("WriteEvent")); SetThreadPriority((HANDLE)CreateThread(0, 0, &filemon, 0, 0, 0), THREAD_PRIORITY_BELOW_NORMAL); #else #ifndef WINDOWED ChangeDisplaySettings((DEVMODEA*)&devmode, CDS_FULLSCREEN); HDC hDC = GetDC(CreateWindowExA(0, (LPCSTR)ATOM_STATIC, 0, WS_POPUP | WS_VISIBLE | WS_MAXIMIZE, 0, 0, 0, 0, 0, 0, 0, 0)); #else HDC hDC = GetDC(CreateWindowExA(0, (LPCSTR)ATOM_STATIC, 0, WS_VISIBLE | WS_SYSMENU, 0, 0, SCREENWIDTH, SCREENHEIGHT, 0, 0, 0, 0)); #endif #endif SetPixelFormat(hDC, ChoosePixelFormat(hDC, (const PIXELFORMATDESCRIPTOR*)&devmode.pfd), 0); // if size is a problem, try this: //SetPixelFormat(hDC, 8, 0); wglMakeCurrent(hDC, wglCreateContext(hDC)); #ifdef _DEBUG initShaders(); #endif glCreateShaderProgramEXT = (PFNGLCREATESHADERPROGRAMEXTPROC)wglGetProcAddress(sglCreateShaderProgramEXT); glUseProgram = (PFNGLUSEPROGRAMPROC)wglGetProcAddress(sglUseProgram); glUniform4f = (PFNGLUNIFORM4FPROC)wglGetProcAddress(sglUniform4f); #ifndef _DEBUG for (int i = 0; i < 12; ++i) { glUseProgram(glCreateShaderProgramEXT(GL_FRAGMENT_SHADER, mark_fs_0)); mark_fs_0[shaderCountOffset]++; if (i == 9) { mark_fs_0[shaderCountOffset] = 'A'; } glUniform4f(0, i, SCREENHEIGHT, ASPECTOFFSET, 0.0f); glRecti(-1, -1, 1, 1); } ShowCursor(FALSE); #endif PlaySound(); do { get_Sample(); float fTime = (float)MMTime.u.sample / SCENE_LENGTH; #ifdef _DEBUG if (::WaitForSingleObject(gh_ShaderCompileEvent, 0) == WAIT_OBJECT_0) { ::Sleep(50); glUseProgram(createFragmentProgram(gs_ShaderFile)); PrintErrors(); } #else glUseProgram((int)fTime + 1); #endif int i = ((MMTime.u.sample >> 8) << 5) + 2 * 2; glUniform4f(0, fTime, SCREENHEIGHT, ASPECTOFFSET, 0); glRecti(-1, -1, 1, 1); SwapBuffers(hDC); #ifdef _DEBUG MSG msg; if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) return; else { TranslateMessage(&msg); DispatchMessage(&msg); } } #else ::PeekMessage(0, 0, 0, 0, 0); #endif } while #ifdef _DEBUG (true); #else (MMTime.u.sample < MAX_SAMPLES && !GetAsyncKeyState(VK_ESCAPE)); #endif ExitProcess(0); }