cr88192

BJX2, Color Cell Encode (ConGfx/Doom/Quake)

Jul 18th, 2018
376
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.58 KB | None | 0 0
  1. /** Color Cell Encoder, Inner Function
  2.   * src: source framebuffer, current frame
  3.   * lsrc: scratch framebuffer, to detect/skip unchanging blocks.
  4.   * rdsta: first part of destination
  5.   * rdstb: second part of destination
  6.   * Note: that rdsta and rdstb need not be adjacent.
  7.   * Note: also that screen width is hard-coded in this version.
  8.   */
  9. void    VID_ConGfx_EncBlock16P(u16 *src, u16 *lsrc, u32 *rdsta, u32 *rdstb)
  10. {
  11.     u16 *cs, *ct;
  12.     int cmin, cmax;
  13.     register int cavg, calo, cahi;
  14.     int clra, clrb;
  15.     u32 px2;
  16.     u32 dxa, dxb;
  17.     u64 lpx0, lpx1, lpx2, lpx3, lpx4;
  18.     register int k0, k1;
  19.     int i, j, k;
  20.  
  21.     //NOTE: BGBCC Codegen Hint.
  22.     //Hints register allocator to enable use of all 32 GPRs.
  23.     __hint_use_egpr();
  24.  
  25.     //Note: BGBCC is kinda stupid, so branches result in spilling most of the registers...
  26.  
  27.     //Detect if pixels haven't changed
  28.     ct=lsrc; cs=src; i=0;
  29.     lpx0=*(u64 *)cs;    lpx4=*(u64 *)ct;
  30.     cs+=BASEWIDTH;      ct+=BASEWIDTH;
  31.     i|=(lpx0!=lpx4);
  32.     lpx1=*(u64 *)cs;    lpx4=*(u64 *)ct;
  33.     cs+=BASEWIDTH;      ct+=BASEWIDTH;
  34.     i|=(lpx1!=lpx4);
  35.     lpx2=*(u64 *)cs;    lpx4=*(u64 *)ct;
  36.     cs+=BASEWIDTH;      ct+=BASEWIDTH;
  37.     i|=(lpx2!=lpx4);
  38.     lpx3=*(u64 *)cs;    lpx4=*(u64 *)ct;
  39.     i|=(lpx3!=lpx4);
  40.  
  41.     if(!i)  return;     //Hasn't changed, do nothing
  42.  
  43.     //Save new pixels to scratch buffer
  44.     ct=lsrc;
  45.     *(u64 *)ct=lpx0;    ct+=BASEWIDTH;
  46.     *(u64 *)ct=lpx1;    ct+=BASEWIDTH;
  47.     *(u64 *)ct=lpx2;    ct+=BASEWIDTH;
  48.     *(u64 *)ct=lpx3;
  49.  
  50.     calo=65536; cahi=-1;
  51.  
  52.     //NOTE: BGBCC: __int_min() and __int_max() are intrinsics wrapping the CSELT instruction.
  53.  
  54.     //Find the lightest and darkest pixels:
  55.     k0=(u16)(lpx0    );     k1=(u16)(lpx0>>16);
  56.     calo=__int_min(calo, k0);       cahi=__int_max(cahi, k0);
  57.     k0=(u16)(lpx0>>32);
  58.     calo=__int_min(calo, k1);       cahi=__int_max(cahi, k1);
  59.     k1=(u16)(lpx0>>48);
  60.     calo=__int_min(calo, k0);       cahi=__int_max(cahi, k0);
  61.     calo=__int_min(calo, k1);       cahi=__int_max(cahi, k1);
  62.  
  63.     k0=(u16)(lpx1    );     k1=(u16)(lpx1>>16);
  64.     calo=__int_min(calo, k0);       cahi=__int_max(cahi, k0);
  65.     k0=(u16)(lpx1>>32);
  66.     calo=__int_min(calo, k1);       cahi=__int_max(cahi, k1);
  67.     k1=(u16)(lpx1>>48);
  68.     calo=__int_min(calo, k0);       cahi=__int_max(cahi, k0);
  69.     calo=__int_min(calo, k1);       cahi=__int_max(cahi, k1);
  70.  
  71.     k0=(u16)(lpx2    );     k1=(u16)(lpx2>>16);
  72.     calo=__int_min(calo, k0);       cahi=__int_max(cahi, k0);
  73.     k0=(u16)(lpx2>>32);
  74.     calo=__int_min(calo, k1);       cahi=__int_max(cahi, k1);
  75.     k1=(u16)(lpx2>>48);
  76.     calo=__int_min(calo, k0);       cahi=__int_max(cahi, k0);
  77.     calo=__int_min(calo, k1);       cahi=__int_max(cahi, k1);
  78.  
  79.     k0=(u16)(lpx3    );             k1=(u16)(lpx3>>16);
  80.     calo=__int_min(calo, k0);       cahi=__int_max(cahi, k0);
  81.     k0=(u16)(lpx3>>32);
  82.     calo=__int_min(calo, k1);       cahi=__int_max(cahi, k1);
  83.     k1=(u16)(lpx3>>48);
  84.     calo=__int_min(calo, k0);       cahi=__int_max(cahi, k0);
  85.     calo=__int_min(calo, k1);       cahi=__int_max(cahi, k1);
  86.  
  87.     //OK, we have range, calc average, lower, and upper threshold:
  88.     cmin=calo;  cmax=cahi;
  89.     cavg=(cmin+cmax)>>1;
  90.     calo=(cmin+cavg)>>1;
  91.     cahi=(cmax+cavg)>>1;
  92.  
  93.     //Find pixel bits; Note that MUL, DIV, and mem-access are expensive in BJX2
  94.     //Especially don't want DIV, because DIV is implemented in software (hidden C runtime call; 100s of cycles).
  95.     //But, what we do have, is 32 GPRs and a fairly cheap 'a>b' operator...
  96.  
  97.     px2=0;
  98.  
  99.     k0=(u16)(lpx0    );             k1=(u16)(lpx0>>16);
  100.     px2=(px2<<2)|((k0>cavg)<<1);    px2|=(k0>cahi)|(calo>k0);
  101.     k0=(u16)(lpx0>>32);
  102.     px2=(px2<<2)|((k1>cavg)<<1);    px2|=(k1>cahi)|(calo>k1);
  103.     k1=(u16)(lpx0>>48);
  104.     px2=(px2<<2)|((k0>cavg)<<1);    px2|=(k0>cahi)|(calo>k0);
  105.     px2=(px2<<2)|((k1>cavg)<<1);    px2|=(k1>cahi)|(calo>k1);
  106.  
  107.     k0=(u16)(lpx1    );             k1=(u16)(lpx1>>16);
  108.     px2=(px2<<2)|((k0>cavg)<<1);    px2|=(k0>cahi)|(calo>k0);
  109.     k0=(u16)(lpx1>>32);
  110.     px2=(px2<<2)|((k1>cavg)<<1);    px2|=(k1>cahi)|(calo>k1);
  111.     k1=(u16)(lpx1>>48);
  112.     px2=(px2<<2)|((k0>cavg)<<1);    px2|=(k0>cahi)|(calo>k0);
  113.     px2=(px2<<2)|((k1>cavg)<<1);    px2|=(k1>cahi)|(calo>k1);
  114.  
  115.     k0=(u16)(lpx2    );             k1=(u16)(lpx2>>16);
  116.     px2=(px2<<2)|((k0>cavg)<<1);    px2|=(k0>cahi)|(calo>k0);
  117.     k0=(u16)(lpx2>>32);
  118.     px2=(px2<<2)|((k1>cavg)<<1);    px2|=(k1>cahi)|(calo>k1);
  119.     k1=(u16)(lpx2>>48);
  120.     px2=(px2<<2)|((k0>cavg)<<1);    px2|=(k0>cahi)|(calo>k0);
  121.     px2=(px2<<2)|((k1>cavg)<<1);    px2|=(k1>cahi)|(calo>k1);
  122.  
  123.     k0=(u16)(lpx3    );             k1=(u16)(lpx3>>16);
  124.     px2=(px2<<2)|((k0>cavg)<<1);    px2|=(k0>cahi)|(calo>k0);
  125.     k0=(u16)(lpx3>>32);
  126.     px2=(px2<<2)|((k1>cavg)<<1);    px2|=(k1>cahi)|(calo>k1);
  127.     k1=(u16)(lpx3>>48);
  128.     px2=(px2<<2)|((k0>cavg)<<1);    px2|=(k0>cahi)|(calo>k0);
  129.     px2=(px2<<2)|((k1>cavg)<<1);    px2|=(k1>cahi)|(calo>k1);
  130.  
  131.     px2=px2^((~(px2>>1))&0x55555555);
  132.  
  133.     clrb=cmin>>1;                       clra=cmax>>1;
  134.     dxa=0xC0000000|(clrb<<15)|clra;     dxb=px2;
  135.     *rdsta=dxa;                         *rdstb=dxb;
  136. }
Add Comment
Please, Sign In to add comment