{$R-}
Unit Video;

Interface

Const BPPMaxMode    = 4;
      BPP           : Array[0..BPPMaxMode] Of Byte = (32,24,16,15,8);
      BPPText       : Array[0..BPPMaxMode] Of String = ('32bits Truecolor - S3 optimized   ',
                                                        '24bits Truecolor - Tseng optimized',
                                                        '16bits Hicolor                    ',
                                                        '15bits Hicolor                    ',
                                                        '8bits Grayscale - SAFETY MODE     ');
      Video_IVSVersion = '0.6.5';
      Video_ModeDesc : Array[0..BPPMaxMode,0..3] Of String = (('We recommend this mode','to run the demo because','it is the fastest mode.','Optimized for S3 cards.'),
                                                              ('If you have a Tseng video','adaptor, we recommend','to use this mode, instead','of 32bit mode.'),
                                                              ('This mode is supported by','nearly all videocards.','Use it if you have problems','with truecolor modes.'),
                                                              ('This mode is supported by','nearly all videocards.','Use it if you have problems','with truecolor modes.'),
                                                              ('This mode looks _REALLY_ ugly','but supported on any VGA','and compatible cards.',''));


Var Video_Modes        : Array[0..BPPMaxMode] Of Word;
    Video_SelectedMode : Word;
    Video_SelectedBPP  : Byte;
    Video_LFB          : DWord;
    Video_MappedBuffer : DWord;

    Video_Copy         : Procedure;
    Video_Screen       : Pointer;

    TerminateDemo      : Boolean;

Procedure Video_Init;
Procedure Video_ValidateModes;
Procedure Video_SelectMode;
Procedure Video_Close;
Procedure ExitDemo;

Implementation

Uses CRT,Graph,DPMILib,USM;


Procedure ExitDemo;
Begin
 USMP_StopPlays;
 Video_Close;
 TextMode(CO80);
 TextColor(7); TextBackGround(0);
 while keypressed do readkey;
 WriteLn;
 WriteLn('þ INQUISITION - DIFFERENCES MAKE THE ACTION! (TM)');
 WriteLn;
 WriteLn('þ R E F L E C T I O N S');
 WriteLn('þ at AntIQ''98');
 Halt(1);
End;

{$L SETUP.OBJ}
Procedure SetupAnsi; External;
Procedure DisplaySetupAnsi;
Var Counter   : DWord;
    CopyChar  : Byte;
    CopyColor : Byte;
Begin
 For Counter:=0 To 1840 Do Begin
   CopyChar:=Mem[Ofs(SetupAnsi)+Counter*2];
   CopyColor:=Mem[Ofs(SetupAnsi)+Counter*2+1];
   If CopyChar=0 Then CopyChar:=32;
   Mem[$B8000+Counter*2]:=CopyChar;
   Mem[$B8000+Counter*2+1]:=CopyColor;
  End;
End;

Procedure Video_ValidateModes;
Var Counter : DWord;
Begin
 For Counter:=0 To BPPMaxMode Do Begin
   Video_Modes[Counter]:=DetectSVGAMode(320,200,BPP[Counter],LFBOnly);
  End;
 Video_Modes[BPPMaxMode]:=$13;
End;

Procedure Video_SelectMode;
Var Counter  : DWord; Counter2 : DWord;
    Active   : Byte; Pressed : Char; ExitMenu : Boolean;
    PrevAct  : Byte;
