Add missing prototypes
[manicminer.git] / manic.c
blob0971dd621aa89fb7d60aece9331bf6479c1647a6
1 /*////////////////////////////////////////////////////////////
2 //
3 // Manic Miner PC
4 //
5 // 8/1997 By Andy Noble
6 //
7 // Compile: wcl386 /oneatx /zp4 /5 /fp3 manic.c
8 //
9 // LINUX PORT BY ADAM D. MOSS : adam@gimp.org
10 //
11 /////////////////////////////////////////////////////////////*/
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <math.h>
16 #include <sys/time.h>
17 #include <unistd.h>
19 #ifdef USE_X11
20 #include "emu_util.h"
21 #endif
24 /* ADMNOTE */
25 #ifdef USE_X11
26 #include <sys/ipc.h>
27 #include <sys/shm.h>
28 #include <X11/Xlib.h>
29 #include <X11/Xutil.h>
30 #include <X11/extensions/XShm.h>
31 #include <X11/cursorfont.h>
32 #include <X11/keysymdef.h>
33 #else
34 #include <vga.h>
35 #endif /* USE_X11 */
38 #ifdef USE_MIKMOD
39 #include <sys/stat.h>
40 #include <mikmod.h>
41 #include <ptform.h>
42 #endif /* USE_MIKMOD */
45 #include "mm-keydf.c"
48 /*/////////////////////////////////////////////////////////////
49 // Keyboard Variables
50 /////////////////////////////////////////////////////////////*/
52 typedef unsigned long DWORD;
53 typedef unsigned short WORD;
54 typedef unsigned char BYTE;
56 typedef unsigned int uint32;
57 typedef unsigned short int uint16;
58 typedef unsigned char uint8;
62 /*************************************************************/
63 /*************************************************************/
64 /************** X INIT STUFF *********************************/
65 #ifdef USE_X11
67 int wwidth = 320;
68 int wheight = 200;
70 Colormap cmap;
71 Display *display;
72 Window window;
73 GC gc;
74 XImage *ximage;
75 Cursor cursor;
77 int has_colourmap=0;
78 int depth=0;
79 int depth_bytes=0;
80 int bytesdeep;
82 static int shmem_flag=1;
83 static XShmSegmentInfo shminfo1;
84 static int gXErrorFlag;
86 XColor pal[256];
87 XColor xcolor;
88 void* pix;
90 #define error(x) fprintf(stderr,"%s\n",x);fflush(stderr);abort
92 static int HandleXError(dpy, event)
93 Display *dpy;
94 XErrorEvent *event;
96 gXErrorFlag = 1;
98 return 0;
101 static void InstallXErrorHandler()
103 XSetErrorHandler(HandleXError);
104 XFlush(display);
107 static void DeInstallXErrorHandler()
109 XSetErrorHandler(NULL);
110 XFlush(display);
113 void init_Xdisplay(char *name)
115 char *hello = "Manic Miner";
116 XSizeHints hint;
117 XSetWindowAttributes xswa;
118 XColor cursorfg, cursorbg;
119 int screen;
122 display = XOpenDisplay(name);
124 if (display == NULL)
125 error("Cannot open display.\n");
127 screen = DefaultScreen(display);
129 printf("DefaultDepth: %d, DisplayCells: %d, defaultvisualid: %ld, defaultclass: %d, BYTESDEEP: ",
130 DefaultDepth(display,screen),
131 DisplayCells(display,screen),
132 DefaultVisual(display,screen)->visualid,
133 DefaultVisual(display,screen)->class);
135 has_colourmap = (DefaultVisual(display,screen)->class&1);
136 depth = DefaultDepth(display,screen);
137 bytesdeep = (int)ceil(((double)depth)/8.0);
138 depth_bytes = bytesdeep = bytesdeep == 3 ? 4 : bytesdeep;
140 printf("%d \n\n", depth_bytes);
142 if ((bytesdeep!=1)&&(bytesdeep!=2)&&(bytesdeep!=4))
144 error("!!!WARNING!!!\nThis game probably can't cope with your X server's graphics mode.\nWe like 8, 15/16, or 32-bit modes.\nWe'll carry on regardless.\nIt probably won't work.\n");
148 hint.width = hint.max_width = hint.min_width = wwidth;
149 hint.height = hint.max_height =hint.min_height = wheight;
151 hint.flags = PSize|PMinSize|PMaxSize;
153 window = XCreateWindow(display, DefaultRootWindow(display), 0,0,
154 hint.width, hint.height, 0,
155 CopyFromParent, InputOutput, CopyFromParent,
156 0, NULL);
158 XSetWMNormalHints( display, window, &hint );
160 cursor = XCreateFontCursor( display, XC_circle );
161 cursorfg.red = 65535;
162 cursorfg.blue = cursorfg.green = 0;
163 cursorbg.red = cursorbg.green = cursorbg.blue = 0;
164 XRecolorCursor( display, cursor, &cursorfg, &cursorbg );
165 XDefineCursor( display, window, cursor );
168 xswa.event_mask = KeyPressMask | KeyReleaseMask
169 | EnterWindowMask | LeaveWindowMask;
170 XSelectInput(display, window, xswa.event_mask);
172 XSetStandardProperties (display, window, hello, hello, None, NULL, 0, &hint);
173 XMapWindow(display, window);
175 /* allocate colours */
176 gc = DefaultGC(display, screen);
177 cmap = DefaultColormap(display, screen);
179 pix = calloc(1, 256 * bytesdeep);
181 if (XShmQueryExtension(display))
183 shmem_flag = 1;
184 printf("Using SHM. Neat.\n");
186 else
188 shmem_flag = 0;
189 fprintf(stderr, "Ugh, no SHM. Never mind.\n");
192 XSync(display, False);
194 /************** SHM INIT *************************************/
196 InstallXErrorHandler();
198 if (shmem_flag)
200 ximage = XShmCreateImage(display, None, depth, ZPixmap, NULL,
201 &shminfo1,
202 wwidth, wheight);
204 /* If no go, then revert to normal Xlib calls. */
206 if (ximage==NULL)
208 if (ximage!=NULL)
209 XDestroyImage(ximage);
210 fprintf(stderr, "Shared memory error, disabling (Ximage error)\n");
213 /* Success here, continue. */
215 shminfo1.shmid = shmget(IPC_PRIVATE,
216 wwidth*wheight*depth_bytes,
217 IPC_CREAT | 0777);
219 if (shminfo1.shmid<0)
221 XDestroyImage(ximage);
222 fprintf(stderr, "Shared memory error, disabling (seg id error)\n");
225 shminfo1.shmaddr = (char *) shmat(shminfo1.shmid, 0, 0);
227 if (shminfo1.shmaddr==((char *) -1))
229 XDestroyImage(ximage);
230 if (shminfo1.shmaddr!=((char *) -1))
231 shmdt(shminfo1.shmaddr);
232 fprintf(stderr, "Shared memory error, disabling (address error)\n");
235 ximage->data = shminfo1.shmaddr;
237 shminfo1.readOnly = False;
238 XShmAttach(display, &shminfo1);
240 XSync(display, False);
242 if (gXErrorFlag)
244 /* Ultimate failure here. */
245 XDestroyImage(ximage);
246 shmdt(shminfo1.shmaddr);
247 fprintf(stderr, "Shared memory error, disabling.\n");
248 gXErrorFlag = 0;
250 else
252 shmctl(shminfo1.shmid, IPC_RMID, 0);
255 fprintf(stderr, "Sharing memory. [ %d x %d ]\n",wwidth,wheight);
258 DeInstallXErrorHandler();
260 /********* END OF SHM INIT ***********************************/
261 XSync(display, False);
263 #endif
264 /************** END OF X INIT STUFF **************************/
265 /*************************************************************/
266 /*************************************************************/
270 unsigned long Old_Isr;
271 BYTE KeyTable[256];
272 /*/////////////////////////////////////////////////////////////
273 // Revision Number
274 /////////////////////////////////////////////////////////////*/
275 BYTE VERSION[]={"V1.07"};
279 /* ADMNOTE: darn case-insensitive DOS C compilers ;) */
280 #define DrawEUGENE DrawEugene
281 #define DrawKONG DrawKong
282 #define DrawWILLY DrawWilly
283 #define DrawVROBO DrawVRobo
284 #define cls Cls
287 /* LINUX SOUND STUFF */
288 int dsp;
289 int enable_sound;
290 #define SOUNDDEVICE "/dev/dsp"
291 #define SAMPLERATE 44100
293 /* ADMNOTE: MIDAS STUBS - FIXME */
295 typedef struct _MIDASsampleSTRUCT
297 BYTE* data;
298 int length;
299 } MIDASsampleSTRUCT;
300 typedef MIDASsampleSTRUCT* MIDASsample;
301 typedef void* MIDASmodule;
302 typedef void* MIDASmodulePlayHandle;
303 typedef void* MIDASplayStatus;
304 void MIDASstartup(void)
306 int bits = AFMT_U8;
307 int stereo = 0;
308 int rate = SAMPLERATE;
309 int frag=0x00020009;
311 if ((dsp=open(SOUNDDEVICE,O_WRONLY))==-1)
313 perror(SOUNDDEVICE);
314 enable_sound = 0;
315 return;
318 enable_sound = 1;
320 ioctl(dsp,SNDCTL_DSP_SETFRAGMENT, &frag);
321 ioctl(dsp,SNDCTL_DSP_RESET);
322 ioctl(dsp,SNDCTL_DSP_SAMPLESIZE,&bits);
323 ioctl(dsp,SNDCTL_DSP_STEREO,&stereo);
324 ioctl(dsp,SNDCTL_DSP_SPEED,&rate);
325 ioctl(dsp,SNDCTL_DSP_SYNC);
326 ioctl(dsp,SNDCTL_DSP_NONBLOCK);
328 void MIDASconfig(void) {};
329 void MIDASsaveConfig(char* a) {};
330 void MIDASloadConfig(char* a) {};
331 int MIDASgetDisplayRefreshRate(void) {};
332 int MIDASinit(void) {};
333 void MIDASsetOption(int a, int b) {};
334 void* MIDASloadModule(char* a) {};
335 void* MIDASloadWaveSample(char* a, int b)
337 MIDASsample newsample;
338 struct stat sts;
339 FILE* fp;
341 newsample = malloc(sizeof(MIDASsampleSTRUCT));
343 stat(a, &sts);
344 newsample->length = sts.st_size;
346 newsample->data = malloc(newsample->length);
348 fp = fopen(a, "rb");
349 fread(newsample->data, newsample->length, 1, fp);
350 fclose(fp);
352 return(newsample);
354 void MIDASsetTimerCallbacks(int a, int b, char* c, char* d, char* e) {};
355 void MIDASopenChannels(int a) {};
356 void MIDASstopModule(void* a) {};
357 void MIDAScloseChannels(void) {};
358 void MIDASclose(void) {};
359 void MIDASfreeModule(void* a) {};
360 void MIDASfreeSample(void* a)
362 free(((MIDASsample)a)->data);
363 free((MIDASsample)a);
365 void MIDASplaySample(void* a, int b, int c, int d, int e, int f)
367 if (enable_sound)
369 if (d==SAMPLERATE)
371 //int rate = d;
372 // ioctl(dsp,SNDCTL_DSP_SPEED,&rate);
373 write(dsp, ((MIDASsample)a)->data, ((MIDASsample)a)->length);
375 else
377 int i,j,len,destlen;
378 static BYTE* sbuff = NULL;
379 static sbuff_len = 0;
381 len = ((MIDASsample)a)->length;
382 destlen = (len*SAMPLERATE)/d;
384 if (destlen > sbuff_len)
386 free(sbuff);
387 sbuff = malloc(destlen);
388 sbuff_len = destlen;
391 for (i=0;i<destlen;i++)
392 sbuff[i] = ((((MIDASsample)a)->data)[(i*len)/destlen]);
395 write(dsp, sbuff, destlen);
399 void* MIDASplayModuleSection(void* a, int b, int c, int d, int e) {};
400 void* MIDASplayMoleSection(void* a, int b, int c, int d, int e) {};
401 void MIDASsetMusicVolume(void* a, int b) {};
402 void MIDASgetPlayStatus(void* a, void* b) {};
403 #define MIDAS_CALL
404 #define TRUE (0==0)
405 #define FALSE (0!=0)
406 #define MIDAS_OPTION_FILTER_MODE 0
407 #define MIDAS_FILTER_NONE 0
408 #define MIDAS_LOOP_NO 0
409 #define MIDAS_PAN_MIDDLE 0
412 #define MIDAS_CALL /**/
413 #define TRUE (0==0)
414 #define FALSE (0!=0)
415 #define MIDAS_OPTION_FILTER_MODE 0
416 #define MIDAS_FILTER_NONE 0
417 #define MIDAS_LOOP_NO 0
418 #define MIDAS_PAN_MIDDLE 0
419 #ifdef USE_MIKMOD
420 typedef SAMPLE* MIDASsample;
421 typedef UNIMOD* MIDASmodule;
422 typedef UNIMOD* MIDASmodulePlayHandle;
423 #else
424 typedef char* MIDASsample;
425 typedef char* MIDASmodule;
426 typedef char* MIDASmodulePlayHandle;
427 #endif
428 void MIDASstartup(void)
430 #ifdef USE_MIKMOD
431 md_mixfreq = 44100; /* standard mixing freq */
432 md_dmabufsize = 1024; /* standard dma buf size (max 32000) */
433 md_device = 0; /* standard device: autodetect */
434 md_volume = 128; /* driver volume (max 128) */
435 md_musicvolume = 128; /* music volume (max 128) */
436 md_sndfxvolume = 128; /* sound effects volume (max 128) */
437 md_pansep = 100; /* panning separation (0 = mono, 128 = full stereo) */
438 md_reverb = 0; /* Reverb (max 15) */
439 md_mode = DMODE_16BITS |
440 DMODE_INTERP |
441 DMODE_STEREO |
442 DMODE_SOFT_MUSIC |
443 DMODE_SOFT_SNDFX; /* default mixing mode */
445 MikMod_RegisterAllLoaders();
446 MikMod_RegisterAllDrivers();
447 MikMod_SetNumVoices(6,6);
448 #endif
450 void MIDASconfig(void) {};
451 void MIDASsaveConfig(char* a) {};
452 void MIDASloadConfig(char* a) {};
453 int MIDASgetDisplayRefreshRate(void) {};
454 int MIDASinit(void)
456 #ifdef USE_MIKMOD
457 MikMod_Init();
458 #endif
459 return TRUE;
461 void MIDASsetOption(int a, int b) {};
462 MIDASmodule MIDASloadModule(char* a)
464 MIDASmodule s;
466 #ifdef USE_MIKMOD
467 s = MikMod_LoadSong(a, 6);
468 #endif
470 return s;
472 MIDASsample MIDASloadWaveSample(char* a, int b)
474 MIDASsample newsample;
475 #ifdef USE_MIKMOD
476 struct stat sts;
477 FILE* fp;
479 newsample = calloc(1, sizeof(SAMPLE));
481 stat(a, &sts);
483 newsample->length = sts.st_size;
484 /* newsample->flags = SF_UNSIGNED; */
485 newsample->speed = 22050;
486 newsample->volume = 63;
488 fp = fopen(a, "rb");
489 SL_RegisterSample(newsample,MD_SNDFX,fp);
490 SL_LoadSamples();
492 /* printf("%p\n",newsample);fflush(stdout); */
493 #endif
495 return(newsample);
497 void MIDASsetTimerCallbacks(int a, int b, char* c, char* d, char* e) {};
498 void MIDASopenChannels(int a) {};
499 void MIDASstopModule(void* a)
501 #ifdef USE_MIKMOD
502 MP_SetPosition(a, 17);
503 /* MikMod_Update(); */
504 Player_Stop();
505 #endif
507 void MIDAScloseChannels(void) {};
508 void MIDASclose(void) {};
509 void MIDASfreeModule(MIDASmodule a) {};
510 void MIDASfreeSample(MIDASsample a)
512 #ifdef USE_MIKMOD
513 if (a != NULL)
515 MD_SampleUnLoad(a->handle);
516 free(a);
518 #endif
520 void MIDASplaySample(MIDASsample a, int b, int c, int d, int e, int f)
522 #ifdef USE_MIKMOD
523 int voice;
525 /* MikMod_Update(); */
526 voice = MikMod_PlaySample(a, 0, 0);
527 /* Voice_SetVolume(voice, e); */
528 Voice_SetFrequency(voice, d);
529 Voice_SetPanning(voice, 128);
530 /* MikMod_Update(); */
531 #endif
533 MIDASmodule MIDASplayModuleSection(MIDASmodule a, int b, int c, int d, int e)
535 #ifdef USE_MIKMOD
536 MP_SetPosition(a, b);
538 Player_Start(a);
539 /* MikMod_Update(); */
540 #endif
541 return a;
543 void MIDASsetMusicVolume(MIDASmodule a, int b)
545 /* md_musicvolume = (b*127)/64; */
551 /*/////////////////////////////////////////////////////////////
552 // Includes
553 /////////////////////////////////////////////////////////////*/
554 #include "mm-pal.c"
556 #include "mm-map2.c"
557 #include "mm-blocx.c"
558 #include "mm-conv.c"
559 #include "mm-exits.c"
560 #include "mm-keys2.c"
561 #include "mm-tplat.c"
562 #include "mm-air.c"
563 #include "mm-hrobo.c"
564 #include "mm-vrobo.c"
565 #include "mm-final.c"
566 #include "mm-swit.c"
567 #include "mm-font.c"
568 #include "mm-fant.c"
569 #include "mm-over.c"
571 #include "mm-eug2.c"
572 #include "mm-kong.c"
573 #include "mm-sky.c"
574 #include "mm-sun.c"
575 #include "mm-fill.c"
576 #include "mm-piano.c"
577 #include "mm-pkeys.c"
578 #include "mm-load.c"
580 #include "mm-willy.c"
581 #include "mm-ftsml.c"
583 #include "mm-house.c"
584 #include "mm-win.c"
586 #include "mm-end.c"
588 /*/////////////////////////////////////////////////////////////
589 // Globals
590 /////////////////////////////////////////////////////////////*/
592 BYTE old_video;
593 /*ADMNOTE
594 //BYTE *screen=(BYTE *)0xa0000;
595 //BYTE screen[64000 * 4]; */
596 BYTE* screen = NULL;
597 #ifdef USE_X11
598 #else
599 BYTE* realscreen = NULL;
600 #endif
601 BYTE page1[64000];
602 BYTE page2[64000];
603 int pix_offset = 0;
604 int yoff[400];
606 BYTE page,vpage;
608 BYTE bright[]= {0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1};
609 BYTE bright2[]={0,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1};
611 #define KONGPAUSE 8
613 BYTE PALwhite[768];
614 BYTE PALblack[768];
615 BYTE PALfade[768];
616 BYTE PALover[768];
618 /*/////////////////////////////////////////////////////////////
619 // Current Map Info
620 /////////////////////////////////////////////////////////////*/
622 BYTE cMAP[512];
623 BYTE cCRUMB[512];
624 BYTE cTITLE[33];
626 BYTE cBGink;
627 BYTE cBGpaper;
629 BYTE cPLAT1ink;
630 BYTE cPLAT1paper;
632 BYTE cPLAT2ink;
633 BYTE cPLAT2paper;
635 BYTE cWALLink;
636 BYTE cWALLpaper;
638 BYTE cCRUMBink;
639 BYTE cCRUMBpaper;
641 BYTE cKILL1ink;
642 BYTE cKILL1paper;
644 BYTE cKILL2ink;
645 BYTE cKILL2paper;
647 BYTE cCONVink;
648 BYTE cCONVpaper;
650 BYTE cBORDER;
652 BYTE cPLAT1gfx;
653 BYTE cPLAT2gfx;
654 BYTE cWALLgfx;
655 BYTE cCRUMBgfx;
656 BYTE cKILL1gfx;
657 BYTE cKILL2gfx;
658 BYTE cCONVgfx;
659 BYTE cEXITgfx;
660 BYTE cKEYgfx;
662 WORD cWILLYx;
663 WORD cWILLYy;
664 WORD cWILLYxold[2];
665 WORD cWILLYyold[2];
666 WORD cWILLYf;
667 BYTE cWILLYd;
668 BYTE cWILLYm;
669 BYTE cWILLYj;
670 BYTE cWILLYbuff[2][256];
671 WORD cWILLYjp[]={4,4,3,3,2,2,1,1,0,0,1,1,2,2,3,3,4,4};
672 WORD cWILLYfall;
673 WORD cWILLYjs;
675 WORD cCONVx;
676 WORD cCONVy;
677 BYTE cCONVd;
678 BYTE cCONVl;
679 BYTE cCONVf;
680 BYTE cCONVm;
682 WORD cKEYx[5];
683 WORD cKEYy[5];
684 BYTE cKEYb[5];
685 BYTE cKEYs[5];
687 WORD cSWITCHx[2];
688 WORD cSWITCHy[2];
689 BYTE cSWITCHs[2];
691 WORD cEXITx;
692 WORD cEXITy;
693 BYTE cEXITb;
694 BYTE cEXITm;
696 BYTE cAIR;
697 BYTE cAIRp;
699 BYTE cHROBOink[4];
700 BYTE cHROBOpaper[4];
701 WORD cHROBOx[4];
702 WORD cHROBOy[4];
703 WORD cHROBOmin[4];
704 WORD cHROBOmax[4];
705 BYTE cHROBOd[4];
706 BYTE cHROBOs[4];
707 WORD cHROBOgfx[4];
708 BYTE cHROBOflip[4];
709 BYTE cHROBOanim[4];
710 WORD cHROBOxold[4][2];
711 WORD cHROBOyold[4][2];
713 BYTE cVROBOink[4];
714 BYTE cVROBOpaper[4];
715 WORD cVROBOx[4];
716 WORD cVROBOy[4];
717 WORD cVROBOmin[4];
718 WORD cVROBOmax[4];
719 BYTE cVROBOd[4];
720 BYTE cVROBOs[4];
721 WORD cVROBOgfx[4];
722 BYTE cVROBOanim[4];
723 WORD cVROBOxold[4][2];
724 WORD cVROBOyold[4][2];
726 /*/////////////////////////////////////////////////////////////
727 // Special Robots
728 /////////////////////////////////////////////////////////////*/
730 WORD EUGENEx;
731 WORD EUGENEy;
732 WORD EUGENEmin;
733 WORD EUGENEmax;
734 BYTE EUGENEd;
735 BYTE EUGENEm;
736 BYTE EUGENEc;
737 WORD EUGENExold[2];
738 WORD EUGENEyold[2];
740 BYTE SWITCH1m;
741 BYTE SWITCH2m;
743 WORD HOLEy;
744 BYTE HOLEl;
746 WORD KONGx;
747 WORD KONGy;
748 WORD KONGxold[2];
749 WORD KONGyold[2];
750 WORD KONGmax;
751 BYTE KONGm;
752 BYTE KONGc;
753 BYTE KONGf;
754 BYTE KONGp;
756 WORD SKYx[3];
757 WORD SKYy[3];
758 WORD SKYmax[3];
759 WORD SKYxold[3][2];
760 WORD SKYyold[3][2];
761 BYTE SKYs[3];
762 BYTE SKYf[3];
763 BYTE SKYm[3];
764 BYTE SKYc[3];
765 BYTE SKYp[3];
767 BYTE DEATHm;
768 WORD DEATHc;
770 WORD BOOTy;
772 WORD SUNy;
773 BYTE SUNm;
774 BYTE SUNh;
775 BYTE SUNbuff[2][384];
776 WORD SUNyold[2];
777 BYTE SUNhold[2];
779 /*/////////////////////////////////////////////////////////////
780 // Solar Power Generator
781 /////////////////////////////////////////////////////////////*/
783 WORD SPGx[2][64];
784 WORD SPGy[2][64];
786 /*/////////////////////////////////////////////////////////////
787 // Game Globals
788 /////////////////////////////////////////////////////////////*/
790 unsigned long SCORE;
791 unsigned long HISCORE=0;
792 unsigned long EXTRA;
793 unsigned long EXTRAdelta=10000;
794 BYTE EXTRAm;
795 BYTE EXTRAc;
797 WORD LIVES;
798 BYTE LIVESf;
799 BYTE LIVESp;
800 BYTE LEVEL=0;
802 BYTE MUSICon=1;
804 BYTE old=0;
806 BYTE SPEED=2;
808 BYTE MODE=3;
809 BYTE GAMEm=0;
811 BYTE DEMOm=0;
812 BYTE DEMOp;
814 BYTE TITLEm=0;
815 BYTE TITLEwf;
816 BYTE TITLEwp;
818 BYTE OVERm=0;
819 BYTE OVERink;
820 BYTE OVERp;
822 BYTE INK=7;
823 BYTE PAPER=0;
825 BYTE CHEAT=0;
826 BYTE CHEATp=0;
827 BYTE CHEATh;
828 BYTE CHEATkey[]={9,11,3,10,3,7};
830 BYTE PAUSE;
831 BYTE LASTm;
832 WORD LASTc;
833 BYTE LASTp;
834 WORD WINDOW[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
836 BYTE TEXTm;
837 WORD TEXTpause;
838 BYTE TEXTpoint;
839 BYTE TEXTink;
840 BYTE TEXTfade;
842 /*///////////////////////////////////////////////////////////*/
844 BYTE PIANOkhit[32];
845 BYTE PIANOkey[]={0,1,1,2,0,1,2,0,1,1,2,0,1,2,0,1,2,0,1,1,2,0,1,2,0,1,1,2,0,1,2,3};
846 WORD PIANOc;
847 BYTE PIANObodge1;
848 BYTE PIANObodge2;
849 BYTE PIANObodgep;
850 BYTE PIANObodgep2;
852 BYTE SCROLLbuff[]=" ";
853 WORD SCROLLpos;
854 BYTE PIXELbuff[264*8];
855 WORD PIXELoff;
857 BYTE LOADm;
858 BYTE LOADp;
860 BYTE PREFSm;
861 BYTE PREFSh1;
862 BYTE PREFSh2;
863 BYTE PREFSh3;
865 BYTE CHAN[]={0,1,2,8,9,10,16,17,18};
868 /*/////////////////////////////////////////////////////////////
869 // Tales from a Parallel Universe
870 /////////////////////////////////////////////////////////////*/
872 BYTE TONKS=0;
874 /*/////////////////////////////////////////////////////////////
875 // Audio Stuff
876 /////////////////////////////////////////////////////////////*/
877 #define INGAMEpc 0x00
878 #define INGAMEspec 0x09
879 #define TITLEmusic 0x0d
880 #define OPTIONSmusic 0x12
881 #define FINALcavern 0x16
882 #define ENDsequence 0x20
884 BYTE MUSICtype=0;
885 BYTE VOL=64;
887 BYTE MUSICh;
892 /*ADMNOTE: we manually handle timers on UNIX
893 //WORD volatile FrCt=0; */
894 WORD FrCt=0;
895 /* 60 Hz */
896 #define FHZ 60
897 #define microsec_per_frame 16666
898 WORD UpdateFrCt(void)
900 static int firsttime = TRUE;
901 static long long first_timer_ctr;
902 static long long this_timer_ctr;
903 static int this_frnum;
904 static int last_frnum;
905 struct timeval tv;
907 if (firsttime)
909 gettimeofday(&tv, NULL);
910 first_timer_ctr = (tv.tv_sec*1000000)+tv.tv_usec;
911 firsttime = FALSE;
912 last_frnum = 0;
915 gettimeofday(&tv, NULL);
916 this_timer_ctr = (tv.tv_sec*1000000)+tv.tv_usec;
918 this_frnum = (this_timer_ctr - first_timer_ctr) / microsec_per_frame;
920 FrCt += (this_frnum - last_frnum);
922 last_frnum = this_frnum;
924 return(FrCt);
928 WORD NEXTBIT=0;
929 DWORD REFRESH;
930 MIDASsample wav;
931 MIDASsample die;
932 MIDASsample pick;
933 MIDASmodule mod;
934 MIDASmodulePlayHandle modon=0;
936 BYTE FORCE;
937 /*/////////////////////////////////////////////////////////////
939 /////////////////////////////////////////////////////////////*/
941 void MIDAS_CALL PREvr(void);
943 /*/////////////////////////////////////////////////////////////
944 // Main Code.
945 /////////////////////////////////////////////////////////////*/
946 int main(int argc, BYTE *argv[])
948 int quit=0;
950 #ifdef USE_X11
951 init_Xdisplay(NULL);
953 slowdown_init(FHZ);
954 #else
955 /*ADMNOTE: set up SVGALIB */
956 vga_init();
957 vga_setmode(5);
958 keyboard_init();
959 keyboard_setdefaulteventhandler();
960 realscreen=(BYTE*) vga_getgraphmem();
961 #endif
963 pix_offset = 33 + 4*320; /* for screen centering in this mode */
966 if(argc==2)
968 FORCE=1;
970 else
972 FORCE=0;
975 MIDASstartup();
977 LoadInfo();
979 SetupSound();
981 GetVideoMode( &old_video );
983 screen = page1;
985 /*------------------------------------------------------------- */
987 REFRESH=MIDASgetDisplayRefreshRate();
988 if(REFRESH==0)
989 REFRESH=59450;
991 MIDASsetOption(MIDAS_OPTION_FILTER_MODE,MIDAS_FILTER_NONE);
993 if(MIDASinit()==FALSE)
995 return(0);
998 mod=MIDASloadModule("mm-data1.dat");
999 //ADMNOTE: filenames changed, now not M$ wav
1000 wav=MIDASloadWaveSample("mm-data2.raw",MIDAS_LOOP_NO);
1001 die=MIDASloadWaveSample("mm-data3.raw",MIDAS_LOOP_NO);
1002 pick=MIDASloadWaveSample("mm-data4.raw",MIDAS_LOOP_NO);
1003 /* wav=MIDASloadWaveSample("mm-data2.dat",MIDAS_LOOP_NO);
1004 die=MIDASloadWaveSample("mm-data3.dat",MIDAS_LOOP_NO);
1005 pick=MIDASloadWaveSample("mm-data4.dat",MIDAS_LOOP_NO);*/
1007 MIDASsetTimerCallbacks(REFRESH,TRUE,&PREvr,NULL,NULL);
1008 MIDASopenChannels(9);
1010 /*------------------------------------------------------------- */
1012 SetKeyboard();
1014 Cls(0);
1015 WaitVR();
1016 PaletteSet(PALblack);
1018 WaitVR();
1019 Cls(0);
1020 SwapPage();
1022 WaitVR();
1023 PaletteSet(PALmain);
1024 Cls(0);
1025 SwapPage();
1027 LOADm=0;
1033 switch(MODE)
1035 case 0://TITLES
1036 Titles();
1037 break;
1038 case 1://DEMO
1039 DoDemo();
1040 break;
1041 case 2://GAME
1042 DoGame();
1043 break;
1044 case 3://LOADING
1045 DoLoading();
1046 break;
1050 if( KeyTable[key_f10]==1 )
1051 quit=1;
1054 while( quit==0 );
1056 /*------------------------------------------------------------- */
1057 if(modon!=0)
1058 MIDASstopModule(modon);
1060 MIDAScloseChannels();
1061 MIDASfreeModule(mod);
1062 MIDASfreeSample(wav);
1063 MIDASfreeSample(die);
1064 MIDASfreeSample(pick);
1065 MIDASclose();
1067 /*------------------------------------------------------------- */
1069 WaitVR2();
1070 PaletteSet(PALblack);
1072 WaitVR2();
1073 SetVideoMode(old_video);
1075 SaveInfo();
1077 printf("Manic Miner PC %s.\n",VERSION);
1078 printf("Andy Noble (andy@andyn.demon.co.uk) 8/1997 - DOS version\n");
1079 printf("Adam D. Moss (adam@foxbox.org) 12/1997 - UNIX port\n");
1081 /*printf("Refresh=%d\n\n",REFRESH); */
1083 /*ADMNOTE - vga/kbd stuff*/
1084 #ifdef USE_X11
1085 #else
1086 keyboard_close();
1087 vga_setmode(TEXT);
1088 #endif
1091 return(0);
1094 /*/////////////////////////////////////////////////////////////
1095 // Restore Bios Keyboard Interupt
1096 /////////////////////////////////////////////////////////////*/
1097 void RemoveKeyboard( void )
1101 /*/////////////////////////////////////////////////////////////
1102 // Set Our Keyboard Interupt
1103 /////////////////////////////////////////////////////////////*/
1104 void SetKeyboard( void )
1107 memset( KeyTable, (BYTE)0, 256 );
1112 /*/////////////////////////////////////////////////////////////
1113 // Pressed any key ?
1114 /////////////////////////////////////////////////////////////*/
1117 AnyKeyx
1118 (void)
1121 int count;
1123 /* ADMNOTE */
1124 /* if (random()%3000 == 0) return (1);*/
1126 for( count=0; count<128; count++ )
1128 if(KeyTable[count] != 0 )
1129 return(1);
1131 return(0);
1135 ///////////////////////////////////////////////////////////////
1136 // Flush our Keyboard Buffer
1137 ///////////////////////////////////////////////////////////////
1138 void FlushKey( void )
1140 memset( KeyTable, (BYTE)0, 256 );
1143 ///////////////////////////////////////////////////////////////
1144 // Set Screen Mode.
1145 ///////////////////////////////////////////////////////////////
1146 void SetVideoMode(int mode)
1151 ///////////////////////////////////////////////////////////////
1152 // Get Screen Mode.
1153 ///////////////////////////////////////////////////////////////
1154 void GetVideoMode( BYTE *vidmode )
1160 /*/////////////////////////////////////////////////////////////
1161 // Wait Vertical Retrace
1162 /////////////////////////////////////////////////////////////*/
1163 void WaitVR( void )
1165 #ifdef USE_X11
1166 #else
1167 WORD old;
1169 /*ADMNOTE*/
1170 old=UpdateFrCt();
1171 #endif
1173 #ifdef USE_MIKMOD
1174 MikMod_Update();
1175 #endif
1177 #ifdef USE_X11
1178 /*putchar('1'+slowdown_slow());*/
1179 XFlush(display);
1180 slowdown_slow();
1181 #else
1182 while(old==UpdateFrCt()) {};
1183 #endif
1185 /*ADMNOTE: we throw in a keyboard check here! */
1186 DoKeymap();
1188 /*old=FrCt;
1189 while(old==FrCt);*/
1193 /*/////////////////////////////////////////////////////////////
1194 // Wait Vertical Retrace
1195 /////////////////////////////////////////////////////////////*/
1196 void WaitVR2( void )
1198 DoKeymap();
1200 #ifdef USE_MIKMOD
1201 MikMod_Update();
1202 #endif
1204 WaitVR3();
1207 #ifdef USE_X11
1209 #ifdef USE_MIKMOD
1210 MikMod_Update();
1211 #endif
1212 WaitVR3();
1213 #ifdef USE_MIKMOD
1214 MikMod_Update();
1215 #endif
1216 WaitVR3();
1218 #else
1219 vga_waitretrace();
1220 #endif
1226 /*/////////////////////////////////////////////////////////////
1227 // ADMNOTE: UNIX: Update keyboard state
1228 /////////////////////////////////////////////////////////////*/
1229 int DoKeymap ( void )
1231 #ifdef USE_X11
1233 KeySym ks = 0;
1234 int kstat;
1235 XEvent event;
1236 char buf[21];
1238 while (XPending(display))
1240 XNextEvent(display, &event);
1242 switch (event.type)
1244 case KeyPress:
1245 kstat = 1;
1246 case KeyRelease:
1247 if (event.type == KeyRelease)
1248 kstat = 0;
1250 XLookupString(&event.xkey, buf, 20, &ks, NULL);
1252 switch (ks)
1254 case 0xFF0D : KeyTable[key_return] = kstat; break;
1255 case 0xFF52 :
1256 case 0xFF97 :
1257 case ' ' : KeyTable[key_space] = kstat; break;
1258 case 0xFF51 :
1259 case 'O' :
1260 case 'o' : KeyTable[key_o] = kstat; break;
1261 case 0xFF53 :
1262 case 'P' :
1263 case 'p' : KeyTable[key_p] = kstat; break;
1264 case 0xFF1B : KeyTable[key_esc] = kstat; break;
1265 case 0xFF91 :
1266 case 0xFFBE : KeyTable[key_f1] = kstat; break;
1267 case 0xFF92 :
1268 case 0xFFBF : KeyTable[key_f2] = kstat; break;
1269 case 0xFF93 :
1270 case 0xFFC0 : KeyTable[key_f3] = kstat; break;
1271 case 0xFF94 :
1272 case 0xFFC1 : KeyTable[key_f4] = kstat; break;
1273 case 0xFFC7 : KeyTable[key_f10] = kstat; break;
1274 default: break;
1277 break;
1278 default: break;
1282 #else
1283 if (keyboard_update()==0) return;
1285 /* Otherwise, something changed with the keyboard...
1286 // ah, sod it... */
1288 memcpy(KeyTable, keyboard_getstate(), 256);
1289 #endif
1294 * PHYSICALLY DISPLAY 'SCREEN'
1296 void showscreen(void)
1298 #ifdef USE_X11
1299 if (shmem_flag)
1301 XShmPutImage(display, window, gc, ximage,
1302 0,0,
1303 0,0,
1304 wwidth, wheight, False);
1306 else
1308 XPutImage(display, window, gc, ximage,
1309 0,0,
1310 0,0,
1311 wwidth, wheight);
1313 XSync(display, False);
1314 #else
1315 memcpy(realscreen, screen, 64000);
1316 #endif
1320 /*/////////////////////////////////////////////////////////////
1321 // Swap Pages
1322 /////////////////////////////////////////////////////////////*/
1323 void SwapPage( void )
1325 WORD data;
1326 BYTE temp;
1328 /* ADMNOTE */
1329 page++;
1330 page&=1;
1331 vpage++;
1332 vpage&=1;
1333 WaitVR();
1334 showscreen();
1335 screen = (page==0 ? page1 : page2);
1336 old++;
1337 old&=1;
1338 return;
1340 /*/////////////////////////////////////////////////////////////
1341 // Swap Pages
1342 /////////////////////////////////////////////////////////////*/
1343 void SwapPage2( void)
1345 WORD data;
1346 BYTE temp;
1348 /*ADMNOTE */
1349 page++;
1350 page&=1;
1351 vpage++;
1352 vpage&=1;
1353 WaitVR3();
1354 showscreen();
1355 screen = (page==0 ? page1 : page2);
1356 old++;
1357 old&=1;
1358 return;
1361 /*/////////////////////////////////////////////////////////////
1362 // Wait Vertical Retrace
1363 /////////////////////////////////////////////////////////////*/
1364 void WaitVR3( void )
1366 WORD old;
1368 /* ADMNOTE: */
1370 #ifdef USE_MIKMOD
1371 MikMod_Update();
1372 #endif
1374 #ifdef USE_X11
1375 /*putchar('1'+slowdown_slow()); */
1376 XFlush(display);
1377 slowdown_slow();
1378 #else
1379 while(NEXTBIT>=UpdateFrCt()) {};
1380 #endif
1381 FrCt=0;
1382 DoKeymap();
1384 /*while(NEXTBIT>=FrCt);
1385 FrCt=0; */
1388 /*/////////////////////////////////////////////////////////////
1389 // Plot a Pixel to the Screen
1390 /////////////////////////////////////////////////////////////*/
1392 void PlotPixel( int x, int y, BYTE colour )
1394 int offset = 320*y + x + pix_offset;
1396 screen[offset] = colour;
1398 #ifdef USE_X11
1399 switch (bytesdeep)
1401 case 1:
1402 ((uint8 *)ximage->data)[offset] = ((uint8 *)pix)[colour]; break;
1403 case 2:
1404 ((uint16 *)ximage->data)[offset] = ((uint16 *)pix)[colour]; break;
1405 default:
1406 ((uint32 *)ximage->data)[offset] = ((uint32 *)pix)[colour]; break;
1408 #endif
1411 /*/////////////////////////////////////////////////////////////
1412 // Get a Pixel from the Screen
1413 /////////////////////////////////////////////////////////////*/
1414 char GetPixel( int x, int y )
1416 return (screen[320*y + x + pix_offset]);
1419 /*/////////////////////////////////////////////////////////////
1420 // Clear Current Page
1421 /////////////////////////////////////////////////////////////*/
1422 void Cls( BYTE col )
1424 int pcol, i;
1425 uint16* u16p;
1426 uint32* u32p;
1428 memset(screen, col, 64000);
1430 #ifdef USE_X11
1431 switch (bytesdeep)
1433 case 1:
1434 pcol = ((uint8 *)pix)[col];
1435 memset((uint8 *)ximage->data, pcol, wwidth*wheight);
1436 break;
1437 case 2:
1438 pcol = ((uint16 *)pix)[col];
1439 u16p = (uint16 *)ximage->data;
1440 for (i=0;i<wwidth*wheight;i++)
1442 *u16p++ = pcol;
1444 break;
1445 default:
1446 pcol = ((uint32 *)pix)[col];
1447 u32p = (uint32 *)ximage->data;
1448 for (i=0;i<wwidth*wheight;i++)
1450 *u32p++ = pcol;
1452 break;
1454 #endif
1458 /*/////////////////////////////////////////////////////////////
1459 // Set Palette1 with Palette2
1460 /////////////////////////////////////////////////////////////*/
1462 void PaletteFill( char *pal1, char *pal2 )
1464 int count;
1466 for(count=0;count<768;count++)
1467 pal1[count]=pal2[count];
1470 /*/////////////////////////////////////////////////////////////
1471 // Set palette
1472 /////////////////////////////////////////////////////////////*/
1474 void PaletteSet( char *pal1 )
1476 int count;
1478 #ifdef USE_X11
1479 static uint8 *lastpal = NULL;
1481 if (lastpal == NULL)
1483 lastpal = calloc(1, 256*3);
1486 for (count=0; count<256; count++)
1488 if (
1489 (lastpal[count*3+0] != pal1[count*3+0]) ||
1490 (lastpal[count*3+1] != pal1[count*3+1]) ||
1491 (lastpal[count*3+2] != pal1[count*3+2])
1494 pal[count].red = (pal1[count*3+0] * 65535) / 63 ;
1495 pal[count].green = (pal1[count*3+1] * 65535) / 63 ;
1496 pal[count].blue = (pal1[count*3+2] * 65535) / 63 ;
1497 pal[count].flags|=DoRed|DoGreen|DoBlue;
1499 if ( XAllocColor(display, cmap, &pal[count]) == 0 )
1500 printf("** XAllocColor FAILED **\n");
1502 switch (bytesdeep)
1504 case 1: ((uint8 *)pix)[count] =
1505 (uint8) pal[count].pixel; break;
1506 case 2: ((uint16 *)pix)[count] =
1507 (uint16) pal[count].pixel; break;
1508 default: ((uint32 *)pix)[count] =
1509 (uint32) pal[count].pixel; break;
1513 memcpy(lastpal, pal1, 256*3);
1515 #else
1517 for (count=0;count<256;count++)
1518 vga_setpalette(count,pal1[count*3],
1519 pal1[count*3 +1],
1520 pal1[count*3 +2]);
1522 #endif
1525 /*/////////////////////////////////////////////////////////////
1526 // Fade Palette
1527 /////////////////////////////////////////////////////////////*/
1529 int PaletteFade( unsigned char *pal1, unsigned char *pal2 )
1531 int count,changed;
1533 changed=0;
1535 for(count=0;count<768;count++)
1538 if(*pal1 != *pal2)
1540 if(*pal1 > *pal2)
1542 *pal2+=1;
1543 changed=1;
1545 else
1547 *pal2-=1;
1548 changed=1;
1552 pal1++;
1553 pal2++;
1556 return(changed);
1559 /*/////////////////////////////////////////////////////////////
1560 // Print Text
1561 /////////////////////////////////////////////////////////////*/
1562 void FontPrint( int xpos, int ypos, BYTE *text )
1564 int count,count2,count3;
1565 int currentx,currenty;
1566 int alpha;
1567 BYTE *fonty;
1569 count=0;
1571 xpos*=8;
1572 ypos*=8;
1574 currentx=xpos;
1575 currenty=ypos;
1577 while( *text != 0 )
1579 alpha=(int)*text;
1580 text++;
1582 if(alpha==170) /*="|" */
1584 currentx=0;
1585 currenty+=8;
1586 alpha=(int)*text;
1587 text++;
1591 alpha-=32;
1593 if(alpha>96)
1594 alpha-=32;
1596 alpha*=64;
1597 count++;
1598 if(count==33)
1599 return;
1601 fonty=(fontb+alpha);
1603 xpos=currentx;
1604 ypos=currenty;
1606 for(count2=0;count2<8;count2++)
1608 for(count3=0;count3<8;count3++)
1610 if( (*fonty != 0))
1611 PlotPixel(xpos,ypos,INK);
1612 else
1613 PlotPixel(xpos,ypos,PAPER);
1615 fonty++;
1616 xpos++;
1618 xpos=currentx;
1619 ypos++;
1621 currentx+=8;
1625 /*/////////////////////////////////////////////////////////////
1626 // Print Text
1627 /////////////////////////////////////////////////////////////*/
1628 void FontPrint2( int xpos, int ypos, BYTE *text )
1630 int count,count2,count3;
1631 int currentx,currenty;
1632 int alpha;
1633 BYTE *fonty,*fonty2,data,data2;
1635 count=0;
1637 xpos*=8;
1638 ypos*=8;
1640 currentx=xpos;
1641 currenty=ypos;
1643 while( *text != 0 )
1645 alpha=(int)*text;
1646 text++;
1648 if(alpha==170) /*="|" */
1650 currentx=0;
1651 currenty+=8;
1652 alpha=(int)*text;
1653 text++;
1657 alpha-=32;
1659 if(alpha>96)
1660 alpha-=32;
1662 alpha*=64;
1663 count++;
1664 if(count==33)
1665 return;
1667 fonty=(fontb+alpha);
1668 fonty2=(GFXfant+alpha);
1670 xpos=currentx;
1671 ypos=currenty;
1673 for(count2=0;count2<8;count2++)
1675 for(count3=0;count3<8;count3++)
1677 if( (*fonty != 0))
1678 PlotPixel(xpos,ypos,0);
1679 else
1681 if(*fonty2==1)
1683 data=GetPixel(xpos,ypos);
1684 data2=data&15;
1685 data2+=3;
1686 if(data2>15)
1687 data2=15;
1688 data&=240;
1689 data|=data2;
1690 PlotPixel(xpos,ypos,data);
1693 fonty++;
1694 fonty2++;
1695 xpos++;
1697 xpos=currentx;
1698 ypos++;
1700 currentx+=8;
1706 /*/////////////////////////////////////////////////////////////
1707 // Show a Long Word
1708 /////////////////////////////////////////////////////////////*/
1709 void ShowSix( int xpos, int ypos, unsigned long data )
1711 BYTE convtext[]={" "};
1712 BYTE printtext[]={" "};
1713 int count1,count2;
1714 BYTE *pointy;
1716 /* ADMNOTE: no ultoa in ansi/iso C
1717 /* ultoa( data,&convtext,10);*/
1718 sprintf(convtext, "%u", data);
1720 count2=0;
1721 for(count1=0;count1<7;count1++)
1723 if(convtext[count1]!=32)
1724 count2++;
1727 pointy=printtext+7;
1728 pointy-=count2;
1730 for(count1=0;count1<count2;count1++)
1732 *pointy=convtext[count1];
1733 pointy++;
1737 for(count1=0;count1<6;count1++)
1739 if(printtext[count1]==32)
1740 printtext[count1]=48;
1743 FontPrint(xpos,ypos,&printtext);
1746 /*/////////////////////////////////////////////////////////////
1747 // Print Text Small
1748 /////////////////////////////////////////////////////////////*/
1749 void FontPrintSmall( int xpos, int ypos, BYTE *text )
1751 int count,count2,count3;
1752 int currentx,currenty;
1753 int alpha;
1754 BYTE *fonty;
1756 count=0;
1758 xpos*=4;
1759 ypos*=6;
1761 currentx=xpos;
1762 currenty=ypos;
1764 while( *text != 0 )
1766 alpha=(int)*text;
1767 text++;
1769 if(alpha==170) /*="ª" */
1771 currentx=0;
1772 currenty+=8;
1773 alpha=(int)*text;
1774 text++;
1777 if(alpha==96) /*="`" */
1779 INK=(*text)-96;
1780 text++;
1781 alpha=(int)*text;
1782 text++;
1785 alpha-=32;
1787 if(alpha>64)
1788 alpha-=32;
1790 alpha*=64;
1792 fonty=(fonts+alpha);
1794 xpos=currentx;
1795 ypos=currenty;
1797 for(count2=0;count2<6;count2++)
1799 for(count3=0;count3<4;count3++)
1801 if( (*fonty != 0))
1802 PlotPixel(xpos,ypos,INK);
1803 else
1804 PlotPixel(xpos,ypos,PAPER);
1806 fonty++;
1807 xpos++;
1809 fonty+=4;
1810 xpos=currentx;
1811 ypos++;
1813 currentx+=4;
1818 /*/////////////////////////////////////////////////////////////
1819 // Main Code Includes
1820 /////////////////////////////////////////////////////////////*/
1821 #include "mm-core.c"
1822 #include "mm-game.c"
1823 #include "mm-demo.c"
1824 /*/////////////////////////////////////////////////////////////
1825 // Titles
1826 /////////////////////////////////////////////////////////////*/
1827 void Titles(void)
1829 switch(TITLEm)
1831 case 0:
1832 TitleSetup();
1833 break;
1834 case 1:
1835 DoPiano();
1836 break;
1837 case 2:
1838 ClearPiano();
1839 break;
1840 case 3:
1841 DoTitleScroll();
1842 break;
1843 case 4:
1844 DoPrefs();
1845 break;
1849 /*/////////////////////////////////////////////////////////////
1850 // Do Background Fill 1
1851 /////////////////////////////////////////////////////////////*/
1852 void Fill1(void)
1854 int x,y,block2;
1855 BYTE data;
1857 block2=0;
1859 for(y=0;y<24;y++)
1861 for(x=0;x<16;x++)
1863 data=GFXfill[block2];
1864 PlotPixel(152+x,40+y,data);
1865 block2++;
1870 /*////////////////////////////////////////////////////////////
1871 // Do Background Fill 2
1872 /////////////////////////////////////////////////////////////*/
1873 void Fill2(void)
1875 int x,y,block2;
1876 BYTE data;
1878 block2=384;
1880 for(y=0;y<24;y++)
1882 for(x=0;x<72;x++)
1884 data=GFXfill[block2];
1885 PlotPixel(176+x,40+y,data);
1886 block2++;
1890 /*/////////////////////////////////////////////////////////////
1891 // Setup Tiltes
1892 /////////////////////////////////////////////////////////////*/
1893 void TitleSetup(void)
1895 int i;
1897 for(i=0;i<768;i++)
1899 PALover[i]=PALmain[i];
1902 PIANOc=0;
1903 for(i=0;i<32;i++)
1904 PIANOkhit[i]=0;
1906 TITLEwf=2;
1907 TITLEwp=0;
1908 SCROLLpos=0;
1909 PIXELoff=0;
1911 UpdateScrollBuffer();
1912 FillPixelBuff();
1914 TITLEm=1;
1916 modon=MIDASplayModuleSection(mod,0x0d,0x11,0x0d,FALSE);
1918 TitleSetupExtra();
1919 SwapPage();
1920 PaletteSet(PALmain);
1921 TitleSetupExtra();
1922 SwapPage();
1925 /*/////////////////////////////////////////////////////////////
1926 // Setup Extra Bits
1927 /////////////////////////////////////////////////////////////*/
1928 void TitleSetupExtra(void)
1930 int i;
1932 cls(240);
1934 PAPER=0;
1935 for(i=0;i<24;i++)
1937 FontPrint(0,i," ");
1939 DrawFinal();
1941 SUNm=1;
1942 SUNy=32;
1943 SUNh=16;
1944 DoSun();
1946 Fill1();
1947 Fill2();
1949 DrawPiano();
1950 DrawWilly4(TITLEwf);
1952 DrawTPlate2();
1953 DrawAirBG();
1956 /*/////////////////////////////////////////////////////////////
1957 // Draw Piano
1958 /////////////////////////////////////////////////////////////*/
1959 void DrawPiano(void)
1961 int x,y,block2;
1962 BYTE data;
1964 block2=0;
1966 for(y=0;y<64;y++)
1968 for(x=0;x<256;x++)
1970 data=GFXpiano[block2];
1971 PlotPixel(x,64+y,data);
1972 block2++;
1976 /*/////////////////////////////////////////////////////////////
1977 // Draw Level Title Plate
1978 /////////////////////////////////////////////////////////////*/
1979 void DrawTPlate2(void)
1981 int x,y;
1982 BYTE data;
1984 for(y=0;y<8;y++)
1986 for(x=0;x<256;x++)
1988 PlotPixel(x,128+y,GFXtplate[(y*256)+x]);
1991 FontPrint2(8,16,"\x7f1997 Andy Noble");
1993 /*/////////////////////////////////////////////////////////////
1994 // Play The Piano
1995 /////////////////////////////////////////////////////////////*/
1996 void DoPiano(void)
1998 int i,j;
1999 BYTE key1,key2,key3,key4;
2001 for(i=0;i<32;i++)
2002 PIANOkhit[i]=0;
2004 /* ADM */
2005 /* MIDASgetPlayStatus(modon,&stat);
2007 if(stat.pattern==14)
2009 TITLEm=2;
2010 MIDASstopModule(modon);
2011 modon=0;
2012 } */
2014 #ifdef USE_MIKMOD
2015 if(mod->sngpos==17)
2017 TITLEm=2;
2018 MIDASstopModule(modon);
2019 modon=0;
2021 #endif
2024 UpdatePianoKeys();
2025 SwapPage();
2027 if(KeyTable[key_f1]==1)
2029 TITLEm=4;
2030 PREFSm=0;
2031 MIDASstopModule(modon);
2032 modon=0;
2035 if( KeyTable[key_return]==1 )
2038 TITLEm=0;
2039 DEMOm=0;
2040 MODE=2;
2041 MIDASstopModule(modon);
2042 modon=0;
2047 /*/////////////////////////////////////////////////////////////
2048 // Draw Piano Key
2049 /////////////////////////////////////////////////////////////*/
2050 void DrawKey(int xpos,int ypos,BYTE block)
2052 int x,y,block2;
2053 BYTE data;
2055 xpos*=8;
2056 ypos*=8;
2058 block2=(WORD)block;
2059 block2*=128;
2061 for(y=0;y<16;y++)
2063 for(x=0;x<8;x++)
2065 data=GFXpkeys[block2];
2066 PlotPixel(xpos+x,ypos+y,data);
2067 block2++;
2072 /*/////////////////////////////////////////////////////////////
2073 // Update Piano Keys
2074 ////////////////////////////////////////////////////////////*/
2075 void UpdatePianoKeys(void)
2077 int i;
2079 for(i=0;i<32;i++)
2081 if(PIANOkhit[i]==1)
2083 DrawKey(i,14,PIANOkey[i]+4);
2085 else
2087 DrawKey(i,14,PIANOkey[i]);
2091 /*/////////////////////////////////////////////////////////////
2092 // Clear Piano
2093 /////////////////////////////////////////////////////////////*/
2094 void ClearPiano(void)
2096 int i;
2098 for(i=0;i<32;i++)
2099 PIANOkhit[i]=0;
2101 UpdatePianoKeys();
2102 SwapPage();
2103 UpdatePianoKeys();
2104 SwapPage();
2106 TITLEm=3;
2107 SCROLLpos=0;
2109 /*/////////////////////////////////////////////////////////////
2110 // Draw Willy
2111 /////////////////////////////////////////////////////////////*/
2112 void DrawWilly4(BYTE block)
2114 int x,y,block2;
2115 BYTE data;
2117 block2=(WORD)block;
2118 block2*=256;
2120 for(y=0;y<16;y++)
2122 for(x=0;x<16;x++)
2124 data=GFXwilly[block2];
2126 if(data)
2128 PlotPixel(232+x,72+y,data);
2130 else
2132 PlotPixel(232+x,72+y,39);
2134 block2++;
2139 /*/////////////////////////////////////////////////////////////
2140 // Do Title Scroll
2141 /////////////////////////////////////////////////////////////*/
2142 void DoTitleScroll(void)
2144 SwapPage();
2146 TITLEwp++;
2147 if(TITLEwp==16)
2149 TITLEwp=0;
2150 TITLEwf+=2;
2151 TITLEwf&=7;
2153 DrawWilly4(TITLEwf+4);
2155 DrawScroll();
2157 PIXELoff++;
2158 if(PIXELoff==8)
2160 PIXELoff=0;
2161 SCROLLpos++;
2162 if(SCROLLpos==290)
2164 TITLEm=0;
2165 DEMOm=0;
2166 MODE=1;
2168 if(MUSICtype==0)
2169 modon=MIDASplayModuleSection(mod,0x00,0x08,0x00,TRUE);
2170 else
2171 modon=MIDASplayModuleSection(mod,0x09,0x0c,0x00,TRUE);
2173 if(MUSICon==1)
2174 MIDASsetMusicVolume(modon,64);
2175 else
2176 MIDASsetMusicVolume(modon,0);
2179 else
2181 UpdateScrollBuffer();
2182 FillPixelBuff();
2186 if(KeyTable[key_f1]==1)
2188 TITLEm=4;
2189 PREFSm=0;
2192 if( KeyTable[key_return]==1 )
2195 TITLEm=0;
2196 DEMOm=0;
2197 MODE=2;
2201 /*/////////////////////////////////////////////////////////////
2202 // Update Scroll Buffer
2203 /////////////////////////////////////////////////////////////*/
2204 void UpdateScrollBuffer(void)
2206 int i;
2208 for(i=0;i<33;i++)
2210 SCROLLbuff[i]=SCROLLtext[SCROLLpos+i];
2214 /*/////////////////////////////////////////////////////////////
2215 // Fill Pixel buffer with text
2216 /////////////////////////////////////////////////////////////*/
2217 void FillPixelBuff(void)
2219 int i,x,y,dx,dy;
2220 WORD alpha;
2221 WORD point;
2222 BYTE *font,*alias,data,data2;
2224 dx=0;dy=0;
2226 for(i=0;i<33;i++)
2228 alpha=(WORD)SCROLLbuff[i];
2229 alpha-=32;
2230 alpha*=64;
2232 font=(fontb+alpha);
2233 alias=(GFXfant+alpha);
2235 for(y=0;y<8;y++)
2237 for(x=0;x<8;x++)
2239 data=*font;
2240 if(data!=0)
2241 PIXELbuff[((dy+y)*264)+(dx+x)]=102;
2242 else
2243 PIXELbuff[((dy+y)*264)+(dx+x)]=PAPER;
2245 data2=*alias;
2246 if(data2!=0)
2247 PIXELbuff[((dy+y)*264)+(dx+x)]=107;
2249 font++;
2250 alias++;
2254 dx+=8;
2258 /*/////////////////////////////////////////////////////////////
2259 // Draw Scroll
2260 /////////////////////////////////////////////////////////////*/
2261 void DrawScroll(void)
2263 int x,y;
2265 for(y=0;y<8;y++)
2267 for(x=0;x<256;x++)
2269 PlotPixel(x,152+y,PIXELbuff[(y*264)+(PIXELoff+x)]);
2274 /*/////////////////////////////////////////////////////////////
2275 // Do Loading Screen
2276 /////////////////////////////////////////////////////////////*/
2277 void DoLoading(void)
2279 switch(LOADm)
2281 case 0:
2282 LoadSetup();
2283 break;
2284 case 1:
2285 LoadAnim();
2286 break;
2290 /*/////////////////////////////////////////////////////////////
2291 // Setup Loading Screen
2292 /////////////////////////////////////////////////////////////*/
2293 void LoadSetup(void)
2295 int i,x,y;
2296 BYTE data;
2298 for(y=0;y<8;y++)
2300 for(x=0;x<32;x++)
2302 data=GFXload[(y*32)+x];
2303 PAPER=data;
2304 FontPrint(x,9+y," ");
2307 PAPER=0;
2308 INK=124;
2310 FontPrint(28,23,VERSION);
2312 SwapPage();
2314 for(y=0;y<8;y++)
2316 for(x=0;x<32;x++)
2318 data=GFXload[256+((y*32)+x)];
2319 PAPER=data;
2320 FontPrint(x,9+y," ");
2323 PAPER=0;
2324 INK=124;
2325 FontPrint(28,23,VERSION);
2327 LOADm=1;
2330 /*/////////////////////////////////////////////////////////////
2331 // Animate Loading Screen
2332 /////////////////////////////////////////////////////////////*/
2333 void LoadAnim(void)
2335 LOADp++;
2336 if(LOADp==25)
2338 LOADp=0;
2339 SwapPage();
2341 else
2343 WaitVR();
2346 if(AnyKeyx()==1)
2348 MODE=0;
2352 /*/////////////////////////////////////////////////////////////
2353 // Preferences Screen
2354 /////////////////////////////////////////////////////////////*/
2355 void DoPrefs(void)
2357 switch(PREFSm)
2359 case 0:
2360 SetupPrefs();
2361 break;
2362 case 1:
2363 PrefsUpdate();
2364 break;
2368 /*/////////////////////////////////////////////////////////////
2369 // Setup Prefs
2370 /////////////////////////////////////////////////////////////*/
2371 void SetupPrefs(void)
2373 int count;
2375 for(count=0;count<768;count++)
2377 PALover[count]=PALmain[count];
2380 DoPrefsExtra();
2381 SwapPage();
2383 PaletteSet(PALover);
2384 DoPrefsExtra();
2386 PREFSh1=0;
2387 PREFSh2=0;
2388 PREFSh3=0;
2389 PREFSm=1;
2391 modon=MIDASplayModuleSection(mod,0x12,0x15,0x12,TRUE);
2394 /*/////////////////////////////////////////////////////////////
2395 // Prefs Screen Setup
2396 /////////////////////////////////////////////////////////////*/
2397 void DoPrefsExtra(void)
2399 int x,y,i;
2401 i=240;
2403 cls(0);
2405 for(x=0;x<32;x++)
2407 PAPER=i;
2408 FontPrint(x,0," ");
2409 i++;
2410 if(i>254)
2411 i=240;
2414 for(y=1;y<24;y++)
2416 PAPER=i;
2417 FontPrint(31,y," ");
2418 i++;
2419 if(i>254)
2420 i=240;
2423 for(x=1;x<32;x++)
2425 PAPER=i;
2426 FontPrint(31-x,23," ");
2427 i++;
2428 if(i>254)
2429 i=240;
2432 for(y=1;y<23;y++)
2434 PAPER=i;
2435 FontPrint(0,23-y," ");
2436 i++;
2437 if(i>254)
2438 i=240;
2442 PAPER=0;
2443 INK=7;
2445 FontPrintSmall(24,2, "`fManic Miner PC");
2447 FontPrintSmall(23,3, "`g(C)`e1997 `gAndy Noble");
2448 FontPrintSmall(10,4, "`gBased on an original game by `eMatthew Smith`g.");
2449 FontPrintSmall(7,5, "`g(C) `e1983 `fBUG-BYTE`g Ltd. And `fSoftware Projects`g Ltd.");
2450 FontPrintSmall(18,6, "`g(C) `e1997 `fAlchemist Research`g.");
2452 FontPrintSmall(7,8, "`dProgramming`g, `dGraphics`e...............`fAndy Noble`e.");
2453 FontPrintSmall(7,9, "`dMUSIC ARRANGED BY`e.................`fMatt Simmonds`e.");
2454 FontPrintSmall(7,10,"`dExtra Levels`e.................`fLee `d'`gBLOOD!`d' `fTonks`e.");
2455 FontPrintSmall(7,11,"`dTesting and Ideas`e.................`fEwan Christie`e.");
2457 FontPrintSmall(3,13, "`dI would just like to say ThankYou to the following people");
2459 FontPrintSmall(3,15, "`fSahara Surfers`d..............`eFor MIDAS Digital Audio System");
2460 FontPrintSmall(3,16, "`fCharles Scheffold and Thomas Pytel`d.....`eFor the fab PMODE/W");
2461 FontPrintSmall(3,17, "`fTyrone L. Cartwright`d............`eFor help with the bad guys");
2463 FontPrintSmall(3,19, "`fDavid H. Tolley`d.................`eFor the constant slaggings");
2464 FontPrintSmall(3,20, "`fGerton Lunter`d........................`eFor the excellent Z80");
2465 FontPrintSmall(3,21, "`fJames McKay`d.................`eFor the equally excellent X128");
2467 FontPrintSmall(5,22, "`cEverybody who e-mailed me with words of encouragement.");
2469 FontPrintSmall(13,24,"`fAnd all the Guys on COMP.SYS.SINCLAIR");
2470 FontPrintSmall(4,25, "`eWho keep me informed and amused about all things Speccy.");
2472 FontPrintSmall(15,27,"`f F2 F3 F4");
2473 FontPrintSmall(15,28,"`bGame Speed Levels Melody");
2474 FontPrintSmall(15,29,"`c ORIGINAL ORIGINAL ORIGINAL");
2476 PrintSpeed();
2477 PrintMaps();
2478 PrintMusic();
2482 /*/////////////////////////////////////////////////////////////
2483 // Update setup screen
2484 /////////////////////////////////////////////////////////////*/
2485 void PrefsUpdate(void)
2487 RotPal();
2488 SwapPage();
2489 PaletteSet(PALover);
2491 if(PREFSh1==1)
2493 if(KeyTable[key_f2]!=1)
2495 SPEED++;
2496 if(SPEED==5)
2497 SPEED=0;
2499 PREFSh1=0;
2502 if(KeyTable[key_f2]==1)
2504 PREFSh1=1;
2507 if(PREFSh2==1)
2509 if(KeyTable[key_f3]!=1)
2511 TONKS++;
2512 TONKS&=1;
2514 PREFSh2=0;
2517 if(KeyTable[key_f3]==1)
2519 PREFSh2=1;
2522 if(PREFSh3==1)
2524 if(KeyTable[key_f4]!=1)
2526 MUSICtype++;
2527 MUSICtype&=1;
2529 PREFSh3=0;
2532 if(KeyTable[key_f4]==1)
2534 PREFSh3=1;
2537 if(KeyTable[key_esc]==1)
2539 MODE=0;
2540 TITLEm=0;
2541 MIDASstopModule(modon);
2542 modon=0;
2545 PrintSpeed();
2546 PrintMaps();
2547 PrintMusic();
2551 /*/////////////////////////////////////////////////////////////
2552 // Display Game Speed
2553 /////////////////////////////////////////////////////////////*/
2554 void PrintSpeed(void)
2556 switch(SPEED)
2558 case 0:
2559 INK=1;
2560 FontPrintSmall(16,29," SILLY! ");
2561 break;
2562 case 1:
2563 INK=3;
2564 FontPrintSmall(16,29," HARD ");
2565 break;
2566 case 2:
2567 INK=4;
2568 FontPrintSmall(16,29," 1997 ");
2569 break;
2570 case 3:
2571 INK=7;
2572 FontPrintSmall(16,29,"ORIGINAL");
2573 break;
2574 case 4:
2575 INK=5;
2576 FontPrintSmall(16,29," BORING ");
2577 break;
2581 /*/////////////////////////////////////////////////////////////
2582 // Display Game Maps
2583 /////////////////////////////////////////////////////////////*/
2584 void PrintMaps(void)
2586 switch(TONKS)
2588 case 0:
2589 INK=7;
2590 FontPrintSmall(28,29,"ORIGINAL");
2591 break;
2592 case 1:
2593 INK=4;
2594 FontPrintSmall(28,29," BLOOD! ");
2595 break;
2599 /*/////////////////////////////////////////////////////////////
2600 // Display Game Music
2601 /////////////////////////////////////////////////////////////*/
2602 void PrintMusic(void)
2604 switch(MUSICtype)
2606 case 0:
2607 INK=4;
2608 FontPrintSmall(40,29," 1997 ");
2609 break;
2610 case 1:
2611 INK=7;
2612 FontPrintSmall(40,29,"ORIGINAL");
2613 break;
2617 /*/////////////////////////////////////////////////////////////
2618 // Save Stuff on Exit
2619 /////////////////////////////////////////////////////////////*/
2620 void SaveInfo(void)
2622 FILE *file;
2624 file=fopen( "mm-conf.cfg", "wb" );
2625 fwrite( &HISCORE, sizeof(unsigned long), 1, file );
2626 fwrite( &SPEED, sizeof(BYTE), 1, file );
2627 fwrite( &TONKS, sizeof(BYTE), 1, file );
2628 fwrite( &MUSICtype, sizeof(BYTE), 1, file );
2629 fclose( file );
2632 /*/////////////////////////////////////////////////////////////
2633 // Load Stuff at Start
2634 /////////////////////////////////////////////////////////////*/
2635 void LoadInfo(void)
2637 FILE *file;
2639 file=fopen( "mm-conf.cfg", "rb" );
2640 if(file==NULL)
2642 HISCORE=0;
2643 SPEED=3;
2644 TONKS=0;
2645 MUSICtype=0;
2646 return;
2648 fread( &HISCORE, sizeof(unsigned long), 1, file );
2649 fread( &SPEED, sizeof(BYTE), 1, file );
2650 fread( &TONKS, sizeof(BYTE), 1, file );
2651 fread( &MUSICtype, sizeof(BYTE), 1, file );
2652 fclose( file );
2655 /*/////////////////////////////////////////////////////////////
2656 // Pre Vertical Retrace
2657 /////////////////////////////////////////////////////////////*/
2658 void PREvr(void)
2660 FrCt++;
2663 /*/////////////////////////////////////////////////////////////
2664 // Setup Sound Card
2665 /////////////////////////////////////////////////////////////*/
2666 void SetupSound(void)
2668 FILE *file;
2670 file=fopen( "mm-midas.cfg", "rb" );
2671 if((file==NULL)||(FORCE==1))
2673 if(file!=NULL)
2674 fclose(file);
2676 MIDASconfig();
2677 MIDASsaveConfig("mm-midas.cfg");
2679 else
2681 fclose(file);
2682 MIDASloadConfig("mm-midas.cfg");