|
|
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.