Example #1
0
/********************************************************************
*	 ConvertTMPQHeader
********************************************************************/
void ConvertTMPQHeader(void *header)
{
	TMPQHeader2 * theHeader = (TMPQHeader2 *)header;
	
	theHeader->dwID = SwapULong(theHeader->dwID);
	theHeader->dwHeaderSize = SwapULong(theHeader->dwHeaderSize);
	theHeader->dwArchiveSize = SwapULong(theHeader->dwArchiveSize);
	theHeader->wFormatVersion = SwapUShort(theHeader->wFormatVersion);
	theHeader->wBlockSize = SwapUShort(theHeader->wBlockSize);
	theHeader->dwHashTablePos = SwapULong(theHeader->dwHashTablePos);
	theHeader->dwBlockTablePos = SwapULong(theHeader->dwBlockTablePos);
	theHeader->dwHashTableSize = SwapULong(theHeader->dwHashTableSize);
	theHeader->dwBlockTableSize = SwapULong(theHeader->dwBlockTableSize);

	if(theHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2)
	{
		DWORD dwTemp = theHeader->ExtBlockTablePos.LowPart;
		theHeader->ExtBlockTablePos.LowPart = theHeader->ExtBlockTablePos.HighPart;
		theHeader->ExtBlockTablePos.HighPart = dwTemp;
		theHeader->ExtBlockTablePos.LowPart = SwapULong(theHeader->ExtBlockTablePos.LowPart);
		theHeader->ExtBlockTablePos.HighPart = SwapULong(theHeader->ExtBlockTablePos.HighPart);
		theHeader->wHashTablePosHigh = SwapUShort(theHeader->wHashTablePosHigh);
		theHeader->wBlockTablePosHigh = SwapUShort(theHeader->wBlockTablePosHigh);
	}
}
Example #2
0
void nfHiColorDecomp(unsigned char *comp,unsigned int x, unsigned int y,
	unsigned int w, unsigned int h)
{
    unsigned char *tbuf;
    unsigned int new_row;
    unsigned int parms_sz;
    unsigned short *bx;
    unsigned char *si;
    unsigned char *di;
    unsigned int dx;
    unsigned int si2;
    unsigned int i,j,k;
    unsigned char a,b;

    nf_new_x = x*SWIDTH*2;
    nf_new_w = w*SWIDTH*2;
    nf_new_y = y*SHEIGHT;
    nf_new_h = h*SHEIGHT;

    new_row = nf_new_row0 - nf_new_w;
    parms_sz = (w*h*nf_fqty)<<1;

    // Move to correct place in current buffer
    tbuf = nf_buf_cur;
    if (x||y) {
		tbuf += nf_new_y*nf_width + nf_new_x;
	}

	// ds:si indexes comp (to get new section data)
	// es:di indexes current screen buffer
	// dx is a frequently used constant
	// ds/fs:bx indexes section params

    si = comp;
    di = tbuf;
    dx = nf_new_line;	// width - SWIDTH

	bx = (unsigned short *) si;	 // Parms index
	si+= parms_sz;	 // Skip over flags (w*h*2)

	// Iterate over params and copy new hires data to appropriate sections.

   	for (k=0;k<h;k++) {
		for (i=0;i<w;i++) {
			if (!*bx) {
				Move16;		/* First row */
				di+=dx;
				Move16;		/* Second row */
                   di+=dx;
                   Move16;		/* Third row */
                   di+=dx;
                   Move16;		/* Fourth row */
                   di+=dx;
                   Move16;		/* Fifth row */
                   di+=dx;
                   Move16;		/* Sixth row */
                   di+=dx;
                   Move16;		/* Seventh row */
                   di+=dx;
                   Move16;		/* Eighth row */
				di-=nf_back_right;
			}
			++bx;
			di+=SWIDTH*2;
		}
		di+=new_row;
	}

	// Iterate over flags and motion source addresses from params
	//  to determine which sections to move.
	// fs:bx indexes params.
	// ds:si indexes source from buffer
	//   ds will either be segment of current or previous buffer
	//   si will be computed as +- 16K relative to di.

	bx = (unsigned short *) comp;	// Move back to start of section parms
	di = tbuf;
   	for (k=0;k<h;k++) {
		for (i=0;i<w;i++) {
			si2 = (unsigned int) SwapUShort(*bx);
			if (si2&0x8000) {
	// Move one section from previous screen to current screen.
	// Enter with ds pointing to previous screen,
	//  es:di to destination screen section,
	//  relative value of source offset in si.

ms_30:
				si2-=0xC000;	// Make si absolute
				si2+=si2;
				si2+=(di-nf_buf_cur);	/* Get the offset */
				si=nf_buf_prv+si2;	/* Make true pointer */
                       Move162;		/* First row */
				si+=dx;
                       di+=dx;
                       Move162;		/* Second row */
				si+=dx;
                       di+=dx;
                       Move162;		/* Third row */
				si+=dx;
                       di+=dx;
                       Move162;		/* Fourth row */
				si+=dx;
                       di+=dx;
                       Move162;		/* Fifth row */
				si+=dx;
                       di+=dx;
                       Move162;		/* Sixth row */
				si+=dx;
                       di+=dx;
                       Move162;		/* Seventh row */
				si+=dx;
                       di+=dx;
                       Move162;		/* Eighth row */
                       di-=nf_back_right;
			} else if (si2) {
ms_10:
	// Move one section from current screen to current screen.
	// Enter with ds pointing to current screen,
	//  es:di to destination screen section,
	//  relative value of source offset in si.

				si2-=0x4000;	// Make si absolute
				si2+=si2;
				si=di+si2;
                       Move162;		/* First row */
				si+=dx;
                       di+=dx;
                       Move162;		/* Second row */
				si+=dx;
                       di+=dx;
                       Move162;		/* Third row */
				si+=dx;
                       di+=dx;
                       Move162;		/* Fourth row */
				si+=dx;
                       di+=dx;
                       Move162;		/* Fifth row */
				si+=dx;
                       di+=dx;
                       Move162;		/* Sixth row */
				si+=dx;
                       di+=dx;
                       Move162;		/* Seventh row */
				si+=dx;
                       di+=dx;
                       Move162;		/* Eighth row */
                       di-=nf_back_right;
			}
			++bx;
			di+=SWIDTH*2;
		}
		di+=new_row;
	}
}
Example #3
0
//
// ACS_translateScriptACS0
//
static void ACS_translateScriptACS0(acs0_tracer_t *tracer, int32_t *codeIndexMap)
{
   byte *brover;
   int32_t *codePtr = tracer->vm->code, *rover;
   uint32_t index, opSize;
   int32_t op, temp;
   acs0_opdata_t const *opdata;
   int32_t **jumps, **jumpItr;

   // This is used to store all of the places that need to have a jump target
   // translated. The count was determined by the tracer.
   jumps = (int32_t **)Z_Malloc(tracer->jumpCount * sizeof(int32_t *), PU_STATIC, NULL);
   jumpItr = jumps;

   // Set the first instruction to a KILL.
   *codePtr++ = ACS_OP_KILL;

   for(index = 0; index < tracer->lumpLength;)
   {
      // Search for code.
      if(!tracer->codeTouched[index])
      {
         ++index;
         continue;
      }

      // Read next instruction from file.
      op = ACS_readOpACS0(tracer, &opSize, index);

      rover = (int32_t *)(tracer->data + index + opSize);

      // Unrecognized instructions need to stop execution.
      if(op >= ACS0_OPMAX || op < 0)
      {
         *codePtr++ = ACS_OP_KILL;
         index += opSize;
         continue;
      }

      opdata = &ACS0opdata[op];

      // Record jump target.
      codeIndexMap[index] = codePtr - tracer->vm->code;

      // Calculate next index.
      index += ACS_countOpSizeACS0(tracer, index, opSize, opdata);

      switch(op)
      {
      case ACS0_OP_LINESPEC1:
      case ACS0_OP_LINESPEC2:
      case ACS0_OP_LINESPEC3:
      case ACS0_OP_LINESPEC4:
      case ACS0_OP_LINESPEC5:
         temp = op - ACS0_OP_LINESPEC1 + 1;
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = SwapLong(*rover++);
         *codePtr++ = temp;
         break;

      case ACS0_OP_LINESPEC1_IMM:
      case ACS0_OP_LINESPEC2_IMM:
      case ACS0_OP_LINESPEC3_IMM:
      case ACS0_OP_LINESPEC4_IMM:
      case ACS0_OP_LINESPEC5_IMM:
         temp = opdata->args - 1;
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = SwapLong(*rover++);
         *codePtr++ = temp;
         while(temp--)
            *codePtr++ = SwapLong(*rover++);
         break;

      case ACS0_OP_LINESPEC5_RET:
         temp = op - ACS0_OP_LINESPEC5_RET + 5;
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = SwapLong(*rover++);
         *codePtr++ = temp;
         break;

      case ACS0_OP_LINESPEC1_IMM_BYTE:
      case ACS0_OP_LINESPEC2_IMM_BYTE:
      case ACS0_OP_LINESPEC3_IMM_BYTE:
      case ACS0_OP_LINESPEC4_IMM_BYTE:
      case ACS0_OP_LINESPEC5_IMM_BYTE:
         brover = (byte *)rover;
         temp = opdata->args - 1;
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = *brover++;
         *codePtr++ = temp;
         while(temp--)
            *codePtr++ = *brover++;
         break;

      case ACS0_OP_GET_IMM_BYTE:
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = *(byte *)rover;
         break;

      case ACS0_OP_GET2_IMM_BYTE:
      case ACS0_OP_GET3_IMM_BYTE:
      case ACS0_OP_GET4_IMM_BYTE:
      case ACS0_OP_GET5_IMM_BYTE:
         brover = (byte *)rover;
         temp = op - ACS0_OP_GET2_IMM_BYTE + 2;
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = temp;
         while(temp--)
            *codePtr++ = *brover++;
         break;

      case ACS0_OP_GET_THINGX:
      case ACS0_OP_GET_THINGY:
      case ACS0_OP_GET_THINGZ:
      case ACS0_OP_GET_THINGFLOORZ:
      case ACS0_OP_GET_THINGANGLE:
      case ACS0_OP_SET_THINGANGLE:
      case ACS0_OP_GET_THINGCEILINGZ:
      case ACS0_OP_GET_THINGPITCH:
      case ACS0_OP_SET_THINGPITCH:
      case ACS0_OP_CHK_THINGCEILINGTEXTURE:
      case ACS0_OP_CHK_THINGFLOORTEXTURE:
      case ACS0_OP_GET_THINGLIGHTLEVEL:
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = ACS_translateThingVarACS0(opdata);
         break;

      case ACS0_OP_GETARR_IMM_BYTE:
         brover = (byte *)rover;
         temp = *brover++;
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = temp;
         while(temp--)
            *codePtr++ = *brover++;
         break;

      case ACS0_OP_BRANCH_IMM:
      case ACS0_OP_BRANCH_NOTZERO:
      case ACS0_OP_BRANCH_ZERO:
         *jumpItr++ = codePtr + 1;
         goto case_direct;

      case ACS0_OP_BRANCH_CASE:
         *jumpItr++ = codePtr + 2;
         goto case_direct;

      case ACS0_OP_CHANGEFLOOR_IMM:
      case ACS0_OP_CHANGECEILING_IMM:
         ACS_translateFuncACS0(codePtr, opdata);
         *codePtr++ = SwapLong(*rover++);
         *codePtr++ = tracer->vm->getStringIndex(SwapLong(*rover++)); // tag string
         for(int i = opdata->args - 2; i--;)
            *codePtr++ = SwapLong(*rover++);
         break;

      case ACS0_OP_DELAY_IMM_BYTE:
         brover = (byte *)rover;
         *codePtr++ = opdata->opdata->op;
         for(int i = opdata->args; i--;)
            *codePtr++ = *brover++;
         break;

      case ACS0_OP_ACTIVATORHEALTH:
      case ACS0_OP_ACTIVATORARMOR:
      case ACS0_OP_ACTIVATORFRAGS:
      case ACS0_OP_PLAYERNUMBER:
      case ACS0_OP_ACTIVATORTID:
         *codePtr++ = ACS_OP_GET_IMM;
         *codePtr++ = 0;
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = ACS_translateThingVarACS0(opdata);
         break;

      case ACS0_OP_GAMETYPE_ONEFLAGCTF:
         *codePtr++ = ACS_OP_GET_IMM;
         *codePtr++ = 0;
         break;

      case ACS0_OP_GAMETYPE_SINGLEPLAYER:
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = ACS_OP_GET_IMM;
         *codePtr++ = gt_single;
         *codePtr++ = ACS_OP_CMP_EQ;
         break;

      case ACS0_OP_RANDOM_IMM_BYTE:
         brover = (byte *)rover;
         ACS_translateFuncACS0(codePtr, opdata);
         for(int i = opdata->args; i--;)
            *codePtr++ = *brover++;
         break;

      case ACS0_OP_SETMUSIC_IMM:
      case ACS0_OP_SETMUSICLOCAL_IMM:
      case ACS0_OP_SPAWNPOINT_IMM:
      case ACS0_OP_SPAWNSPOT_IMM:
         ACS_translateFuncACS0(codePtr, opdata);
         *codePtr++ = tracer->vm->getStringIndex(SwapLong(*rover++)); // tag string
         for(int i = opdata->args - 1; i--;)
            *codePtr++ = SwapLong(*rover++);
         break;

      case ACS0_OP_BRANCH_CALLDISCARD:
         *codePtr++ = opdata->opdata->op;
         if(tracer->compressed)
            *codePtr++ = *(byte *)rover;
         else
            *codePtr++ = SwapLong(*rover);
         *codePtr++ = ACS_OP_STACK_DROP;
         break;

      case ACS0_OP_BRANCH_RETURNVOID:
         *codePtr++ = ACS_OP_GET_IMM;
         *codePtr++ = 0;
         *codePtr++ = opdata->opdata->op;
         break;

      case ACS0_OP_BRANCH_CASETABLE:
         // Align rover.
         rover = (int32_t *)(((uintptr_t)rover + 3) & ~3);
         temp = SwapLong(*rover++);

         *codePtr++ = opdata->opdata->op;
         *codePtr++ = temp;

         while(temp--)
         {
            *codePtr++ = SwapLong(*rover++);
            *jumpItr++ = codePtr;
            *codePtr++ = SwapLong(*rover++);
         }
         break;

      case ACS0_OP_CALLFUNC:
         if(tracer->compressed)
         {
            brover = (uint8_t *)rover;
            uint8_t  argc = *brover++;
            uint16_t func = SwapUShort(*(uint16_t *)brover);
            ACS_translateFuncACS0(codePtr, func, argc);
         }
         else
            ACS_translateFuncACS0(codePtr, SwapLong(rover[1]), SwapLong(rover[0]));
         break;

      default: case_direct:
         // Direct translation.
         if(opdata->opdata->op == ACS_OP_CALLFUNC ||
            opdata->opdata->op == ACS_OP_CALLFUNC_IMM)
         {
            ACS_translateFuncACS0(codePtr, opdata);
         }
         else
            *codePtr++ = opdata->opdata->op;

         if(tracer->compressed && opdata->compressed)
         {
            brover = (byte *)rover;
            for(int i = opdata->args; i--;)
               *codePtr++ = *brover++;
         }
         else
         {
            for(int i = opdata->args; i--;)
               *codePtr++ = SwapLong(*rover++);
         }

         break;
      }
   }

   // Set the last instruction to a KILL.
   *codePtr++ = ACS_OP_KILL;

#ifdef RANGECHECK
   // If this isn't true, something very wrong has happened internally.
   if(codePtr != tracer->vm->code + tracer->vm->numCode)
   {
      I_Error("Incorrect code count. %i/%i/%i", (int)(codePtr - tracer->vm->code),
              (int)tracer->vm->numCode, (int)(tracer->lumpLength / 4));
   }

   // Same here, this is just a sanity check.
   if(jumpItr != jumps + tracer->jumpCount)
   {
      I_Error("Incorrect jump count. %i/%i", (int)(jumpItr - jumps),
              (int)tracer->jumpCount);
   }
#endif

   // Translate jumps. Has to be done after code in order to jump forward.
   while(jumpItr != jumps)
   {
      codePtr = *--jumpItr;

      if ((uint32_t)*codePtr < tracer->lumpLength)
         *codePtr = codeIndexMap[*codePtr];
      else
         *codePtr = 0;
   }
}
Example #4
0
//
// ACS_traceScriptACS0
//
static void ACS_traceScriptACS0(acs0_tracer_t *tracer, uint32_t index)
{
   uint32_t indexNext, opSize;
   int32_t op;
   acs0_opdata_t const *opdata;

   for(;;)
   {
      // Read next instruction from file.
      op = ACS_readOpACS0(tracer, &opSize, index);

      // Invalid opcode terminates tracer.
      if(op >= ACS0_OPMAX || op < 0)
      {
         // But flag it so that a KILL gets generated by the translator.
         ACS_touchScriptACS0(tracer->codeTouched + index, tracer->codeTouched + index + opSize);
         ++tracer->vm->numCode;
         return;
      }

      opdata = &ACS0opdata[op];

      // Calculate next index.
      indexNext = index + ACS_countOpSizeACS0(tracer, index, opSize, opdata);

      // Leaving the bounds of the lump also terminates the tracer.
      if(indexNext > tracer->lumpLength) return;

      // If already touched this instruction, stop tracing.
      if(ACS_touchScriptACS0(tracer->codeTouched + index, tracer->codeTouched + indexNext))
         return;

      // Determine how many internal codes this counts for.
      switch(op)
      {
      case ACS0_OP_LINESPEC1_IMM:
      case ACS0_OP_LINESPEC2_IMM:
      case ACS0_OP_LINESPEC3_IMM:
      case ACS0_OP_LINESPEC4_IMM:
      case ACS0_OP_LINESPEC5_IMM:
      case ACS0_OP_LINESPEC1_IMM_BYTE:
      case ACS0_OP_LINESPEC2_IMM_BYTE:
      case ACS0_OP_LINESPEC3_IMM_BYTE:
      case ACS0_OP_LINESPEC4_IMM_BYTE:
      case ACS0_OP_LINESPEC5_IMM_BYTE:
      case ACS0_OP_GET2_IMM_BYTE:
      case ACS0_OP_GET3_IMM_BYTE:
      case ACS0_OP_GET4_IMM_BYTE:
      case ACS0_OP_GET5_IMM_BYTE:
         tracer->vm->numCode += opdata->args + 2;
         break;

      case ACS0_OP_GETARR_IMM_BYTE:
         tracer->vm->numCode += *(tracer->data + index + opSize) + 2;
         break;

      case ACS0_OP_ACTIVATORHEALTH:
      case ACS0_OP_ACTIVATORARMOR:
      case ACS0_OP_ACTIVATORFRAGS:
      case ACS0_OP_BRANCH_RETURNVOID:
      case ACS0_OP_PLAYERNUMBER:
      case ACS0_OP_ACTIVATORTID:
      case ACS0_OP_SIGILPIECES:
         tracer->vm->numCode += opdata->opdata->args + 1 + 2; // GET_IMM 0
         break;

      case ACS0_OP_GAMETYPE_ONEFLAGCTF:
         tracer->vm->numCode += 2; // GET_IMM
         break;
      case ACS0_OP_GAMETYPE_SINGLEPLAYER:
         tracer->vm->numCode += 4; // GAMETYPE + GET_IMM + CMP_EQ
         break;

      case ACS0_OP_BRANCH_CALLDISCARD:
         tracer->vm->numCode += opdata->opdata->args + 1 + 1; // DROP
         break;

      case ACS0_OP_BRANCH_CASETABLE:
         tracer->vm->numCode += 2;
         // More alignment stuff. (Wow, that's a mouthfull.)
         tracer->vm->numCode += SwapULong(*(uint32_t *)(((uintptr_t)tracer->data + index + opSize + 3) & ~3)) * 2;
         break;

      case ACS0_OP_CALLFUNC:
         if(tracer->compressed)
         {
            uint8_t  argc = tracer->data[index + opSize];
            uint16_t func = SwapUShort(*(uint16_t *)(tracer->data + index + opSize + 1));
            tracer->vm->numCode += ACS_traceFuncACS0(func, argc);
         }
         else
         {
            uint32_t argc = SwapULong(*(uint32_t *)(tracer->data + index + opSize + 0));
            uint32_t func = SwapULong(*(uint32_t *)(tracer->data + index + opSize + 4));
            tracer->vm->numCode += ACS_traceFuncACS0(func, argc);
         }
         break;

      default:
         // Translation to CALLFUNC.
         if(opdata->opdata->op == ACS_OP_CALLFUNC_IMM)
         {
            // Adds the func and argc arguments.
            tracer->vm->numCode += opdata->args + 1 + 2;
            break;
         }

         // Direct translation.
#ifdef RANGECHECK
         // This should never happen.
         if(opdata->opdata->args == -1)
            I_Error("Unknown translation for opcode. opcode %i", (int)op);
#endif

         tracer->vm->numCode += opdata->opdata->args + 1;
         break;
      }

      // Advance the index past the instruction.
      switch(op)
      {
      case ACS0_OP_SCRIPT_TERMINATE:
      case ACS0_OP_BRANCH_RETURN:
      case ACS0_OP_BRANCH_RETURNVOID:
         return;

      case ACS0_OP_BRANCH_IMM:
         ++tracer->jumpCount;
         index = SwapLong(*(int32_t *)(tracer->data + index + opSize));
         continue;

      case ACS0_OP_BRANCH_NOTZERO:
      case ACS0_OP_BRANCH_ZERO:
         ++tracer->jumpCount;
         ACS_traceScriptACS0(tracer, SwapLong(*(int32_t *)(tracer->data + index + opSize)));
         break;

      case ACS0_OP_BRANCH_CASE:
         ++tracer->jumpCount;
         ACS_traceScriptACS0(tracer, SwapLong(*(int32_t *)(tracer->data + index + opSize + 4)));
         break;

      case ACS0_OP_BRANCH_CASETABLE:
         {
            uint32_t jumps, *rover;

            rover = (uint32_t *)(tracer->data + index + opSize);
            // And alignment again.
            rover = (uint32_t *)(((uintptr_t)rover + 3) & ~3);
            jumps = SwapULong(*rover++);

            tracer->jumpCount += jumps;

            // Trace all of the jump targets.
            // Start by incrementing rover to point to address.
            for(++rover; jumps--; rover += 2)
               ACS_traceScriptACS0(tracer, SwapULong(*rover));
         }
         break;
      }

      index = indexNext;
   }
}