Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • amiga/zz9000-firmware
  • shanshe/zz9000-firmware
  • apolkosnik/zz9000-firmware
3 results
Select Git revision
Show changes
Commits on Source (124)
Showing
with 5671 additions and 1 deletion
...@@ -24,4 +24,4 @@ masscopy*.sh ...@@ -24,4 +24,4 @@ masscopy*.sh
SDK.log.* SDK.log.*
ZZ9000_proto.srcs/sources_1 ZZ9000_proto.srcs/sources_1
ZZ9000_proto.sdk/ZZ9000Test/bootimage/BOOT.bin ZZ9000_proto.sdk/ZZ9000Test/bootimage/BOOT.bin
fw-archive
...@@ -9,6 +9,8 @@ RM := rm -rf ...@@ -9,6 +9,8 @@ RM := rm -rf
# All of the sources participating in the build are defined here # All of the sources participating in the build are defined here
-include sources.mk -include sources.mk
-include src/usb/subdir.mk -include src/usb/subdir.mk
-include src/mp3/subdir.mk
-include src/compression/audio/subdir.mk
-include src/subdir.mk -include src/subdir.mk
-include subdir.mk -include subdir.mk
-include objects.mk -include objects.mk
......
...@@ -17,5 +17,7 @@ ELFSIZE := ...@@ -17,5 +17,7 @@ ELFSIZE :=
# Every subdirectory with source files must be described here # Every subdirectory with source files must be described here
SUBDIRS := \ SUBDIRS := \
src \ src \
src/compression/audio \
src/mp3 \
src/usb \ src/usb \
This diff is collapsed.
This diff is collapsed.
#include <stdio.h>
#include "xadcps.h"
// XADC adc converter instance
XAdcPs Xadc;
int xadc_init() {
printf("[adc] xadc_init()...\n");
XAdcPs_Config* cfg;
cfg = XAdcPs_LookupConfig(XPAR_XADCPS_0_DEVICE_ID);
XAdcPs_CfgInitialize(&Xadc, cfg, cfg->BaseAddress);
int status = XAdcPs_SelfTest(&Xadc);
printf("[adc] xadc_init() done: %d\n", status);
return status;
}
float xadc_get_temperature() {
u16 raw = XAdcPs_GetAdcData(&Xadc, XADCPS_CH_TEMP);
return XAdcPs_RawToTemperature(raw);
}
float xadc_get_aux_voltage() {
u16 raw = XAdcPs_GetAdcData(&Xadc, XADCPS_CH_VCCAUX);
return XAdcPs_RawToVoltage(raw);
}
float xadc_get_int_voltage() {
u16 raw = XAdcPs_GetAdcData(&Xadc, XADCPS_CH_VCCINT);
return XAdcPs_RawToVoltage(raw);
}
int xadc_init();
float xadc_get_temperature();
float xadc_get_aux_voltage();
float xadc_get_int_voltage();
This diff is collapsed.
#ifndef __AX_H__
#define __AX_H__
#include <stdint.h>
enum {
AP_TX_BUF_OFFS_HI,
AP_TX_BUF_OFFS_LO,
AP_RX_BUF_OFFS_HI,
AP_RX_BUF_OFFS_LO,
AP_DSP_PROG_OFFS_HI,
AP_DSP_PROG_OFFS_LO,
AP_DSP_PARAM_OFFS_HI,
AP_DSP_PARAM_OFFS_LO,
AP_DSP_UPLOAD,
AP_DSP_SET_LOWPASS,
AP_DSP_SET_VOLUMES,
AP_DSP_SET_PREFACTOR,
AP_DSP_SET_EQ_BAND1,
AP_DSP_SET_EQ_BAND2,
AP_DSP_SET_EQ_BAND3,
AP_DSP_SET_EQ_BAND4,
AP_DSP_SET_EQ_BAND5,
AP_DSP_SET_EQ_BAND6,
AP_DSP_SET_EQ_BAND7,
AP_DSP_SET_EQ_BAND8,
AP_DSP_SET_EQ_BAND9,
AP_DSP_SET_EQ_BAND10,
AP_DSP_SET_STEREO_VOLUME,
ZZ_NUM_AUDIO_PARAMS
};
int audio_adau_init(int program_dsp);
void audio_init_i2s();
void isr_audio(void *dummy);
void isr_audio_rx(void *dummy);
void audio_set_interrupt_enabled(int en);
void audio_clear_interrupt();
uint32_t audio_get_interrupt();
uint32_t audio_get_dma_transfer_count();
int audio_swab(uint16_t audio_buf_samples, uint32_t offset, int byteswap);
void audio_set_tx_buffer(uint8_t* addr);
void audio_set_rx_buffer(uint8_t* addr);
void resample_s16(int16_t *input, int16_t *output,
int in_sample_rate, int out_sample_rate, int output_samples);
void audio_silence();
void audio_debug_timer(int zdata);
void audio_program_adau(u8* program, u32 program_len);
void audio_program_adau_params(u8* params, u32 param_len);
void audio_adau_set_lpf_params(int f0);
// vol range: 0-255. 127 = 0db
void audio_adau_set_mixer_vol(int vol1, int vol2);
// gain range: 0 = -12dB .. 50 = 0dB .. 100 = 12 dB
void audio_adau_set_eq_gain(int band, int gain);
// pre range: 0 = -12dB .. 50 = 0dB .. 100 = 12 dB
void audio_adau_set_prefactor(int pre);
// vol range: 0 = muted .. 50 = -6dB .. 100 = 0dB
// pan range: 0 = left .. 50 = center .. 100 = right
void audio_adau_set_vol_pan(int vol, int pan);
#endif
#include "bootrom.h"
#include "xil_types.h"
#include "memorymap.h"
#include <stdio.h>
// zzusb.device converted to an array
#include "zzusb-device.h"
// boot.rom converted to an array
#include "zzbootrom.h"
const u16 BOOT_ROM[] = {
0x9000, 0x2000, // WORDWIDE+CONFIGTIME DAsize
0x004e, 0x003c, // DiagPt: 0x4e BootPt: 0x3c
0x000e, 0x0000, // DevName pointer Resvd 1
0x0000,
// DevName
0x7a7a,0x7573, // zzusb.device
0x622e,0x6465,
0x7669,0x6365,
0x0000,
// Boot@0x20
// Diag@0x20+0x12 = 0x32
};
void boot_rom_init() {
u8* romp = (u8*)BOOT_ROM;
u16* ramp = (u16*)BOOT_ROM_ADDRESS;
u8* ramp8 = (u8*)BOOT_ROM_ADDRESS;
for (int i=0; i<sizeof(BOOT_ROM); i++) {
ramp[i] = (romp[i*2]<<8) | (romp[i*2+1]);
}
for (int i=0; i<boot_rom_len; i++) {
// code starts at 0x20
ramp8[0x20 + i] = boot_rom[i+0x20];
}
for (int i=0; i<zzusb_device_len; i++) {
ramp8[0x400 + i] = zzusb_device[i];
}
printf("boot_rom_init() done.\r\n");
}
#ifndef BOOTROM_H_
#define BOOTROM_H_
void boot_rom_init();
#endif
// Adapted from ScummVM SMUSH codec37 class
#include <string.h>
#include "codec37.h"
void bompDecodeLine(uint8_t *dst, const uint8_t *src, int len);
static int num_decoders = 0;
struct Codec37Decoder c37_decoders[4];
void Codec37Decoder_Init(int idx, int width, int height)
{
struct Codec37Decoder *dc = &c37_decoders[idx];
memset(dc, 0x00, sizeof(struct Codec37Decoder));
dc->_width = width;
dc->_height = height;
dc->_frameSize = width * height;
dc->_deltaSize = dc->_frameSize * 3 + 0x13600;
dc->_deltaBuf = (byte *)0x30000000 + num_decoders * 0x1000000;
dc->_deltaBufs[0] = dc->_deltaBuf + 0x4D80;
dc->_deltaBufs[1] = dc->_deltaBuf + 0xE880 + dc->_frameSize;
dc->_curtable = 0;
dc->_prevSeqNb = 0;
dc->_tableLastPitch = -1;
dc->_tableLastIndex = -1;
}
void Codec37Decoder_Next()
{
num_decoders++;
if (num_decoders > 3) {
num_decoders = 0;
}
}
int Codec37Decoder_GetCur()
{
return num_decoders;
}
void Codec37Decoder_MakeTable(int idx, int pitch, int index)
{
struct Codec37Decoder *dc = &c37_decoders[idx];
static const int8_t maketable_bytes[] = {
0, 0, 1, 0, 2, 0, 3, 0, 5, 0,
8, 0, 13, 0, 21, 0, -1, 0, -2, 0,
-3, 0, -5, 0, -8, 0, -13, 0, -17, 0,
-21, 0, 0, 1, 1, 1, 2, 1, 3, 1,
5, 1, 8, 1, 13, 1, 21, 1, -1, 1,
-2, 1, -3, 1, -5, 1, -8, 1, -13, 1,
-17, 1, -21, 1, 0, 2, 1, 2, 2, 2,
3, 2, 5, 2, 8, 2, 13, 2, 21, 2,
-1, 2, -2, 2, -3, 2, -5, 2, -8, 2,
-13, 2, -17, 2, -21, 2, 0, 3, 1, 3,
2, 3, 3, 3, 5, 3, 8, 3, 13, 3,
21, 3, -1, 3, -2, 3, -3, 3, -5, 3,
-8, 3, -13, 3, -17, 3, -21, 3, 0, 5,
1, 5, 2, 5, 3, 5, 5, 5, 8, 5,
13, 5, 21, 5, -1, 5, -2, 5, -3, 5,
-5, 5, -8, 5, -13, 5, -17, 5, -21, 5,
0, 8, 1, 8, 2, 8, 3, 8, 5, 8,
8, 8, 13, 8, 21, 8, -1, 8, -2, 8,
-3, 8, -5, 8, -8, 8, -13, 8, -17, 8,
-21, 8, 0, 13, 1, 13, 2, 13, 3, 13,
5, 13, 8, 13, 13, 13, 21, 13, -1, 13,
-2, 13, -3, 13, -5, 13, -8, 13, -13, 13,
-17, 13, -21, 13, 0, 21, 1, 21, 2, 21,
3, 21, 5, 21, 8, 21, 13, 21, 21, 21,
-1, 21, -2, 21, -3, 21, -5, 21, -8, 21,
-13, 21, -17, 21, -21, 21, 0, -1, 1, -1,
2, -1, 3, -1, 5, -1, 8, -1, 13, -1,
21, -1, -1, -1, -2, -1, -3, -1, -5, -1,
-8, -1, -13, -1, -17, -1, -21, -1, 0, -2,
1, -2, 2, -2, 3, -2, 5, -2, 8, -2,
13, -2, 21, -2, -1, -2, -2, -2, -3, -2,
-5, -2, -8, -2, -13, -2, -17, -2, -21, -2,
0, -3, 1, -3, 2, -3, 3, -3, 5, -3,
8, -3, 13, -3, 21, -3, -1, -3, -2, -3,
-3, -3, -5, -3, -8, -3, -13, -3, -17, -3,
-21, -3, 0, -5, 1, -5, 2, -5, 3, -5,
5, -5, 8, -5, 13, -5, 21, -5, -1, -5,
-2, -5, -3, -5, -5, -5, -8, -5, -13, -5,
-17, -5, -21, -5, 0, -8, 1, -8, 2, -8,
3, -8, 5, -8, 8, -8, 13, -8, 21, -8,
-1, -8, -2, -8, -3, -8, -5, -8, -8, -8,
-13, -8, -17, -8, -21, -8, 0, -13, 1, -13,
2, -13, 3, -13, 5, -13, 8, -13, 13, -13,
21, -13, -1, -13, -2, -13, -3, -13, -5, -13,
-8, -13, -13, -13, -17, -13, -21, -13, 0, -17,
1, -17, 2, -17, 3, -17, 5, -17, 8, -17,
13, -17, 21, -17, -1, -17, -2, -17, -3, -17,
-5, -17, -8, -17, -13, -17, -17, -17, -21, -17,
0, -21, 1, -21, 2, -21, 3, -21, 5, -21,
8, -21, 13, -21, 21, -21, -1, -21, -2, -21,
-3, -21, -5, -21, -8, -21, -13, -21, -17, -21,
0, 0, -8, -29, 8, -29, -18, -25, 17, -25,
0, -23, -6, -22, 6, -22, -13, -19, 12, -19,
0, -18, 25, -18, -25, -17, -5, -17, 5, -17,
-10, -15, 10, -15, 0, -14, -4, -13, 4, -13,
19, -13, -19, -12, -8, -11, -2, -11, 0, -11,
2, -11, 8, -11, -15, -10, -4, -10, 4, -10,
15, -10, -6, -9, -1, -9, 1, -9, 6, -9,
-29, -8, -11, -8, -8, -8, -3, -8, 3, -8,
8, -8, 11, -8, 29, -8, -5, -7, -2, -7,
0, -7, 2, -7, 5, -7, -22, -6, -9, -6,
-6, -6, -3, -6, -1, -6, 1, -6, 3, -6,
6, -6, 9, -6, 22, -6, -17, -5, -7, -5,
-4, -5, -2, -5, 0, -5, 2, -5, 4, -5,
7, -5, 17, -5, -13, -4, -10, -4, -5, -4,
-3, -4, -1, -4, 0, -4, 1, -4, 3, -4,
5, -4, 10, -4, 13, -4, -8, -3, -6, -3,
-4, -3, -3, -3, -2, -3, -1, -3, 0, -3,
1, -3, 2, -3, 4, -3, 6, -3, 8, -3,
-11, -2, -7, -2, -5, -2, -3, -2, -2, -2,
-1, -2, 0, -2, 1, -2, 2, -2, 3, -2,
5, -2, 7, -2, 11, -2, -9, -1, -6, -1,
-4, -1, -3, -1, -2, -1, -1, -1, 0, -1,
1, -1, 2, -1, 3, -1, 4, -1, 6, -1,
9, -1, -31, 0, -23, 0, -18, 0, -14, 0,
-11, 0, -7, 0, -5, 0, -4, 0, -3, 0,
-2, 0, -1, 0, 0, -31, 1, 0, 2, 0,
3, 0, 4, 0, 5, 0, 7, 0, 11, 0,
14, 0, 18, 0, 23, 0, 31, 0, -9, 1,
-6, 1, -4, 1, -3, 1, -2, 1, -1, 1,
0, 1, 1, 1, 2, 1, 3, 1, 4, 1,
6, 1, 9, 1, -11, 2, -7, 2, -5, 2,
-3, 2, -2, 2, -1, 2, 0, 2, 1, 2,
2, 2, 3, 2, 5, 2, 7, 2, 11, 2,
-8, 3, -6, 3, -4, 3, -2, 3, -1, 3,
0, 3, 1, 3, 2, 3, 3, 3, 4, 3,
6, 3, 8, 3, -13, 4, -10, 4, -5, 4,
-3, 4, -1, 4, 0, 4, 1, 4, 3, 4,
5, 4, 10, 4, 13, 4, -17, 5, -7, 5,
-4, 5, -2, 5, 0, 5, 2, 5, 4, 5,
7, 5, 17, 5, -22, 6, -9, 6, -6, 6,
-3, 6, -1, 6, 1, 6, 3, 6, 6, 6,
9, 6, 22, 6, -5, 7, -2, 7, 0, 7,
2, 7, 5, 7, -29, 8, -11, 8, -8, 8,
-3, 8, 3, 8, 8, 8, 11, 8, 29, 8,
-6, 9, -1, 9, 1, 9, 6, 9, -15, 10,
-4, 10, 4, 10, 15, 10, -8, 11, -2, 11,
0, 11, 2, 11, 8, 11, 19, 12, -19, 13,
-4, 13, 4, 13, 0, 14, -10, 15, 10, 15,
-5, 17, 5, 17, 25, 17, -25, 18, 0, 18,
-12, 19, 13, 19, -6, 22, 6, 22, 0, 23,
-17, 25, 18, 25, -8, 29, 8, 29, 0, 31,
0, 0, -6, -22, 6, -22, -13, -19, 12, -19,
0, -18, -5, -17, 5, -17, -10, -15, 10, -15,
0, -14, -4, -13, 4, -13, 19, -13, -19, -12,
-8, -11, -2, -11, 0, -11, 2, -11, 8, -11,
-15, -10, -4, -10, 4, -10, 15, -10, -6, -9,
-1, -9, 1, -9, 6, -9, -11, -8, -8, -8,
-3, -8, 0, -8, 3, -8, 8, -8, 11, -8,
-5, -7, -2, -7, 0, -7, 2, -7, 5, -7,
-22, -6, -9, -6, -6, -6, -3, -6, -1, -6,
1, -6, 3, -6, 6, -6, 9, -6, 22, -6,
-17, -5, -7, -5, -4, -5, -2, -5, -1, -5,
0, -5, 1, -5, 2, -5, 4, -5, 7, -5,
17, -5, -13, -4, -10, -4, -5, -4, -3, -4,
-2, -4, -1, -4, 0, -4, 1, -4, 2, -4,
3, -4, 5, -4, 10, -4, 13, -4, -8, -3,
-6, -3, -4, -3, -3, -3, -2, -3, -1, -3,
0, -3, 1, -3, 2, -3, 3, -3, 4, -3,
6, -3, 8, -3, -11, -2, -7, -2, -5, -2,
-4, -2, -3, -2, -2, -2, -1, -2, 0, -2,
1, -2, 2, -2, 3, -2, 4, -2, 5, -2,
7, -2, 11, -2, -9, -1, -6, -1, -5, -1,
-4, -1, -3, -1, -2, -1, -1, -1, 0, -1,
1, -1, 2, -1, 3, -1, 4, -1, 5, -1,
6, -1, 9, -1, -23, 0, -18, 0, -14, 0,
-11, 0, -7, 0, -5, 0, -4, 0, -3, 0,
-2, 0, -1, 0, 0, -23, 1, 0, 2, 0,
3, 0, 4, 0, 5, 0, 7, 0, 11, 0,
14, 0, 18, 0, 23, 0, -9, 1, -6, 1,
-5, 1, -4, 1, -3, 1, -2, 1, -1, 1,
0, 1, 1, 1, 2, 1, 3, 1, 4, 1,
5, 1, 6, 1, 9, 1, -11, 2, -7, 2,
-5, 2, -4, 2, -3, 2, -2, 2, -1, 2,
0, 2, 1, 2, 2, 2, 3, 2, 4, 2,
5, 2, 7, 2, 11, 2, -8, 3, -6, 3,
-4, 3, -3, 3, -2, 3, -1, 3, 0, 3,
1, 3, 2, 3, 3, 3, 4, 3, 6, 3,
8, 3, -13, 4, -10, 4, -5, 4, -3, 4,
-2, 4, -1, 4, 0, 4, 1, 4, 2, 4,
3, 4, 5, 4, 10, 4, 13, 4, -17, 5,
-7, 5, -4, 5, -2, 5, -1, 5, 0, 5,
1, 5, 2, 5, 4, 5, 7, 5, 17, 5,
-22, 6, -9, 6, -6, 6, -3, 6, -1, 6,
1, 6, 3, 6, 6, 6, 9, 6, 22, 6,
-5, 7, -2, 7, 0, 7, 2, 7, 5, 7,
-11, 8, -8, 8, -3, 8, 0, 8, 3, 8,
8, 8, 11, 8, -6, 9, -1, 9, 1, 9,
6, 9, -15, 10, -4, 10, 4, 10, 15, 10,
-8, 11, -2, 11, 0, 11, 2, 11, 8, 11,
19, 12, -19, 13, -4, 13, 4, 13, 0, 14,
-10, 15, 10, 15, -5, 17, 5, 17, 0, 18,
-12, 19, 13, 19, -6, 22, 6, 22, 0, 23,
};
if (dc->_tableLastPitch == pitch && dc->_tableLastIndex == index)
return;
dc->_tableLastPitch = pitch;
dc->_tableLastIndex = index;
index *= 255;
for (int32 i = 0; i < 255; i++) {
int32 j = (i + index) * 2;
dc->_offsetTable[i] = maketable_bytes[j + 1] * pitch + maketable_bytes[j];
}
}
void Codec37Decoder_proc1(int idx, byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table)
{
//struct Codec37Decoder *dc = &c37_decoders[idx];
uint8_t code;
uint8_t filling, skipCode;
int32 len;
int i, p;
uint32_t pitches[16];
i = bw;
for (p = 0; p < 16; ++p) {
pitches[p] = (p >> 2) * pitch + (p & 0x3);
}
code = 0;
filling = 0;
len = -1;
while (1) {
if (len < 0) {
filling = (*src & 1) == 1;
len = *src++ >> 1;
skipCode = 0;
} else {
skipCode = 1;
}
if (!filling || !skipCode) {
code = *src++;
if (code == 0xFF) {
--len;
for (p = 0; p < 0x10; ++p) {
if (len < 0) {
filling = (*src & 1) == 1;
len = *src++ >> 1;
if (filling) {
code = *src++;
}
}
if (filling) {
*(dst + pitches[p]) = code;
} else {
*(dst + pitches[p]) = *src++;
}
--len;
}
dst += 4;
--i;
if (i == 0) {
dst += pitch * 3;
--bh;
if (bh == 0) return;
i = bw;
}
continue;
}
}
byte *dst2 = dst + offset_table[code] + next_offs;
COPY_4X4(dst2, dst, pitch);
--i;
if (i == 0) {
dst += pitch * 3;
--bh;
if (bh == 0) return;
i = bw;
}
--len;
}
}
void Codec37Decoder_proc3WithFDFE(int idx, byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table)
{
struct Codec37Decoder *dc = &c37_decoders[idx];
do {
int32 i = bw;
do {
int32 code = *src++;
if (code == 0xFD) {
LITERAL_4X4(src, dst, pitch);
} else if (code == 0xFE) {
LITERAL_4X1(src, dst, pitch);
} else if (code == 0xFF) {
LITERAL_1X1(src, dst, pitch);
} else {
byte *dst2 = dst + dc->_offsetTable[code] + next_offs;
COPY_4X4(dst2, dst, pitch);
}
} while (--i);
dst += pitch * 3;
} while (--bh);
}
void Codec37Decoder_proc3WithoutFDFE(int idx, byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table)
{
struct Codec37Decoder *dc = &c37_decoders[idx];
do {
int32 i = bw;
do {
int32 code = *src++;
if (code == 0xFF) {
LITERAL_1X1(src, dst, pitch);
} else {
byte *dst2 = dst + dc->_offsetTable[code] + next_offs;
COPY_4X4(dst2, dst, pitch);
}
} while (--i);
dst += pitch * 3;
} while (--bh);
}
void Codec37Decoder_proc4WithFDFE(int idx, byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table)
{
struct Codec37Decoder *dc = &c37_decoders[idx];
do {
int32 i = bw;
do {
int32 code = *src++;
if (code == 0xFD) {
LITERAL_4X4(src, dst, pitch);
} else if (code == 0xFE) {
LITERAL_4X1(src, dst, pitch);
} else if (code == 0xFF) {
LITERAL_1X1(src, dst, pitch);
} else if (code == 0x00) {
int32 length = *src++ + 1;
for (int32 l = 0; l < length; l++) {
byte *dst2 = dst + next_offs;
COPY_4X4(dst2, dst, pitch);
i--;
if (i == 0) {
dst += pitch * 3;
bh--;
i = bw;
}
}
if (bh == 0) {
return;
}
i++;
} else {
byte *dst2 = dst + dc->_offsetTable[code] + next_offs;
COPY_4X4(dst2, dst, pitch);
}
} while (--i);
dst += pitch * 3;
} while (--bh);
}
void Codec37Decoder_proc4WithoutFDFE(int idx, byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table)
{
struct Codec37Decoder *dc = &c37_decoders[idx];
do {
int32 i = bw;
do {
int32 code = *src++;
if (code == 0xFF) {
LITERAL_1X1(src, dst, pitch);
} else if (code == 0x00) {
int32 length = *src++ + 1;
for (int32 l = 0; l < length; l++) {
byte *dst2 = dst + next_offs;
COPY_4X4(dst2, dst, pitch);
i--;
if (i == 0) {
dst += pitch * 3;
bh--;
i = bw;
}
}
if (bh == 0) {
return;
}
i++;
} else {
byte *dst2 = dst + dc->_offsetTable[code] + next_offs;
COPY_4X4(dst2, dst, pitch);
}
} while (--i);
dst += pitch * 3;
} while (--bh);
}
inline uint16 READ_UINT16(const void *ptr) {
return *(const uint16 *)(ptr);
}
inline uint32 READ_UINT32(const void *ptr) {
return *(const uint32 *)(ptr);
}
void Codec37Decoder_decode(int idx, uint8_t *dst, uint8_t *src)
{
struct Codec37Decoder *dc = &c37_decoders[idx];
int32 bw = (dc->_width + 3) / 4, bh = (dc->_height + 3) / 4;
int32 pitch = bw * 4;
int16 seq_nb = READ_UINT16(src + 2);
int32 decoded_size = READ_UINT32(src + 4);
byte mask_flags = src[12];
Codec37Decoder_MakeTable(idx, pitch, src[1]);
int32 tmp;
switch (src[0]) {
case 0:
if ((dc->_deltaBufs[dc->_curtable] - dc->_deltaBuf) > 0) {
memset(dc->_deltaBuf, 0, dc->_deltaBufs[dc->_curtable] - dc->_deltaBuf);
}
tmp = (dc->_deltaBuf + dc->_deltaSize) - dc->_deltaBufs[dc->_curtable] - decoded_size;
if (tmp > 0) {
memset(dc->_deltaBufs[dc->_curtable] + decoded_size, 0, tmp);
}
memcpy(dc->_deltaBufs[dc->_curtable], src + 16, decoded_size);
break;
case 1:
if ((seq_nb & 1) || !(mask_flags & 1)) {
dc->_curtable ^= 1;
}
Codec37Decoder_proc1(idx, dc->_deltaBufs[dc->_curtable], src + 16, dc->_deltaBufs[dc->_curtable ^ 1] - dc->_deltaBufs[dc->_curtable], bw, bh, pitch, dc->_offsetTable);
break;
case 2:
bompDecodeLine(dc->_deltaBufs[dc->_curtable], src + 16, decoded_size);
if ((dc->_deltaBufs[dc->_curtable] - dc->_deltaBuf) > 0) {
memset(dc->_deltaBuf, 0, dc->_deltaBufs[dc->_curtable] - dc->_deltaBuf);
}
tmp = (dc->_deltaBuf + dc->_deltaSize) - dc->_deltaBufs[dc->_curtable] - decoded_size;
if (tmp > 0) {
memset(dc->_deltaBufs[dc->_curtable] + decoded_size, 0, tmp);
}
break;
case 3:
if ((seq_nb & 1) || !(mask_flags & 1)) {
dc->_curtable ^= 1;
}
if ((mask_flags & 4) != 0) {
Codec37Decoder_proc3WithFDFE(idx, dc->_deltaBufs[dc->_curtable], src + 16,
dc->_deltaBufs[dc->_curtable ^ 1] - dc->_deltaBufs[dc->_curtable], bw, bh,
pitch, dc->_offsetTable);
} else {
Codec37Decoder_proc3WithoutFDFE(idx, dc->_deltaBufs[dc->_curtable], src + 16,
dc->_deltaBufs[dc->_curtable ^ 1] - dc->_deltaBufs[dc->_curtable], bw, bh,
pitch, dc->_offsetTable);
}
break;
case 4:
if ((seq_nb & 1) || !(mask_flags & 1)) {
dc->_curtable ^= 1;
}
if ((mask_flags & 4) != 0) {
Codec37Decoder_proc4WithFDFE(idx, dc->_deltaBufs[dc->_curtable], src + 16,
dc->_deltaBufs[dc->_curtable ^ 1] - dc->_deltaBufs[dc->_curtable], bw, bh,
pitch, dc->_offsetTable);
} else {
Codec37Decoder_proc4WithoutFDFE(idx, dc->_deltaBufs[dc->_curtable], src + 16,
dc->_deltaBufs[dc->_curtable ^ 1] - dc->_deltaBufs[dc->_curtable], bw, bh,
pitch, dc->_offsetTable);
}
break;
default:
break;
}
dc->_prevSeqNb = seq_nb;
memcpy(dst, dc->_deltaBufs[dc->_curtable], dc->_frameSize);
}
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include <stdint.h>
#define byte uint8_t
#define int32 int32_t
#define int16 int16_t
#define uint16 uint16_t
#define uint32 uint32_t
#define DECLARE_LITERAL_TEMP(v) \
uint32 v
#define READ_LITERAL_PIXEL(src, v) \
do { \
v = *src++; \
v += (v << 8) + (v << 16) + (v << 24); \
} while (0)
#define WRITE_4X1_LINE(dst, v) \
*(uint32 *)(dst) = v
#define COPY_4X1_LINE(dst, src) \
*(uint32 *)(dst) = *(const uint32 *)(src)
/* Fill a 4x4 pixel block with a literal pixel value */
#define LITERAL_4X4(src, dst, pitch) \
do { \
int x; \
DECLARE_LITERAL_TEMP(t); \
READ_LITERAL_PIXEL(src, t); \
for (x=0; x<4; x++) { \
WRITE_4X1_LINE(dst + pitch * x, t); \
} \
dst += 4; \
} while (0)
/* Fill four 4x1 pixel blocks with literal pixel values */
#define LITERAL_4X1(src, dst, pitch) \
do { \
int x; \
DECLARE_LITERAL_TEMP(t); \
for (x=0; x<4; x++) { \
READ_LITERAL_PIXEL(src, t); \
WRITE_4X1_LINE(dst + pitch * x, t); \
} \
dst += 4; \
} while (0)
/* Fill sixteen 1x1 pixel blocks with literal pixel values */
#define LITERAL_1X1(src, dst, pitch) \
do { \
int x; \
for (x=0; x<4; x++) { \
COPY_4X1_LINE(dst + pitch * x, src); \
src += 4; \
} \
dst += 4; \
} while (0)
/* Copy a 4x4 pixel block from a different place in the framebuffer */
#define COPY_4X4(dst2, dst, pitch) \
do { \
int x; \
for (x=0; x<4; x++) { \
COPY_4X1_LINE(dst + pitch * x, dst2 + pitch * x); \
} \
dst += 4; \
} while (0)
struct Codec37Decoder {
int32 _deltaSize;
byte *_deltaBufs[2];
byte *_deltaBuf;
int16 _offsetTable[255];
int _curtable;
uint16 _prevSeqNb;
int _tableLastPitch;
int _tableLastIndex;
int32 _frameSize;
int _width, _height;
};
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include <stdint.h>
#include <xil_types.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
void bompDecodeLine(uint8_t *dst, const uint8_t *src, int len);
static int num_decoders = 0;
#define int32 int32_t
#define byte uint8_t
#define int16 int16_t
#define int8 int8_t
#define uint16 uint16_t
#define uint32 uint32_t
#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0])))
struct Codec47Decoder {
int32 _deltaSize;
byte *_deltaBufs[2];
byte *_deltaBuf;
byte *_curBuf;
int32 _prevSeqNb;
int _lastTableWidth;
const byte *_d_src, *_paramPtr;
int _d_pitch;
int32 _offset1, _offset2;
byte *_tableBig;
byte *_tableSmall;
int16 _table[256];
int32 _frameSize;
int _width, _height;
};
struct Codec47Decoder c47_decoders[4];
void Codec47Decoder_Next()
{
num_decoders++;
if (num_decoders > 3) {
num_decoders = 0;
}
}
int Codec47Decoder_GetCur()
{
return num_decoders;
}
#define COPY_4X1_LINE(dst, src) \
*(uint32 *)(dst) = *(const uint32 *)(src)
#define COPY_2X1_LINE(dst, src) \
*(uint16 *)(dst) = *(const uint16 *)(src)
#define FILL_4X1_LINE(dst, val) \
do { \
(dst)[0] = val; \
(dst)[1] = val; \
(dst)[2] = val; \
(dst)[3] = val; \
} while (0)
#define FILL_2X1_LINE(dst, val) \
do { \
(dst)[0] = val; \
(dst)[1] = val; \
} while (0)
inline int32 ABS(int32 x)
{
return (x >= 0) ? x : -x;
}
inline uint16 READ_UINT16(const void *ptr) {
return *(const uint16 *)(ptr);
}
inline uint32 READ_UINT32(const void *ptr) {
return *(const uint32 *)(ptr);
}
static const int8 codec47_table_small1[] = {
0, 1, 2, 3, 3, 3, 3, 2, 1, 0, 0, 0, 1, 2, 2, 1,
};
static const int8 codec47_table_small2[] = {
0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 2, 1, 1, 1, 2, 2,
};
static const int8 codec47_table_big1[] = {
0, 2, 5, 7, 7, 7, 7, 7, 7, 5, 2, 0, 0, 0, 0, 0,
};
static const int8 codec47_table_big2[] = {
0, 0, 0, 0, 1, 3, 4, 6, 7, 7, 7, 7, 6, 4, 3, 1,
};
static const int8 codec47_table[] = {
0, 0, -1, -43, 6, -43, -9, -42, 13, -41,
-16, -40, 19, -39, -23, -36, 26, -34, -2, -33,
4, -33, -29, -32, -9, -32, 11, -31, -16, -29,
32, -29, 18, -28, -34, -26, -22, -25, -1, -25,
3, -25, -7, -24, 8, -24, 24, -23, 36, -23,
-12, -22, 13, -21, -38, -20, 0, -20, -27, -19,
-4, -19, 4, -19, -17, -18, -8, -17, 8, -17,
18, -17, 28, -17, 39, -17, -12, -15, 12, -15,
-21, -14, -1, -14, 1, -14, -41, -13, -5, -13,
5, -13, 21, -13, -31, -12, -15, -11, -8, -11,
8, -11, 15, -11, -2, -10, 1, -10, 31, -10,
-23, -9, -11, -9, -5, -9, 4, -9, 11, -9,
42, -9, 6, -8, 24, -8, -18, -7, -7, -7,
-3, -7, -1, -7, 2, -7, 18, -7, -43, -6,
-13, -6, -4, -6, 4, -6, 8, -6, -33, -5,
-9, -5, -2, -5, 0, -5, 2, -5, 5, -5,
13, -5, -25, -4, -6, -4, -3, -4, 3, -4,
9, -4, -19, -3, -7, -3, -4, -3, -2, -3,
-1, -3, 0, -3, 1, -3, 2, -3, 4, -3,
6, -3, 33, -3, -14, -2, -10, -2, -5, -2,
-3, -2, -2, -2, -1, -2, 0, -2, 1, -2,
2, -2, 3, -2, 5, -2, 7, -2, 14, -2,
19, -2, 25, -2, 43, -2, -7, -1, -3, -1,
-2, -1, -1, -1, 0, -1, 1, -1, 2, -1,
3, -1, 10, -1, -5, 0, -3, 0, -2, 0,
-1, 0, 1, 0, 2, 0, 3, 0, 5, 0,
7, 0, -10, 1, -7, 1, -3, 1, -2, 1,
-1, 1, 0, 1, 1, 1, 2, 1, 3, 1,
-43, 2, -25, 2, -19, 2, -14, 2, -5, 2,
-3, 2, -2, 2, -1, 2, 0, 2, 1, 2,
2, 2, 3, 2, 5, 2, 7, 2, 10, 2,
14, 2, -33, 3, -6, 3, -4, 3, -2, 3,
-1, 3, 0, 3, 1, 3, 2, 3, 4, 3,
19, 3, -9, 4, -3, 4, 3, 4, 7, 4,
25, 4, -13, 5, -5, 5, -2, 5, 0, 5,
2, 5, 5, 5, 9, 5, 33, 5, -8, 6,
-4, 6, 4, 6, 13, 6, 43, 6, -18, 7,
-2, 7, 0, 7, 2, 7, 7, 7, 18, 7,
-24, 8, -6, 8, -42, 9, -11, 9, -4, 9,
5, 9, 11, 9, 23, 9, -31, 10, -1, 10,
2, 10, -15, 11, -8, 11, 8, 11, 15, 11,
31, 12, -21, 13, -5, 13, 5, 13, 41, 13,
-1, 14, 1, 14, 21, 14, -12, 15, 12, 15,
-39, 17, -28, 17, -18, 17, -8, 17, 8, 17,
17, 18, -4, 19, 0, 19, 4, 19, 27, 19,
38, 20, -13, 21, 12, 22, -36, 23, -24, 23,
-8, 24, 7, 24, -3, 25, 1, 25, 22, 25,
34, 26, -18, 28, -32, 29, 16, 29, -11, 31,
9, 32, 29, 32, -4, 33, 2, 33, -26, 34,
23, 36, -19, 39, 16, 40, -13, 41, 9, 42,
-6, 43, 1, 43, 0, 0, 0, 0, 0, 0
};
void c47_makeTablesInterpolation(int idx, int param) {
struct Codec47Decoder *dc = &c47_decoders[idx];
int32 variable1, variable2;
int32 b1, b2;
int32 value_table47_1_2, value_table47_1_1, value_table47_2_2, value_table47_2_1;
int32 tableSmallBig[64], tmp, s;
const int8 *table47_1 = 0, *table47_2 = 0;
int32 *ptr_small_big;
byte *ptr;
int i, x, y;
if (param == 8) {
table47_1 = codec47_table_big1;
table47_2 = codec47_table_big2;
ptr = dc->_tableBig;
for (i = 0; i < 256; i++) {
ptr[384] = 0;
ptr[385] = 0;
ptr += 388;
}
} else if (param == 4) {
table47_1 = codec47_table_small1;
table47_2 = codec47_table_small2;
ptr = dc->_tableSmall;
for (i = 0; i < 256; i++) {
ptr[96] = 0;
ptr[97] = 0;
ptr += 128;
}
} else {
printf("Codec47Decoder::makeTablesInterpolation: unknown param %d", param);
return;
}
s = 0;
for (x = 0; x < 16; x++) {
value_table47_1_1 = table47_1[x];
value_table47_2_1 = table47_2[x];
for (y = 0; y < 16; y++) {
value_table47_1_2 = table47_1[y];
value_table47_2_2 = table47_2[y];
if (value_table47_2_1 == 0) {
b1 = 0;
} else if (value_table47_2_1 == param - 1) {
b1 = 1;
} else if (value_table47_1_1 == 0) {
b1 = 2;
} else if (value_table47_1_1 == param - 1) {
b1 = 3;
} else {
b1 = 4;
}
if (value_table47_2_2 == 0) {
b2 = 0;
} else if (value_table47_2_2 == param - 1) {
b2 = 1;
} else if (value_table47_1_2 == 0) {
b2 = 2;
} else if (value_table47_1_2 == param - 1) {
b2 = 3;
} else {
b2 = 4;
}
memset(tableSmallBig, 0, param * param * 4);
variable2 = ABS(value_table47_2_2 - value_table47_2_1);
tmp = ABS(value_table47_1_2 - value_table47_1_1);
if (variable2 <= tmp) {
variable2 = tmp;
}
for (variable1 = 0; variable1 <= variable2; variable1++) {
int32 variable3, variable4;
if (variable2 > 0) {
// Linearly interpolate between value_table47_1_1 and value_table47_1_2
// respectively value_table47_2_1 and value_table47_2_2.
variable4 = (value_table47_1_1 * variable1 + value_table47_1_2 * (variable2 - variable1) + variable2 / 2) / variable2;
variable3 = (value_table47_2_1 * variable1 + value_table47_2_2 * (variable2 - variable1) + variable2 / 2) / variable2;
} else {
variable4 = value_table47_1_1;
variable3 = value_table47_2_1;
}
ptr_small_big = &tableSmallBig[param * variable3 + variable4];
*ptr_small_big = 1;
if ((b1 == 2 && b2 == 3) || (b2 == 2 && b1 == 3) ||
(b1 == 0 && b2 != 1) || (b2 == 0 && b1 != 1)) {
if (variable3 >= 0) {
i = variable3 + 1;
while (i--) {
*ptr_small_big = 1;
ptr_small_big -= param;
}
}
} else if ((b2 != 0 && b1 == 1) || (b1 != 0 && b2 == 1)) {
if (param > variable3) {
i = param - variable3;
while (i--) {
*ptr_small_big = 1;
ptr_small_big += param;
}
}
} else if ((b1 == 2 && b2 != 3) || (b2 == 2 && b1 != 3)) {
if (variable4 >= 0) {
i = variable4 + 1;
while (i--) {
*(ptr_small_big--) = 1;
}
}
} else if ((b1 == 0 && b2 == 1) || (b2 == 0 && b1 == 1) ||
(b1 == 3 && b2 != 2) || (b2 == 3 && b1 != 2)) {
if (param > variable4) {
i = param - variable4;
while (i--) {
*(ptr_small_big++) = 1;
}
}
}
}
if (param == 8) {
for (i = 64 - 1; i >= 0; i--) {
if (tableSmallBig[i] != 0) {
dc->_tableBig[256 + s + dc->_tableBig[384 + s]] = (byte)i;
dc->_tableBig[384 + s]++;
} else {
dc->_tableBig[320 + s + dc->_tableBig[385 + s]] = (byte)i;
dc->_tableBig[385 + s]++;
}
}
s += 388;
}
if (param == 4) {
for (i = 16 - 1; i >= 0; i--) {
if (tableSmallBig[i] != 0) {
dc->_tableSmall[64 + s + dc->_tableSmall[96 + s]] = (byte)i;
dc->_tableSmall[96 + s]++;
} else {
dc->_tableSmall[80 + s + dc->_tableSmall[97 + s]] = (byte)i;
dc->_tableSmall[97 + s]++;
}
}
s += 128;
}
}
}
}
void c47_makeTables47(int idx, int width) {
struct Codec47Decoder *dc = &c47_decoders[idx];
if (dc->_lastTableWidth == width)
return;
dc->_lastTableWidth = width;
int32 a, c, d;
int16 tmp;
for (int l = 0; l < ARRAYSIZE(codec47_table); l += 2) {
dc->_table[l / 2] = (int16)(codec47_table[l + 1] * width + codec47_table[l]);
}
// Note: _table[255] is never inited; but since only the first 0xF8
// entries of it are used anyway, this doesn't matter.
a = 0;
c = 0;
do {
for (d = 0; d < dc->_tableSmall[96 + c]; d++) {
tmp = dc->_tableSmall[64 + c + d];
tmp = (int16)((byte)(tmp >> 2) * width + (tmp & 3));
dc->_tableSmall[c + d * 2] = (byte)tmp;
dc->_tableSmall[c + d * 2 + 1] = tmp >> 8;
}
for (d = 0; d < dc->_tableSmall[97 + c]; d++) {
tmp = dc->_tableSmall[80 + c + d];
tmp = (int16)((byte)(tmp >> 2) * width + (tmp & 3));
dc->_tableSmall[32 + c + d * 2] = (byte)tmp;
dc->_tableSmall[32 + c + d * 2 + 1] = tmp >> 8;
}
for (d = 0; d < dc->_tableBig[384 + a]; d++) {
tmp = dc->_tableBig[256 + a + d];
tmp = (int16)((byte)(tmp >> 3) * width + (tmp & 7));
dc->_tableBig[a + d * 2] = (byte)tmp;
dc->_tableBig[a + d * 2 + 1] = tmp >> 8;
}
for (d = 0; d < dc->_tableBig[385 + a]; d++) {
tmp = dc->_tableBig[320 + a + d];
tmp = (int16)((byte)(tmp >> 3) * width + (tmp & 7));
dc->_tableBig[128 + a + d * 2] = (byte)tmp;
dc->_tableBig[128 + a + d * 2 + 1] = tmp >> 8;
}
a += 388;
c += 128;
} while (c < 32768);
}
void c47_level3(int idx, byte *d_dst) {
struct Codec47Decoder *dc = &c47_decoders[idx];
int32 tmp;
byte code = *dc->_d_src++;
if (code < 0xF8) {
tmp = dc->_table[code] + dc->_offset1;
COPY_2X1_LINE(d_dst, d_dst + tmp);
COPY_2X1_LINE(d_dst + dc->_d_pitch, d_dst + dc->_d_pitch + tmp);
} else if (code == 0xFF) {
COPY_2X1_LINE(d_dst, dc->_d_src + 0);
COPY_2X1_LINE(d_dst + dc->_d_pitch, dc->_d_src + 2);
dc->_d_src += 4;
} else if (code == 0xFE) {
byte t = *dc->_d_src++;
FILL_2X1_LINE(d_dst, t);
FILL_2X1_LINE(d_dst + dc->_d_pitch, t);
} else if (code == 0xFC) {
tmp = dc->_offset2;
COPY_2X1_LINE(d_dst, d_dst + tmp);
COPY_2X1_LINE(d_dst + dc->_d_pitch, d_dst + dc->_d_pitch + tmp);
} else {
byte t = dc->_paramPtr[code];
FILL_2X1_LINE(d_dst, t);
FILL_2X1_LINE(d_dst + dc->_d_pitch, t);
}
}
void c47_level2(int idx, byte *d_dst) {
struct Codec47Decoder *dc = &c47_decoders[idx];
int32 tmp;
byte code = *dc->_d_src++;
int i;
if (code < 0xF8) {
tmp = dc->_table[code] + dc->_offset1;
for (i = 0; i < 4; i++) {
COPY_4X1_LINE(d_dst, d_dst + tmp);
d_dst += dc->_d_pitch;
}
} else if (code == 0xFF) {
c47_level3(idx, d_dst);
d_dst += 2;
c47_level3(idx, d_dst);
d_dst += dc->_d_pitch * 2 - 2;
c47_level3(idx, d_dst);
d_dst += 2;
c47_level3(idx, d_dst);
} else if (code == 0xFE) {
byte t = *dc->_d_src++;
for (i = 0; i < 4; i++) {
FILL_4X1_LINE(d_dst, t);
d_dst += dc->_d_pitch;
}
} else if (code == 0xFD) {
byte *tmp_ptr = dc->_tableSmall + *dc->_d_src++ * 128;
int32 l = tmp_ptr[96];
byte val = *dc->_d_src++;
int16 *tmp_ptr2 = (int16 *)tmp_ptr;
while (l--) {
*(d_dst + READ_UINT16(tmp_ptr2)) = val;
tmp_ptr2++;
}
l = tmp_ptr[97];
val = *dc->_d_src++;
tmp_ptr2 = (int16 *)(tmp_ptr + 32);
while (l--) {
*(d_dst + READ_UINT16(tmp_ptr2)) = val;
tmp_ptr2++;
}
} else if (code == 0xFC) {
tmp = dc->_offset2;
for (i = 0; i < 4; i++) {
COPY_4X1_LINE(d_dst, d_dst + tmp);
d_dst += dc->_d_pitch;
}
} else {
byte t = dc->_paramPtr[code];
for (i = 0; i < 4; i++) {
FILL_4X1_LINE(d_dst, t);
d_dst += dc->_d_pitch;
}
}
}
void c47_level1(int idx, byte *d_dst) {
struct Codec47Decoder *dc = &c47_decoders[idx];
int32 tmp, tmp2;
byte code = *dc->_d_src++;
int i;
if (code < 0xF8) {
tmp2 = dc->_table[code] + dc->_offset1;
for (i = 0; i < 8; i++) {
COPY_4X1_LINE(d_dst + 0, d_dst + tmp2);
COPY_4X1_LINE(d_dst + 4, d_dst + tmp2 + 4);
d_dst += dc->_d_pitch;
}
} else if (code == 0xFF) {
c47_level2(idx, d_dst);
d_dst += 4;
c47_level2(idx, d_dst);
d_dst += dc->_d_pitch * 4 - 4;
c47_level2(idx, d_dst);
d_dst += 4;
c47_level2(idx, d_dst);
} else if (code == 0xFE) {
byte t = *dc->_d_src++;
for (i = 0; i < 8; i++) {
FILL_4X1_LINE(d_dst, t);
FILL_4X1_LINE(d_dst + 4, t);
d_dst += dc->_d_pitch;
}
} else if (code == 0xFD) {
tmp = *dc->_d_src++;
byte *tmp_ptr = dc->_tableBig + tmp * 388;
byte l = tmp_ptr[384];
byte val = *dc->_d_src++;
int16 *tmp_ptr2 = (int16 *)tmp_ptr;
while (l--) {
*(d_dst + READ_UINT16(tmp_ptr2)) = val;
tmp_ptr2++;
}
l = tmp_ptr[385];
val = *dc->_d_src++;
tmp_ptr2 = (int16 *)(tmp_ptr + 128);
while (l--) {
*(d_dst + READ_UINT16(tmp_ptr2)) = val;
tmp_ptr2++;
}
} else if (code == 0xFC) {
tmp2 = dc->_offset2;
for (i = 0; i < 8; i++) {
COPY_4X1_LINE(d_dst + 0, d_dst + tmp2);
COPY_4X1_LINE(d_dst + 4, d_dst + tmp2 + 4);
d_dst += dc->_d_pitch;
}
} else {
byte t = dc->_paramPtr[code];
for (i = 0; i < 8; i++) {
FILL_4X1_LINE(d_dst, t);
FILL_4X1_LINE(d_dst + 4, t);
d_dst += dc->_d_pitch;
}
}
}
void c47_decode2(int idx, byte *dst, const byte *src, int width, int height, const byte *param_ptr) {
struct Codec47Decoder *dc = &c47_decoders[idx];
dc->_d_src = src;
dc->_paramPtr = param_ptr - 0xf8;
int bw = (width + 7) / 8;
int bh = (height + 7) / 8;
int next_line = width * 7;
dc->_d_pitch = width;
do {
int tmp_bw = bw;
do {
c47_level1(idx, dst);
dst += 8;
} while (--tmp_bw);
dst += next_line;
} while (--bh);
}
inline void SWAP(uint8_t *a, uint8_t *b) {
uint8_t *tmp = b;
b = a;
a = tmp;
}
void Codec47Decoder_Init(int idx, int width, int height) {
struct Codec47Decoder *dc = &c47_decoders[idx];
dc->_lastTableWidth = -1;
dc->_width = width;
dc->_height = height;
dc->_tableBig = (byte *)0x30000000 + num_decoders * 0x1000000;
dc->_tableSmall = (byte *)0x30800000 + num_decoders * 0x1000000;
if ((dc->_tableBig != NULL) && (dc->_tableSmall != NULL)) {
printf("c47: Making interpolation tables.\n");
c47_makeTablesInterpolation(idx, 4);
c47_makeTablesInterpolation(idx, 8);
}
dc->_frameSize = dc->_width * dc->_height;
dc->_deltaSize = dc->_frameSize * 3;
dc->_deltaBuf = (byte *)0x31000000 + num_decoders * 0x1000000;
dc->_deltaBufs[0] = dc->_deltaBuf;
dc->_deltaBufs[1] = dc->_deltaBuf + dc->_frameSize;
dc->_curBuf = dc->_deltaBuf + dc->_frameSize * 2;
}
uint8_t Codec47Decoder_decode(int idx, byte *dst, const byte *src) {
struct Codec47Decoder *dc = &c47_decoders[idx];
if ((dc->_tableBig == NULL) || (dc->_tableSmall == NULL) || (dc->_deltaBuf == NULL))
return 0;
dc->_offset1 = dc->_deltaBufs[1] - dc->_curBuf;
dc->_offset2 = dc->_deltaBufs[0] - dc->_curBuf;
int32 seq_nb = READ_UINT16(src + 0);
const byte *gfx_data = src + 26;
if (seq_nb == 0) {
c47_makeTables47(idx, dc->_width);
memset(dc->_deltaBufs[0], src[12], dc->_frameSize);
memset(dc->_deltaBufs[1], src[13], dc->_frameSize);
dc->_prevSeqNb = -1;
}
if ((src[4] & 1) != 0) {
gfx_data += 32896;
}
switch (src[2]) {
case 0:
memcpy(dc->_curBuf, gfx_data, dc->_frameSize);
break;
case 1:
// Used by Outlaws, but not by any SCUMM game.
printf("codec47: not implemented decode1 proc");
break;
case 2:
if (seq_nb == dc->_prevSeqNb + 1) {
c47_decode2(idx, dc->_curBuf, gfx_data, dc->_width, dc->_height, src + 8);
}
break;
case 3:
memcpy(dc->_curBuf, dc->_deltaBufs[1], dc->_frameSize);
break;
case 4:
memcpy(dc->_curBuf, dc->_deltaBufs[0], dc->_frameSize);
break;
case 5:
bompDecodeLine(dc->_curBuf, gfx_data, READ_UINT32(src + 14));
break;
default:
break;
}
memcpy(dst, dc->_curBuf, dc->_frameSize);
if (seq_nb == dc->_prevSeqNb + 1) {
if (src[3] == 1) {
SWAP(dc->_curBuf, dc->_deltaBufs[1]);
} else if (src[3] == 2) {
SWAP(dc->_deltaBufs[0], dc->_deltaBufs[1]);
SWAP(dc->_deltaBufs[1], dc->_curBuf);
}
}
dc->_prevSeqNb = seq_nb;
return 1;
}
#include "gfx.h"
#include "compression/compression.h"
#include <string.h>
void decompress_rle_smush1_data(uint8_t * src, uint8_t * dst, uint32_t size, uint16_t width, uint16_t height, uint16_t pitch)
{
int size_line, h, length;
uint8_t code, val;
uint8_t *dst_base = dst;
for (h = 0; h < height; h++) {
size_line = ((uint16_t *)src)[0];
src += 2;
while (size_line > 0) {
code = *src++;
size_line--;
length = (code >> 1) + 1;
if (code & 1) {
val = *src++;
size_line--;
if (val)
memset(dst, val, length);
dst += length;
} else {
size_line -= length;
while (length--) {
val = *src++;
if (val)
*dst = val;
dst++;
}
}
}
dst_base += pitch;
dst = dst_base;
}
}
void bompDecodeLine(uint8_t *dst, const uint8_t *src, int len) {
int num;
uint8_t code, color;
while (len > 0) {
code = *src++;
num = (code >> 1) + 1;
if (num > len)
num = len;
len -= num;
if (code & 1) {
color = *src++;
memset(dst, color, num);
} else {
memcpy(dst, src, num);
src += num;
}
dst += num;
}
}
This diff is collapsed.
void decompress_rle_smush1_data(uint8_t * src, uint8_t * dst, uint32_t size, uint16_t w, uint16_t h, uint16_t pitch);
void Codec37Decoder_Init(int idx, int width, int height);
void Codec37Decoder_decode(int idx, uint8_t *dst, uint8_t *src);
int Codec37Decoder_GetCur();
void Codec37Decoder_Next();
void Codec47Decoder_Init(int idx, int width, int height);
void Codec47Decoder_decode(int idx, uint8_t *dst, uint8_t *src);
int Codec47Decoder_GetCur();
void Codec47Decoder_Next();
void init_imc_tables();
uint32_t decompress_adpcm(uint8_t *compInput, uint8_t *compOutput, int channels);
This diff is collapsed.
struct ZZ9K_ENV {
uint32_t api_version;
uint32_t argv[8];
uint32_t argc;
int (*fn_putchar)(char);
void (*fn_set_output_putchar_to_events)(char);
void (*fn_set_output_events_blocking)(char);
void (*fn_put_event_code)(uint16_t);
uint16_t (*fn_get_event_serial)();
uint16_t (*fn_get_event_code)();
char (*fn_output_event_acked)();
};
void arm_app_init();
volatile struct ZZ9K_ENV* arm_app_get_run_env();
void arm_app_run(uint32_t arm_run_address);
void arm_app_input_event(uint32_t evt);
uint32_t arm_app_output_event();
void arm_exception_handler_id_reset(void *callback);
void arm_exception_handler_id_data_abort(void *callback);
void arm_exception_handler_id_prefetch_abort(void *callback);
void arm_exception_handler_illinst(void *callback);
This diff is collapsed.