Begin
 Video_ValidateModes;
 Video_LFB:=GetLFBAddress;
 ClrScr; DisplaySetupAnsi;
 GotoXY(1,24); TextColor(6); WriteLn('þ INQUISITION VIDEO SERVER VERSION ',Video_IVSVersion,' þ');
 HideCursor;
 Counter:=0; ExitMenu:=False;
 Repeat Active:=Counter; Inc(Counter); Until Video_Modes[Active]<>0;
 Repeat
  TextColor(6); TextBackGround(0); Window(51,13,80,18); ClrScr;
  For Counter:=0 To 3 Do WriteLn(Video_ModeDesc[Active,Counter]);
  GotoXY(1,6);
  If Active<BPPMaxMode Then Write('LFB at :',Video_LFB Shr 20,'MB') Else Write('NO LINEAR FRAMEBUFFER');
  Window(1,1,80,25);
  For Counter:=0 To BPPMaxMode Do Begin
    GotoXY(3,13+Counter*2);
    If Video_Modes[Counter]=0 Then TextColor(6) Else TextColor(15);
    If Active=Counter Then TextBackGround(4) Else TextBackGround(0);
    Write(' 320*200 ',BPPText[Counter],'  ');
   End;
  Pressed:=ReadKey;
  If Pressed=#0 Then Begin
    Pressed:=ReadKey;
    PrevAct:=Active;
    Case Pressed Of
      #72 : Begin If Active>0 Then Repeat Dec(Active); Until (Video_Modes[Active]<>0) Or (Active=0);
                  If (Active=0) And (Video_Modes[Active]=0) Then Active:=PrevAct; End;
      #80 : Begin If Active<BPPMaxMode Then Repeat Inc(Active); Until (Video_Modes[Active]<>0) Or (Active=BPPMaxMode);
                  If (Active=BPPMaxMode) And (Video_Modes[Active]=0) Then Active:=PrevAct; End;
     End;
    End Else Begin If Pressed=#13 Then ExitMenu:=True; End;
 Until ExitMenu;
 Video_SelectedMode:=Video_Modes[Active];
 Video_SelectedBPP:=Active;
 While KeyPressed Do ReadKey;
 TerminateDemo:=False;
End;

Procedure CopyMode32RGB; Forward;
Procedure CopyMode32BGR; Forward;
Procedure CopyMode24RGB; Forward;
Procedure CopyMode24BGR; Forward;
Procedure CopyMode16;    Forward;
Procedure CopyMode15;    Forward;
Procedure CopyModeBW;    Forward;

Procedure Video_Init;
Var VESAModeInfo : VBEModeInfoType;
    Regs         : TRMRegs;
    Counter      : DWord;
