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