]> 4ch.mooo.com Git - 16.git/blob - src/lib/16_tail.c
p16 is being worked on a bunch by me wwww [16_ca needs huge amounts of work and I...
[16.git] / src / lib / 16_tail.c
1 /* Project 16 Source Code~\r
2  * Copyright (C) 2012-2017 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
3  *\r
4  * This file is part of Project 16.\r
5  *\r
6  * Project 16 is free software; you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 3 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * Project 16 is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
18  * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
19  * Fifth Floor, Boston, MA 02110-1301 USA.\r
20  *\r
21  */\r
22 /*\r
23  * 16 tail library\r
24  */\r
25 \r
26 #include "src/lib/16_tail.h"\r
27 #include "src/lib/16text.h"\r
28 \r
29 static word far* clockw= (word far*) 0x046C; /* 18.2hz clock */\r
30 \r
31 /*\r
32 ==========================\r
33 =\r
34 = Startup16\r
35 =\r
36 = Load a few things right away\r
37 =\r
38 ==========================\r
39 */\r
40 \r
41 void Startup16(global_game_variables_t *gvar)\r
42 {\r
43 #ifdef __WATCOMC__\r
44         start_timer(gvar);\r
45 #endif\r
46         gvar->video.VL_Started=0;\r
47         TL_VidInit(gvar);\r
48         gvar->mm.mmstarted=0;\r
49         gvar->pm.PMStarted=0;\r
50         MM_Startup(gvar);\r
51 #ifdef __WATCOMC__\r
52 #ifdef __DEBUG_InputMgr__\r
53         if(!dbg_nointest)\r
54 #endif\r
55         IN_Startup(gvar);\r
56 #endif\r
57 #ifdef __16_PM__\r
58         PM_Startup(gvar);\r
59         PM_CheckMainMem(gvar);\r
60         PM_UnlockMainMem(gvar);\r
61 #endif\r
62         CA_Startup(gvar);\r
63 }\r
64 \r
65 //===========================================================================\r
66 \r
67 /*\r
68 ==========================\r
69 =\r
70 = Shutdown16\r
71 =\r
72 = Shuts down all ID_?? managers\r
73 =\r
74 ==========================\r
75 */\r
76 \r
77 void Shutdown16(global_game_variables_t *gvar)\r
78 {\r
79 #ifdef __16_PM__\r
80         PM_Shutdown(gvar);\r
81 #endif\r
82 #ifdef __WATCOMC__\r
83 #ifdef __DEBUG_InputMgr__\r
84         if(!dbg_nointest)\r
85 #endif\r
86         IN_Shutdown(gvar);\r
87 #endif\r
88         CA_Shutdown(gvar);\r
89         MM_Shutdown(gvar);\r
90 #ifdef __WATCOMC__\r
91         if(gvar->video.VL_Started)\r
92                 VGAmodeX(0, 1, gvar);\r
93 #endif\r
94 }\r
95 \r
96 void    TL_VidInit(global_game_variables_t *gvar)\r
97 {\r
98 #ifdef __WATCOMC__\r
99         // DOSLIB: check our environment\r
100         probe_dos();\r
101 \r
102         // DOSLIB: what CPU are we using?\r
103         // NTS: I can see from the makefile Sparky4 intends this to run on 8088 by the -0 switch in CFLAGS.\r
104         //        So this code by itself shouldn't care too much what CPU it's running on. Except that other\r
105         //        parts of this project (DOSLIB itself) rely on CPU detection to know what is appropriate for\r
106         //        the CPU to carry out tasks. --J.C.\r
107         cpu_probe();\r
108 \r
109         // DOSLIB: check for VGA\r
110         if (!probe_vga()) {\r
111                 printf("VGA probe failed\n");\r
112                 return;\r
113         }\r
114         // hardware must be VGA or higher!\r
115         if (!(vga_state.vga_flags & VGA_IS_VGA)) {\r
116                 printf("This program requires VGA or higher graphics hardware\n");\r
117                 return;\r
118         }\r
119 \r
120         if (_DEBUG_INIT() == 0) {\r
121 #ifdef DEBUGSERIAL\r
122                 //printf("WARNING: Failed to initialize DEBUG output\n");\r
123 #endif\r
124         }\r
125         _DEBUG("Serial debug output started\n"); // NTS: All serial output must end messages with newline, or DOSBox-X will not emit text to log\r
126         _DEBUGF("Serial debug output printf test %u %u %u\n",1U,2U,3U);\r
127 \r
128         textInit();\r
129 \r
130         // get old video mode\r
131         //in.h.ah = 0xf;\r
132         //int86(0x10, &in, &out);\r
133         if(!gvar->video.old_mode) gvar->video.old_mode = vgaGetMode();//out.h.al;\r
134 #else\r
135         gvar->video.old_mode = 3;\r
136 #endif\r
137 }\r
138 \r
139 \r
140 //===========================================================================\r
141 \r
142 /*\r
143 ====================\r
144 =\r
145 = ReadConfig\r
146 =\r
147 ====================\r
148 */\r
149 \r
150 /*void ReadConfig(void)\r
151 {\r
152         int                                      file;\r
153         SDMode            sd;\r
154         SMMode            sm;\r
155         SDSMode          sds;\r
156 \r
157 \r
158         if ( (file = open(configname,O_BINARY | O_RDONLY)) != -1)\r
159         {\r
160         //\r
161         // valid config file\r
162         //\r
163                 read(file,Scores,sizeof(HighScore) * MaxScores);\r
164 \r
165                 read(file,&sd,sizeof(sd));\r
166                 read(file,&sm,sizeof(sm));\r
167                 read(file,&sds,sizeof(sds));\r
168 \r
169                 read(file,&mouseenabled,sizeof(mouseenabled));\r
170                 read(file,&joystickenabled,sizeof(joystickenabled));\r
171                 read(file,&joypadenabled,sizeof(joypadenabled));\r
172                 read(file,&joystickprogressive,sizeof(joystickprogressive));\r
173                 read(file,&joystickport,sizeof(joystickport));\r
174 \r
175                 read(file,&dirscan,sizeof(dirscan));\r
176                 read(file,&buttonscan,sizeof(buttonscan));\r
177                 read(file,&buttonmouse,sizeof(buttonmouse));\r
178                 read(file,&buttonjoy,sizeof(buttonjoy));\r
179 \r
180                 read(file,&viewsize,sizeof(viewsize));\r
181                 read(file,&mouseadjustment,sizeof(mouseadjustment));\r
182 \r
183                 close(file);\r
184 \r
185                 if (sd == sdm_AdLib && !AdLibPresent && !SoundBlasterPresent)\r
186                 {\r
187                         sd = sdm_PC;\r
188                         sd = smm_Off;\r
189                 }\r
190 \r
191                 if ((sds == sds_SoundBlaster && !SoundBlasterPresent) ||\r
192                         (sds == sds_SoundSource && !SoundSourcePresent))\r
193                         sds = sds_Off;\r
194 \r
195                 if (!MousePresent)\r
196                         mouseenabled = false;\r
197                 if (!JoysPresent[joystickport])\r
198                         joystickenabled = false;\r
199 \r
200                 MainMenu[6].active=1;\r
201                 MainItems.curpos=0;\r
202         }\r
203         else\r
204         {\r
205         //\r
206         // no config file, so select by hardware\r
207         //\r
208                 if (SoundBlasterPresent || AdLibPresent)\r
209                 {\r
210                         sd = sdm_AdLib;\r
211                         sm = smm_AdLib;\r
212                 }\r
213                 else\r
214                 {\r
215                         sd = sdm_PC;\r
216                         sm = smm_Off;\r
217                 }\r
218 \r
219                 if (SoundBlasterPresent)\r
220                         sds = sds_SoundBlaster;\r
221                 else if (SoundSourcePresent)\r
222                         sds = sds_SoundSource;\r
223                 else\r
224                         sds = sds_Off;\r
225 \r
226                 if (MousePresent)\r
227                         mouseenabled = true;\r
228 \r
229                 joystickenabled = false;\r
230                 joypadenabled = false;\r
231                 joystickport = 0;\r
232                 joystickprogressive = false;\r
233 \r
234                 viewsize = 15;\r
235                 mouseadjustment=5;\r
236         }\r
237 \r
238         SD_SetMusicMode (sm);\r
239         SD_SetSoundMode (sd);\r
240         SD_SetDigiDevice (sds);\r
241 }*/\r
242 \r
243 \r
244 /*\r
245 ====================\r
246 =\r
247 = WriteConfig\r
248 =\r
249 ====================\r
250 */\r
251 \r
252 /*void WriteConfig(void)\r
253 {\r
254         int                                      file;\r
255 \r
256         file = open(configname,O_CREAT | O_BINARY | O_WRONLY,\r
257                                 S_IREAD | S_IWRITE | S_IFREG);\r
258 \r
259         if (file != -1)\r
260         {\r
261                 write(file,Scores,sizeof(HighScore) * MaxScores);\r
262 \r
263                 write(file,&SoundMode,sizeof(SoundMode));\r
264                 write(file,&MusicMode,sizeof(MusicMode));\r
265                 write(file,&DigiMode,sizeof(DigiMode));\r
266 \r
267                 write(file,&mouseenabled,sizeof(mouseenabled));\r
268                 write(file,&joystickenabled,sizeof(joystickenabled));\r
269                 write(file,&joypadenabled,sizeof(joypadenabled));\r
270                 write(file,&joystickprogressive,sizeof(joystickprogressive));\r
271                 write(file,&joystickport,sizeof(joystickport));\r
272 \r
273                 write(file,&dirscan,sizeof(dirscan));\r
274                 write(file,&buttonscan,sizeof(buttonscan));\r
275                 write(file,&buttonmouse,sizeof(buttonmouse));\r
276                 write(file,&buttonjoy,sizeof(buttonjoy));\r
277 \r
278                 write(file,&viewsize,sizeof(viewsize));\r
279                 write(file,&mouseadjustment,sizeof(mouseadjustment));\r
280 \r
281                 close(file);\r
282         }\r
283 }*/\r
284 \r
285 //===========================================================================\r
286 \r
287 /*\r
288 ===================\r
289 =\r
290 = FizzleFade\r
291 =\r
292 ===================\r
293 */\r
294 \r
295 #define PIXPERFRAME     1600\r
296 \r
297 void FizzleFade (unsigned source, unsigned dest,\r
298         unsigned width,unsigned height, boolean abortable, global_game_variables_t *gv)\r
299 {\r
300         unsigned        drawofs,pagedelta;\r
301         unsigned        char maskb[8] = {1,2,4,8,16,32,64,128};\r
302         unsigned        x,y,p,frame;\r
303         long            rndval;\r
304         word TimeCount = *clockw;\r
305         word screenseg = SCREENSEG;\r
306 \r
307         pagedelta = dest-source;\r
308 //++++  VL_SetScreen (dest,0);\r
309         rndval = 1;\r
310         x = y = 0;\r
311 \r
312         __asm {\r
313                 mov     es,[screenseg]\r
314                 mov     dx,SC_INDEX\r
315                 mov     al,SC_MAPMASK\r
316                 out     dx,al\r
317         }\r
318 \r
319         TimeCount=frame=0;\r
320         do      // while (1)\r
321         {\r
322                 if (abortable)\r
323                 {\r
324                         IN_ReadControl(0,gv);\r
325                         if (gv->player[0].info.button0 || gv->player[0].info.button1 || gv->in.inst->Keyboard[sc_Space]\r
326                         || gv->in.inst->Keyboard[sc_Enter])\r
327                         {\r
328 //++++                          VW_ScreenToScreen (source,dest,width/8,height);\r
329                                 return;\r
330                         }\r
331                 }\r
332 \r
333                 for (p=0;p<PIXPERFRAME;p++)\r
334                 {\r
335                         //\r
336                         // seperate random value into x/y pair\r
337                         //\r
338                         __asm {\r
339                                 mov     ax,[WORD PTR rndval]\r
340                                 mov     dx,[WORD PTR rndval+2]\r
341                                 mov     bx,ax\r
342                                 dec     bl\r
343                                 mov     [BYTE PTR y],bl                 // low 8 bits - 1 = y xoordinate\r
344                                 mov     bx,ax\r
345                                 mov     cx,dx\r
346                                 shr     cx,1\r
347                                 rcr     bx,1\r
348                                 shr     bx,1\r
349                                 shr     bx,1\r
350                                 shr     bx,1\r
351                                 shr     bx,1\r
352                                 shr     bx,1\r
353                                 shr     bx,1\r
354                                 shr     bx,1\r
355                                 mov     [x],bx                                  // next 9 bits = x xoordinate\r
356                         //\r
357                         // advance to next random element\r
358                         //\r
359                                 shr     dx,1\r
360                                 rcr     ax,1\r
361                                 jnc     noxor\r
362                                 xor     dx,0x0001\r
363                                 xor     ax,0x2000\r
364 #ifdef __BORLANDC__\r
365                         }\r
366 #endif\r
367 noxor:\r
368 #ifdef __BORLANDC__\r
369                         __asm {\r
370 #endif\r
371                                 mov     [WORD PTR rndval],ax\r
372                                 mov     [WORD PTR rndval+2],dx\r
373                         }\r
374 \r
375                         if (x>width || y>height)\r
376                                 continue;\r
377                         drawofs = source+gv->video.ofs.ylookup[y];\r
378 \r
379                         __asm {\r
380                                 mov     cx,[x]\r
381                                 mov     si,cx\r
382                                 and     si,7\r
383                                 mov     dx,GC_INDEX\r
384                                 mov     al,GC_BITMASK\r
385                                 mov     ah,BYTE PTR [maskb+si]\r
386                                 out     dx,ax\r
387 \r
388                                 mov     si,[drawofs]\r
389                                 shr     cx,1\r
390                                 shr     cx,1\r
391                                 shr     cx,1\r
392                                 add     si,cx\r
393                                 mov     di,si\r
394                                 add     di,[pagedelta]\r
395 \r
396                                 mov     dx,GC_INDEX\r
397                                 mov     al,GC_READMAP                   // leave GC_INDEX set to READMAP\r
398                                 out         dx,al\r
399 \r
400                                 mov     dx,SC_INDEX+1\r
401                                 mov     al,1\r
402                                 out         dx,al\r
403                                 mov     dx,GC_INDEX+1\r
404                                 mov     al,0\r
405                                 out         dx,al\r
406 \r
407                                 mov     bl,[es:si]\r
408                                 xchg    [es:di],bl\r
409 \r
410                                 mov     dx,SC_INDEX+1\r
411                                 mov     al,2\r
412                                 out         dx,al\r
413                                 mov     dx,GC_INDEX+1\r
414                                 mov     al,1\r
415                                 out         dx,al\r
416 \r
417                                 mov     bl,[es:si]\r
418                                 xchg    [es:di],bl\r
419 \r
420                                 mov     dx,SC_INDEX+1\r
421                                 mov     al,4\r
422                                 out         dx,al\r
423                                 mov     dx,GC_INDEX+1\r
424                                 mov     al,2\r
425                                 out         dx,al\r
426 \r
427                                 mov     bl,[es:si]\r
428                                 xchg    [es:di],bl\r
429 \r
430                                 mov     dx,SC_INDEX+1\r
431                                 mov     al,8\r
432                                 out         dx,al\r
433                                 mov     dx,GC_INDEX+1\r
434                                 mov     al,3\r
435                                 out         dx,al\r
436 \r
437                                 mov     bl,[es:si]\r
438                                 xchg    [es:di],bl\r
439                         }\r
440 \r
441                         if (rndval == 1)                // entire sequence has been completed\r
442                         {\r
443 //++++                          VGABITMASK(255);\r
444 //++++                          VGAMAPMASK(15);\r
445                                 return;\r
446                         }\r
447                 }\r
448                 frame++;\r
449 //++++          while (TimeCount<frame){}       // don't go too fast\r
450         } while (1);\r
451 \r
452 \r
453 }\r
454 \r
455 //===========================================================================\r
456 \r
457 /*\r
458 ==================\r
459 =\r
460 = DebugMemory\r
461 =\r
462 ==================\r
463 */\r
464 \r
465 void DebugMemory_(global_game_variables_t *gvar, boolean q)\r
466 {\r
467         /*VW_FixRefreshBuffer ();\r
468         US_CenterWindow (16,7);\r
469 \r
470         US_CPrint ("Memory Usage");\r
471         US_CPrint ("------------");\r
472         US_Print ("Total         :");\r
473         US_PrintUnsigned (mminfo.mainmem/1024);\r
474         US_Print ("k\nFree        :");\r
475         US_PrintUnsigned (MM_UnusedMemory()/1024);\r
476         US_Print ("k\nWith purge:");\r
477         US_PrintUnsigned (MM_TotalFree()/1024);\r
478         US_Print ("k\n");\r
479         VW_UpdateScreen();*/\r
480         if(q){\r
481         printf("========================================\n");\r
482         printf("                DebugMemory_\n");\r
483         printf("========================================\n");}\r
484         if(q) { printf("Memory Usage\n");\r
485         printf("------------\n"); }else printf("        %c%c", 0xD3, 0xC4);\r
486         printf("Total:  "); if(q) printf("      "); printf("%uk", gvar->mmi.mainmem/1024);\r
487         if(q) printf("\n"); else printf("       ");\r
488         printf("Free:   "); if(q) printf("      "); printf("%uk", MM_UnusedMemory(gvar)/1024);\r
489         if(q) printf("\n"); else printf("       ");\r
490         printf("With purge:"); if(q) printf("   "); printf("%uk\n", MM_TotalFree(gvar)/1024);\r
491         if(q) printf("------------\n");\r
492 #ifdef __WATCOMC__\r
493         //IN_Ack ();\r
494 #endif\r
495 //      if(q) MM_ShowMemory (gvar);\r
496 }\r
497 \r
498 /*\r
499 ==========================\r
500 =\r
501 = ClearMemory\r
502 =\r
503 ==========================\r
504 */\r
505 \r
506 void ClearMemory (global_game_variables_t *gvar)\r
507 {\r
508 #ifdef __16_PM__\r
509         PM_UnlockMainMem(gvar);\r
510 #endif\r
511         //snd\r
512         MM_SortMem (gvar);\r
513 }\r
514 \r
515 /*\r
516 ==========================\r
517 =\r
518 = Quit\r
519 =\r
520 ==========================\r
521 */\r
522 \r
523 void Quit (global_game_variables_t *gvar, char *error)\r
524 {\r
525         //unsigned              finscreen;\r
526         memptr  screen=0;\r
527 \r
528         ClearMemory (gvar);\r
529         if (!*error)\r
530         {\r
531 // #ifndef JAPAN\r
532 //              CA_CacheGrChunk (ORDERSCREEN);\r
533 //              screen = grsegs[ORDERSCREEN];\r
534 // #endif\r
535 //              WriteConfig ();\r
536         }\r
537         else\r
538         {\r
539 //              CA_CacheGrChunk (ERRORSCREEN);\r
540 //              screen = grsegs[ERRORSCREEN];\r
541         }\r
542         Shutdown16(gvar);\r
543 \r
544         if (error && *error)\r
545         {\r
546                 //movedata((unsigned)screen,7,0xb800,0,7*160);\r
547                 gotoxy (10,4);\r
548                 fprintf(stderr, "%s\n", error);\r
549                 gotoxy (1,8);\r
550                 exit(1);\r
551         }\r
552         else\r
553         if (!error || !(*error))\r
554         {\r
555                 clrscr();\r
556 #ifndef JAPAN\r
557                 movedata ((unsigned)screen,7,0xb800,0,4000);\r
558                 gotoxy(1,24);\r
559 #endif\r
560 //asm   mov     bh,0\r
561 //asm   mov     dh,23   // row\r
562 //asm   mov     dl,0    // collumn\r
563 //asm   mov ah,2\r
564 //asm   int     0x10\r
565         }\r
566 \r
567         exit(0);\r
568 }\r
569 \r
570 //===========================================================================\r
571 \r
572 #ifndef __WATCOMC__\r
573 char global_temp_status_text[512];\r
574 char global_temp_status_text2[512];\r
575 #else\r
576 //\r
577 // for mary4 (XT)\r
578 // this is from my XT's BIOS\r
579 // http://www.phatcode.net/downloads.php?id=101\r
580 //\r
581 void turboXT(byte bakapee)\r
582 {\r
583         __asm {\r
584                 push    ax\r
585                 push    bx\r
586                 push    cx\r
587                 in      al, 61h                         //; Read equipment flags\r
588                 xor     al, bakapee                     //;   toggle speed\r
589                 out     61h, al                         //; Write new flags back\r
590 \r
591                 mov     bx, 0F89h                       //; low pitch blip\r
592                 and     al, 4                           //; Is turbo mode set?\r
593                 jz      @@do_beep\r
594                 mov     bx, 52Eh                        //; high pitch blip\r
595 \r
596         @@do_beep:\r
597                 mov     al, 10110110b           //; Timer IC 8253 square waves\r
598                 out     43h, al                         //;   channel 2, speaker\r
599                 mov     ax, bx\r
600                 out     42h, al                         //;   send low order\r
601                 mov     al, ah                          //;   load high order\r
602                 out     42h, al                         //;   send high order\r
603                 in      al, 61h                         //; Read IC 8255 machine status\r
604                 push    ax\r
605                 or      al, 00000011b\r
606                 out     61h, al                         //; Turn speaker on\r
607                 mov     cx, 2000h\r
608         @@delay:\r
609                 loop    @@delay\r
610                 pop     ax\r
611                 out     61h, al                         //; Turn speaker off\r
612                 pop     cx\r
613                 pop     bx\r
614                 pop     ax\r
615         }\r
616 }\r
617 #endif\r
618 \r
619 const char *word_to_binary(word x)\r
620 {\r
621         static char b[17];\r
622         int z;\r
623 \r
624         b[0] = '\0';\r
625         for (z = 16; z > 0; z >>= 1)\r
626         {\r
627                 strcat(b, ((x & z) == z) ? "1" : "0");\r
628         }\r
629         return b;\r
630 }\r
631 \r
632 const char *nibble_to_binary(nibble x)\r
633 {\r
634         static char b[9];\r
635         int z;\r
636 \r
637         b[0] = '\0';\r
638         for (z = 8; z > 0; z >>= 1)\r
639         {\r
640                 strcat(b, ((x & z) == z) ? "1" : "0");\r
641         }\r
642         return b;\r
643 }\r
644 \r
645 const char *boolean_to_binary(boolean x)\r
646 {\r
647         static char b[9];\r
648         int z;\r
649 \r
650         b[0] = '\0';\r
651         for (z = 1; z > 0; z >>= 1)\r
652         {\r
653                 strcat(b, ((x & z) == z) ? "1" : "0");\r
654         }\r
655         return b;\r
656 }\r
657 \r
658 void nibbletest()\r
659 {\r
660         nibble pee;\r
661         printf("nibbletest\n");\r
662         /* nibble to binary string */\r
663         for(pee=0;pee<18;pee++)\r
664                 printf("        %u %s\n", pee, nibble_to_binary(pee));\r
665         printf("        sizeof(nibble)=%s\n", nibble_to_binary(sizeof(nibble)));\r
666         printf("end of nibble test\n");\r
667 }\r
668 \r
669 void booleantest()\r
670 {\r
671         boolean pee;\r
672         printf("booleantest\n");\r
673         /* boolean to binary string */\r
674         for(pee=0;pee<4;pee++)\r
675                 printf("        %u %s\n", pee, boolean_to_binary(pee));\r
676         printf("        sizeof(boolean)=%s\n", boolean_to_binary(sizeof(boolean)));\r
677         printf("end of boolean test\n");\r
678 }\r
679 \r
680 #ifdef __BORLANDC__\r
681 word modexPalOverscan(word col)\r
682 {\r
683         //modexWaitBorder();\r
684         outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
685         outp(PAL_DATA_REG, col);\r
686         return col;\r
687 }\r
688 #endif\r