OSDN Git Service

p16 is being worked on a bunch by me wwww [16_ca needs huge amounts of work and I...
[proj16/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         gvar->video.VL_Initiated = 1;\r
138 }\r
139 \r
140 \r
141 //===========================================================================\r
142 \r
143 /*\r
144 ====================\r
145 =\r
146 = ReadConfig\r
147 =\r
148 ====================\r
149 */\r
150 \r
151 /*void ReadConfig(void)\r
152 {\r
153         int                                      file;\r
154         SDMode            sd;\r
155         SMMode            sm;\r
156         SDSMode          sds;\r
157 \r
158 \r
159         if ( (file = open(configname,O_BINARY | O_RDONLY)) != -1)\r
160         {\r
161         //\r
162         // valid config file\r
163         //\r
164                 read(file,Scores,sizeof(HighScore) * MaxScores);\r
165 \r
166                 read(file,&sd,sizeof(sd));\r
167                 read(file,&sm,sizeof(sm));\r
168                 read(file,&sds,sizeof(sds));\r
169 \r
170                 read(file,&mouseenabled,sizeof(mouseenabled));\r
171                 read(file,&joystickenabled,sizeof(joystickenabled));\r
172                 read(file,&joypadenabled,sizeof(joypadenabled));\r
173                 read(file,&joystickprogressive,sizeof(joystickprogressive));\r
174                 read(file,&joystickport,sizeof(joystickport));\r
175 \r
176                 read(file,&dirscan,sizeof(dirscan));\r
177                 read(file,&buttonscan,sizeof(buttonscan));\r
178                 read(file,&buttonmouse,sizeof(buttonmouse));\r
179                 read(file,&buttonjoy,sizeof(buttonjoy));\r
180 \r
181                 read(file,&viewsize,sizeof(viewsize));\r
182                 read(file,&mouseadjustment,sizeof(mouseadjustment));\r
183 \r
184                 close(file);\r
185 \r
186                 if (sd == sdm_AdLib && !AdLibPresent && !SoundBlasterPresent)\r
187                 {\r
188                         sd = sdm_PC;\r
189                         sd = smm_Off;\r
190                 }\r
191 \r
192                 if ((sds == sds_SoundBlaster && !SoundBlasterPresent) ||\r
193                         (sds == sds_SoundSource && !SoundSourcePresent))\r
194                         sds = sds_Off;\r
195 \r
196                 if (!MousePresent)\r
197                         mouseenabled = false;\r
198                 if (!JoysPresent[joystickport])\r
199                         joystickenabled = false;\r
200 \r
201                 MainMenu[6].active=1;\r
202                 MainItems.curpos=0;\r
203         }\r
204         else\r
205         {\r
206         //\r
207         // no config file, so select by hardware\r
208         //\r
209                 if (SoundBlasterPresent || AdLibPresent)\r
210                 {\r
211                         sd = sdm_AdLib;\r
212                         sm = smm_AdLib;\r
213                 }\r
214                 else\r
215                 {\r
216                         sd = sdm_PC;\r
217                         sm = smm_Off;\r
218                 }\r
219 \r
220                 if (SoundBlasterPresent)\r
221                         sds = sds_SoundBlaster;\r
222                 else if (SoundSourcePresent)\r
223                         sds = sds_SoundSource;\r
224                 else\r
225                         sds = sds_Off;\r
226 \r
227                 if (MousePresent)\r
228                         mouseenabled = true;\r
229 \r
230                 joystickenabled = false;\r
231                 joypadenabled = false;\r
232                 joystickport = 0;\r
233                 joystickprogressive = false;\r
234 \r
235                 viewsize = 15;\r
236                 mouseadjustment=5;\r
237         }\r
238 \r
239         SD_SetMusicMode (sm);\r
240         SD_SetSoundMode (sd);\r
241         SD_SetDigiDevice (sds);\r
242 }*/\r
243 \r
244 \r
245 /*\r
246 ====================\r
247 =\r
248 = WriteConfig\r
249 =\r
250 ====================\r
251 */\r
252 \r
253 /*void WriteConfig(void)\r
254 {\r
255         int                                      file;\r
256 \r
257         file = open(configname,O_CREAT | O_BINARY | O_WRONLY,\r
258                                 S_IREAD | S_IWRITE | S_IFREG);\r
259 \r
260         if (file != -1)\r
261         {\r
262                 write(file,Scores,sizeof(HighScore) * MaxScores);\r
263 \r
264                 write(file,&SoundMode,sizeof(SoundMode));\r
265                 write(file,&MusicMode,sizeof(MusicMode));\r
266                 write(file,&DigiMode,sizeof(DigiMode));\r
267 \r
268                 write(file,&mouseenabled,sizeof(mouseenabled));\r
269                 write(file,&joystickenabled,sizeof(joystickenabled));\r
270                 write(file,&joypadenabled,sizeof(joypadenabled));\r
271                 write(file,&joystickprogressive,sizeof(joystickprogressive));\r
272                 write(file,&joystickport,sizeof(joystickport));\r
273 \r
274                 write(file,&dirscan,sizeof(dirscan));\r
275                 write(file,&buttonscan,sizeof(buttonscan));\r
276                 write(file,&buttonmouse,sizeof(buttonmouse));\r
277                 write(file,&buttonjoy,sizeof(buttonjoy));\r
278 \r
279                 write(file,&viewsize,sizeof(viewsize));\r
280                 write(file,&mouseadjustment,sizeof(mouseadjustment));\r
281 \r
282                 close(file);\r
283         }\r
284 }*/\r
285 \r
286 //===========================================================================\r
287 \r
288 /*\r
289 ===================\r
290 =\r
291 = FizzleFade\r
292 =\r
293 ===================\r
294 */\r
295 \r
296 #define PIXPERFRAME     1600\r
297 \r
298 void FizzleFade (unsigned source, unsigned dest,\r
299         unsigned width,unsigned height, boolean abortable, global_game_variables_t *gv)\r
300 {\r
301         unsigned        drawofs,pagedelta;\r
302         unsigned        char maskb[8] = {1,2,4,8,16,32,64,128};\r
303         unsigned        x,y,p,frame;\r
304         long            rndval;\r
305         word TimeCount = *clockw;\r
306         word screenseg = SCREENSEG;\r
307 \r
308         pagedelta = dest-source;\r
309 //++++  VL_SetScreen (dest,0);\r
310         rndval = 1;\r
311         x = y = 0;\r
312 \r
313         __asm {\r
314                 mov     es,[screenseg]\r
315                 mov     dx,SC_INDEX\r
316                 mov     al,SC_MAPMASK\r
317                 out     dx,al\r
318         }\r
319 \r
320         TimeCount=frame=0;\r
321         do      // while (1)\r
322         {\r
323                 if (abortable)\r
324                 {\r
325                         IN_ReadControl(0,gv);\r
326                         if (gv->player[0].info.button0 || gv->player[0].info.button1 || gv->in.inst->Keyboard[sc_Space]\r
327                         || gv->in.inst->Keyboard[sc_Enter])\r
328                         {\r
329 //++++                          VW_ScreenToScreen (source,dest,width/8,height);\r
330                                 return;\r
331                         }\r
332                 }\r
333 \r
334                 for (p=0;p<PIXPERFRAME;p++)\r
335                 {\r
336                         //\r
337                         // seperate random value into x/y pair\r
338                         //\r
339                         __asm {\r
340                                 mov     ax,[WORD PTR rndval]\r
341                                 mov     dx,[WORD PTR rndval+2]\r
342                                 mov     bx,ax\r
343                                 dec     bl\r
344                                 mov     [BYTE PTR y],bl                 // low 8 bits - 1 = y xoordinate\r
345                                 mov     bx,ax\r
346                                 mov     cx,dx\r
347                                 shr     cx,1\r
348                                 rcr     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                                 shr     bx,1\r
356                                 mov     [x],bx                                  // next 9 bits = x xoordinate\r
357                         //\r
358                         // advance to next random element\r
359                         //\r
360                                 shr     dx,1\r
361                                 rcr     ax,1\r
362                                 jnc     noxor\r
363                                 xor     dx,0x0001\r
364                                 xor     ax,0x2000\r
365 #ifdef __BORLANDC__\r
366                         }\r
367 #endif\r
368 noxor:\r
369 #ifdef __BORLANDC__\r
370                         __asm {\r
371 #endif\r
372                                 mov     [WORD PTR rndval],ax\r
373                                 mov     [WORD PTR rndval+2],dx\r
374                         }\r
375 \r
376                         if (x>width || y>height)\r
377                                 continue;\r
378                         drawofs = source+gv->video.ofs.ylookup[y];\r
379 \r
380                         __asm {\r
381                                 mov     cx,[x]\r
382                                 mov     si,cx\r
383                                 and     si,7\r
384                                 mov     dx,GC_INDEX\r
385                                 mov     al,GC_BITMASK\r
386                                 mov     ah,BYTE PTR [maskb+si]\r
387                                 out     dx,ax\r
388 \r
389                                 mov     si,[drawofs]\r
390                                 shr     cx,1\r
391                                 shr     cx,1\r
392                                 shr     cx,1\r
393                                 add     si,cx\r
394                                 mov     di,si\r
395                                 add     di,[pagedelta]\r
396 \r
397                                 mov     dx,GC_INDEX\r
398                                 mov     al,GC_READMAP                   // leave GC_INDEX set to READMAP\r
399                                 out         dx,al\r
400 \r
401                                 mov     dx,SC_INDEX+1\r
402                                 mov     al,1\r
403                                 out         dx,al\r
404                                 mov     dx,GC_INDEX+1\r
405                                 mov     al,0\r
406                                 out         dx,al\r
407 \r
408                                 mov     bl,[es:si]\r
409                                 xchg    [es:di],bl\r
410 \r
411                                 mov     dx,SC_INDEX+1\r
412                                 mov     al,2\r
413                                 out         dx,al\r
414                                 mov     dx,GC_INDEX+1\r
415                                 mov     al,1\r
416                                 out         dx,al\r
417 \r
418                                 mov     bl,[es:si]\r
419                                 xchg    [es:di],bl\r
420 \r
421                                 mov     dx,SC_INDEX+1\r
422                                 mov     al,4\r
423                                 out         dx,al\r
424                                 mov     dx,GC_INDEX+1\r
425                                 mov     al,2\r
426                                 out         dx,al\r
427 \r
428                                 mov     bl,[es:si]\r
429                                 xchg    [es:di],bl\r
430 \r
431                                 mov     dx,SC_INDEX+1\r
432                                 mov     al,8\r
433                                 out         dx,al\r
434                                 mov     dx,GC_INDEX+1\r
435                                 mov     al,3\r
436                                 out         dx,al\r
437 \r
438                                 mov     bl,[es:si]\r
439                                 xchg    [es:di],bl\r
440                         }\r
441 \r
442                         if (rndval == 1)                // entire sequence has been completed\r
443                         {\r
444 //++++                          VGABITMASK(255);\r
445 //++++                          VGAMAPMASK(15);\r
446                                 return;\r
447                         }\r
448                 }\r
449                 frame++;\r
450 //++++          while (TimeCount<frame){}       // don't go too fast\r
451         } while (1);\r
452 \r
453 \r
454 }\r
455 \r
456 //===========================================================================\r
457 \r
458 /*\r
459 ==================\r
460 =\r
461 = DebugMemory\r
462 =\r
463 ==================\r
464 */\r
465 \r
466 void DebugMemory_(global_game_variables_t *gvar, boolean q)\r
467 {\r
468         /*VW_FixRefreshBuffer ();\r
469         US_CenterWindow (16,7);\r
470 \r
471         US_CPrint ("Memory Usage");\r
472         US_CPrint ("------------");\r
473         US_Print ("Total         :");\r
474         US_PrintUnsigned (mminfo.mainmem/1024);\r
475         US_Print ("k\nFree        :");\r
476         US_PrintUnsigned (MM_UnusedMemory()/1024);\r
477         US_Print ("k\nWith purge:");\r
478         US_PrintUnsigned (MM_TotalFree()/1024);\r
479         US_Print ("k\n");\r
480         VW_UpdateScreen();*/\r
481         if(q){\r
482         printf("========================================\n");\r
483         printf("                DebugMemory_\n");\r
484         printf("========================================\n");}\r
485         if(q) { printf("Memory Usage\n");\r
486         printf("------------\n"); }else printf("        %c%c", 0xD3, 0xC4);\r
487         printf("Total:  "); if(q) printf("      "); printf("%uk", gvar->mmi.mainmem/1024);\r
488         if(q) printf("\n"); else printf("       ");\r
489         printf("Free:   "); if(q) printf("      "); printf("%uk", MM_UnusedMemory(gvar)/1024);\r
490         if(q) printf("\n"); else printf("       ");\r
491         printf("With purge:"); if(q) printf("   "); printf("%uk\n", MM_TotalFree(gvar)/1024);\r
492         if(q) printf("------------\n");\r
493 #ifdef __WATCOMC__\r
494         //IN_Ack ();\r
495 #endif\r
496 //      if(q) MM_ShowMemory (gvar);\r
497 }\r
498 \r
499 /*\r
500 ==========================\r
501 =\r
502 = ClearMemory\r
503 =\r
504 ==========================\r
505 */\r
506 \r
507 void ClearMemory (global_game_variables_t *gvar)\r
508 {\r
509 #ifdef __16_PM__\r
510         PM_UnlockMainMem(gvar);\r
511 #endif\r
512         //sd\r
513         MM_SortMem (gvar);\r
514 }\r
515 \r
516 /*\r
517 ==========================\r
518 =\r
519 = Quit\r
520 =\r
521 ==========================\r
522 */\r
523 \r
524 void Quit (global_game_variables_t *gvar, char *error)\r
525 {\r
526         //unsigned              finscreen;\r
527         memptr  screen=0;\r
528 \r
529         ClearMemory (gvar);\r
530         if (!*error)\r
531         {\r
532 // #ifndef JAPAN\r
533 //              CA_CacheGrChunk (ORDERSCREEN);\r
534 //              screen = grsegs[ORDERSCREEN];\r
535 // #endif\r
536 //              WriteConfig ();\r
537         }\r
538         else\r
539         {\r
540 //              CA_CacheGrChunk (ERRORSCREEN);\r
541 //              screen = grsegs[ERRORSCREEN];\r
542         }\r
543         Shutdown16(gvar);\r
544 \r
545         if (error && *error)\r
546         {\r
547                 //movedata((unsigned)screen,7,0xb800,0,7*160);\r
548                 gotoxy (10,4);\r
549                 fprintf(stderr, "%s\n", error);\r
550                 gotoxy (1,8);\r
551                 exit(1);\r
552         }\r
553         else\r
554         if (!error || !(*error))\r
555         {\r
556                 clrscr();\r
557 #ifndef JAPAN\r
558                 movedata ((unsigned)screen,7,0xb800,0,4000);\r
559                 gotoxy(1,24);\r
560 #endif\r
561 //asm   mov     bh,0\r
562 //asm   mov     dh,23   // row\r
563 //asm   mov     dl,0    // collumn\r
564 //asm   mov ah,2\r
565 //asm   int     0x10\r
566         }\r
567 \r
568         exit(0);\r
569 }\r
570 \r
571 //===========================================================================\r
572 \r
573 #ifndef __WATCOMC__\r
574 char global_temp_status_text[512];\r
575 char global_temp_status_text2[512];\r
576 #else\r
577 //\r
578 // for mary4 (XT)\r
579 // this is from my XT's BIOS\r
580 // http://www.phatcode.net/downloads.php?id=101\r
581 //\r
582 void turboXT(byte bakapee)\r
583 {\r
584         __asm {\r
585                 push    ax\r
586                 push    bx\r
587                 push    cx\r
588                 in      al, 61h                         //; Read equipment flags\r
589                 xor     al, bakapee                     //;   toggle speed\r
590                 out     61h, al                         //; Write new flags back\r
591 \r
592                 mov     bx, 0F89h                       //; low pitch blip\r
593                 and     al, 4                           //; Is turbo mode set?\r
594                 jz      @@do_beep\r
595                 mov     bx, 52Eh                        //; high pitch blip\r
596 \r
597         @@do_beep:\r
598                 mov     al, 10110110b           //; Timer IC 8253 square waves\r
599                 out     43h, al                         //;   channel 2, speaker\r
600                 mov     ax, bx\r
601                 out     42h, al                         //;   send low order\r
602                 mov     al, ah                          //;   load high order\r
603                 out     42h, al                         //;   send high order\r
604                 in      al, 61h                         //; Read IC 8255 machine status\r
605                 push    ax\r
606                 or      al, 00000011b\r
607                 out     61h, al                         //; Turn speaker on\r
608                 mov     cx, 2000h\r
609         @@delay:\r
610                 loop    @@delay\r
611                 pop     ax\r
612                 out     61h, al                         //; Turn speaker off\r
613                 pop     cx\r
614                 pop     bx\r
615                 pop     ax\r
616         }\r
617 }\r
618 #endif\r
619 \r
620 const char *word_to_binary(word x)\r
621 {\r
622         static char b[17];\r
623         int z;\r
624 \r
625         b[0] = '\0';\r
626         for (z = 16; z > 0; z >>= 1)\r
627         {\r
628                 strcat(b, ((x & z) == z) ? "1" : "0");\r
629         }\r
630         return b;\r
631 }\r
632 \r
633 const char *nibble_to_binary(nibble x)\r
634 {\r
635         static char b[9];\r
636         int z;\r
637 \r
638         b[0] = '\0';\r
639         for (z = 8; z > 0; z >>= 1)\r
640         {\r
641                 strcat(b, ((x & z) == z) ? "1" : "0");\r
642         }\r
643         return b;\r
644 }\r
645 \r
646 const char *boolean_to_binary(boolean x)\r
647 {\r
648         static char b[9];\r
649         int z;\r
650 \r
651         b[0] = '\0';\r
652         for (z = 1; z > 0; z >>= 1)\r
653         {\r
654                 strcat(b, ((x & z) == z) ? "1" : "0");\r
655         }\r
656         return b;\r
657 }\r
658 \r
659 void nibbletest()\r
660 {\r
661         nibble pee;\r
662         printf("nibbletest\n");\r
663         /* nibble to binary string */\r
664         for(pee=0;pee<18;pee++)\r
665                 printf("        %u %s\n", pee, nibble_to_binary(pee));\r
666         printf("        sizeof(nibble)=%s\n", nibble_to_binary(sizeof(nibble)));\r
667         printf("end of nibble test\n");\r
668 }\r
669 \r
670 void booleantest()\r
671 {\r
672         boolean pee;\r
673         printf("booleantest\n");\r
674         /* boolean to binary string */\r
675         for(pee=0;pee<4;pee++)\r
676                 printf("        %u %s\n", pee, boolean_to_binary(pee));\r
677         printf("        sizeof(boolean)=%s\n", boolean_to_binary(sizeof(boolean)));\r
678         printf("end of boolean test\n");\r
679 }\r
680 \r
681 #ifdef __BORLANDC__\r
682 word modexPalOverscan(word col)\r
683 {\r
684         //modexWaitBorder();\r
685         outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
686         outp(PAL_DATA_REG, col);\r
687         return col;\r
688 }\r
689 #endif\r