char* GetString(char *pFilePtr, char **ppString) { char *pEnd; pFilePtr = MFSkipWhite(pFilePtr); if(*pFilePtr != '\"') { MFDebug_Warn(3, "Error: GetString() expected a string."); *ppString = (char*)""; return pFilePtr; } pFilePtr++; pEnd = pFilePtr; while(*pEnd != '\"' && *pEnd != 0 && !MFIsNewline(*pEnd)) pEnd++; if(*pEnd != '\"') { MFDebug_Warn(3, "Error: GetString() encountered an unterminated String."); *ppString = (char*)""; return pFilePtr; } *ppString = (char*)MFStrN(pFilePtr, (int)(pEnd - pFilePtr)); pFilePtr = pEnd + 1; return pFilePtr; }
bool MFCheckForOpenGLError(bool bBreakOnError) { GLenum err = glGetError(); if(err != GL_NO_ERROR) { #if !defined(MF_OPENGL_ES) const GLubyte *errorString = gluErrorString(err); if(bBreakOnError) { MFDebug_Assert(err == GL_NO_ERROR, MFStr("OpenGL Error %04X: %s", err, errorString)); } else { MFDebug_Warn(1, MFStr("OpenGL Error %04X: %s", err, errorString)); } #else if(bBreakOnError) { MFDebug_Assert(err == GL_NO_ERROR, MFStr("OpenGL Error: %04X", err)); } else { MFDebug_Warn(1, MFStr("OpenGL Error: %04X", err)); } #endif return true; } return false; }
MF_API void MFMidi_SendPacket(MFDevice *pDevice, const uint8 *pBytes, size_t len) { MFMidiPC_MidiOutputDevice *pMidi = (MFMidiPC_MidiOutputDevice*)pDevice->pInternal; // TODO: get hdr from pool... MIDIHDR hdr; MFZeroMemory(&hdr, sizeof(hdr)); hdr.lpData = (LPSTR)pBytes; hdr.dwBufferLength = (DWORD)len; hdr.dwBytesRecorded = (DWORD)len; hdr.dwUser = (DWORD_PTR)pDevice; MMRESULT r = midiOutPrepareHeader(pMidi->hMidiOut, &hdr, sizeof(hdr)); if (r != MMSYSERR_NOERROR) { wchar_t errorBuffer[256]; midiOutGetErrorText(r, errorBuffer, sizeof(errorBuffer)); MFDebug_Warn(1, MFStr("Failed to send MIDI message: %s", MFString_WCharAsUTF8(errorBuffer))); return; } r = midiOutLongMsg(pMidi->hMidiOut, &hdr, sizeof(hdr)); if (r != MMSYSERR_NOERROR) { wchar_t errorBuffer[256]; midiOutGetErrorText(r, errorBuffer, sizeof(errorBuffer)); MFDebug_Warn(1, MFStr("Failed to send MIDI message: %s", MFString_WCharAsUTF8(errorBuffer))); } }
bool MFRenderer_ResetDisplay(MFDisplay *pDisplay, const MFDisplaySettings *pSettings) { MFDebug_Warn(4, MFStr("MFRenderer_ResetDisplay(%d, %d, %s)", pSettings->width, pSettings->height, pSettings->bFullscreen ? "true" : "false")); bool bFullscreenChanged = pDisplay->settings.bFullscreen != pSettings->bFullscreen; // change display mode... if(bFullscreenChanged || (pSettings->bFullscreen && (pDisplay->settings.width != pSettings->width || pDisplay->settings.height != pSettings->height))) { #if MF_DISPLAY == MF_DRIVER_WIN32 if(pSettings->bFullscreen) { DEVMODE dmScreenSettings; memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); dmScreenSettings.dmSize = sizeof(dmScreenSettings); dmScreenSettings.dmPelsWidth = pSettings->width; dmScreenSettings.dmPelsHeight = pSettings->height; dmScreenSettings.dmBitsPerPel = 32; dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; if(ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { MFDebug_Warn(2, "The requested fullscreen mode is not supported by your video card."); return false; } if(bFullscreenChanged) ShowCursor(FALSE); } else { if(ChangeDisplaySettings(NULL, 0) != DISP_CHANGE_SUCCESSFUL) { MFDebug_Warn(2, "Unable to return to windowed mode!"); return false; } if(bFullscreenChanged) ShowCursor(TRUE); } #endif } gpDeviceColourTarget->imageFormat = ImgFmt_A8R8G8B8; gpDeviceColourTarget->pSurfaces[0].width = pSettings->width; gpDeviceColourTarget->pSurfaces[0].height = pSettings->height; gpDeviceColourTarget->pSurfaces[0].platformData = (uint64)gDefaultRenderTarget; gpDeviceZTarget->imageFormat = ImgFmt_D24S8; gpDeviceZTarget->pSurfaces[0].width = pSettings->width; gpDeviceZTarget->pSurfaces[0].height = pSettings->height; gpDeviceZTarget->pSurfaces[0].platformData = 0; gpDeviceRenderTarget->width = pSettings->width; gpDeviceRenderTarget->height = pSettings->height; MFRenderer_ResetViewport(); return true; }
MF_API bool MFMidi_Start(MFDevice *pDevice) { MFMidiPC_MidiInputDevice *pMidi = (MFMidiPC_MidiInputDevice*)pDevice->pInternal; if (pDevice->state == MFDevState_Active) { MFDebug_Warn(1, "Midi input device already started!"); return false; } if (pDevice->state != MFDevState_Ready) { MFDebug_Warn(1, "Midi input device not ready!"); return false; } pMidi->numEvents = pMidi->numEventsRead = 0; MMRESULT r = midiInStart(pMidi->hMidiIn); if (r != MMSYSERR_NOERROR) { pDevice->state = MFDevState_Unknown; wchar_t errorBuffer[256]; midiInGetErrorText(r, errorBuffer, sizeof(errorBuffer)); MFDebug_Warn(1, MFStr("Couldn't start MIDI device: %s", MFString_WCharAsUTF8(errorBuffer))); return false; } pDevice->state = MFDevState_Active; return true; }
MF_API bool MFMidi_OpenOutput(MFDevice *pDevice) { MFDebug_Assert(pDevice->type == MFDT_MidiOutput, "Not a MIDI device!"); if (pDevice->state == MFDevState_Ready) { MFDebug_Warn(1, "Midi output device already opened!"); return false; } if (pDevice->state != MFDevState_Available) { MFDebug_Warn(1, "Unable to open midi output device!"); return false; } MFMidiPC_MidiOutputDevice *pMidi = (MFMidiPC_MidiOutputDevice*)pDevice->pInternal; // find and open the device // TODO: FIXME! this won't work if there are 2 instances of the same device attached to the PC!!! UINT numOutputDevices = midiOutGetNumDevs(); UINT i = 0; for (; i < numOutputDevices; ++i) { MIDIOUTCAPS caps; MMRESULT r = midiOutGetDevCaps(i, &caps, sizeof(caps)); if (r != MMSYSERR_NOERROR) continue; if (caps.wMid == pMidi->mid && caps.wPid == pMidi->pid) break; } if (i == numOutputDevices) { MFDebug_Log(0, MFStr("Midi output device '%s' not found!", pDevice->strings[MFDS_ID])); pDevice->state = MFDevState_Unknown; // set this flag? return false; } MMRESULT r = midiOutOpen(&pMidi->hMidiOut, i, (DWORD_PTR)MidiOutProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION); if (r != MMSYSERR_NOERROR) { pMidi->hMidiOut = NULL; pDevice->state = MFDevState_Unknown; wchar_t errorBuffer[256]; midiOutGetErrorText(r, errorBuffer, sizeof(errorBuffer)); MFDebug_Warn(1, MFStr("Failed to open MIDI output device: %s", MFString_WCharAsUTF8(errorBuffer))); return false; } pDevice->state = MFDevState_Ready; return true; }
char* ReadSceneChunk(char *pFilePtr, char *pToken) { if(!MFString_CaseCmp(pToken, "*SCENE_FILENAME")) { char *pName; pFilePtr = GetString(pFilePtr, &pName); if(MFString_Length(pName) > 255) { MFDebug_Warn(3, MFStr("Error: More than 256 characters in nodel name, \"%s\"", pName)); return pFilePtr; } pModel->name = pName; MFDebug_Log(4, MFStr("Model: %s", pName)); } else if(!MFString_CaseCmp(pToken, "*SCENE_FIRSTFRAME")) { } else if(!MFString_CaseCmp(pToken, "*SCENE_LASTFRAME")) { } else if(!MFString_CaseCmp(pToken, "*SCENE_FRAMESPEED")) { } else if(!MFString_CaseCmp(pToken, "*SCENE_TICKSPERFRAME")) { } else if(!MFString_CaseCmp(pToken, "*SCENE_BACKGROUND_STATIC")) { } else if(!MFString_CaseCmp(pToken, "*SCENE_AMBIENT_STATIC")) { } else { MFDebug_Warn(3, MFStr("Unknown token: %s", pToken)); } return pFilePtr; }
const char *ParseAnimationSet(const char *pText) { const char *pName = GetNextToken(pText, &pText); if(MFString_Compare(pName, "{")) SkipToken(pText, "{"); const char *pTok = GetNextToken(pText, &pText); while(MFString_Compare(pTok, "}")) { if(!MFString_Compare(pTok, "Animation")) { pText = ParseAnimation(pText); } else { MFDebug_Warn(4, MFStr("Unexpected token '%s'\n", pTok)); SkipSection(pText); } pTok = GetNextToken(pText, &pText); } return pText; }
char* GetInt(char *pFilePtr, int *pInt) { char *pEnd, *pToken; bool negative = false; pFilePtr = MFSkipWhite(pFilePtr); if(*pFilePtr == '-') { negative = true; pFilePtr++; } pEnd = pFilePtr; while(MFIsNumeric(*pEnd)) pEnd++; if(!MFIsWhite(*pEnd) && !MFIsNewline(*pEnd) && *pEnd != 0) { MFDebug_Warn(3, "Error: GetInt() found non numeric character."); *pInt = 0; return pFilePtr; } pToken = (char*)MFStrN(pFilePtr, (int)(pEnd - pFilePtr)); pFilePtr = pEnd; *pInt = atoi(pToken); if(negative) *pInt = -*pInt; return pFilePtr; }
char* ReadMaterialChunk(char *pFilePtr, char *pToken) { if(!MFString_CaseCmp(pToken, "*MATERIAL_COUNT")) { int count; pFilePtr = GetInt(pFilePtr, &count); pModel->GetMaterialChunk()->materials.resize(count); MFDebug_Log(4, MFStr("Found %d materials.", count)); } else if(!MFString_CaseCmp(pToken, "*MATERIAL")) { int matID; pFilePtr = GetInt(pFilePtr, &matID); pMaterial = &pModel->GetMaterialChunk()->materials[matID]; pFilePtr = ProcessBlock(pFilePtr, "*MATERIAL", ReadMaterial); } else { MFDebug_Warn(3, MFStr("Unknown token: %s", pToken)); } return pFilePtr; }
char* GetFloat(char *pFilePtr, float *pFloat) { char *pEnd, *pToken; bool negative = false; int dotFound = 1; pFilePtr = MFSkipWhite(pFilePtr); if(*pFilePtr == '-') { negative = true; pFilePtr++; } pEnd = pFilePtr; while(MFIsNumeric(*pEnd) || (*pEnd == '.' && dotFound--)) pEnd++; pToken = (char*)MFStrN(pFilePtr, (int)(pEnd-pFilePtr)); if(*pEnd == 'f') pEnd++; if(!MFIsWhite(*pEnd) && !MFIsNewline(*pEnd) && *pEnd != 0) { MFDebug_Warn(3, "Error: GetFloat() found non numeric character."); *pFloat = 0.0f; return pFilePtr; } pFilePtr = pEnd; *pFloat = (float)atof(pToken); if(negative) *pFloat = -*pFloat; return pFilePtr; }
int F3DFile::ReadOBJ(const char *pFilename) { pModel = this; MFFile *pFile = MFFileSystem_Open(pFilename, MFOF_Read); if(!pFile) { MFDebug_Warn(2, MFStr("Failed to open OBJ file %s", pFilename)); return 1; } uint64 size = MFFile_Seek(pFile, 0, MFSeek_End); MFFile_Seek(pFile, 0, MFSeek_Begin); char *pMem = (char*)MFHeap_Alloc((size_t)size+1); MFFile_Read(pFile, pMem, size); pMem[size] = 0; MFFile_Close(pFile); ParseOBJFile(pMem); MFHeap_Free(pMem); return 0; }
int F3DFile::ReadMD2(const char *pFilename) { pModel = this; size_t size; char *pFile = MFFileSystem_Load(pFilename, &size); if(!pFile) { MFDebug_Warn(2, MFStr("Failed to open MD2 file %s", pFilename)); return 1; } int a; for(a=MFString_Length(pFilename)-1; a>=0; --a) { if(pFilename[a] == '/' || pFilename[a] == '\\') { break; } } MFString_Copy(pModel->name, &pFilename[a+1]); pModel->name[MFString_Length(pModel->name) - 4] = 0; ParseMD2File(pFile, size); MFHeap_Free(pFile); return 0; }
static void CALLBACK MidiOutProc(HMIDIOUT hMidiOut, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { MFDevice *pDevice = (MFDevice*)dwInstance; MFMidiPC_MidiOutputDevice *pMidi = (MFMidiPC_MidiOutputDevice*)pDevice->pInternal; switch (wMsg) { case MOM_OPEN: MFDebug_Log(0, MFStr("Opened MIDI output device: %s", pDevice->strings[MFDS_ID])); break; case MOM_CLOSE: MFDebug_Log(0, MFStr("Opened MIDI output device: %s", pDevice->strings[MFDS_ID])); break; case MOM_DONE: { MIDIHDR *pHdr = (MIDIHDR*)dwParam1; MMRESULT r = midiOutUnprepareHeader(pMidi->hMidiOut, pHdr, sizeof(*pHdr)); if (r != MMSYSERR_NOERROR) { wchar_t errorBuffer[256]; midiOutGetErrorText(r, errorBuffer, sizeof(errorBuffer)); MFDebug_Warn(1, MFStr("Failed to cleanup MIDI message: %s", MFString_WCharAsUTF8(errorBuffer))); } // TODO: return to pool... break; } case MOM_POSITIONCB: MFDebug_Log(0, "MIDI output device: Position CB"); break; } }
int MFSockets_InitModulePlatformSpecific() { int error; #if defined(MF_XBOX) // we cant start the network on xbox if we are debugging... :( DWORD launchDataType; LAUNCH_DATA launchData; XGetLaunchInfo(&launchDataType, &launchData); if(launchDataType == LDT_FROM_DEBUGGER_CMDLINE) return 0; #endif // startup the network... error = WSAStartup(MAKEWORD(WS_MAJOR, WS_MINOR), &wsData); if(error != 0) { MFDebug_Warn(1, "Winsock failed to start.."); return 0; } // check for correct version if(LOBYTE(wsData.wVersion) != WS_MAJOR || HIBYTE(wsData.wVersion) != WS_MINOR) { // incorrect WinSock version WSACleanup(); return 0; } wsActive = true; return 1; }
// read/write a file to a filesystem MF_API char* MFFileSystem_Load(const char *pFilename, size_t *pBytesRead, size_t extraBytes) { char *pBuffer = NULL; MFFile *hFile = MFFileSystem_Open(pFilename, MFOF_Read|MFOF_Binary); if(hFile) { uint64 size = MFFile_GetSize(hFile); if(size > 0) { #if defined(MF_32BIT) if(size >= 1LL << 32) { MFDebug_Warn(1, MFStr("File is larger than the available address space!", pFilename)); return NULL; } #endif pBuffer = (char*)MFHeap_Alloc((size_t)size + extraBytes); size_t bytesRead = MFFile_Read(hFile, pBuffer, (size_t)size); if(extraBytes > 0) pBuffer[size] = 0; if(pBytesRead) *pBytesRead = bytesRead; } MFFile_Close(hFile); } return pBuffer; }
int F3DFile::ReadMD2(const char *pFilename) { pModel = this; size_t size; char *pFile = MFFileSystem_Load(pFilename, &size); if(!pFile) { MFDebug_Warn(2, MFStr("Failed to open MD2 file %s", pFilename)); return 1; } int a; for(a=(int)MFString_Length(pFilename)-1; a>=0; --a) { if(pFilename[a] == '/' || pFilename[a] == '\\') { break; } } pModel->name = pFilename + a+1; pModel->name.TruncateExtension(); ParseMD2File(pFile, size); MFHeap_Free(pFile); return 0; }
int MFFileSystemZipFile_Mount(MFMount *pMount, MFMountData *pMountData) { MFCALLSTACK; MFDebug_Assert(pMountData->cbSize == sizeof(MFMountDataZipFile), "Incorrect size for MFMountDataNative structure. Invalid pMountData."); MFMountDataZipFile *pMountZipFile = (MFMountDataZipFile*)pMountData; bool flatten = (pMount->volumeInfo.flags & MFMF_FlattenDirectoryStructure) != 0; bool recursive = (pMount->volumeInfo.flags & MFMF_Recursive) != 0; MFDebug_Assert(flatten, ".zip file currently only supports a flattened directory structure."); if(!recursive) MFDebug_Warn(3, "Mounting Zip filesystems without the 'Recursive' flag is invalid. Zip file will be mounted recursive anyway."); // attempt to open zipfile.. zlib_filefunc_def zipIOFunctions; zipIOFunctions.zopen_file = zopen_file_func; zipIOFunctions.zread_file = zread_file_func; zipIOFunctions.zwrite_file = zwrite_file_func; zipIOFunctions.ztell_file = ztell_file_func; zipIOFunctions.zseek_file = zseek_file_func; zipIOFunctions.zclose_file = zclose_file_func; zipIOFunctions.zerror_file = ztesterror_file_func; zipIOFunctions.opaque = pMountZipFile->pZipArchive; unzFile zipFile = unzOpen2(NULL, &zipIOFunctions); if(!zipFile) { MFDebug_Warn(1, "FileSystem: Supplied file handle is not a valid .zip file."); return -1; } pMount->pFilesysData = zipFile; // make sure the toc is being cached... if(pMount->volumeInfo.flags & MFMF_DontCacheTOC) { MFDebug_Warn(2, "Zip files MUST cache the toc"); pMount->volumeInfo.flags &= ~MFMF_DontCacheTOC; } return 0; }
MF_API const MFDisplayAdaptorDesc *MFDisplay_GetDisplayAdaptorDesc(int adaptor) { if(adaptor >= 0 && adaptor < gNumDisplayDevices) { MFDebug_Warn(2, "Invalid adaptor!"); return NULL; } return &gpDisplayAdaptors[adaptor]; }
MF_API void MFSound_StartCapture(MFDevice *pDevice, MFAudioCaptureCallback *pCallback, void *pUserData) { MFDebug_Assert(pDevice->type == MFDT_AudioCapture, "Incorrect device type!"); MFAudioCaptureDevice &device = *(MFAudioCaptureDevice*)pDevice->pInternal; if(device.pAudioClient) { device.pSampleCallback = pCallback; device.pUserData = pUserData; HRESULT hr = device.pAudioClient->Start(); // Start recording. if(FAILED(hr)) MFDebug_Warn(2, "Couldn't start capture"); device.bActive = true; } else MFDebug_Warn(2, "Couldn't start capture (audio client not available)"); }
MFMatrix& MFMatrix::Inverse(const MFMatrix &mat) { MFMatrix out; register float det_1; float pos, neg, temp; // * Calculate the determinant of submatrix A and determine if the // * the matrix is singular as limited by the single precision // * floating-point data representation. pos = neg = 0.0; temp = mat.m[0] * mat.m[5] * mat.m[10]; ACCUMULATE temp = mat.m[1] * mat.m[6] * mat.m[8]; ACCUMULATE temp = mat.m[2] * mat.m[4] * mat.m[9]; ACCUMULATE temp = -mat.m[2] * mat.m[5] * mat.m[8]; ACCUMULATE temp = -mat.m[1] * mat.m[4] * mat.m[10]; ACCUMULATE temp = -mat.m[0] * mat.m[6] * mat.m[9]; ACCUMULATE det_1 = pos + neg; // Is the submatrix A singular? if ((det_1 == 0.0f) || (fabsf(det_1 / (pos - neg)) < PRECISION_LIMIT)) { // MFMatrix M has no inverse MFDebug_Warn(3, "MFMatrix::Inverse: Singular matrix (Matrix has no inverse)...\n"); return *this; } // Calculate inverse(A) = adj(A) / det(A) det_1 = 1.0f / det_1; out.m[0] = (mat.m[5]*mat.m[10] - mat.m[6]*mat.m[9]) * det_1; out.m[4] = -(mat.m[4]*mat.m[10] - mat.m[6]*mat.m[8]) * det_1; out.m[8] = (mat.m[4]*mat.m[9] - mat.m[5]*mat.m[8]) * det_1; out.m[1] = -(mat.m[1]*mat.m[10] - mat.m[2]*mat.m[9]) * det_1; out.m[5] = (mat.m[0]*mat.m[10] - mat.m[2]*mat.m[8]) * det_1; out.m[9] = -(mat.m[0]*mat.m[9] - mat.m[1]*mat.m[8]) * det_1; out.m[2] = (mat.m[1]*mat.m[6] - mat.m[2]*mat.m[5]) * det_1; out.m[6] = -(mat.m[0]*mat.m[6] - mat.m[2]*mat.m[4]) * det_1; out.m[10] = (mat.m[0]*mat.m[5] - mat.m[1]*mat.m[4]) * det_1; // Calculate -C * inverse(A) out.m[12] = -(mat.m[12]*out.m[0] + mat.m[13]*out.m[4] + mat.m[14]*out.m[8]); out.m[13] = -(mat.m[12]*out.m[1] + mat.m[13]*out.m[5] + mat.m[14]*out.m[9]); out.m[14] = -(mat.m[12]*out.m[2] + mat.m[13]*out.m[6] + mat.m[14]*out.m[10]); // Fill in last column out.m[3] = out.m[7] = out.m[11] = 0.0f; out.m[15] = 1.0f; return *this = out; }
MF_API void MFWindow_Destroy(MFWindow *_pWindow) { MFWindow_PC *pWindow = (MFWindow_PC*)_pWindow; // TODO: destroy associated display here? if(!DestroyWindow(pWindow->hWnd)) MFDebug_Warn(1, "Couldn't destroy window!"); MFHeap_Free(pWindow); }
void MFRenderer_LostFocus(MFDisplay *pDisplay) { #if MF_DISPLAY == MF_DRIVER_WIN32 if(pDisplay->settings.bFullscreen) { if(ChangeDisplaySettings(NULL, 0) == DISP_CHANGE_SUCCESSFUL) ShowCursor(TRUE); else MFDebug_Warn(2, "Unable to return to windowed mode!"); } #endif }
bool MFFileNative_FindFirst(MFFind *pFind, const char *pSearchPattern, MFFindData *pFindData) { SceIoDirent findData; int findStatus; // separate path and search pattern.. char *pPath = (char*)MFStr("%s/%s%s", gPSPSystemPath, (char*)pFind->pMount->pFilesysData, pSearchPattern); const char *pPattern = pPath; char *pLast = MFString_RChr(pPath, '/'); if(pLast) { *pLast = 0; pPattern = pLast + 1; } else { // find pattern refers to current directory.. pPath = "."; } // open the directory SceUID hFind = sceIoDopen(pPath); if(hFind < 0) { MFDebug_Warn(2, MFStr("Couldnt open directory '%s' with search pattern '%s'", pPath, pPattern)); return false; } findStatus = sceIoDread(hFind, &findData); MFDebug_Assert(findStatus >= 0, "Error reading directory."); if(findStatus == 0) return false; pFindData->attributes = (FIO_SO_ISDIR(findData.d_stat.st_attr) ? MFFA_Directory : 0) | (FIO_SO_ISLNK(findData.d_stat.st_attr) ? MFFA_SymLink : 0); pFindData->fileSize = (uint64)findData.d_stat.st_size; MFString_Copy((char*)pFindData->pFilename, findData.d_name); MFString_CopyCat(pFindData->pSystemPath, (char*)pFind->pMount->pFilesysData, pSearchPattern); pLast = MFString_RChr(pFindData->pSystemPath, '/'); if(pLast) pLast[1] = 0; else pFindData->pSystemPath[0] = 0; pFind->pFilesystemData = (void*)hFind; return true; }
static void DestroyOutputDevice(MFDevice *pDevice) { MFMidiPC_MidiOutputDevice *pDev = (MFMidiPC_MidiOutputDevice*)pDevice->pInternal; if (pDev->hMidiOut) { MFDebug_Warn(1, MFStr("MIDI output device not closed: %s", pDevice->strings[MFDS_ID])); midiOutReset(pDev->hMidiOut); midiOutClose(pDev->hMidiOut); } MFHeap_Free(pDev); }
MF_API void MFMidi_SendShortMessage(MFDevice *pDevice, uint32 message) { MFMidiPC_MidiOutputDevice *pMidi = (MFMidiPC_MidiOutputDevice*)pDevice->pInternal; MMRESULT r = midiOutShortMsg(pMidi->hMidiOut, (DWORD)message); if (r != MMSYSERR_NOERROR) { wchar_t errorBuffer[256]; midiOutGetErrorText(r, errorBuffer, sizeof(errorBuffer)); MFDebug_Warn(1, MFStr("Failed to send MIDI message: %s", MFString_WCharAsUTF8(errorBuffer))); } }
// open a file from the mounted filesystem stack MF_API MFFile* MFFileSystem_Open(const char *pFilename, uint32 openFlags) { MFDebug_Log(5, MFStr("Call: MFFileSystem_Open(\"%s\", 0x%x)", pFilename, openFlags)); GET_MODULE_DATA(MFFileSystemState); MFMount *pMount = pModuleData->pMountList; const char *pMountpoint = NULL; // search for a mountpoint size_t len = MFString_Length(pFilename); for(size_t a=0; a<len; a++) { if(pFilename[a] == ':') { pMountpoint = MFStrN(pFilename, a); pFilename += a+1; break; } if(pFilename[a] == '.') { // if we have found a dot, this cant be a mountpoint // (mountpoints may only be alphanumeric) break; } } // search for file through the mount list... while(pMount) { int onlyexclusive = pMount->volumeInfo.flags & MFMF_OnlyAllowExclusiveAccess; if((!pMountpoint && !onlyexclusive) || (pMountpoint && !MFString_CaseCmp(pMountpoint, pMount->volumeInfo.pVolumeName))) { // open the file from a mount MFFile *hFile = pModuleData->ppFileSystemList[pMount->volumeInfo.fileSystem]->callbacks.FSOpen(pMount, pFilename, openFlags); if(hFile) return hFile; } pMount = pMount->pNext; } if(!(openFlags & MFOF_TryOpen)) MFDebug_Warn(4, MFStr("MFFile_Open(\"%s\", 0x%x) - Failed to open file", pFilename, openFlags)); return NULL; }
MF_API void MFMidi_Stop(MFDevice *pDevice) { MFMidiPC_MidiInputDevice *pMidi = (MFMidiPC_MidiInputDevice*)pDevice->pInternal; if (pDevice->state != MFDevState_Active) { MFDebug_Warn(1, "Midi input device not started!"); return; } midiInReset(pMidi->hMidiIn); pDevice->state = MFDevState_Ready; }
void ParseXFile(char *pFilePtr) { if(MFString_CaseCmpN(pFilePtr, "xof ", 4)) { MFDebug_Warn(4, "File is not an .x file\n"); return; } if(!MFString_CaseCmpN(&pFilePtr[8], "txt ", 4)) { pFilePtr += 16; LoadTextXFile(pFilePtr); } else if(!MFString_CaseCmpN(&pFilePtr[8], "bin ", 4)) { MFDebug_Warn(4, "Binary .x files not yet supported...\n"); } else { MFDebug_Warn(4, "Not a valid .x file...\n"); } }
MF_API void MFMidi_CloseOutput(MFDevice *pDevice) { MFMidiPC_MidiOutputDevice *pMidi = (MFMidiPC_MidiOutputDevice*)pDevice->pInternal; if (!pMidi->hMidiOut) { MFDebug_Warn(1, "Midi output device not opened!"); return; } midiOutReset(pMidi->hMidiOut); midiOutClose(pMidi->hMidiOut); pMidi->hMidiOut = NULL; pDevice->state = MFDevState_Available; }