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