1 /*////////////////////////////////////////////////////////////
5 // 8/1997 By Andy Noble
7 // Compile: wcl386 /oneatx /zp4 /5 /fp3 manic.c
9 // LINUX PORT BY ADAM D. MOSS : adam@gimp.org
11 /////////////////////////////////////////////////////////////*/
29 #include <X11/Xutil.h>
30 #include <X11/extensions/XShm.h>
31 #include <X11/cursorfont.h>
32 #include <X11/keysymdef.h>
42 #endif /* USE_MIKMOD */
48 /*/////////////////////////////////////////////////////////////
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 *********************************/
82 static int shmem_flag
=1;
83 static XShmSegmentInfo shminfo1
;
84 static int gXErrorFlag
;
90 #define error(x) fprintf(stderr,"%s\n",x);fflush(stderr);abort
92 static int HandleXError(dpy
, event
)
101 static void InstallXErrorHandler()
103 XSetErrorHandler(HandleXError
);
107 static void DeInstallXErrorHandler()
109 XSetErrorHandler(NULL
);
113 void init_Xdisplay(char *name
)
115 char *hello
= "Manic Miner";
117 XSetWindowAttributes xswa
;
118 XColor cursorfg
, cursorbg
;
122 display
= XOpenDisplay(name
);
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
,
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
))
184 printf("Using SHM. Neat.\n");
189 fprintf(stderr
, "Ugh, no SHM. Never mind.\n");
192 XSync(display
, False
);
194 /************** SHM INIT *************************************/
196 InstallXErrorHandler();
200 ximage
= XShmCreateImage(display
, None
, depth
, ZPixmap
, NULL
,
204 /* If no go, then revert to normal Xlib calls. */
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
,
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
);
244 /* Ultimate failure here. */
245 XDestroyImage(ximage
);
246 shmdt(shminfo1
.shmaddr
);
247 fprintf(stderr
, "Shared memory error, disabling.\n");
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
);
264 /************** END OF X INIT STUFF **************************/
265 /*************************************************************/
266 /*************************************************************/
270 unsigned long Old_Isr
;
272 /*/////////////////////////////////////////////////////////////
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
287 /* LINUX SOUND STUFF */
290 #define SOUNDDEVICE "/dev/dsp"
291 #define SAMPLERATE 44100
293 /* ADMNOTE: MIDAS STUBS - FIXME */
295 typedef struct _MIDASsampleSTRUCT
300 typedef MIDASsampleSTRUCT* MIDASsample;
301 typedef void* MIDASmodule;
302 typedef void* MIDASmodulePlayHandle;
303 typedef void* MIDASplayStatus;
304 void MIDASstartup(void)
308 int rate = SAMPLERATE;
311 if ((dsp=open(SOUNDDEVICE,O_WRONLY))==-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;
341 newsample = malloc(sizeof(MIDASsampleSTRUCT));
344 newsample->length = sts.st_size;
346 newsample->data = malloc(newsample->length);
349 fread(newsample->data, newsample->length, 1, fp);
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)
372 // ioctl(dsp,SNDCTL_DSP_SPEED,&rate);
373 write(dsp, ((MIDASsample)a)->data, ((MIDASsample)a)->length);
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)
387 sbuff = malloc(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) {};
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 /**/
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
420 typedef SAMPLE
* MIDASsample
;
421 typedef UNIMOD
* MIDASmodule
;
422 typedef UNIMOD
* MIDASmodulePlayHandle
;
424 typedef char* MIDASsample
;
425 typedef char* MIDASmodule
;
426 typedef char* MIDASmodulePlayHandle
;
428 void MIDASstartup(void)
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
|
443 DMODE_SOFT_SNDFX
; /* default mixing mode */
445 MikMod_RegisterAllLoaders();
446 MikMod_RegisterAllDrivers();
447 MikMod_SetNumVoices(6,6);
450 void MIDASconfig(void) {};
451 void MIDASsaveConfig(char* a
) {};
452 void MIDASloadConfig(char* a
) {};
453 int MIDASgetDisplayRefreshRate(void) {};
461 void MIDASsetOption(int a
, int b
) {};
462 MIDASmodule
MIDASloadModule(char* a
)
467 s
= MikMod_LoadSong(a
, 6);
472 MIDASsample
MIDASloadWaveSample(char* a
, int b
)
474 MIDASsample newsample
;
479 newsample
= calloc(1, sizeof(SAMPLE
));
483 newsample
->length
= sts
.st_size
;
484 /* newsample->flags = SF_UNSIGNED; */
485 newsample
->speed
= 22050;
486 newsample
->volume
= 63;
489 SL_RegisterSample(newsample
,MD_SNDFX
,fp
);
492 /* printf("%p\n",newsample);fflush(stdout); */
497 void MIDASsetTimerCallbacks(int a
, int b
, char* c
, char* d
, char* e
) {};
498 void MIDASopenChannels(int a
) {};
499 void MIDASstopModule(void* a
)
502 MP_SetPosition(a
, 17);
503 /* MikMod_Update(); */
507 void MIDAScloseChannels(void) {};
508 void MIDASclose(void) {};
509 void MIDASfreeModule(MIDASmodule a
) {};
510 void MIDASfreeSample(MIDASsample a
)
515 MD_SampleUnLoad(a
->handle
);
520 void MIDASplaySample(MIDASsample a
, int b
, int c
, int d
, int e
, int f
)
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(); */
533 MIDASmodule
MIDASplayModuleSection(MIDASmodule a
, int b
, int c
, int d
, int e
)
536 MP_SetPosition(a
, b
);
539 /* MikMod_Update(); */
543 void MIDASsetMusicVolume(MIDASmodule a
, int b
)
545 /* md_musicvolume = (b*127)/64; */
551 /*/////////////////////////////////////////////////////////////
553 /////////////////////////////////////////////////////////////*/
557 #include "mm-blocx.c"
559 #include "mm-exits.c"
560 #include "mm-keys2.c"
561 #include "mm-tplat.c"
563 #include "mm-hrobo.c"
564 #include "mm-vrobo.c"
565 #include "mm-final.c"
576 #include "mm-piano.c"
577 #include "mm-pkeys.c"
580 #include "mm-willy.c"
581 #include "mm-ftsml.c"
583 #include "mm-house.c"
588 /*/////////////////////////////////////////////////////////////
590 /////////////////////////////////////////////////////////////*/
594 //BYTE *screen=(BYTE *)0xa0000;
595 //BYTE screen[64000 * 4]; */
599 BYTE
* realscreen
= NULL
;
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};
618 /*/////////////////////////////////////////////////////////////
620 /////////////////////////////////////////////////////////////*/
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};
710 WORD cHROBOxold[4][2];
711 WORD cHROBOyold[4][2];
723 WORD cVROBOxold[4][2];
724 WORD cVROBOyold[4][2];
726 /*/////////////////////////////////////////////////////////////
728 /////////////////////////////////////////////////////////////*/
775 BYTE SUNbuff[2][384];
779 /*/////////////////////////////////////////////////////////////
780 // Solar Power Generator
781 /////////////////////////////////////////////////////////////*/
786 /*/////////////////////////////////////////////////////////////
788 /////////////////////////////////////////////////////////////*/
791 unsigned long HISCORE=0;
793 unsigned long EXTRAdelta=10000;
828 BYTE CHEATkey[]={9,11,3,10,3,7};
834 WORD WINDOW[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
842 /*///////////////////////////////////////////////////////////*/
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};
852 BYTE SCROLLbuff[]=" ";
854 BYTE PIXELbuff[264*8];
865 BYTE CHAN[]={0,1,2,8,9,10,16,17,18};
868 /*/////////////////////////////////////////////////////////////
869 // Tales from a Parallel Universe
870 /////////////////////////////////////////////////////////////*/
874 /*/////////////////////////////////////////////////////////////
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
892 /*ADMNOTE: we manually handle timers on UNIX
893 //WORD volatile FrCt=0; */
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
;
909 gettimeofday(&tv
, NULL
);
910 first_timer_ctr
= (tv
.tv_sec
*1000000)+tv
.tv_usec
;
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
;
934 MIDASmodulePlayHandle modon
=0;
937 /*/////////////////////////////////////////////////////////////
939 /////////////////////////////////////////////////////////////*/
941 void MIDAS_CALL PREvr(void);
943 /*/////////////////////////////////////////////////////////////
945 /////////////////////////////////////////////////////////////*/
946 int main(int argc, BYTE *argv[])
955 /*ADMNOTE: set up SVGALIB */
959 keyboard_setdefaulteventhandler();
960 realscreen
=(BYTE
*) vga_getgraphmem();
963 pix_offset
= 33 + 4*320; /* for screen centering in this mode */
981 GetVideoMode( &old_video
);
985 /*------------------------------------------------------------- */
987 REFRESH
=MIDASgetDisplayRefreshRate();
991 MIDASsetOption(MIDAS_OPTION_FILTER_MODE
,MIDAS_FILTER_NONE
);
993 if(MIDASinit()==FALSE
)
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 /*------------------------------------------------------------- */
1016 PaletteSet(PALblack
);
1023 PaletteSet(PALmain
);
1050 if( KeyTable
[key_f10
]==1 )
1056 /*------------------------------------------------------------- */
1058 MIDASstopModule(modon
);
1060 MIDAScloseChannels();
1061 MIDASfreeModule(mod
);
1062 MIDASfreeSample(wav
);
1063 MIDASfreeSample(die
);
1064 MIDASfreeSample(pick
);
1067 /*------------------------------------------------------------- */
1070 PaletteSet(PALblack
);
1073 SetVideoMode(old_video
);
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*/
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 /////////////////////////////////////////////////////////////*/
1124 /* if (random()%3000 == 0) return (1);*/
1126 for( count
=0; count
<128; count
++ )
1128 if(KeyTable
[count
] != 0 )
1135 ///////////////////////////////////////////////////////////////
1136 // Flush our Keyboard Buffer
1137 ///////////////////////////////////////////////////////////////
1138 void FlushKey( void )
1140 memset( KeyTable
, (BYTE
)0, 256 );
1143 ///////////////////////////////////////////////////////////////
1145 ///////////////////////////////////////////////////////////////
1146 void SetVideoMode(int mode
)
1151 ///////////////////////////////////////////////////////////////
1153 ///////////////////////////////////////////////////////////////
1154 void GetVideoMode( BYTE
*vidmode
)
1160 /*/////////////////////////////////////////////////////////////
1161 // Wait Vertical Retrace
1162 /////////////////////////////////////////////////////////////*/
1178 /*putchar('1'+slowdown_slow());*/
1182 while(old
==UpdateFrCt()) {};
1185 /*ADMNOTE: we throw in a keyboard check here! */
1193 /*/////////////////////////////////////////////////////////////
1194 // Wait Vertical Retrace
1195 /////////////////////////////////////////////////////////////*/
1196 void WaitVR2( void )
1226 /*/////////////////////////////////////////////////////////////
1227 // ADMNOTE: UNIX: Update keyboard state
1228 /////////////////////////////////////////////////////////////*/
1229 int DoKeymap ( void )
1238 while (XPending(display))
1240 XNextEvent(display, &event);
1247 if (event.type == KeyRelease)
1250 XLookupString(&event.xkey, buf, 20, &ks, NULL);
1254 case 0xFF0D : KeyTable[key_return] = kstat; break;
1257 case ' ' : KeyTable[key_space] = kstat; break;
1260 case 'o' : KeyTable[key_o] = kstat; break;
1263 case 'p' : KeyTable[key_p] = kstat; break;
1264 case 0xFF1B : KeyTable[key_esc] = kstat; break;
1266 case 0xFFBE : KeyTable[key_f1] = kstat; break;
1268 case 0xFFBF : KeyTable[key_f2] = kstat; break;
1270 case 0xFFC0 : KeyTable[key_f3] = kstat; break;
1272 case 0xFFC1 : KeyTable[key_f4] = kstat; break;
1273 case 0xFFC7 : KeyTable[key_f10] = kstat; break;
1283 if (keyboard_update()==0) return;
1285 /* Otherwise, something changed with the keyboard...
1288 memcpy(KeyTable
, keyboard_getstate(), 256);
1294 * PHYSICALLY DISPLAY 'SCREEN'
1296 void showscreen(void)
1301 XShmPutImage(display
, window
, gc
, ximage
,
1304 wwidth
, wheight
, False
);
1308 XPutImage(display
, window
, gc
, ximage
,
1313 XSync(display
, False
);
1315 memcpy(realscreen
, screen
, 64000);
1320 /*/////////////////////////////////////////////////////////////
1322 /////////////////////////////////////////////////////////////*/
1323 void SwapPage( void )
1335 screen
= (page
==0 ? page1
: page2
);
1340 /*/////////////////////////////////////////////////////////////
1342 /////////////////////////////////////////////////////////////*/
1343 void SwapPage2( void)
1355 screen
= (page
==0 ? page1
: page2
);
1361 /*/////////////////////////////////////////////////////////////
1362 // Wait Vertical Retrace
1363 /////////////////////////////////////////////////////////////*/
1364 void WaitVR3( void )
1375 /*putchar('1'+slowdown_slow()); */
1379 while(NEXTBIT
>=UpdateFrCt()) {};
1384 /*while(NEXTBIT>=FrCt);
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;
1402 ((uint8 *)ximage->data)[offset] = ((uint8 *)pix)[colour]; break;
1404 ((uint16 *)ximage->data)[offset] = ((uint16 *)pix)[colour]; break;
1406 ((uint32 *)ximage->data)[offset] = ((uint32 *)pix)[colour]; break;
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 )
1428 memset(screen, col, 64000);
1434 pcol = ((uint8 *)pix)[col];
1435 memset((uint8 *)ximage->data, pcol, wwidth*wheight);
1438 pcol = ((uint16 *)pix)[col];
1439 u16p = (uint16 *)ximage->data;
1440 for (i=0;i<wwidth*wheight;i++)
1446 pcol = ((uint32 *)pix)[col];
1447 u32p = (uint32 *)ximage->data;
1448 for (i=0;i<wwidth*wheight;i++)
1458 /*/////////////////////////////////////////////////////////////
1459 // Set Palette1 with Palette2
1460 /////////////////////////////////////////////////////////////*/
1462 void PaletteFill( char *pal1, char *pal2 )
1466 for(count=0;count<768;count++)
1467 pal1[count]=pal2[count];
1470 /*/////////////////////////////////////////////////////////////
1472 /////////////////////////////////////////////////////////////*/
1474 void PaletteSet( char *pal1 )
1479 static uint8 *lastpal = NULL;
1481 if (lastpal == NULL)
1483 lastpal = calloc(1, 256*3);
1486 for (count=0; count<256; count++)
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");
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);
1517 for (count=0;count<256;count++)
1518 vga_setpalette(count,pal1[count*3],
1525 /*/////////////////////////////////////////////////////////////
1527 /////////////////////////////////////////////////////////////*/
1529 int PaletteFade( unsigned char *pal1, unsigned char *pal2 )
1535 for(count=0;count<768;count++)
1559 /*/////////////////////////////////////////////////////////////
1561 /////////////////////////////////////////////////////////////*/
1562 void FontPrint( int xpos, int ypos, BYTE *text )
1564 int count,count2,count3;
1565 int currentx,currenty;
1582 if(alpha==170) /*="|" */
1601 fonty
=(fontb
+alpha
);
1606 for(count2
=0;count2
<8;count2
++)
1608 for(count3
=0;count3
<8;count3
++)
1611 PlotPixel(xpos
,ypos
,INK
);
1613 PlotPixel(xpos
,ypos
,PAPER
);
1625 /*/////////////////////////////////////////////////////////////
1627 /////////////////////////////////////////////////////////////*/
1628 void FontPrint2( int xpos, int ypos, BYTE *text )
1630 int count,count2,count3;
1631 int currentx,currenty;
1633 BYTE *fonty,*fonty2,data,data2;
1648 if(alpha==170) /*="|" */
1667 fonty
=(fontb
+alpha
);
1668 fonty2
=(GFXfant
+alpha
);
1673 for(count2
=0;count2
<8;count2
++)
1675 for(count3
=0;count3
<8;count3
++)
1678 PlotPixel(xpos
,ypos
,0);
1683 data
=GetPixel(xpos
,ypos
);
1690 PlotPixel(xpos
,ypos
,data
);
1706 /*/////////////////////////////////////////////////////////////
1708 /////////////////////////////////////////////////////////////*/
1709 void ShowSix( int xpos, int ypos, unsigned long data )
1711 BYTE convtext[]={" "};
1712 BYTE printtext[]={" "};
1716 /* ADMNOTE: no ultoa in ansi/iso C
1717 /* ultoa( data,&convtext,10);*/
1718 sprintf(convtext
, "%u", data
);
1721 for(count1
=0;count1
<7;count1
++)
1723 if(convtext
[count1
]!=32)
1730 for(count1
=0;count1
<count2
;count1
++)
1732 *pointy
=convtext
[count1
];
1737 for(count1
=0;count1
<6;count1
++)
1739 if(printtext
[count1
]==32)
1740 printtext
[count1
]=48;
1743 FontPrint(xpos
,ypos
,&printtext
);
1746 /*/////////////////////////////////////////////////////////////
1748 /////////////////////////////////////////////////////////////*/
1749 void FontPrintSmall( int xpos, int ypos, BYTE *text )
1751 int count,count2,count3;
1752 int currentx,currenty;
1769 if(alpha==170) /*="ª" */
1777 if(alpha
==96) /*="`" */
1792 fonty
=(fonts
+alpha
);
1797 for(count2
=0;count2
<6;count2
++)
1799 for(count3
=0;count3
<4;count3
++)
1802 PlotPixel(xpos
,ypos
,INK
);
1804 PlotPixel(xpos
,ypos
,PAPER
);
1818 /*/////////////////////////////////////////////////////////////
1819 // Main Code Includes
1820 /////////////////////////////////////////////////////////////*/
1821 #include "mm-core.c"
1822 #include "mm-game.c"
1823 #include "mm-demo.c"
1824 /*/////////////////////////////////////////////////////////////
1826 /////////////////////////////////////////////////////////////*/
1849 /*/////////////////////////////////////////////////////////////
1850 // Do Background Fill 1
1851 /////////////////////////////////////////////////////////////*/
1863 data=GFXfill[block2];
1864 PlotPixel(152+x,40+y,data);
1870 /*////////////////////////////////////////////////////////////
1871 // Do Background Fill 2
1872 /////////////////////////////////////////////////////////////*/
1884 data=GFXfill[block2];
1885 PlotPixel(176+x,40+y,data);
1890 /*/////////////////////////////////////////////////////////////
1892 /////////////////////////////////////////////////////////////*/
1893 void TitleSetup(void)
1899 PALover[i]=PALmain[i];
1911 UpdateScrollBuffer();
1916 modon=MIDASplayModuleSection(mod,0x0d,0x11,0x0d,FALSE);
1920 PaletteSet(PALmain);
1925 /*/////////////////////////////////////////////////////////////
1927 /////////////////////////////////////////////////////////////*/
1928 void TitleSetupExtra(void)
1950 DrawWilly4(TITLEwf);
1956 /*/////////////////////////////////////////////////////////////
1958 /////////////////////////////////////////////////////////////*/
1959 void DrawPiano(void)
1970 data=GFXpiano[block2];
1971 PlotPixel(x,64+y,data);
1976 /*/////////////////////////////////////////////////////////////
1977 // Draw Level Title Plate
1978 /////////////////////////////////////////////////////////////*/
1979 void DrawTPlate2(void)
1988 PlotPixel(x,128+y,GFXtplate[(y*256)+x]);
1991 FontPrint2(8,16,"\x7f1997 Andy Noble");
1993 /*/////////////////////////////////////////////////////////////
1995 /////////////////////////////////////////////////////////////*/
1999 BYTE key1,key2,key3,key4;
2005 /* MIDASgetPlayStatus(modon,&stat);
2007 if(stat.pattern==14)
2010 MIDASstopModule(modon);
2018 MIDASstopModule(modon
);
2027 if(KeyTable
[key_f1
]==1)
2031 MIDASstopModule(modon
);
2035 if( KeyTable
[key_return
]==1 )
2041 MIDASstopModule(modon
);
2047 /*/////////////////////////////////////////////////////////////
2049 /////////////////////////////////////////////////////////////*/
2050 void DrawKey(int xpos,int ypos,BYTE block)
2065 data=GFXpkeys[block2];
2066 PlotPixel(xpos+x,ypos+y,data);
2072 /*/////////////////////////////////////////////////////////////
2073 // Update Piano Keys
2074 ////////////////////////////////////////////////////////////*/
2075 void UpdatePianoKeys(void)
2083 DrawKey(i
,14,PIANOkey
[i
]+4);
2087 DrawKey(i
,14,PIANOkey
[i
]);
2091 /*/////////////////////////////////////////////////////////////
2093 /////////////////////////////////////////////////////////////*/
2094 void ClearPiano(void)
2109 /*/////////////////////////////////////////////////////////////
2111 /////////////////////////////////////////////////////////////*/
2112 void DrawWilly4(BYTE block)
2124 data=GFXwilly[block2];
2128 PlotPixel(232+x,72+y,data);
2132 PlotPixel(232+x,72+y,39);
2139 /*/////////////////////////////////////////////////////////////
2141 /////////////////////////////////////////////////////////////*/
2142 void DoTitleScroll(void)
2153 DrawWilly4(TITLEwf+4);
2169 modon=MIDASplayModuleSection(mod,0x00,0x08,0x00,TRUE);
2171 modon=MIDASplayModuleSection(mod,0x09,0x0c,0x00,TRUE);
2174 MIDASsetMusicVolume(modon,64);
2176 MIDASsetMusicVolume(modon,0);
2181 UpdateScrollBuffer();
2186 if(KeyTable[key_f1]==1)
2192 if( KeyTable[key_return]==1 )
2201 /*/////////////////////////////////////////////////////////////
2202 // Update Scroll Buffer
2203 /////////////////////////////////////////////////////////////*/
2204 void UpdateScrollBuffer(void)
2210 SCROLLbuff[i]=SCROLLtext[SCROLLpos+i];
2214 /*/////////////////////////////////////////////////////////////
2215 // Fill Pixel buffer with text
2216 /////////////////////////////////////////////////////////////*/
2217 void FillPixelBuff(void)
2222 BYTE *font,*alias,data,data2;
2228 alpha=(WORD)SCROLLbuff[i];
2233 alias=(GFXfant+alpha);
2241 PIXELbuff[((dy+y)*264)+(dx+x)]=102;
2243 PIXELbuff[((dy+y)*264)+(dx+x)]=PAPER;
2247 PIXELbuff[((dy+y)*264)+(dx+x)]=107;
2258 /*/////////////////////////////////////////////////////////////
2260 /////////////////////////////////////////////////////////////*/
2261 void DrawScroll(void)
2269 PlotPixel(x,152+y,PIXELbuff[(y*264)+(PIXELoff+x)]);
2274 /*/////////////////////////////////////////////////////////////
2275 // Do Loading Screen
2276 /////////////////////////////////////////////////////////////*/
2277 void DoLoading(void)
2290 /*/////////////////////////////////////////////////////////////
2291 // Setup Loading Screen
2292 /////////////////////////////////////////////////////////////*/
2293 void LoadSetup(void)
2302 data=GFXload[(y*32)+x];
2304 FontPrint(x,9+y," ");
2310 FontPrint(28,23,VERSION);
2318 data=GFXload[256+((y*32)+x)];
2320 FontPrint(x,9+y," ");
2325 FontPrint(28,23,VERSION);
2330 /*/////////////////////////////////////////////////////////////
2331 // Animate Loading Screen
2332 /////////////////////////////////////////////////////////////*/
2352 /*/////////////////////////////////////////////////////////////
2353 // Preferences Screen
2354 /////////////////////////////////////////////////////////////*/
2368 /*/////////////////////////////////////////////////////////////
2370 /////////////////////////////////////////////////////////////*/
2371 void SetupPrefs(void)
2375 for(count=0;count<768;count++)
2377 PALover[count]=PALmain[count];
2383 PaletteSet(PALover);
2391 modon=MIDASplayModuleSection(mod,0x12,0x15,0x12,TRUE);
2394 /*/////////////////////////////////////////////////////////////
2395 // Prefs Screen Setup
2396 /////////////////////////////////////////////////////////////*/
2397 void DoPrefsExtra(void)
2417 FontPrint(31,y," ");
2426 FontPrint(31-x,23," ");
2435 FontPrint(0,23-y," ");
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");
2482 /*/////////////////////////////////////////////////////////////
2483 // Update setup screen
2484 /////////////////////////////////////////////////////////////*/
2485 void PrefsUpdate(void)
2489 PaletteSet(PALover);
2493 if(KeyTable[key_f2]!=1)
2502 if(KeyTable[key_f2]==1)
2509 if(KeyTable[key_f3]!=1)
2517 if(KeyTable[key_f3]==1)
2524 if(KeyTable[key_f4]!=1)
2532 if(KeyTable[key_f4]==1)
2537 if(KeyTable[key_esc]==1)
2541 MIDASstopModule(modon);
2551 /*/////////////////////////////////////////////////////////////
2552 // Display Game Speed
2553 /////////////////////////////////////////////////////////////*/
2554 void PrintSpeed(void)
2560 FontPrintSmall(16,29," SILLY! ");
2564 FontPrintSmall(16,29," HARD ");
2568 FontPrintSmall(16,29," 1997 ");
2572 FontPrintSmall(16,29,"ORIGINAL");
2576 FontPrintSmall(16,29," BORING ");
2581 /*/////////////////////////////////////////////////////////////
2582 // Display Game Maps
2583 /////////////////////////////////////////////////////////////*/
2584 void PrintMaps(void)
2590 FontPrintSmall(28,29,"ORIGINAL");
2594 FontPrintSmall(28,29," BLOOD! ");
2599 /*/////////////////////////////////////////////////////////////
2600 // Display Game Music
2601 /////////////////////////////////////////////////////////////*/
2602 void PrintMusic(void)
2608 FontPrintSmall(40,29," 1997 ");
2612 FontPrintSmall(40,29,"ORIGINAL");
2617 /*/////////////////////////////////////////////////////////////
2618 // Save Stuff on Exit
2619 /////////////////////////////////////////////////////////////*/
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 );
2632 /*/////////////////////////////////////////////////////////////
2633 // Load Stuff at Start
2634 /////////////////////////////////////////////////////////////*/
2639 file=fopen( "mm-conf.cfg", "rb" );
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 );
2655 /*/////////////////////////////////////////////////////////////
2656 // Pre Vertical Retrace
2657 /////////////////////////////////////////////////////////////*/
2663 /*/////////////////////////////////////////////////////////////
2665 /////////////////////////////////////////////////////////////*/
2666 void SetupSound(void)
2670 file=fopen( "mm-midas.cfg", "rb" );
2671 if((file==NULL)||(FORCE==1))
2677 MIDASsaveConfig("mm-midas.cfg");
2682 MIDASloadConfig("mm-midas.cfg");