]> 4ch.mooo.com Git - 16.git/blob - src/imfplay.c
p16 is being worked on a bunch by me wwww [16_ca needs huge amounts of work and I...
[16.git] / src / imfplay.c
1 /* midi.c
2  *
3  * Adlib OPL2/OPL3 FM synthesizer chipset test program.
4  * Play MIDI file using the OPLx synthesizer (well, poorly anyway)
5  * (C) 2010-2012 Jonathan Campbell.
6  * Hackipedia DOS library.
7  *
8  * This code is licensed under the LGPL.
9  * <insert LGPL legal text here>
10  *
11  * Compiles for intended target environments:
12  *   - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]
13  */
14
15 #include "src/lib/16_head.h"
16 #include "src/lib/16_tail.h"
17 #include "src/lib/16_pm.h"
18 #include "src/lib/16_ca.h"
19 #include "src/lib/16_mm.h"
20 #include "src/lib/16_hc.h"
21 #include "src/lib/16_dbg.h"
22 #include "src/lib/16_sd.h"
23
24 // #include <stdio.h>
25 // #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
26 // #include <stdlib.h>
27 // #include <string.h>
28 // #include <unistd.h>
29 // #include <malloc.h>
30 // #include <ctype.h>
31 // #include <fcntl.h>
32 // #include <math.h>
33 // #include <dos.h>
34
35 extern struct glob_game_vars    *ggvv;
36
37 /*static void (interrupt *old_irq0)();
38 static volatile unsigned long irq0_ticks=0;
39 static volatile unsigned int irq0_cnt=0,irq0_add=0,irq0_max=0;
40
41 #pragma pack(push,1)
42 struct imf_entry {
43         uint8_t         reg,data;
44         uint16_t        delay;
45 };
46 #pragma pack(pop)
47
48 static struct imf_entry*        imf_music=NULL;
49 static struct imf_entry*        imf_play_ptr=NULL;
50 static struct imf_entry*        imf_music_end=NULL;
51 static uint16_t                 imf_delay_countdown=0;
52
53 #define PRINTBB {\
54         printf("-------------------------------------------------------------------------------\n");\
55         printf("buffer:\n");\
56         printf("bigbuffer       %Fp\t", gvar->ca.audiosegs[0]);\
57         printf("&%Fp\n", MEMPTR gvar->ca.audiosegs[0]);\
58         printf("imf_music       %Fp\t", imf_music);\
59         printf("&%Fp\n", imf_music);\
60         printf("imf_play_ptr    %Fp\t", imf_play_ptr);\
61         printf("&%Fp\n", imf_play_ptr);\
62         printf("imf_music_end   %Fp\t", imf_music_end);\
63         printf("&%Fp\n", imf_music_end);\
64         printf("-------------------------------------------------------------------------------\n");\
65 }
66
67 void imf_free_music(global_game_variables_t *gvar) {
68         if (imf_music) free(imf_music);
69         MM_FreePtr(MEMPTR gvar->ca.audiosegs[0], gvar);
70         imf_music = imf_play_ptr = imf_music_end = NULL;
71         imf_delay_countdown = 0;
72 }
73
74 int imf_load_music(const char *path, global_game_variables_t *gvar) {
75         unsigned long len;
76         unsigned char buf[8];
77         int fd;
78
79         imf_free_music(gvar);
80
81         fd = open(path,O_RDONLY|O_BINARY);
82         if (fd < 0) return 0;
83
84         len = lseek(fd,0,SEEK_END);
85         lseek(fd,0,SEEK_SET);
86         read(fd,buf,2);
87         if (buf[0] != 0 || buf[1] != 0) // type 1 IMF
88                 len = *((uint16_t*)buf);
89         else
90                 lseek(fd,0,SEEK_SET);
91
92         if (len == 0 || len > 65535UL) {
93                 close(fd);
94                 return 0;
95         }
96         len -= len & 3;
97
98 //      imf_music = malloc(len);
99         MM_GetPtr(MEMPTR gvar->ca.audiosegs[0],len, gvar);
100         imf_music = (struct imf_entry *)gvar->ca.audiosegs[0];
101         if (imf_music == NULL) {
102                 close(fd);
103                 return 0;
104         }
105         read(fd,imf_music,len);
106         close(fd);
107
108         imf_play_ptr = imf_music;
109         imf_music_end = imf_music + (len >> 2UL);
110         PRINTBB;
111         return 1;
112 }
113 */
114 #ifndef LIBIRQ0
115 // WARNING: subroutine call in interrupt handler. make sure you compile with -zu flag for large/compact memory models
116 void interrupt irq0()
117 {
118         ggvv->ca.sd.irq0_ticks++;
119         if ((ggvv->ca.sd.irq0_cnt += ggvv->ca.sd.irq0_add) >= ggvv->ca.sd.irq0_max) {
120                 ggvv->ca.sd.irq0_cnt -= ggvv->ca.sd.irq0_max;
121                 old_irq0();
122         }
123         else {
124                 p8259_OCW2(0,P8259_OCW2_NON_SPECIFIC_EOI);
125         }
126 }
127 #endif
128 /*
129 void imf_tick() {
130         if (imf_delay_countdown == 0) {
131                 do {
132                         adlib_write(imf_play_ptr->reg,imf_play_ptr->data);
133                         imf_delay_countdown = imf_play_ptr->delay;
134                         imf_play_ptr++;
135                         if (imf_play_ptr == imf_music_end)
136                         {
137                                 printf("replay\n");
138                                 imf_play_ptr = imf_music;
139                         }
140                 } while (imf_delay_countdown == 0);
141         }
142         else {
143                 imf_delay_countdown--;
144         }
145 }
146
147 void adlib_shut_up() {
148         int i;
149
150         memset(adlib_fm,0,sizeof(adlib_fm));
151         memset(&adlib_reg_bd,0,sizeof(adlib_reg_bd));
152         for (i=0;i < adlib_fm_voices;i++) {
153                 struct adlib_fm_operator *f;
154                 f = &adlib_fm[i].mod;
155                 f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;
156                 f = &adlib_fm[i].car;
157                 f->ch_a = f->ch_b = f->ch_c = f->ch_d = 1;
158         }
159
160         for (i=0;i < adlib_fm_voices;i++) {
161                 struct adlib_fm_operator *f;
162
163                 f = &adlib_fm[i].mod;
164                 f->mod_multiple = 1;
165                 f->total_level = 63 - 16;
166                 f->attack_rate = 15;
167                 f->decay_rate = 4;
168                 f->sustain_level = 0;
169                 f->release_rate = 8;
170                 f->f_number = 400;
171                 f->sustain = 1;
172                 f->octave = 4;
173                 f->key_on = 0;
174
175                 f = &adlib_fm[i].car;
176                 f->mod_multiple = 1;
177                 f->total_level = 63 - 16;
178                 f->attack_rate = 15;
179                 f->decay_rate = 4;
180                 f->sustain_level = 0;
181                 f->release_rate = 8;
182                 f->f_number = 0;
183                 f->sustain = 1;
184                 f->octave = 0;
185                 f->key_on = 0;
186         }
187
188         adlib_apply_all();
189 }*/
190
191 void main(int argc,char **argv) {
192         static global_game_variables_t gvar;
193         unsigned long tickrate = 700;
194         unsigned long ptick;
195         int c;
196 #ifdef __DEBUG_CA__
197         dbg_debugca=1;
198 #endif
199 #ifdef __DEBUG_MM_
200         dbg_debugmm=1;
201 #endif
202         ggvv=&gvar;
203         MM_Startup(&gvar);
204         PM_Startup(&gvar); PM_CheckMainMem(&gvar); PM_UnlockMainMem(&gvar);
205         CA_Startup(&gvar);
206         printf("ADLIB FM test program IMFPLAY\n");
207         if (argc < 2) {
208                 printf("You must specify an IMF file to play\n");
209                 return;
210         }
211
212         SD_Initimf(&gvar);
213
214         if (!SD_imf_load_music(argv[1], &gvar)) {
215                 printf("Failed to load IMF Music\n");
216                 return;
217         }
218
219         write_8254_system_timer(T8254_REF_CLOCK_HZ / tickrate);
220         old_irq0 = _dos_getvect(8);/*IRQ0*/
221         _dos_setvect(8,irq0);
222
223         _cli();
224         gvar.ca.sd.irq0_ticks = ptick = 0;
225         _sti();
226
227         while (1) {
228                 unsigned long adv;
229
230                 _cli();
231                 adv = gvar.ca.sd.irq0_ticks - ptick;
232                 if (adv >= 100UL) adv = 100UL;
233                 ptick = gvar.ca.sd.irq0_ticks;
234                 _sti();
235
236                 while (adv != 0) {
237                         SD_imf_tick(&gvar);
238                         adv--;
239                 }
240
241                 if (kbhit()) {
242                         c = getch();
243                         if (c == 0) c = getch() << 8;
244
245                         if (c == 27) {
246                                 break;
247                         }
248                 }
249         }
250 //      printf("contents of the imf_music\n[\n%s\n]\n", imf_music);
251
252         SD_imf_free_music(&gvar);
253         SD_adlib_shut_up();
254         shutdown_adlib();
255         _dos_setvect(8,old_irq0);
256         write_8254_system_timer(0);/* back to normal 18.2Hz */
257         PM_Shutdown(&gvar);
258         CA_Shutdown(&gvar);
259         MM_Shutdown(&gvar);
260 }