Advertisement
Guest User

Untitled

a guest
Apr 9th, 2017
328
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 7.77 KB | None | 0 0
  1. unit DDraw;
  2.  
  3. interface
  4. uses
  5.   Windows, DirectDraw;
  6.  
  7. var
  8.  
  9.   d_x: integer = 1024;
  10.   d_y: integer = 256;
  11.  
  12.   IsWindowed: boolean = false;
  13.  
  14.   rcSaveWindowSize,
  15.   fscreen: TRECT;
  16.  
  17.   IsColor: boolean = true;
  18.  
  19.   ColorMode:integer = 3;
  20.  
  21.  
  22. function  DirectDrawInit(ddWnd: HWND): boolean;
  23. procedure ToggleFullScreen(ddWnd: HWND);
  24. procedure DrawScreen(ddWnd: hwnd; BKSCR:pointer; ScrReg:integer);
  25. procedure CreatePixelTable;
  26.  
  27. implementation
  28.  
  29. var
  30.   lpDD: IDIRECTDRAW7 = nil;
  31.   lpDDSPrimary: IDIRECTDRAWSURFACE7 = nil;
  32.   lpDDSBack: IDIRECTDRAWSURFACE7 = nil;
  33.   lpClipper: iDirectDrawClipper = nil;
  34.  
  35. // пиксельный массив для быстрого вывода
  36.   pix32tbl : PIntegerArray = nil;
  37.   pix32data: array [0..256*8] of integer;
  38.  
  39.  
  40. function DirectDrawWindowedInit(ddWnd: HWND): boolean;
  41. begin
  42.   IsWindowed := true;
  43.   lpDD.FlipToGDISurface;
  44.   lpDD.SetCooperativeLevel(ddWnd, DDSCL_NORMAL);
  45.   lpDDSPrimary.SetClipper(lpClipper);
  46.   result := true;
  47. end;
  48.  
  49.  
  50. function DirectDrawInit(ddWnd: HWND): boolean;
  51. var
  52.   ddrval: HRESULT;
  53.   DD: IDIRECTDRAW;
  54.   ddsd: DDSURFACEDESC2;
  55. begin
  56.   result := false;
  57.  
  58.   CreatePixelTable;
  59.  
  60.   ddrval := DirectDrawCreate(nil, DD, nil); if ddrval <> DD_OK then exit;
  61. // получить интерфейс IDirectDraw7
  62.   DD.QueryInterface(IID_IDirectDraw7, lpDD);
  63. // using DDSCL_NORMAL means we will coexist with GDI
  64.   ddrval := lpDD.SetCooperativeLevel(ddWnd, DDSCL_NORMAL);
  65.  
  66. // создание основной поверхности
  67.   FillChar(ddsd, SizeOf(ddsd), 0);
  68.   ddsd.dwSize := sizeof(ddsd);
  69.   ddsd.dwFlags := DDSD_CAPS;
  70.   ddsd.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE;
  71.  
  72.   ddrval := lpDD.CreateSurface(ddsd, lpDDSPrimary, nil);
  73.   if (ddrval <> DD_OK) then exit;
  74.  
  75. // создание вторичной поверхности
  76.   ddsd.dwFlags := DDSD_CAPS or DDSD_HEIGHT or DDSD_WIDTH;
  77.   ddsd.ddsCaps.dwCaps := DDSCAPS_OFFSCREENPLAIN;
  78.   ddsd.dwWidth := d_x;
  79.   ddsd.dwHeight := d_y;
  80.  
  81.   ddrval := lpDD.CreateSurface(ddsd, lpDDSBack, nil);
  82.   if (ddrval <> DD_OK) then exit;
  83.  
  84. // Создание клипера окна
  85.   ddrval := lpDD.CreateClipper(0, lpClipper, nil);
  86.   if (ddrval <> DD_OK) then exit;
  87. // Установливаем клипер в наш HWND,
  88.   ddrval := lpClipper.SetHWnd(0, ddWnd);
  89.  
  90.   GetWindowRect(ddWnd, rcSaveWindowSize);
  91.   DirectDrawWindowedInit(ddWnd);
  92.   result := true;
  93. end;
  94.  
  95.  
  96. function DirectDrawFullScreenInit(d_hwnd: HWND): boolean;
  97. begin
  98.   IsWindowed := false;
  99.   lpDD.SetCooperativeLevel(d_hwnd, DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN);
  100.   GetWindowRect(GetDesktopWindow, fscreen);
  101.   lpDDSPrimary.SetClipper(nil);
  102.   result := true;
  103. end;
  104.  
  105. procedure ToggleFullScreen(ddWnd: hwnd);
  106. begin
  107. //  finiObjects(ddWnd);
  108.   if IsWindowed then
  109.   begin
  110.  
  111.     SetWindowLong(ddwnd,GWL_STYLE,WS_OVERLAPPEDWINDOW and not WS_SYSMENU);
  112.  
  113.     ShowCursor(false);
  114.  
  115. //    GetWindowRect(ddWnd, rcSaveWindowSize);
  116.     DirectDrawFullScreenInit(ddWnd);
  117.  
  118.   end
  119.   else
  120.   begin
  121.  
  122.     DirectDrawWindowedInit(ddWnd);
  123.  
  124.     SetWindowPos(ddWnd, 0, rcSaveWindowSize.Left, rcSaveWindowSize.Top,
  125.       rcSaveWindowSize.Right - rcSaveWindowSize.Left, rcSaveWindowSize.Bottom - rcSaveWindowSize.Top, SWP_DRAWFRAME);
  126.  
  127.     SetWindowLong(ddwnd,GWL_STYLE,WS_OVERLAPPEDWINDOW);
  128.     ShowWindow(ddwnd, SW_SHOWDEFAULT);
  129.     ShowCursor(true);
  130.   end;
  131. end;
  132.  
  133. //
  134. // Пакетная запись пиксельной таблицы (цвет = 32бит),
  135. // в экранный буфер, с удвоением при размере 1024
  136. //
  137. procedure PSet(scr,clr:pointer);
  138. asm
  139. //    mov eax,scr
  140. //    mov edx,clr
  141.     movaps xmm0, [edx]
  142.     movaps xmm1, [edx+16]
  143.  
  144.     cmp d_x, 1024
  145.     jnz @@sk
  146.  
  147.     movaps xmm2, xmm0     //111111 222222 333333 444444
  148.     shufps xmm0,xmm0,50h  //111111 111111 222222 222222
  149.     shufps xmm2,xmm2,0fah //333333 333333 444444 444444
  150.  
  151.     movaps [eax], xmm0
  152.     movaps [eax+16], xmm2
  153.  
  154. /////////////////////
  155.     movaps xmm0, xmm1
  156.  
  157.     shufps xmm0,xmm0,50h
  158.     shufps xmm1,xmm1,0fah
  159.  
  160.     movaps [eax+16+16], xmm0
  161.     movaps [eax+16+16+16], xmm1
  162.     ret
  163.  
  164. @@sk:
  165.     movaps [eax], xmm0
  166.     movaps [eax+16], xmm1
  167. end;
  168.  
  169.  
  170. procedure DrawScreen(ddWnd: hwnd; BKScr:pointer; ScrReg:integer);
  171. type
  172.   TByteArray = array [0..65535] of byte;
  173.   PByteArray = ^TByteArray;
  174.  
  175. var
  176.    BKScreen: PByteArray;
  177.    BackScr: PIntegerArray;
  178.    x, y, y2, data: integer;
  179.    p: tPOINT;
  180.    ddsd: DDSURFACEDESC2;
  181. begin
  182. // проверить доступность и восстановление экранов
  183.   if lpDDSBack.IsLost <> S_OK then begin
  184.      lpDDSBack._Restore;
  185.      lpDDSPrimary._Restore;
  186.   end;
  187.  
  188.   ddsd.dwSize  := sizeof(ddsd);
  189.  
  190.   if lpDDSBack.Lock (nil, ddsd, DDLOCK_SURFACEMEMORYPTR, 0) <> S_OK
  191.   then exit;
  192. // получить указатель памяти теневого буффера
  193.   BackScr := ddsd.lpSurface;
  194.  
  195.   BKScreen := BKScr;
  196.  
  197.   for y := 0 to 255 do begin
  198.  
  199. //    y2 := y - (k1801vm1.mem.b[p177664] - 216);
  200.  
  201.     y2 := y - byte(ScrReg - 216);
  202.  
  203.     if y2 < 0 then y2 := y2 + 256;
  204.     if y2 < 0 then y2 := y2 + 256;
  205.     if y2 >= 256 then y2 := y2 - 256;
  206.  
  207.     for x := 0 to 63 do begin
  208.  
  209.     data := BKScreen[x + y * 64];
  210.  
  211.     PSet(@BackScr[(x * (d_x div 64) ) + (y2 * d_x)],@pix32tbl[data*8]);
  212.  
  213. // очистить неактивную часть экрана в режиме "РП"
  214.     if byte(hi(ScrReg) and 2) = 0 then if y > 63 then
  215.     PSet(@BackScr[(x * (d_x div 64) ) + (y * d_x)],@pix32tbl[0]);
  216.  
  217.      end;//x
  218.    end;//y
  219.  
  220.   if lpDDSBack.Unlock (nil) <> S_OK then exit;
  221.  
  222.   if (IsWindowed) then
  223.   begin
  224.     p.x := 0; p.y := 0;
  225.     ClientToScreen(ddWnd, p);
  226.     GetClientRect(ddWnd, fscreen);
  227.     OffsetRect(fscreen, p.x, p.y);
  228.   end;
  229.  
  230.   lpDDSPrimary.Blt(@fscreen, lpDDSBack, nil, DDBLT_ASYNC, nil);
  231. end;
  232.  
  233. procedure CreatePixelTable;
  234. var
  235.   v_data, bit, pix0,pix1,color, i,j: integer;
  236.  
  237. begin
  238.     if pix32tbl = nil then begin
  239.     pix32tbl := @pix32data;
  240. //выровнять указатель массива для комманд SSE
  241.     while integer(pix32tbl)and $f <> 0 do
  242.             integer(pix32tbl) := integer(pix32tbl)+1;
  243.     end;
  244.  
  245.  
  246.     for i := 0 to 255 do begin
  247.  
  248.           v_data := i;
  249.  
  250.           for bit := 0 to 3 do
  251.           begin
  252.  
  253.             color := v_data and 3;
  254.             v_data := (v_data shr 2);
  255.  
  256.                pix0:=0;
  257.                pix1:=0;
  258.  
  259.            if ColorMode = 2 then        
  260.                case color of
  261.  
  262.                1: pix0 := $90090FF;
  263.                2: pix1 := integer($9902f070);
  264.                3: begin
  265.                   pix0 := $f07f7f;
  266.                   pix1 := $f07f7f;
  267.                  end;
  268.                end;
  269.  
  270.            if ColorMode = 3 then        
  271.                case color of
  272.  
  273.         1: begin
  274.                   pix0 := $90090FF;
  275.                   pix1 := $000708F;
  276.                  end;
  277.         2: begin
  278.                   pix0 := $007F00;
  279.                   pix1 := integer($9902f070);
  280.                  end;
  281.         3: begin
  282.                   pix0 := $f07f7f;
  283.                   pix1 := $f07f7f;
  284.                  end;
  285.                end;
  286.  
  287.            if ColorMode = 1 then        
  288.                case color of
  289.  
  290.         1: begin
  291.                   pix0 := $0000FF;
  292.                   pix1 := $0000FF;
  293.                  end;
  294.         2: begin
  295.                   pix0 := $00FF00;
  296.                   pix1 := $00FF00;
  297.                  end;
  298.         3: begin
  299.                   pix0 := $FF0000;
  300.                   pix1 := $FF0000;
  301.                  end;
  302.         end;
  303.  
  304.  
  305.            if ColorMode = 0 then        
  306.                case color of
  307.  
  308.         1:pix0 := $FFFFFF;
  309.         2:pix1 := $FFFFFF;
  310.         3: begin
  311.           pix0 := $FFFFFF;
  312.           pix1 := $FFFFFF;
  313.          end;
  314.         end;
  315.  
  316.                pix32tbl [(i*8)+(bit*2)] := pix0;
  317.                pix32tbl [1+(i*8)+(bit*2)] := pix1;
  318.            end; //bit
  319.     end;//i
  320. end;
  321.  
  322. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement