mkgra.c

来自「DGen源码最后版本」· C语言 代码 · 共 270 行

C
270
字号
#include <stdio.h>#include <stdlib.h>#include <string.h>// Builder for the gra.asm NASM module// Renders md tiles// Currently 15-bit and 16-bit are the same, since// the palette value is just copied across, so use draw_tile_16() for bothstatic int depth_to_bytes(int depth){       if (depth<=8)  return 1;  else if (depth<=16) return 2;  else if (depth<=24) return 3;  else                return 4;}static int emit_clear_to_col(FILE *hand,int bpp){  fprintf (hand,";extern \"C\" int clear_to_col_%d\n",bpp);  fprintf (hand,    ";  (unsigned char *dest,int len,unsigned int col);\n"    "\n"  );  fprintf (hand,"global _clear_to_col_%d\n",bpp);  fprintf (hand,"times ($$-$) & 3 db 0\n");  fprintf (hand,"_clear_to_col_%d:\n",bpp);  fprintf (hand,    "push edi\n"    "push ecx\n"    "mov edi,[esp+12] ; edi is a pointer to the bitmap\n"    "mov ecx,[esp+16] ; ecx is the amount of pixel to clear\n"    "mov eax,[esp+20] ; eax is the color\n"  );  if (bpp<=8)    fprintf (hand,"rep stosb\n");  else if (bpp<=16)    fprintf (hand,"rep stosw\n");  else if (bpp<=24)  {    fprintf (hand,"clear_to_col_twenty_four:\n");    fprintf (hand,"  stosw\n");    fprintf (hand,"  ror eax,16\n");    fprintf (hand,"  stosb\n");    fprintf (hand,"  rol eax,16\n");    fprintf (hand,"loop clear_to_col_twenty_four\n");    ; // help!  }  else    fprintf (hand,"rep stosd\n");  fprintf (hand,    "pop  ecx\n"    "pop  edi\n"    "xor eax,eax\n"    "ret\n"    "\n\n\n"  );  return 0;}static int emit_draw_tile(FILE *hand,int bpp,int flip,int interlace){  static int label_no=0;//  static int xloop_no=0,yloop_no=0;  // flip&1 = horizontal flip   flip&2 = vertical flip  static char fname[4][7]={"","_hf","_vf","_hf_vf"};  flip&=3;  fprintf (hand,    ";  (unsigned char *dest,int pitch,unsigned char *tilep,unsigned int *palette);\n"    ";//                 %%1       %%2            %%3                 %%4\n"    "\n"  );  fprintf (hand,"global _draw_tile_%s%d%s\n",interlace?"i_":"",bpp,fname[flip]);  fprintf (hand,"times ($$-$) & 3 db 0\n");  fprintf (hand,"_draw_tile_%s%d%s:\n",interlace?"i_":"",bpp,fname[flip]);  fprintf (hand,    "\n"    "push ebx\n"    "push ecx\n"    "push edx\n"    "push esi\n"    "push edi\n"    "push ebp\n"    "\n"    "mov edi,[esp+28] ; edi is a pointer to the screen\n"    "mov ebx,[esp+32]\n"    "mov esi,[esp+36] ; esi is a pointer to the tilep\n"    "mov ebp,[esp+40] ; ebp is a pointer to the palette\n"  );  if (flip&2)  {    fprintf (hand,"mov eax,ebx\n");    fprintf (hand,"sal eax,3\n");    fprintf (hand,"sub eax,ebx ; eax=pitch*7\n");    fprintf (hand,"add edi,eax ; point to bottom line of tile dest\n");    fprintf (hand,"neg ebx\n");  }  if (flip&1)  {    fprintf (hand,"add ebx,%d\n",8*depth_to_bytes(bpp));    fprintf (hand,"add edi,%d\n",7*depth_to_bytes(bpp));  }  else    fprintf (hand,"sub ebx,%d\n",8*depth_to_bytes(bpp));  {    int x,y;//    fprintf (hand,"and cl,0x0f; Loop 8 times (till cl&0x80==0x80)\n");//    fprintf (hand,"yloop_%d:\n",yloop_no);    for (y=0;y<8;y++) // Unroll above loop    {//      fprintf (hand,"and cl,0xf0; Loop 4 times (till cl&0x04==0x04)\n");//      fprintf (hand,"xloop_%d:\n",xloop_no);      for (x=0;x<8;x++) // x<8 means Unroll above loop      {        // dl is tilep byte        // eax is the colour we are going to draw        // high bits of edx and ecx are currently unused        if ((x&1)==0) fprintf (hand,"mov dl,byte[esi]; Get tile pixel\n");        else          fprintf (hand,"rol dl,4        ; Get tile pixel\n");        fprintf (hand,"mov al,dl\n");        fprintf (hand,"and eax,0xf0 ; palette index now in bits 4-7 of eax\n");        fprintf (hand,"test eax,0xf0\n");        fprintf (hand,"jz trans_%.4x\n",label_no);        fprintf (hand,"ror al,4\n");        fprintf (hand,"mov eax,[ebp+eax*4] ; look up colour in palette\n");        //fprintf (hand,"mov eax,0x%.8x\n", ((x<<2)<<11) | (y<<2) );        if (bpp==8) fprintf (hand,"mov byte[edi],al\n");        else if (bpp==15 || bpp==16)                    fprintf (hand,"mov word[edi],ax\n");        else if (bpp==24)        {          fprintf (hand,"mov byte[edi],al\ninc edi\nror eax,8\n");          fprintf (hand,"mov byte[edi],al\ninc edi\nror eax,8\n");          fprintf (hand,"mov byte[edi],al\nsub edi,2\n");        }        else if (bpp==32) fprintf (hand,"mov dword[edi],eax\n");        fprintf (hand,"trans_%.4x:\n",label_no);        if ((x&1)==1) fprintf (hand,"inc esi\n");        fprintf (hand,"%s edi,%d\n",(flip&1)?"sub":"add",depth_to_bytes(bpp));        label_no++;      }      if (interlace)        fprintf (hand,"add esi,4 ; interlace mode\n");//      fprintf (hand,"inc cl\n");//      fprintf (hand,"test cl,0x04 ; Looped 4 times yet?\n");//      fprintf (hand,"jz xloop_%d\n",xloop_no); xloop_no++;      fprintf (hand,"add edi,ebx\n");    }//    fprintf (hand,"add cl,0x10\n");//    fprintf (hand,"test cl,0x80 ; Looped 8 times yet?\n");//    fprintf (hand,"jz yloop_%d\n",yloop_no);//    yloop_no++;  }  fprintf (hand,    "pop ebp\n"    "pop edi\n"    "pop esi\n"    "pop edx\n"    "pop ecx\n"    "pop ebx\n"    "xor eax,eax\n"    "\n"    "ret\n"    "\n\n\n"  );  return 0;}int main(){  FILE *hand=NULL;  static char outname[]="gra.asm";  hand=fopen(outname,"wt");  if (hand==NULL)  {    printf ("Couldn't open %s\n",outname);    return 1;  }  fprintf (hand,    "; Note - this file is automatically generated by mkgra.c\n\n"    "bits 32\n"    "section .text\n"/*    "global _dave_var\n"    "_dave_var:\n"    "dd 123\n"    ";__memoryreadbyte  dd 0\n"    ";__dreg            dd 0,0,0,0,0,0,0,0\n"    "section .text\n"    "bits 32\n"    "top:\n"    "\n"    "global _daves_asm\n"    "times ($$-$) & 3 db 0\n"    "_daves_asm:\n"    "\n"    "push ebx\n"    "push ecx\n"    "push edx\n"    "push esi\n"    "push edi\n"    "\n"    "mov eax,[esp+24]\n"    "mov ebx,dword[_dave_var]\n"    "add eax,ebx\n"    "\n"    "pop edi\n"    "pop esi\n"    "pop edx\n"    "pop ecx\n"    "pop ebx\n"    "\n"    "ret\n"    "\n"*/  );  {    static int dep[4]={8,16,24,32};    int d,f,i;    for (d=0;d<4;d++)    {      emit_clear_to_col(hand,dep[d]);      for (i=0;i<2;i++)      for (f=0;f<4;f++)      {        emit_draw_tile(hand,dep[d],f,i);      }    }  }  fclose(hand);  return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?