/* This file is part of jpcsp. Jpcsp is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Jpcsp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Jpcsp. If not, see <http://www.gnu.org/licenses/>. */ package jpcsp.Allegrex.compiler.nativeCode.graphics; import jpcsp.Allegrex.compiler.nativeCode.AbstractNativeCodeSequence; import jpcsp.memory.IMemoryReader; import jpcsp.memory.IMemoryWriter; import jpcsp.memory.MemoryReader; import jpcsp.memory.MemoryWriter; /** * @author gid15 * */ public class BinkCodec extends AbstractNativeCodeSequence { // See ffmpeg - binkidtc.c - ff_bink_idct_add_c static public void binkIdctAdd(int contextAddr1, int contextAddr2) { int contextAddr = getRelocatedAddress(contextAddr1, contextAddr2); int dstAddr = getGprA0(); int dstStep = getGprA1(); int blockAddr = getGprA2(); int blockOffset = getGprA3(); int srcAddr = getGprT0(); int srcStep = getGprT1(); final short[] block = new short[64]; IMemoryReader sourceReader = MemoryReader.getMemoryReader(blockAddr, 128, 2); for (int i = 0; i < 64; i++) { block[i] = (short) sourceReader.readNext(); } final int[] context = new int[64]; contextAddr += blockOffset << 8; IMemoryReader contextReader = MemoryReader.getMemoryReader(contextAddr, 256, 4); for (int i = 0; i < 64; i++) { context[i] = contextReader.readNext(); } final int[] temp = new int[64]; for (int i = 0; i < 8; i++) { // See ffmpeg - binkidtc.c - bink_idct_col if (block[i+8] == 0 && block[i+16] == 0 && block[i+24] == 0 && block[i+32] == 0 && block[i+40] == 0 && block[i+48] == 0 && block[i+56] == 0) { int src0 = (block[i] * context[i]) >> 11; temp[i] = src0; temp[i+8] = src0; temp[i+16] = src0; temp[i+24] = src0; temp[i+32] = src0; temp[i+40] = src0; temp[i+48] = src0; temp[i+56] = src0; } else { int src0 = (block[i] * context[i]) >> 11; int src1 = (block[i+8] * context[i+8]) >> 11; int src2 = (block[i+16] * context[i+16]) >> 11; int src6 = (block[i+48] * context[i+48]) >> 11; int src3 = (block[i+24] * context[i+24]) >> 11; int src4 = (block[i+32] * context[i+32]) >> 11; int src5 = (block[i+40] * context[i+40]) >> 11; int src7 = (block[i+56] * context[i+56]) >> 11; int a0 = src0 + src4; int a1 = src0 - src4; int a2 = src2 + src6; int a3 = (2896 * (src2 - src6)) >> 11; int a4 = src5 + src3; int a5 = src5 - src3; int a6 = src1 + src7; int a7 = src1 - src7; int b0 = a6 + a4; int b1 = ((a5 + a7) * 3784) >> 11; int b2 = ((a5 * -5352) >> 11) - b0 + b1; int b3 = (((a6 - a4) * 2896) >> 11) - b2; int b4 = ((a7 * 2217) >> 11) + b3 - b1; temp[i] = a0 + a2 + b0; temp[i+8] = a1 + a3 - a2 + b2; temp[i+16] = a1 - a3 + a2 + b3; temp[i+24] = a0 - a2 - b4; temp[i+32] = a0 - a2 + b4; temp[i+40] = a1 - a3 + a2 - b3; temp[i+48] = a1 + a3 - a2 - b2; temp[i+56] = a0 + a2 - b0; } } final int[] src = new int[8]; final int[] dst = new int[8]; IMemoryReader srcReader = MemoryReader.getMemoryReader(srcAddr, 8 * srcStep, 1); IMemoryWriter dstWriter = MemoryWriter.getMemoryWriter(dstAddr, 8 * dstStep, 1); for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { src[j] = srcReader.readNext(); } srcReader.skip(srcStep - 8); int n = i * 8; int src0 = temp[n]; int src1 = temp[n+1]; int src2 = temp[n+2]; int src3 = temp[n+3]; int src4 = temp[n+4]; int src5 = temp[n+5]; int src6 = temp[n+6]; int src7 = temp[n+7]; int a0 = src0 + src4; int a1 = src0 - src4; int a2 = src2 + src6; int a3 = (2896 * (src2 - src6)) >> 11; int a4 = src5 + src3; int a5 = src5 - src3; int a6 = src1 + src7; int a7 = src1 - src7; int b0 = a6 + a4; int b1 = ((a5 + a7) * 3784) >> 11; int b2 = ((a5 * -5352) >> 11) - b0 + b1; int b3 = (((a6 - a4) * 2896) >> 11) - b2; int b4 = ((a7 * 2217) >> 11) + b3 - b1; dst[0] = src[0] + (((a0 + a2 + b0) + 0x7F) >> 8); dst[1] = src[1] + (((a1 + a3 - a2 + b2) + 0x7F) >> 8); dst[2] = src[2] + (((a1 - a3 + a2 + b3) + 0x7F) >> 8); dst[3] = src[3] + (((a0 - a2 - b4) + 0x7F) >> 8); dst[4] = src[4] + (((a0 - a2 + b4) + 0x7F) >> 8); dst[5] = src[5] + (((a1 - a3 + a2 - b3) + 0x7F) >> 8); dst[6] = src[6] + (((a1 + a3 - a2 - b2) + 0x7F) >> 8); dst[7] = src[7] + (((a0 + a2 - b0) + 0x7F) >> 8); for (int j = 0; j < 8; j++) { dstWriter.writeNext(dst[j]); } dstWriter.flush(); dstWriter.skip(dstStep - 8); } } }