//ensure that registers are set correctly void Vdp1FakeDrawCommands(u8 * ram, Vdp1 * regs) { u16 command = T1ReadWord(ram, regs->addr); u32 commandCounter = 0; u32 returnAddr = 0xffffffff; while (!(command & 0x8000) && commandCounter < 2000) { // fix me // First, process the command if (!(command & 0x4000)) { // if (!skip) switch (command & 0x000F) { case 0: // normal sprite draw case 1: // scaled sprite draw case 2: // distorted sprite draw case 3: /* this one should be invalid, but some games (Hardcore 4x4 for instance) use it instead of 2 */ case 4: // polygon draw case 5: // polyline draw case 6: // line draw case 7: // undocumented polyline draw mirror break; case 8: // user clipping coordinates case 11: // undocumented mirror VIDCore->Vdp1UserClipping(ram, regs); break; case 9: // system clipping coordinates VIDCore->Vdp1SystemClipping(ram, regs); break; case 10: // local coordinate VIDCore->Vdp1LocalCoordinate(ram, regs); break; default: // Abort VDP1LOG("vdp1\t: Bad command: %x\n", command); regs->EDSR |= 2; VIDCore->Vdp1DrawEnd(); regs->LOPR = regs->addr >> 3; regs->COPR = regs->addr >> 3; return; } } // Next, determine where to go next switch ((command & 0x3000) >> 12) { case 0: // NEXT, jump to following table regs->addr += 0x20; break; case 1: // ASSIGN, jump to CMDLINK regs->addr = T1ReadWord(ram, regs->addr + 2) * 8; break; case 2: // CALL, call a subroutine if (returnAddr == 0xFFFFFFFF) returnAddr = regs->addr + 0x20; regs->addr = T1ReadWord(ram, regs->addr + 2) * 8; break; case 3: // RETURN, return from subroutine if (returnAddr != 0xFFFFFFFF) { regs->addr = returnAddr; returnAddr = 0xFFFFFFFF; } else regs->addr += 0x20; break; } command = T1ReadWord(ram, regs->addr); commandCounter++; } }
int * YglQuad(YglSprite * input, YglTexture * output) { unsigned int x, y; YglLevel *level; texturecoordinate_struct *tmp; if (input->priority > 7) { VDP1LOG("sprite with priority %d\n", input->priority); return NULL; } level = &_Ygl->levels[input->priority]; if (level->currentQuad == level->maxQuad) { level->maxQuad += 8; level->quads = (int *) realloc(level->quads, level->maxQuad * sizeof(int)); level->textcoords = (int *) realloc(level->textcoords, level->maxQuad * sizeof(int) * 2); YglCacheReset(); } #ifdef USEMICSHADERS if (level->currentColors == level->maxColors) { level->maxColors += 16; level->colors = (unsigned char *) realloc(level->colors, level->maxColors * sizeof(unsigned char)); YglCacheReset(); } #endif tmp = (texturecoordinate_struct *)(level->textcoords + (level->currentQuad * 2)); memcpy(level->quads + level->currentQuad, input->vertices, 8 * sizeof(int)); #ifdef USEMICSHADERS memcpy(level->colors + level->currentColors, noMeshGouraud, 16 * sizeof(unsigned char)); #endif level->currentQuad += 8; #ifdef USEMICSHADERS level->currentColors += 16; #endif YglTMAllocate(output, input->w, input->h, &x, &y); tmp[0].r = tmp[1].r = tmp[2].r = tmp[3].r = 0; // these can stay at 0 if (input->flip & 0x1) { tmp[0].s = tmp[3].s = x + input->w; tmp[1].s = tmp[2].s = x; } else { tmp[0].s = tmp[3].s = x; tmp[1].s = tmp[2].s = x + input->w; } if (input->flip & 0x2) { tmp[0].t = tmp[1].t = y + input->h; tmp[2].t = tmp[3].t = y; } else { tmp[0].t = tmp[1].t = y; tmp[2].t = tmp[3].t = y + input->h; } tmp[0].q = 1; // These need to be adjusted. I'm not sure what the correct tmp[1].q = 1; // value is, or how to calculate it. tmp[2].q = 1; // tmp[3].q = 1; // switch(input->flip) { case 0: return level->textcoords + ((level->currentQuad - 8) * 2); // upper left coordinates(0) case 1: return level->textcoords + ((level->currentQuad - 6) * 2); // upper right coordinates(2) case 2: return level->textcoords + ((level->currentQuad - 2) * 2); // lower left coordinates(6) case 3: return level->textcoords + ((level->currentQuad - 4) * 2); // lower right coordinates(4) } return 0; }