|
|
1.1 ! root 1: /* ! 2: Hatari ! 3: ! 4: YM File output, for use with STSound etc... ! 5: */ ! 6: ! 7: #include "main.h" ! 8: #include "dialog.h" ! 9: #include "file.h" ! 10: #include "memAlloc.h" ! 11: #include "misc.h" ! 12: #include "psg.h" ! 13: #include "screen.h" ! 14: #include "sound.h" ! 15: #include "statusBar.h" ! 16: #include "view.h" ! 17: #include "ymFormat.h" ! 18: ! 19: #define YM_MAX_VBLS (50*60*8) // 50=1 second, 50*60=1 minute, 50*60*8=8 minutes, or 24000 ! 20: #define YM_RECORDSIZE (4+(YM_MAX_VBLS*NUM_PSG_SOUND_REGISTERS)) // ~330k for 8 minutes ! 21: ! 22: BOOL bRecordingYM = FALSE; ! 23: int nYMVBLS = 0; ! 24: unsigned char *pYMWorkspace = NULL, *pYMData; ! 25: ! 26: //----------------------------------------------------------------------- ! 27: /* ! 28: Start recording YM registers to workspace ! 29: */ ! 30: BOOL YMFormat_BeginRecording(char *pszYMFileName) ! 31: { ! 32: BOOL bSaveYM=FALSE, bWasInWindowsMouse; ! 33: ! 34: // Free any previous data, don't save ! 35: YMFormat_FreeRecording(); ! 36: ! 37: // Make sure we have a filename to use, ask user if not ! 38: if (strlen(pszYMFileName)<=0) { ! 39: // No, back to Windows so can show dialog ! 40: Screen_ReturnFromFullScreen(); ! 41: // Back to Windows mouse ! 42: //FIXME bWasInWindowsMouse = View_ToggleWindowsMouse(MOUSE_WINDOWS); ! 43: // Ask user for filename ! 44: if (File_OpenSelectDlg(/*hWnd,*/pszYMFileName,FILEFILTER_YMFILE,FALSE,TRUE)) ! 45: bSaveYM = TRUE; ! 46: // If we were in ST mouse mode, revert back ! 47: // if (!bWasInWindowsMouse) ! 48: //FIXME View_ToggleWindowsMouse(MOUSE_ST); ! 49: } ! 50: else ! 51: bSaveYM = TRUE; ! 52: ! 53: /* OK to save? */ ! 54: if (bSaveYM) { ! 55: /* Create YM workspace */ ! 56: pYMWorkspace = (unsigned char *)Memory_Alloc(YM_RECORDSIZE); ! 57: if (pYMWorkspace) { ! 58: // Get workspace pointer and store 4 byte header ! 59: pYMData = pYMWorkspace; ! 60: *pYMData++ = 'Y'; ! 61: *pYMData++ = 'M'; ! 62: *pYMData++ = '3'; ! 63: *pYMData++ = '!'; ! 64: ! 65: bRecordingYM = TRUE; /* Ready to record */ ! 66: nYMVBLS = 0; /* Number of VBLs of information */ ! 67: ! 68: /* Set status bar */ ! 69: StatusBar_SetIcon(STATUS_ICON_SOUND,ICONSTATE_ON); ! 70: /* And inform user */ ! 71: Main_Message("YM Sound data recording started.",PROG_NAME /*,MB_OK|MB_ICONINFORMATION*/); ! 72: } ! 73: else { ! 74: /* Failed to allocate memory, cannot record */ ! 75: bRecordingYM = FALSE; ! 76: } ! 77: } ! 78: ! 79: return(bSaveYM); ! 80: } ! 81: ! 82: //----------------------------------------------------------------------- ! 83: /* ! 84: End recording YM registers and save as '.YM' file ! 85: */ ! 86: void YMFormat_EndRecording() ! 87: { ! 88: /* Turn off icon */ ! 89: StatusBar_SetIcon(STATUS_ICON_SOUND,ICONSTATE_OFF); ! 90: ! 91: /* Have recorded information? */ ! 92: if (pYMWorkspace && nYMVBLS) { ! 93: /* Convert YM to correct format(list of register 1, then register 2...) */ ! 94: if (YMFormat_ConvertToStreams()) { ! 95: /* Save YM File */ ! 96: if (0 /*FIXME:*//*strlen(ConfigureParams.Sound.szYMCaptureFileName)>0*/ ) { ! 97: //FIXME File_Save(/*hWnd,*/ConfigureParams.Sound.szYMCaptureFileName,pYMWorkspace,(long)(nYMVBLS*NUM_PSG_SOUND_REGISTERS)+4,FALSE); ! 98: /* And inform user(this only happens from dialog) */ ! 99: Main_Message("YM Sound data recording stopped.",PROG_NAME /*,MB_OK|MB_ICONINFORMATION*/); ! 100: } ! 101: } ! 102: } ! 103: ! 104: /* And free */ ! 105: YMFormat_FreeRecording(); ! 106: } ! 107: ! 108: //----------------------------------------------------------------------- ! 109: /* ! 110: Free up any resources used by YM recording ! 111: */ ! 112: void YMFormat_FreeRecording(void) ! 113: { ! 114: // Free workspace ! 115: if (pYMWorkspace) ! 116: Memory_Free(pYMWorkspace); ! 117: pYMWorkspace = NULL; ! 118: ! 119: // Stop recording ! 120: bRecordingYM = FALSE; ! 121: } ! 122: ! 123: //----------------------------------------------------------------------- ! 124: /* ! 125: Store a VBLs worth of YM registers to workspace - call each VBL ! 126: */ ! 127: void YMFormat_UpdateRecording(void) ! 128: { ! 129: int i; ! 130: ! 131: // Can record this VBL information? ! 132: if (bRecordingYM) { ! 133: // Copy VBL registers to workspace ! 134: for(i=0; i<(NUM_PSG_SOUND_REGISTERS-1); i++) ! 135: *pYMData++ = PSGRegisters[i]; ! 136: // Handle register '13'(PSG_REG_ENV_SHAPE) correctly - store 0xFF is did not write to this frame ! 137: if (bEnvelopeFreqFlag) ! 138: *pYMData++ = PSGRegisters[PSG_REG_ENV_SHAPE]; ! 139: else ! 140: *pYMData++ = 0xff; ! 141: ! 142: // Increase VBL count ! 143: nYMVBLS++; ! 144: // If run out of workspace, just save ! 145: if (nYMVBLS>=YM_MAX_VBLS) ! 146: YMFormat_EndRecording(NULL); ! 147: } ! 148: } ! 149: ! 150: //----------------------------------------------------------------------- ! 151: /* ! 152: Convert YM data to stream for output ! 153: ! 154: Data is: ! 155: 4 Byte header 'YM3!' ! 156: VBL Count x 14 PSG registers ! 157: BUT ! 158: We need data in a register stream, eg Reg 0, VBL 1, VBL 2, VBL n and then next register... ! 159: ! 160: Convert to new workspace and return TRUE if all OK ! 161: */ ! 162: BOOL YMFormat_ConvertToStreams(void) ! 163: { ! 164: unsigned char *pNewYMWorkspace; ! 165: unsigned char *pYMData, *pNewYMData; ! 166: unsigned char *pYMStream, *pNewYMStream; ! 167: int Reg, Count; ! 168: ! 169: // Allocate new workspace to convert data to ! 170: pNewYMWorkspace = (unsigned char *)Memory_Alloc(YM_RECORDSIZE); ! 171: if (pNewYMWorkspace) { ! 172: // Convert data, first copy over header ! 173: pYMData = pYMWorkspace; ! 174: pNewYMData = pNewYMWorkspace; ! 175: *pNewYMData++ = *pYMData++; ! 176: *pNewYMData++ = *pYMData++; ! 177: *pNewYMData++ = *pYMData++; ! 178: *pNewYMData++ = *pYMData++; ! 179: ! 180: // Now copy over each stream ! 181: for(Reg=0; Reg<NUM_PSG_SOUND_REGISTERS; Reg++) { ! 182: // Get pointer to source / destination ! 183: pYMStream = pYMData + Reg; ! 184: pNewYMStream = pNewYMData + (Reg*nYMVBLS); ! 185: ! 186: // Copy recording VBLs worth ! 187: for(Count=0; Count<nYMVBLS; Count++) { ! 188: *pNewYMStream++ = *pYMStream; ! 189: pYMStream += NUM_PSG_SOUND_REGISTERS; ! 190: } ! 191: } ! 192: ! 193: // Delete old workspace and assign new ! 194: Memory_Free(pYMWorkspace); ! 195: pYMWorkspace = pNewYMWorkspace; ! 196: ! 197: return(TRUE); ! 198: } ! 199: else ! 200: return(FALSE); ! 201: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.