REDRIVER2/src_rebuild/EMULATOR/LIBGPU.C

1368 lines
36 KiB
C

#include "LIBGPU.H"
#include "EMULATOR.H"
#include "EMULATOR_GLOBALS.H"
#include "EMULATOR_PRIVATE.H"
#include <stdint.h>
#include <LIBETC.H>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
DISPENV activeDispEnv;
DRAWENV activeDrawEnv; // word_33BC
DRAWENV byte_9CCA4;
int dword_3410 = 0;
char byte_3352 = 0;
#if 0
char fontDebugTexture[] =
{
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x00,
0x00,0x10,0x11,0x00,0x00,0x11,0x11,0x01,0x00,0x10,0x00,0x00,0x00,0x10,0x01,0x00,
0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x10,0x10,0x00,0x00,0x10,0x10,0x00,
0x00,0x01,0x01,0x01,0x00,0x11,0x00,0x01,0x00,0x01,0x01,0x00,0x00,0x11,0x00,0x00,
0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x11,0x01,
0x00,0x01,0x01,0x00,0x00,0x00,0x10,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x10,0x11,0x00,0x00,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,
0x00,0x10,0x11,0x00,0x00,0x00,0x01,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x11,0x11,0x01,
0x00,0x00,0x00,0x00,0x00,0x11,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,
0x00,0x00,0x01,0x01,0x00,0x10,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x10,0x11,0x00,0x00,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x11,0x01,
0x00,0x01,0x01,0x01,0x00,0x01,0x10,0x01,0x00,0x01,0x10,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x01,0x00,
0x00,0x10,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x01,0x00,0x00,0x01,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,
0x00,0x10,0x11,0x00,0x00,0x01,0x10,0x01,0x00,0x10,0x01,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x10,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x10,0x11,0x00,0x00,0x00,0x01,0x00,0x00,0x10,0x11,0x00,0x00,0x10,0x11,0x00,
0x00,0x00,0x10,0x00,0x00,0x11,0x11,0x01,0x00,0x00,0x11,0x00,0x00,0x11,0x11,0x01,
0x00,0x10,0x11,0x00,0x00,0x10,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x11,0x00,
0x00,0x01,0x00,0x01,0x00,0x10,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
0x00,0x00,0x11,0x00,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x01,
0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x01,
0x00,0x01,0x10,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,
0x00,0x10,0x10,0x00,0x00,0x11,0x11,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x00,
0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x10,0x01,0x00,0x00,0x10,0x01,0x00,
0x00,0x00,0x01,0x00,0x00,0x11,0x11,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x10,0x00,
0x00,0x01,0x01,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x11,0x00,
0x00,0x01,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0x11,0x11,0x00,0x00,0x00,0x10,0x00,
0x00,0x10,0x11,0x00,0x00,0x10,0x11,0x01,0x00,0x10,0x01,0x00,0x00,0x10,0x01,0x00,
0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,0x00,
0x00,0x11,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,
0x00,0x11,0x11,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x01,0x00,
0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0x00,0x00,0x11,0x11,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
0x00,0x01,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x01,
0x00,0x00,0x10,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x01,0x00,
0x00,0x01,0x00,0x01,0x00,0x00,0x10,0x00,0x00,0x10,0x01,0x00,0x00,0x10,0x01,0x00,
0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x10,0x11,0x00,0x00,0x10,0x11,0x00,0x00,0x11,0x11,0x01,0x00,0x10,0x11,0x00,
0x00,0x00,0x10,0x00,0x00,0x10,0x11,0x00,0x00,0x10,0x11,0x00,0x00,0x00,0x01,0x00,
0x00,0x10,0x11,0x00,0x00,0x10,0x01,0x00,0x00,0x10,0x01,0x00,0x00,0x10,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x10,0x11,0x00,0x00,0x10,0x11,0x00,0x00,0x11,0x11,0x00,0x00,0x10,0x11,0x00,
0x00,0x11,0x11,0x00,0x00,0x11,0x11,0x01,0x00,0x11,0x11,0x01,0x00,0x10,0x11,0x00,
0x00,0x01,0x00,0x01,0x00,0x10,0x11,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,
0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x10,0x11,0x00,
0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
0x00,0x10,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,
0x00,0x01,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x10,0x00,
0x00,0x01,0x00,0x00,0x00,0x11,0x10,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
0x00,0x01,0x11,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,
0x00,0x10,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x01,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x01,0x00,
0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x11,0x00,0x01,0x00,0x01,0x00,0x01,
0x00,0x01,0x01,0x01,0x00,0x11,0x11,0x01,0x00,0x11,0x11,0x00,0x00,0x01,0x00,0x00,
0x00,0x10,0x00,0x01,0x00,0x11,0x11,0x00,0x00,0x11,0x11,0x00,0x00,0x01,0x00,0x00,
0x00,0x11,0x11,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x11,0x00,0x00,
0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x01,0x01,0x00,0x01,0x00,0x01,
0x00,0x01,0x11,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,
0x00,0x10,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x10,0x01,
0x00,0x01,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x01,0x00,
0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x10,0x01,0x00,0x01,0x00,0x01,
0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
0x00,0x10,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,
0x00,0x01,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x10,0x00,
0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
0x00,0x10,0x11,0x00,0x00,0x01,0x00,0x01,0x00,0x11,0x11,0x00,0x00,0x10,0x11,0x00,
0x00,0x11,0x11,0x00,0x00,0x11,0x11,0x01,0x00,0x01,0x00,0x00,0x00,0x10,0x11,0x00,
0x00,0x01,0x00,0x01,0x00,0x10,0x11,0x00,0x00,0x10,0x11,0x00,0x00,0x01,0x00,0x01,
0x00,0x11,0x11,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x10,0x11,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x11,0x11,0x00,0x00,0x10,0x11,0x00,0x00,0x11,0x11,0x00,0x00,0x10,0x11,0x00,
0x00,0x11,0x11,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x11,0x11,0x01,0x00,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x00,
0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,
0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,
0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
0x00,0x10,0x10,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,0x00,
0x00,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x11,0x11,0x00,0x00,0x01,0x00,0x01,0x00,0x11,0x11,0x00,0x00,0x10,0x11,0x00,
0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x11,0x11,0x01,0x00,0x00,0x01,0x00,
0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x01,
0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x10,0x10,0x00,0x00,0x01,0x01,0x01,
0x00,0x10,0x10,0x00,0x00,0x00,0x01,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x01,0x00,
0x00,0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0x00,0x00,0x00,0x01,0x10,0x00,0x00,0x01,0x10,0x00,0x00,0x01,0x00,0x01,
0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x10,0x10,0x00,0x00,0x11,0x10,0x01,
0x00,0x01,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,
0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0x00,0x00,0x00,0x10,0x01,0x01,0x00,0x01,0x00,0x01,0x00,0x10,0x11,0x00,
0x00,0x00,0x01,0x00,0x00,0x10,0x11,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x01,
0x00,0x01,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x11,0x11,0x01,0x00,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x01,
0x00,0x00,0x00,0x00,0x00,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
#endif
//unk_E88
unsigned char fontDebugClut[] = { 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
struct VertexBufferSplit
{
TextureID textureId;
unsigned short vIndex;
unsigned short vCount;
BlendMode blendMode;
TexFormat texFormat;
};
//#define DEBUG_POLY_COUNT
#if defined(DEBUG_POLY_COUNT)
static int polygon_count = 0;
#endif
struct Vertex g_vertexBuffer[MAX_NUM_POLY_BUFFER_VERTICES];
struct VertexBufferSplit g_splits[MAX_NUM_INDEX_BUFFERS];
int g_vertexIndex;
int g_splitIndex;
void ClearVBO()
{
g_vertexIndex = 0;
g_splitIndex = 0;
g_splits[g_splitIndex].texFormat = (TexFormat)0xFFFF;
}
u_short s_lastSemiTrans = 0xFFFF;
u_short s_lastPolyType = 0xFFFF;
void ResetPolyState()
{
s_lastSemiTrans = 0xFFFF;
s_lastPolyType = 0xFFFF;
}
//#define WIREFRAME_MODE
#if defined(USE_32_BIT_ADDR)
unsigned long terminator[2] = { -1, 0 };
#else
unsigned long terminator = -1;
#endif
void(*drawsync_callback)(void) = NULL;
void* off_3348[] =
{
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
int ClearImage(RECT16* rect, u_char r, u_char g, u_char b)
{
Emulator_Clear(rect->x, rect->y, rect->w, rect->h, r, g, b);
return 0;
}
int ClearImage2(RECT16* rect, u_char r, u_char g, u_char b)
{
Emulator_Clear(rect->x, rect->y, rect->w, rect->h, r, g, b);
return 0;
}
void DrawAggregatedSplits();
int DrawSync(int mode)
{
// Update VRAM seems needed to be here
//Emulator_UpdateVRAM();
if (drawsync_callback != NULL)
{
drawsync_callback();
}
if (g_splitIndex > 0) // don't do flips if nothing to draw.
{
DrawAggregatedSplits();
Emulator_EndScene();
}
return 0;
}
int LoadImagePSX(RECT16* rect, u_long* p)
{
Emulator_CopyVRAM((unsigned short*)p, 0, 0, rect->w, rect->h, rect->x, rect->y);
return 0;
}
int MargePrim(void* p0, void* p1)
{
int v0 = ((unsigned char*)p0)[3];
int v1 = ((unsigned char*)p1)[3];
v0 += v1;
v1 = v0 + 1;
if (v1 < 0x11)
{
((char*)p0)[3] = v1;
((int*)p1)[0] = 0;
return 0;
}
return -1;
}
int MoveImage(RECT16* rect, int x, int y)
{
Emulator_CopyVRAM(NULL, x, y, rect->w, rect->h, rect->x, rect->y);
return 0;
}
int ResetGraph(int mode)
{
UNIMPLEMENTED();
return 0;
}
int SetGraphDebug(int level)
{
UNIMPLEMENTED();
return 0;
}
int StoreImage(RECT16* rect, u_long* p)
{
Emulator_ReadVRAM((unsigned short*)p, rect->x, rect->y, rect->w, rect->h);
return 0;
}
int StoreImage2(RECT16 *RECT16, u_long *p)
{
int result = StoreImage(RECT16, p);
// GPU reset?
return result;
}
u_long* ClearOTag(u_long* ot, int n)
{
//Nothing to do here.
if (n == 0)
return NULL;
//last is special terminator
ot[n - 1] = (unsigned long)&terminator;
for (int i = n - 2; i > -1; i--)
{
ot[i] = (unsigned long)&ot[i + 1];
}
return NULL;
}
u_long* ClearOTagR(u_long* ot, int n)
{
//Nothing to do here.
if (n == 0)
return NULL;
//First is special terminator
setaddr(ot, &terminator);
setlen(ot, 0);
#if defined(USE_32_BIT_ADDR)
for (int i = 2; i < n * 2; i += 2)
#else
for (int i = 1; i < n; i++)
#endif
{
#if defined(USE_32_BIT_ADDR)
setaddr(&ot[i], (unsigned long)&ot[i - 2]);
#else
setaddr(&ot[i], (unsigned long)&ot[i - 1]);
#endif
setlen(&ot[i], 0);
}
return NULL;
}
void SetDispMask(int mask)
{
UNIMPLEMENTED();
}
int FntPrint(char* text, ...)
{
UNIMPLEMENTED();
return 0;
}
DISPENV* GetDispEnv(DISPENV* env)//(F)
{
memcpy(env, &activeDispEnv, sizeof(DISPENV));
return env;
}
DISPENV* PutDispEnv(DISPENV* env)//To Finish
{
memcpy((char*)&activeDispEnv, env, sizeof(DISPENV));
return 0;
}
DISPENV* SetDefDispEnv(DISPENV* env, int x, int y, int w, int h)//(F)
{
env->disp.x = x;
env->disp.y = y;
env->disp.w = w;
env->screen.x = 0;
env->screen.y = 0;
env->screen.w = 0;
env->screen.h = 0;
env->isrgb24 = 0;
env->isinter = 0;
env->pad1 = 0;
env->pad0 = 0;
env->disp.h = h;
return 0;
}
DRAWENV* GetDrawEnv(DRAWENV* env)
{
UNIMPLEMENTED();
return NULL;
}
DRAWENV* PutDrawEnv(DRAWENV* env)//Guessed
{
memcpy((char*)&activeDrawEnv, env, sizeof(DRAWENV));
return 0;
}
DRAWENV* SetDefDrawEnv(DRAWENV* env, int x, int y, int w, int h)//(F)
{
env->clip.x = x;
env->clip.y = y;
env->clip.w = w;
env->tw.x = 0;
env->tw.y = 0;
env->tw.w = 0;
env->tw.h = 0;
env->r0 = 0;
env->g0 = 0;
env->b0 = 0;
env->dtd = 1;
env->clip.h = h;
if (GetVideoMode() == 0)
{
env->dfe = h < 0x121 ? 1 : 0;
}
else
{
env->dfe = h < 0x101 ? 1 : 0;
}
env->ofs[0] = x;
env->ofs[1] = y;
env->tpage = 10;
env->isbg = 0;
return env;
}
void SetDrawEnv(DR_ENV* dr_env, DRAWENV* env)
{
}
void SetDrawMode(DR_MODE* p, int dfe, int dtd, int tpage, RECT16* tw)
{
setDrawMode(p, dfe, dtd, tpage, tw);
}
void SetDrawMove(DR_MOVE* p, RECT16* rect, int x, int y)
{
char uVar1;
ulong uVar2;
uVar1 = 5;
if ((rect->w == 0) || (rect->h == 0)) {
uVar1 = 0;
}
p->code[0] = 0x1000000;
p->code[1] = 0x80000000;
*(char *)((int)&p->tag + 3) = uVar1;
uVar2 = *(ulong *)rect;
p->code[3] = y << 0x10 | x & 0xffffU;
p->code[2] = uVar2;
p->code[4] = *(ulong *)&rect->w;
}
u_long DrawSyncCallback(void(*func)(void))
{
drawsync_callback = func;
return 0;
}
u_short GetClut(int x, int y)
{
return getClut(x, y);
}
void AddSplit(bool semiTrans, int page, TextureID textureId)
{
VertexBufferSplit& curSplit = g_splits[g_splitIndex];
BlendMode blendMode = semiTrans ? GET_TPAGE_BLEND(page) : BM_NONE;
TexFormat texFormat = GET_TPAGE_FORMAT(page);
if (curSplit.blendMode == blendMode && curSplit.texFormat == texFormat && curSplit.textureId == textureId)
{
return;
}
curSplit.vCount = g_vertexIndex - curSplit.vIndex;
VertexBufferSplit& split = g_splits[++g_splitIndex];
split.textureId = textureId;
split.vIndex = g_vertexIndex;
split.vCount = 0;
split.blendMode = blendMode;
split.texFormat = texFormat;
}
void MakeTriangle()
{
g_vertexBuffer[g_vertexIndex + 5] = g_vertexBuffer[g_vertexIndex + 3];
g_vertexBuffer[g_vertexIndex + 3] = g_vertexBuffer[g_vertexIndex];
g_vertexBuffer[g_vertexIndex + 4] = g_vertexBuffer[g_vertexIndex + 2];
}
void DrawSplit(const VertexBufferSplit& split)
{
Emulator_SetTexture(split.textureId, split.texFormat);
Emulator_SetBlendMode(split.blendMode);
Emulator_DrawTriangles(split.vIndex, split.vCount / 3);
}
//
// Draws all polygons after AggregatePTAG
//
void DrawAggregatedSplits()
{
if (g_emulatorPaused)
{
for (int i = 0; i < 3; i++)
{
struct Vertex* vert = &g_vertexBuffer[g_polygonSelected + i];
vert->r = 255;
vert->g = 0;
vert->b = 0;
eprintf("==========================================\n");
eprintf("POLYGON: %d\n", i);
eprintf("X: %d Y: %d\n", vert->x, vert->y);
eprintf("U: %d V: %d\n", vert->u, vert->v);
eprintf("TP: %d CLT: %d\n", vert->page, vert->clut);
eprintf("==========================================\n");
}
Emulator_UpdateInput();
}
// next code ideally should be called before EndScene
Emulator_UpdateVertexBuffer(g_vertexBuffer, g_vertexIndex);
for (int i = 1; i <= g_splitIndex; i++)
DrawSplit(g_splits[i]);
ClearVBO();
#ifdef PGXP
PGXP_ClearCache();
#endif
}
// forward declarations
int ParsePrimitive(uintptr_t primPtr);
int ParseLinkedPrimitiveList(uintptr_t packetStart, uintptr_t packetEnd);
void AggregatePTAGsToSplits(u_long* p, bool singlePrimitive)
{
if (!p)
return;
if (singlePrimitive)
{
#ifdef PGXP
P_TAG* pTag = (P_TAG*)p;
pTag->pgxp_index = 0xFFFF; // force
#endif
// single primitive
ParsePrimitive((uintptr_t)p);
g_splits[g_splitIndex].vCount = g_vertexIndex - g_splits[g_splitIndex].vIndex;
}
else
{
P_TAG* pTag = (P_TAG*)p;
// P_TAG as primitive list
//do
while ((uintptr_t)pTag != (uintptr_t)&terminator)
{
if (pTag->len > 0)
{
int lastSize = ParseLinkedPrimitiveList((uintptr_t)pTag, (uintptr_t)pTag + (uintptr_t)(pTag->len * 4) + 4 + LEN_OFFSET);
if (lastSize == -1)
break; // safe bailout
}
pTag = (P_TAG*)pTag->addr;
}
}
}
//------------------------------------------------------------------
void DrawOTagEnv(u_long* p, DRAWENV* env)
{
do
{
PutDrawEnv(env);
DrawOTag(p);
} while (g_emulatorPaused);
}
void DrawOTag(u_long* p)
{
if (Emulator_BeginScene())
{
ClearVBO();
ResetPolyState();
}
#if defined(DEBUG_POLY_COUNT)
polygon_count = 0;
#endif
if (activeDrawEnv.isbg)
{
ClearImage(&activeDrawEnv.clip, activeDrawEnv.r0, activeDrawEnv.g0, activeDrawEnv.b0);
}
else
{
Emulator_BlitVRAM();
}
AggregatePTAGsToSplits(p, false);
DrawAggregatedSplits();
Emulator_EndScene();
}
void DrawPrim(void* p)
{
if (Emulator_BeginScene())
{
ClearVBO();
ResetPolyState();
}
#if defined(DEBUG_POLY_COUNT)
polygon_count = 0;
#endif
if (activeDrawEnv.isbg)
{
ClearImage(&activeDrawEnv.clip, activeDrawEnv.r0, activeDrawEnv.g0, activeDrawEnv.b0);
}
else {
Emulator_BlitVRAM();
}
AggregatePTAGsToSplits((u_long*)p, true);
}
// parses primitive and pushes it to VBO
// returns primitive size
// -1 means invalid primitive
int ParsePrimitive(uintptr_t primPtr)
{
P_TAG* pTag = (P_TAG*)primPtr;
int textured = (pTag->code & 0x4) != 0;
int blend_mode = 0;
if (textured)
{
if ((pTag->code & 0x1) != 0)
{
blend_mode = 2;
}
else
{
blend_mode = 1;
}
}
else
{
blend_mode = 0;
}
bool semi_transparent = (pTag->code & 2) != 0;
int primitive_size = -1; // -1
#ifdef PGXP
unsigned short gte_index = pTag->pgxp_index;
#else
unsigned short gte_index = 0xFFFF;
#endif
switch (pTag->code & ~3)
{
case 0x0:
{
primitive_size = 4;
break;
}
case 0x20:
{
POLY_F3* poly = (POLY_F3*)pTag;
AddSplit(semi_transparent, activeDrawEnv.tpage, whiteTexture);
Emulator_GenerateVertexArrayTriangle(&g_vertexBuffer[g_vertexIndex], &poly->x0, &poly->x1, &poly->x2, gte_index);
Emulator_GenerateTexcoordArrayTriangleZero(&g_vertexBuffer[g_vertexIndex], 0);
Emulator_GenerateColourArrayTriangle(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0, &poly->r0);
g_vertexIndex += 3;
primitive_size = sizeof(POLY_F3);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x24:
{
POLY_FT3* poly = (POLY_FT3*)pTag;
activeDrawEnv.tpage = poly->tpage;
AddSplit(semi_transparent, poly->tpage, vramTexture);
Emulator_GenerateVertexArrayTriangle(&g_vertexBuffer[g_vertexIndex], &poly->x0, &poly->x1, &poly->x2, gte_index);
Emulator_GenerateTexcoordArrayTriangle(&g_vertexBuffer[g_vertexIndex], &poly->u0, &poly->u1, &poly->u2, poly->tpage, poly->clut, GET_TPAGE_DITHER(lastTpage));
Emulator_GenerateColourArrayTriangle(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0, &poly->r0);
g_vertexIndex += 3;
primitive_size = sizeof(POLY_FT3);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x28:
{
POLY_F4* poly = (POLY_F4*)pTag;
AddSplit(semi_transparent, activeDrawEnv.tpage, whiteTexture);
Emulator_GenerateVertexArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->x0, &poly->x1, &poly->x3, &poly->x2, gte_index);
Emulator_GenerateTexcoordArrayQuadZero(&g_vertexBuffer[g_vertexIndex], 0);
Emulator_GenerateColourArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0, &poly->r0, &poly->r0);
MakeTriangle();
g_vertexIndex += 6;
primitive_size = sizeof(POLY_F4);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x2C:
{
POLY_FT4* poly = (POLY_FT4*)pTag;
activeDrawEnv.tpage = poly->tpage;
AddSplit(semi_transparent, poly->tpage, vramTexture);
Emulator_GenerateVertexArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->x0, &poly->x1, &poly->x3, &poly->x2, gte_index);
Emulator_GenerateTexcoordArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->u0, &poly->u1, &poly->u3, &poly->u2, poly->tpage, poly->clut, GET_TPAGE_DITHER(lastTpage));
Emulator_GenerateColourArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0, &poly->r0, &poly->r0);
MakeTriangle();
g_vertexIndex += 6;
primitive_size = sizeof(POLY_FT4);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x30:
{
POLY_G3* poly = (POLY_G3*)pTag;
AddSplit(semi_transparent, activeDrawEnv.tpage, whiteTexture);
Emulator_GenerateVertexArrayTriangle(&g_vertexBuffer[g_vertexIndex], &poly->x0, &poly->x1, &poly->x2, gte_index);
Emulator_GenerateTexcoordArrayTriangleZero(&g_vertexBuffer[g_vertexIndex], 1);
Emulator_GenerateColourArrayTriangle(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r1, &poly->r2);
g_vertexIndex += 3;
primitive_size = sizeof(POLY_G3);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x34:
{
POLY_GT3* poly = (POLY_GT3*)pTag;
activeDrawEnv.tpage = poly->tpage;
AddSplit(semi_transparent, poly->tpage, vramTexture);
Emulator_GenerateVertexArrayTriangle(&g_vertexBuffer[g_vertexIndex], &poly->x0, &poly->x1, &poly->x2, gte_index);
Emulator_GenerateTexcoordArrayTriangle(&g_vertexBuffer[g_vertexIndex], &poly->u0, &poly->u1, &poly->u2, poly->tpage, poly->clut, GET_TPAGE_DITHER(lastTpage));
Emulator_GenerateColourArrayTriangle(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r1, &poly->r2);
g_vertexIndex += 3;
primitive_size = sizeof(POLY_GT3);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x38:
{
POLY_G4* poly = (POLY_G4*)pTag;
AddSplit(semi_transparent, activeDrawEnv.tpage, whiteTexture);
Emulator_GenerateVertexArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->x0, &poly->x1, &poly->x3, &poly->x2, gte_index);
Emulator_GenerateTexcoordArrayQuadZero(&g_vertexBuffer[g_vertexIndex], 1);
Emulator_GenerateColourArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r1, &poly->r3, &poly->r2);
MakeTriangle();
g_vertexIndex += 6;
primitive_size = sizeof(POLY_G4);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x3C:
{
POLY_GT4* poly = (POLY_GT4*)pTag;
activeDrawEnv.tpage = poly->tpage;
AddSplit(semi_transparent, poly->tpage, vramTexture);
Emulator_GenerateVertexArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->x0, &poly->x1, &poly->x3, &poly->x2, gte_index);
Emulator_GenerateTexcoordArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->u0, &poly->u1, &poly->u3, &poly->u2, poly->tpage, poly->clut, GET_TPAGE_DITHER(lastTpage));
Emulator_GenerateColourArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r1, &poly->r3, &poly->r2);
MakeTriangle();
g_vertexIndex += 6;
primitive_size = sizeof(POLY_GT4);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x40:
{
LINE_F2* poly = (LINE_F2*)pTag;
AddSplit(semi_transparent, activeDrawEnv.tpage, whiteTexture);
Emulator_GenerateLineArray(&g_vertexBuffer[g_vertexIndex], &poly->x0, &poly->x1, gte_index);
Emulator_GenerateTexcoordArrayLineZero(&g_vertexBuffer[g_vertexIndex], 0);
Emulator_GenerateColourArrayLine(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0);
MakeTriangle();
g_vertexIndex += 6;
primitive_size = sizeof(LINE_F2);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x48: // TODO (unused)
{
LINE_F3* poly = (LINE_F3*)pTag;
AddSplit(semi_transparent, activeDrawEnv.tpage, whiteTexture);
{
Emulator_GenerateLineArray(&g_vertexBuffer[g_vertexIndex], &poly->x0, &poly->x1, gte_index);
Emulator_GenerateTexcoordArrayLineZero(&g_vertexBuffer[g_vertexIndex], 0);
Emulator_GenerateColourArrayLine(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0);
MakeTriangle();
g_vertexIndex += 6;
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
}
{
Emulator_GenerateLineArray(&g_vertexBuffer[g_vertexIndex], &poly->x1, &poly->x2, gte_index);
Emulator_GenerateTexcoordArrayLineZero(&g_vertexBuffer[g_vertexIndex], 0);
Emulator_GenerateColourArrayLine(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0);
MakeTriangle();
g_vertexIndex += 6;
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
}
primitive_size = sizeof(LINE_F3);
break;
}
case 0x4c:
{
LINE_F4* poly = (LINE_F4*)pTag;
AddSplit(semi_transparent, activeDrawEnv.tpage, whiteTexture);
{
Emulator_GenerateLineArray(&g_vertexBuffer[g_vertexIndex], &poly->x0, &poly->x1, gte_index);
Emulator_GenerateTexcoordArrayLineZero(&g_vertexBuffer[g_vertexIndex], 0);
Emulator_GenerateColourArrayLine(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0);
MakeTriangle();
g_vertexIndex += 6;
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
}
{
Emulator_GenerateLineArray(&g_vertexBuffer[g_vertexIndex], &poly->x1, &poly->x2, gte_index);
Emulator_GenerateTexcoordArrayLineZero(&g_vertexBuffer[g_vertexIndex], 0);
Emulator_GenerateColourArrayLine(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0);
MakeTriangle();
g_vertexIndex += 6;
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
}
{
Emulator_GenerateLineArray(&g_vertexBuffer[g_vertexIndex], &poly->x2, &poly->x3, gte_index);
Emulator_GenerateTexcoordArrayLineZero(&g_vertexBuffer[g_vertexIndex], 0);
Emulator_GenerateColourArrayLine(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0);
MakeTriangle();
g_vertexIndex += 6;
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
}
primitive_size = sizeof(LINE_F2);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
// TODO: unsupported
primitive_size = sizeof(LINE_F4);
break;
}
case 0x50:
{
LINE_G2* poly = (LINE_G2*)pTag;
AddSplit(semi_transparent, activeDrawEnv.tpage, whiteTexture);
Emulator_GenerateLineArray(&g_vertexBuffer[g_vertexIndex], &poly->x0, &poly->x1, gte_index);
Emulator_GenerateTexcoordArrayLineZero(&g_vertexBuffer[g_vertexIndex], 0);
Emulator_GenerateColourArrayLine(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r1);
MakeTriangle();
g_vertexIndex += 6;
primitive_size = sizeof(LINE_G2);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x60:
{
TILE* poly = (TILE*)pTag;
AddSplit(semi_transparent, activeDrawEnv.tpage, whiteTexture);
Emulator_GenerateVertexArrayRect(&g_vertexBuffer[g_vertexIndex], &poly->x0, poly->w, poly->h, gte_index);
Emulator_GenerateTexcoordArrayQuadZero(&g_vertexBuffer[g_vertexIndex], 0);
Emulator_GenerateColourArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0, &poly->r0, &poly->r0);
MakeTriangle();
g_vertexIndex += 6;
primitive_size = sizeof(TILE);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x64:
{
SPRT* poly = (SPRT*)pTag;
AddSplit(semi_transparent, activeDrawEnv.tpage, vramTexture);
Emulator_GenerateVertexArrayRect(&g_vertexBuffer[g_vertexIndex], &poly->x0, poly->w, poly->h, gte_index);
Emulator_GenerateTexcoordArrayRect(&g_vertexBuffer[g_vertexIndex], &poly->u0, activeDrawEnv.tpage, poly->clut, poly->w, poly->h);
Emulator_GenerateColourArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0, &poly->r0, &poly->r0);
MakeTriangle();
g_vertexIndex += 6;
primitive_size = sizeof(SPRT);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x68:
{
TILE_1* poly = (TILE_1*)pTag;
AddSplit(semi_transparent, activeDrawEnv.tpage, whiteTexture);
Emulator_GenerateVertexArrayRect(&g_vertexBuffer[g_vertexIndex], &poly->x0, 1, 1, gte_index);
Emulator_GenerateTexcoordArrayQuadZero(&g_vertexBuffer[g_vertexIndex], 0);
Emulator_GenerateColourArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0, &poly->r0, &poly->r0);
MakeTriangle();
g_vertexIndex += 6;
primitive_size = sizeof(TILE_1);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x70:
{
TILE_8* poly = (TILE_8*)pTag;
AddSplit(semi_transparent, activeDrawEnv.tpage, whiteTexture);
Emulator_GenerateVertexArrayRect(&g_vertexBuffer[g_vertexIndex], &poly->x0, 8, 8, gte_index);
Emulator_GenerateTexcoordArrayQuadZero(&g_vertexBuffer[g_vertexIndex], 0);
Emulator_GenerateColourArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0, &poly->r0, &poly->r0);
MakeTriangle();
g_vertexIndex += 6;
primitive_size = sizeof(TILE_8);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x74:
{
SPRT_8* poly = (SPRT_8*)pTag;
AddSplit(semi_transparent, activeDrawEnv.tpage, vramTexture);
Emulator_GenerateVertexArrayRect(&g_vertexBuffer[g_vertexIndex], &poly->x0, 8, 8, gte_index);
Emulator_GenerateTexcoordArrayRect(&g_vertexBuffer[g_vertexIndex], &poly->u0, activeDrawEnv.tpage, poly->clut, 8, 8);
Emulator_GenerateColourArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0, &poly->r0, &poly->r0);
MakeTriangle();
g_vertexIndex += 6;
primitive_size = sizeof(SPRT_8);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x78:
{
TILE_16* poly = (TILE_16*)pTag;
AddSplit(semi_transparent, activeDrawEnv.tpage, whiteTexture);
Emulator_GenerateVertexArrayRect(&g_vertexBuffer[g_vertexIndex], &poly->x0, 16, 16, gte_index);
Emulator_GenerateTexcoordArrayQuadZero(&g_vertexBuffer[g_vertexIndex], 0);
Emulator_GenerateColourArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0, &poly->r0, &poly->r0);
MakeTriangle();
g_vertexIndex += 6;
primitive_size = sizeof(TILE_16);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0x7C:
{
SPRT_16* poly = (SPRT_16*)pTag;
AddSplit(semi_transparent, activeDrawEnv.tpage, vramTexture);
Emulator_GenerateVertexArrayRect(&g_vertexBuffer[g_vertexIndex], &poly->x0, 16, 16, gte_index);
Emulator_GenerateTexcoordArrayRect(&g_vertexBuffer[g_vertexIndex], &poly->u0, activeDrawEnv.tpage, poly->clut, 16, 16);
Emulator_GenerateColourArrayQuad(&g_vertexBuffer[g_vertexIndex], &poly->r0, &poly->r0, &poly->r0, &poly->r0);
MakeTriangle();
g_vertexIndex += 6;
primitive_size = sizeof(SPRT_16);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
case 0xE0:
{
switch (pTag->code)
{
case 0xE1:
{
#if defined(USE_32_BIT_ADDR)
unsigned short tpage = ((unsigned short*)pTag)[4];
#else
unsigned short tpage = ((unsigned short*)pTag)[2];
#endif
//if (tpage != 0)
{
activeDrawEnv.tpage = tpage;
}
primitive_size = sizeof(DR_TPAGE);
#if defined(DEBUG_POLY_COUNT)
polygon_count++;
#endif
break;
}
default:
{
eprinterr("Primitive type error");
assert(FALSE);
break;
}
}
break;
}
case 0x80: {
eprinterr("DR_MOVE unimplemented\n");
primitive_size = sizeof(DR_MOVE);
break;
}
default:
{
//Unhandled poly type
eprinterr("Unhandled primitive type: %02X type2:%02X\n", pTag->code, pTag->code & ~3);
break;
}
}
return primitive_size;
}
int ParseLinkedPrimitiveList(uintptr_t packetStart, uintptr_t packetEnd)
{
uintptr_t currentAddress = packetStart;
int lastSize = -1;
while (currentAddress != packetEnd)
{
lastSize = ParsePrimitive(currentAddress);
if (lastSize == -1) // not valid packets submitted
break;
currentAddress += lastSize;
}
g_splits[g_splitIndex].vCount = g_vertexIndex - g_splits[g_splitIndex].vIndex;
return lastSize;
}
void SetSprt16(SPRT_16* p)
{
setSprt16(p);
}
void SetSprt8(SPRT_8* p)
{
setSprt8(p);
}
void SetTile(TILE* p)
{
setTile(p);
}
void SetPolyGT4(POLY_GT4* p)
{
setPolyGT4(p);
}
void SetSemiTrans(void* p, int abe)
{
setSemiTrans(p, abe);
}
void SetShadeTex(void* p, int tge)
{
setShadeTex(p, tge);
}
void SetSprt(SPRT* p)
{
setSprt(p);
}
void SetDumpFnt(int id)
{
UNIMPLEMENTED();
}
void SetLineF3(LINE_F3* p)
{
setLineF3(p);
}
void FntLoad(int tx, int ty)
{
UNIMPLEMENTED();
}
void AddPrim(void* ot, void* p)
{
addPrim(ot, p);
}
void AddPrims(void* ot, void* p0, void* p1)
{
addPrims(ot, p0, p1);
}
void CatPrim(void* p0, void* p1)
{
catPrim(p0, p1);
}
u_short LoadTPage(u_long* pix, int tp, int abr, int x, int y, int w, int h)
{
RECT16 imageArea;
imageArea.x = x;
imageArea.y = y;
imageArea.h = h;
enum
{
TP_4BIT,
TP_8BIT,
TP_16BIT
};
switch (tp)
{
case TP_4BIT:
{
//loc_278
if (w >= 0)
{
imageArea.w = w >> 2;
}
else
{
imageArea.w = (w + 3) >> 2;
}
break;
}
case TP_8BIT:
{
//loc_290
imageArea.w = (w + (w >> 31)) >> 1;
break;
}
case TP_16BIT:
{
//loc_2A4
imageArea.w = w;
break;
}
}
//loc_2AC
LoadImagePSX(&imageArea, pix);
return GetTPage(tp, abr, x, y) & 0xFFFF;
}
u_short GetTPage(int tp, int abr, int x, int y)
{
return getTPage(tp, abr, x, y);
}
u_short LoadClut(u_long* clut, int x, int y)
{
RECT16 rect;//&var_18
setRECT16(&rect, x, y, 256, 1);
LoadImagePSX(&rect, clut);
return GetClut(x, y) & 0xFFFF;
}
u_short LoadClut2(u_long* clut, int x, int y)
{
RECT16 drawArea;
drawArea.x = x;
drawArea.y = y;
drawArea.w = 16;
drawArea.h = 1;
LoadImagePSX(&drawArea, clut);
return getClut(x, y);
}
u_long* KanjiFntFlush(int id)
{
UNIMPLEMENTED();
return 0;
}
u_long* FntFlush(int id)
{
UNIMPLEMENTED();
return 0;
}
int KanjiFntOpen(int x, int y, int w, int h, int dx, int dy, int cx, int cy, int isbg, int n)
{
UNIMPLEMENTED();
return 0;
}
int FntOpen(int x, int y, int w, int h, int isbg, int n)
{
UNIMPLEMENTED();
return 0;
}
void SetPolyF4(POLY_F4* p)
{
setPolyF4(p);
}
void SetPolyFT4(POLY_FT4* p)
{
setPolyFT4(p);
}
void SetPolyG4(POLY_G4* p)
{
setPolyG4(p);
}
void TermPrim(void* p)
{
termPrim(p);
}