Path: blob/master/psx/octoshock/test/miniclient/miniclient.cpp
2 views
#include <stdio.h>12#include "octoshock.h"3#include "psx/psx.h"45// lookup table for crc calculation6static uint16 subq_crctab[256] =7{80x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108,90x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210,100x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B,110xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401,120x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE,130xF5CF, 0xC5AC, 0xD58D, 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6,140x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D,150xC7BC, 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,160xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0x5AF5,170x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC,180xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4,190x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD,200xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13,210x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A,220x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E,230xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,240x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1,250x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB,260x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0,270x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8,280xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657,290x7676, 0x4615, 0x5634, 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9,300xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882,310x28A3, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,320x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 0xFD2E,330xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07,340x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D,350xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74,360x2E93, 0x3EB2, 0x0ED1, 0x1EF037};3839#ifndef __PACKED40#ifdef __GNUC__41#define __PACKED __attribute__((__packed__))42#else43#define __PACKED44#endif45#endif4647#ifndef __GNUC__48#pragma pack(push, 1)49#pragma warning(disable : 4103)50#endif51struct bmpimgheader_struct52{53u32 size;54s32 width;55s32 height;56u16 planes;57u16 bpp;58u32 cmptype;59u32 imgsize;60s32 hppm;61s32 vppm;62u32 numcol;63u32 numimpcol;64} ;65struct bmpfileheader_struct66{67u16 id __PACKED;68u32 size __PACKED;69u16 reserved1 __PACKED;70u16 reserved2 __PACKED;71u32 imgoffset __PACKED;72};73#ifndef __GNUC__74#pragma pack(pop)75#endif7677int WriteBMP32(int width, int height, const void* buf, const char *filename)78{79bmpfileheader_struct fileheader;80bmpimgheader_struct imageheader;81FILE *file;82size_t elems_written = 0;83memset(&fileheader, 0, sizeof(fileheader));84fileheader.size = sizeof(fileheader);85fileheader.id = 'B' | ('M' << 8);86fileheader.imgoffset = sizeof(fileheader)+sizeof(imageheader);8788memset(&imageheader, 0, sizeof(imageheader));89imageheader.size = sizeof(imageheader);90imageheader.width = width;91imageheader.height = height;92imageheader.planes = 1;93imageheader.bpp = 32;94imageheader.cmptype = 0; // None95imageheader.imgsize = imageheader.width * imageheader.height * 4;9697if ((file = fopen(filename,"wb")) == NULL)98return 0;99100elems_written += fwrite(&fileheader, 1, sizeof(fileheader), file);101elems_written += fwrite(&imageheader, 1, sizeof(imageheader), file);102103for(int i=0;i<height;i++)104for(int x=0;x<width;x++)105{106u8* pixel = (u8*)buf + (height-i-1)*width*4;107pixel += (x*4);108elems_written += fwrite(pixel+2,1,1,file);109elems_written += fwrite(pixel+1,1,1,file);110elems_written += fwrite(pixel+0,1,1,file);111elems_written += fwrite(pixel+3,1,1,file);112}113fclose(file);114115return 1;116}117118class BinReader2352119{120public:121BinReader2352(const char* path)122{123inf = fopen(path,"rb");124fseek(inf,0,SEEK_END);125size_t sz = ftell(inf);126fseek(inf,0,SEEK_SET);127lbaCount = (int)(sz/2352);128129shock_CreateDisc(&disc,this,lbaCount,s_ReadTOC,s_ReadLBA2448,false);130}131132ShockDiscRef* disc;133134static s32 s_ReadTOC(void* opaque, ShockTOC *read_target, ShockTOCTrack tracks[100 + 1]) { return ((BinReader2352*)opaque)->ReadTOC(read_target, tracks); }135static s32 s_ReadLBA2448(void* opaque, s32 lba, void* dst) { return ((BinReader2352*)opaque)->ReadLBA2448(lba,dst); }136137~BinReader2352()138{139fclose(inf);140shock_DestroyDisc(disc);141}142143private:144int lbaCount;145FILE* inf;146147148union Sector {149struct {150u8 sync[12];151u8 adr[3];152u8 mode;153union {154struct {155u8 data2048[2048];156u8 ecc[4];157u8 reserved[8];158u8 ecm[276];159};160u8 data2336[2336];161};162};163u8 buf[2352];164};165166union XASector {167struct {168u8 sync[12];169u8 adr[3];170u8 mode;171u8 subheader[8];172union {173u8 data2048[2048];174u8 ecc[4];175u8 ecm[276];176} form1;177union {178u8 data2334[2334];179u8 ecc[4];180} form2;181};182u8 buf[2352];183};184185union {186XASector xasector;187Sector sector;188};189190191s32 ReadTOC( ShockTOC *read_target, ShockTOCTrack tracks[100 + 1])192{193memset(read_target,0,sizeof(*read_target));194read_target->disc_type = 0;195read_target->first_track = 1;196read_target->last_track = 1;197tracks[1].adr = 1;198tracks[1].lba = 0;199tracks[1].control = 4;200tracks[2].adr = 1;201tracks[2].lba = lbaCount;202tracks[2].control = 0;203tracks[100].adr = 1;204tracks[100].lba = lbaCount;205tracks[100].control = 0;206return SHOCK_OK;207}208209s32 ReadLBA2448(s32 lba, void* dst)210{211fseek(inf,lba*2352,SEEK_SET);212fread(dst,1,2352,inf);213//do something for subcode I guess214memset((u8*)dst+2352,0,96);215hacky_MakeSubPQ(lba,(u8*)dst+2352,1,0);216217//not the right thing to do218//return ((Sector*)dst)->mode;219220return SHOCK_OK;221}222223uint8 U8_to_BCD(uint8 num)224{225return( ((num / 10) << 4) + (num % 10) );226}227228void subq_generate_checksum(uint8 *buf)229{230uint16 crc = 0;231232for(int i = 0; i < 0xA; i++)233crc = subq_crctab[(crc >> 8) ^ buf[i]] ^ (crc << 8);234235// Checksum236buf[0xa] = ~(crc >> 8);237buf[0xb] = ~(crc);238}239void hacky_MakeSubPQ(int lba, u8* SubPWBuf, int track, int track_start)240{241uint8 buf[0xC];242uint32 lba_relative;243uint32 ma, sa, fa;244uint32 m, s, f;245uint8 pause_or = 0x00;246247lba_relative = abs((int32)lba - track_start);248249f = (lba_relative % 75);250s = ((lba_relative / 75) % 60);251m = (lba_relative / 75 / 60);252253fa = (lba + 150) % 75;254sa = ((lba + 150) / 75) % 60;255ma = ((lba + 150) / 75 / 60);256257uint8 adr = 0x1; // Q channel data encodes position258259memset(buf, 0, 0xC);260buf[0] = (adr << 0) | (0x04 << 4);261buf[1] = U8_to_BCD(track);262263buf[2] = U8_to_BCD(0x01);264265// Track relative MSF address266buf[3] = U8_to_BCD(m);267buf[4] = U8_to_BCD(s);268buf[5] = U8_to_BCD(f);269270buf[6] = 0; // Zerroooo271272// Absolute MSF address273buf[7] = U8_to_BCD(ma);274buf[8] = U8_to_BCD(sa);275buf[9] = U8_to_BCD(fa);276277subq_generate_checksum(buf);278279for(int i = 0; i < 96; i++)280SubPWBuf[i] |= (((buf[i >> 3] >> (7 - (i & 0x7))) & 1) ? 0x40 : 0x00) | pause_or;281}282283284};285286int main(int argc, char **argv)287{288const char* fwpath = argv[1];289const char* discpath = argv[2];290const char* outdir = argv[3];291292FILE* inf;293294//load up the firmware295char firmware[512*1024];296inf = fopen(fwpath,"rb");297fread(firmware,1,512*1024,inf);298fclose(inf);299300BinReader2352 bin(discpath);301ShockDiscInfo info;302shock_AnalyzeDisc(bin.disc, &info);303printf("disc id: %s\n",info.id);304305//placeholder for instance306void* psx = NULL;307308shock_Create(&psx, REGION_NA, firmware);309shock_OpenTray(psx);310shock_SetDisc(psx,bin.disc);311shock_CloseTray(psx);312shock_Peripheral_Connect(psx,0x01,ePeripheralType_DualShock);313shock_PowerOn(psx);314315int framectr = 0;316for(;;)317{318printf("frame %d\n",framectr);319shock_Step(psx,eShockStep_Frame);320if(framectr%60==0)321{322//dump a screen grab323ShockFramebufferInfo fbinfo;324static u32 buf[1024*1024];325fbinfo.ptr = buf;326fbinfo.flags = eShockFramebufferFlags_Normalize;327shock_GetFramebuffer(psx,&fbinfo);328char fname[128];329sprintf(fname,"%s\\test%03d.bmp",outdir,framectr/60);330WriteBMP32(fbinfo.width,fbinfo.height,buf,fname); //rgb is backwards331}332333framectr++;334}335}336337