Begin
 GetMem(Video_Screen,256000);
 FillChar(Video_Screen^,256000,#0);
 ClearRmRegs(Regs);
 Regs.ES:=Buf_16;
 Regs.AX:=$4F01;
 Regs.DI:=$0000;
 Regs.CX:=Video_SelectedMode;
 RealModeInt($10,Regs);
 Move(Pointer(Buf_32)^,VESAModeInfo,256);
 Case BPP[Video_SelectedBPP] Of
   32 : Begin If VESAModeInfo.RedFieldPosition=0 Then Video_Copy:=CopyMode32BGR
                                                 Else Video_Copy:=CopyMode32RGB; End;
   24 : Begin If VESAModeInfo.RedFieldPosition=0 Then Video_Copy:=CopyMode24BGR
                                                 Else Video_Copy:=CopyMode24RGB; End;
   16 : Begin Video_Copy:=CopyMode16; End;
   15 : Begin Video_Copy:=CopyMode15; End;
   8  : Begin Video_Copy:=CopyModeBW; End;
  End;
 Case BPP[Video_SelectedBPP] Of
   32 : Begin
     Video_MappedBuffer:=MapPhysicalToLinear(VesaModeInfo.PhysBasePtr,4096*1024);
     Asm MOV AX,$4F02; MOV BX,Video_SelectedMode; INT 10H; End;
    End;
   24 : Begin
     Video_MappedBuffer:=MapPhysicalToLinear(VesaModeInfo.PhysBasePtr,4096*1024);
     Asm MOV AX,$4F02; MOV BX,Video_SelectedMode; INT 10H; End;
    End;
   16 : Begin
     Video_MappedBuffer:=MapPhysicalToLinear(VesaModeInfo.PhysBasePtr,4096*1024);
     Asm MOV AX,$4F02; MOV BX,Video_SelectedMode; INT 10H; End;
    End;
   15 : Begin
     Video_MappedBuffer:=MapPhysicalToLinear(VesaModeInfo.PhysBasePtr,4096*1024);
     Asm MOV AX,$4F02; MOV BX,Video_SelectedMode; INT 10H; End;
    End;
   8           : Begin
     Asm MOV AX,$13; INT 10H; End;
     For Counter:=0 To 255 Do SetRGBPalette(Counter,Counter Shr 2,Counter Shr 2,Counter Shr 2);
    End;
  End;

{ SetGraphMode(Video_SelectedMode);}
End;

Procedure Video_Close;
Begin
 FreeMem(Video_Screen,256000);
End;

{ þ INTERNAL FUNCTIONS þ }

Procedure CopyMode32RGB; Assembler;
Asm
 IN  AL,$60
 CMP AL,$80
 JA  @RUN
  MOV TerminateDemo,True
 @RUN:
 MOV ESI,[Video_Screen]
 MOV EDI,[Video_MappedBuffer]
 MOV ECX,64000
 CLD
 REP MOVSD
End;

Procedure CopyMode32BGR; Assembler;
Asm
 IN  AL,$60
 CMP AL,$80
 JA  @RUN
  MOV TerminateDemo,True
 @RUN:
 MOV ESI,[Video_Screen]
 MOV EDI,[Video_MappedBuffer]
 MOV ECX,64000
 CLD
 @CycleHead:
  MOV EAX,[ESI]
  ROL EAX,8
  XCHG AL,AH
  ROR EAX,16
  STOSD
  ADD ESI,4
 LOOP @CycleHead
End;

Procedure CopyMode24RGB; Assembler;
Asm
 IN  AL,$60
 CMP AL,$80
 JA  @RUN
  MOV TerminateDemo,True
 @RUN:
 MOV ESI,[Video_Screen]
 MOV EDI,[Video_MappedBuffer]
 MOV ECX,64000
 CLD
 @CycleHead:
  MOV EAX,[ESI]
  MOV BL,AL
  ROR EAX,8
  MOV [EDI],BL
  INC EDI
  STOSW
  ADD ESI,4
 LOOP @CycleHead
End;

Procedure CopyMode24BGR; Assembler;
Asm
 IN  AL,$60
 CMP AL,$80
 JA  @RUN
  MOV TerminateDemo,True
 @RUN:
 MOV ESI,[Video_Screen]
 MOV EDI,[Video_MappedBuffer]
 MOV ECX,64000
 CLD
 @CycleHead:
  MOV EAX,[ESI]
  ROR EAX,8
  MOV BL,AH
  ROL EAX,8
  XCHG AL,AH
  MOV [EDI],BL
  INC EDI
  STOSW
  ADD ESI,4
 LOOP @CycleHead
End;

Procedure CopyMode16; Assembler;
Asm
 IN  AL,$60
 CMP AL,$80
 JA  @RUN
  MOV TerminateDemo,True
 @RUN:
 MOV ESI,[Video_Screen]
 MOV EDI,[Video_MappedBuffer]
 MOV ECX,64000
 CLD
 @CycleHead:
  XOR EDX,EDX
  XOR EAX,EAX
  MOV EBX,[ESI]
  SHR BL,3
  MOV DL,BL
  SHR BH,2
  MOV AL,BH
  SHL AX,5
  ADD DX,AX
  SHR EBX,8
  MOV AL,BH
  SHR AL,3
  SHL EAX,11
  ADD EDX,EAX
  MOV EAX,EDX
  STOSW
  ADD ESI,4
 LOOP @CycleHead
End;

Procedure CopyMode15; Assembler;
Asm
 IN  AL,$60
 CMP AL,$80
 JA  @RUN
  MOV TerminateDemo,True
 @RUN:
 MOV ESI,[Video_Screen]
 MOV EDI,[Video_MappedBuffer]
 MOV ECX,64000
 CLD
 @CycleHead:
  XOR EDX,EDX
  XOR EAX,EAX
  MOV EBX,[ESI]
  SHR BL,3
  MOV DL,BL
  SHR BH,3
  MOV AL,BH
  SHL AX,5
  ADD DX,AX
  SHR EBX,8
  MOV AL,BH
  SHR AL,3
  SHL EAX,10
  ADD EDX,EAX
  MOV EAX,EDX
  STOSW
  ADD ESI,4
 LOOP @CycleHead
End;

Procedure CopyModeFake; Assembler;
Asm
End;

Procedure CopyModeBW; Assembler;
Asm
 IN  AL,$60
 CMP AL,$80
 JA  @RUN
  MOV TerminateDemo,True
 @RUN:
 MOV ESI,[Video_Screen]
 MOV EDI,$A0000
 MOV ECX,64000
 CLD
 @CycleHead:
  MOV EAX,[ESI]
  MOV BL,AL
  SHR BL,2
  XOR EDX,EDX
  PUSH EAX
  MOV DL,AH
  XCHG AH,AL
  XOR AH,AH
  SHL DX,2
  ADD DX,AX
  SHR DX,3
  ADD BL,DL
  POP EAX
  ROR EAX,8
  SHR AH,3
  ADD BL,AH
  MOV AL,BL
  STOSB
  ADD ESI,4
 LOOP @CycleHead
End;

Begin
End.
