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