- Fixed MP3 play bug on the psp. MP3 files need to have NO Id3v2 tag, or they won't play. Also, volume control is broken
- added dt to moving W's easter egg movement.
- Added fullscreen for windows version
- other stuff ?
This commit is contained in:
wagic.the.homebrew
2008-11-19 12:21:23 +00:00
parent 2434571fa2
commit 349de34106
27 changed files with 1270 additions and 1012 deletions

View File

@@ -12,7 +12,7 @@ OBJS = src/JApp.o src/JGBKFont.o \
src/tinyxml/tinystr.o src/tinyxml/tinyxml.o \
src/tinyxml/tinyxmlparser.o src/tinyxml/tinyxmlerror.o \
src/main.o src/vram.o \
src/JAudio.o src/JCooleyesMP3.o \
src/JAudio.o src/JMP3.o \
src/decoder_prx.o \
src/Encoding.o src/JTTFont.o \
src/JMD2Model.o src/JOBJModel.o \
@@ -23,7 +23,7 @@ LIBDIR = lib/psp
CFLAGS = -O2 -G0 -Wall -DDEVHOOK -DPSPFW3XX
LIBS = -lgif -lfreetype -ljpeg -lpng -lz -lmikmod -lpsppower -lpspmpeg -lpspaudiocodec -lpspaudiolib -lpspaudio -lpspgum -lpspgu -lpsprtc -lm -lstdc++
LIBS = -lgif -lfreetype -ljpeg -lpng -lz -lmikmod -lpsppower -lpspmpeg -lpspaudiocodec -lpspaudiolib -lpspaudio -lpspmp3 -lpspgum -lpspgu -lpsprtc -lm -lstdc++
include $(PSPSDK)/lib/build.mak

View File

@@ -73,15 +73,15 @@ void setChannelFlag(int channel, int flag);
#define SAMPLE_PER_FRAME 1152
#define MAX_MP3_FILE 2
class JCooleyesMP3;
class JMP3;
void PlayMP3(JCooleyesMP3 *mp3, bool looping = false);
void PlayMP3(JMP3 *mp3, bool looping = false);
void StopMP3();
void ResumeMP3();
bool InitMP3Decoder();
void ResumeMP3(JMP3 *mp3);
void ReleaseMP3Decoder();
void MP3AudioOutCallback(void* buf, unsigned int length, void *userdata);
int decodeThread2(SceSize args, void *argp);
extern bool g_MP3DecoderOK;
#endif

59
JGE/include/JMP3.h Normal file
View File

@@ -0,0 +1,59 @@
//-------------------------------------------------------------------------------------
//
// JGE is a hardware accelerated 2D game SDK for PSP/Windows.
//
// Licensed under the BSD license, see LICENSE in JGE root for details.
//
// Copyright (c) 2007 James Hui (a.k.a. Dr.Watson) <jhkhui@gmail.com>
// Copyright (c) 2008 Alexander Berl <raphael@fx-world.org>
// Copyright (c) 2008 WilLoW :--) <wagic.the.homebrew@gmail.com>
//
//-------------------------------------------------------------------------------------
#ifndef _JMP3_
#define _JMP3_
#include <string>
class JMP3
{
protected:
static bool loadModules();
int m_volume;
int m_samplesPlayed;
int m_inBufferSize, m_outBufferSize;
char m_inBuffer[16*1024]; // ?
short m_outBuffer[16*(1152/2)]; //?
int m_numChannels;
int m_samplingRate;
bool m_loop;
int m_lastDecoded;
int m_playTime;
public:
int m_paused;
int m_channel;
int m_mp3Handle;
int m_fileHandle;
static JMP3* mInstance;
JMP3(const std::string& filename, int inBufferSize= 16*1024, int outBufferSize =16*(1152/2));
~JMP3();
static void init();
bool fillBuffers();
bool load(const std::string& filename, int inBufferSize, int outBufferSize);
bool unload();
bool update();
bool play();
bool pause();
bool setLoop(bool loop);
int setVolume(int volume);
int playTime() const;
int playTimeMinutes();
int playTimeSeconds();
};
#endif

View File

@@ -36,7 +36,7 @@
#include <psprtc.h>
#include "JAudio.h"
#include "JCooleyesMP3.h"
#include "JMP3.h"
#endif
@@ -47,11 +47,12 @@ class JMusic
public:
JMusic();
~JMusic();
void Update();
#if defined (WIN32) || defined (LINUX)
FSOUND_SAMPLE *mTrack; // MP3 needed to be of "sample" type for FMOD, FMUSIC_MODULE is for MODs
#else
JCooleyesMP3* mTrack;
JMP3* mTrack;
#endif
};

View File

@@ -60,6 +60,7 @@
#define SCREEN_WIDTH_F 480.0f
#define SCREEN_HEIGHT_F 272.0f
#ifdef WIN32
// #define DEFAULT_BLEND BLEND_DEFAULT
// #define BLEND_OPTION_ADD BLEND_COLORADD

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -16,7 +16,7 @@
#include "../include/JGE.h"
#include "../include/JAudio.h"
#include "../include/JCooleyesMP3.h"
#include "../include/JMP3.h"
#include "../include/JFileSystem.h"
#include "../include/decoder_prx.h"
@@ -29,7 +29,7 @@ short g_DecodedDataOutputBuffer[SAMPLE_PER_FRAME<<2] __attribute__((aligned(64))
bool g_MP3DecoderOK = false;
bool g_GotEDRAM;
JCooleyesMP3* g_CurrentMP3;
JMP3* g_CurrentMP3;
//////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
@@ -38,7 +38,7 @@ WAVDATA currentWav[NUMBER_WAV_CHANNELS]; //
///////////////////////////////////////////////////////////////////
char loadWaveData(WAVDATA* p_wav, char* fileName, char memLoad) // WAVE加载, memLoad-是否加载至内
char loadWaveData(WAVDATA* p_wav, char* fileName, char memLoad) // WAVE加载, memLoad-是否加载至内磥E
{
JFileSystem* fileSystem = JFileSystem::GetInstance();
@@ -172,7 +172,7 @@ void releaseWaveData(WAVDATA* p_wav) // WAVE
}
///////////////////////////////////////////////////////////////////
void audioOutCallback(int channel, void* buf, unsigned int length) // 各通道回
void audioOutCallback(int channel, void* buf, unsigned int length) // 各通道回祦E
{
WAVDATA* p_wav = NULL;
memset(buf, 0, 4096);
@@ -387,122 +387,67 @@ void audioInit() //
memset(&currentWav[i], 0, sizeof(WAVDATA));
p_currentWav[i] = NULL;
}
pspAudioInit();
pspAudioSetChannelCallback(0, audioOutCallback_0, NULL);
pspAudioSetChannelCallback(1, audioOutCallback_1, NULL);
pspAudioSetChannelCallback(2, audioOutCallback_2, NULL);
//pspAudioSetChannelCallback(3, audioOutCallback_3, NULL);
pspAudioSetChannelCallback(3, MP3AudioOutCallback, NULL);
InitMP3Decoder();
JMP3::init();
}
void audioDestroy()
{
ReleaseMP3Decoder();
pspAudioEnd();
}
//////////////////////////////////////////////////////////////////////////
void MP3AudioOutCallback(void* buf, unsigned int length, void *userdata)
{
// PSP_NUM_AUDIO_SAMPLES is 1024, 16bit samples (short), 2 channels for stereo sound
memset(buf, 0, PSP_NUM_AUDIO_SAMPLES<<2);
if (g_CurrentMP3 != NULL)
g_CurrentMP3->FeedAudioData(buf, length);
}
int mp3thread = 0;
//////////////////////////////////////////////////////////////////////////
void PlayMP3(JCooleyesMP3 *mp3, bool looping)
void PlayMP3(JMP3 *mp3, bool looping)
{
if (g_MP3DecoderOK)
{
g_CurrentMP3 = mp3;
mp3->InitBuffers(g_MP3CodecBuffer, g_DecoderBuffer, g_DecodedDataOutputBuffer);
mp3->Play(looping);
}
if (mp3thread) StopMP3();
JMP3::mInstance = mp3;
mp3->setLoop(looping);
mp3->play();
mp3thread = sceKernelCreateThread("decodeThread2", decodeThread2, 0x12, 0xFA0, 0, 0);
printf("thread id : %i\n", mp3thread);
sceKernelStartThread(mp3thread, 0, NULL);
}
//////////////////////////////////////////////////////////////////////////
void StopMP3()
{
if (g_CurrentMP3 != NULL)
{
g_CurrentMP3->Stop();
}
printf("stop 1\n");
JMP3 * mp3 = JMP3::mInstance;
printf("stop 2\n");
if (mp3){
printf("stop 3\n");
mp3->pause();
printf("stop 4\n");
sceKernelWaitThreadEnd(mp3thread, NULL);
printf("stop 5\n");
sceKernelDeleteThread(mp3thread);
printf("stop 6\n");
mp3->unload();
printf("stop 7\n");
JMP3::mInstance = NULL;
mp3thread = 0;
}
printf("stop 8\n");
}
//////////////////////////////////////////////////////////////////////////
void ResumeMP3()
void ResumeMP3(JMP3 * mp3)
{
if (g_CurrentMP3 != NULL)
{
g_CurrentMP3->Resume();
}
mp3->play();
}
//////////////////////////////////////////////////////////////////////////
bool InitMP3Decoder()
{
int result;
// if (sceKernelDevkitVersion() == 0x01050001)
// {
// LoadStartModule("flash0:/kd/me_for_vsh.prx", PSP_MEMORY_PARTITION_KERNEL);
// LoadStartModule("flash0:/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL);
// }
// else
// {
// sceUtilityLoadAvModule(PSP_AV_MODULE_AVCODEC);
// }
// result = pspSdkLoadStartModule("flash0:/kd/me_for_vsh.prx", PSP_MEMORY_PARTITION_KERNEL);
// result = pspSdkLoadStartModule("flash0:/kd/videocodec.prx", PSP_MEMORY_PARTITION_KERNEL);
// result = pspSdkLoadStartModule("flash0:/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL);
// result = pspSdkLoadStartModule("flash0:/kd/mpegbase.prx", PSP_MEMORY_PARTITION_KERNEL);
// result = pspSdkLoadStartModule("flash0:/kd/mpeg_vsh.prx", PSP_MEMORY_PARTITION_USER);
//
// pspSdkFixupImports(result);
prx_static_init();
sceMpegInit();
memset(g_MP3CodecBuffer, 0, sizeof(g_MP3CodecBuffer));
if ( sceAudiocodecCheckNeedMem(g_MP3CodecBuffer, 0x1002) < 0 )
return false;
if ( sceAudiocodecGetEDRAM(g_MP3CodecBuffer, 0x1002) < 0 )
return false;
g_GotEDRAM = true;
if ( sceAudiocodecInit(g_MP3CodecBuffer, 0x1002) < 0 )
return false;
g_MP3DecoderOK = true;
return true;
}
//////////////////////////////////////////////////////////////////////////
void ReleaseMP3Decoder()
{
if ( g_GotEDRAM )
sceAudiocodecReleaseEDRAM(g_MP3CodecBuffer);
}
int decodeThread2(SceSize args, void *argp){
JMP3 * mp3 = NULL;
while((mp3 = JMP3::mInstance) && !mp3->m_paused){
mp3->update();
//sceKernelDelayThread(10000);
}
return 0;
}

233
JGE/src/JMP3.cpp Normal file
View File

@@ -0,0 +1,233 @@
#include <pspkernel.h>
#include <pspdebug.h>
#include <stdio.h>
#include <pspaudio.h>
#include <pspmp3.h>
#include <psputility.h>
#include "../include/JAudio.h"
#include "../include/JFileSystem.h"
#include "../include/JMP3.h"
JMP3* JMP3::mInstance = NULL;
void JMP3::init() {
loadModules();
}
JMP3::JMP3(const std::string& filename, int inBufferSize, int outBufferSize) :
m_volume(PSP_AUDIO_VOLUME_MAX), m_paused(true), m_samplesPlayed(0) {
load(filename, inBufferSize,outBufferSize);
}
JMP3::~JMP3() {
unload();
}
bool JMP3::loadModules() {
int loadAvCodec = sceUtilityLoadModule(PSP_MODULE_AV_AVCODEC);
if (loadAvCodec < 0) {
return false;
}
int loadMp3 = sceUtilityLoadModule(PSP_MODULE_AV_MP3);
if (loadMp3 < 0) {
return false;
}
return true;
}
bool JMP3::fillBuffers() {
SceUChar8* dest;
SceInt32 length;
SceInt32 pos;
int ret = sceMp3GetInfoToAddStreamData(m_mp3Handle, &dest, &length, &pos);
if (ret < 0)
return false;
if (sceIoLseek32(m_fileHandle, pos, SEEK_SET) < 0) {
return false;
}
int readLength = sceIoRead(m_fileHandle, dest, length);
if (readLength < 0)
return false;
ret = sceMp3NotifyAddStreamData(m_mp3Handle, readLength);
if (ret < 0)
return false;
return true;
}
bool JMP3::load(const std::string& filename, int inBufferSize, int outBufferSize) {
printf("load\n");
m_inBufferSize = inBufferSize;
printf("1\n");
//m_inBuffer = new char[m_inBufferSize];
//if (!m_inBuffer)
// return false;
m_outBufferSize = outBufferSize;
printf("2\n");
//m_outBuffer = new short[outBufferSize];
//if (!m_outBuffer)
// return false;
printf("3:%s\n",filename.c_str());
m_fileHandle = sceIoOpen(filename.c_str(), PSP_O_RDONLY, 0777);
if (m_fileHandle < 0)
return false;
printf("4\n");
int ret = sceMp3InitResource();
if (ret < 0)
return false;
SceMp3InitArg initArgs;
int fileSize = sceIoLseek32(m_fileHandle, 0, SEEK_END);
sceIoLseek32(m_fileHandle, 0, SEEK_SET);
unsigned char* testbuffer = new unsigned char[7456];
sceIoRead(m_fileHandle, testbuffer, 7456);
delete testbuffer;
initArgs.unk1 = 0;
initArgs.unk2 = 0;
initArgs.mp3StreamStart = 0;
initArgs.mp3StreamEnd = fileSize;
initArgs.mp3BufSize = m_inBufferSize;
initArgs.mp3Buf = (SceVoid*) m_inBuffer;
initArgs.pcmBufSize = m_outBufferSize;
initArgs.pcmBuf = (SceVoid*) m_outBuffer;
printf("5\n");
m_mp3Handle = sceMp3ReserveMp3Handle(&initArgs);
if (m_mp3Handle < 0)
return false;
// Alright we are all set up, let's fill the first buffer.
printf("5.5\n");
bool _filled= fillBuffers();
if (! _filled) return false;
printf("end = %i, bufsize = %i, outSize = %i\n", fileSize, m_inBufferSize, m_outBufferSize);
// Start this bitch up!
printf("6\n");
int start = sceMp3Init(m_mp3Handle);
if (start < 0)
return false;
printf("7\n");
m_numChannels = sceMp3GetMp3ChannelNum(m_mp3Handle);
printf("8\n");
m_samplingRate = sceMp3GetSamplingRate(m_mp3Handle);
return true;
}
bool JMP3::unload() {
printf("unload 1\n");
if (m_channel >= 0)
sceAudioSRCChRelease();
printf("unload 2\n");
sceMp3ReleaseMp3Handle(m_mp3Handle);
printf("unload 3\n");
sceMp3TermResource();
printf("unload 4\n");
sceIoClose(m_fileHandle);
printf("unload 5\n");
//delete[] m_inBuffer;
printf("unload 6\n");
//delete[] m_outBuffer;
printf("unload 7\n");
return true;
}
bool JMP3::update() {
if (!m_paused) {
if (sceMp3CheckStreamDataNeeded(m_mp3Handle) > 0) {
fillBuffers();
}
short* tempBuffer;
int numDecoded = 0;
while (true) {
numDecoded = sceMp3Decode(m_mp3Handle, &tempBuffer);
if (numDecoded > 0)
break;
int ret = sceMp3CheckStreamDataNeeded(m_mp3Handle);
if (ret <= 0)
break;
fillBuffers();
}
// Okay, let's see if we can't get something outputted :/
if (numDecoded == 0 || numDecoded == 0x80671402) {
sceMp3ResetPlayPosition(m_mp3Handle);
if (!m_loop)
m_paused = true;
m_samplesPlayed = 0;
} else {
if (m_channel < 0 || m_lastDecoded != numDecoded) {
if (m_channel >= 0)
sceAudioSRCChRelease();
m_channel = sceAudioSRCChReserve(numDecoded / (2 * m_numChannels), m_samplingRate, m_numChannels);
}
// Output
m_samplesPlayed += sceAudioSRCOutputBlocking(m_volume, tempBuffer);
m_playTime = (m_samplingRate > 0) ? (m_samplesPlayed / m_samplingRate) : 0;
}
}
return true;
}
bool JMP3::play() {
return (m_paused = false);
}
bool JMP3::pause() {
return (m_paused = true);
}
bool JMP3::setLoop(bool loop) {
sceMp3SetLoopNum(m_mp3Handle, (loop == true) ? -1 : 0);
return (m_loop = loop);
}
int JMP3::setVolume(int volume) {
return (m_volume = volume);
}
int JMP3::playTime() const {
return m_playTime;
}
int JMP3::playTimeMinutes() {
return m_playTime / 60;
}
int JMP3::playTimeSeconds() {
return m_playTime % 60;
}

View File

@@ -10,8 +10,9 @@
#include "../include/JSoundSystem.h"
#include "../include/JAudio.h"
#include "../include/JCooleyesMP3.h"
#include "../include/JMP3.h"
#include <string>
using std::string;
JMusic::JMusic()
{
@@ -26,6 +27,10 @@ JMusic::~JMusic()
delete mTrack;
}
void JMusic::Update(){
//if (mTrack) mTrack->update();
}
JSample::JSample()
{
mSample = NULL;
@@ -93,29 +98,17 @@ void JSoundSystem::DestroySoundSystem()
JMusic *JSoundSystem::LoadMusic(const char *fileName)
{
//char s[strlen(fileName)+1];
//strcpy(s, fileName);
string s = "Res/";
s.append(fileName);
JMusic *music = new JMusic();
if (music)
{
music->mTrack = new JCooleyesMP3();
if (music->mTrack)
music->mTrack->Load(fileName);
music->mTrack = new JMP3(s);
}
JMP3::mInstance = music->mTrack;
return music;
}
// void JSoundSystem::FreeMusic(JMusic *music)
// {
// if (music)
// {
// if (music->mTrack)
// delete music->mTrack;
//
// }
// }
JSample *JSoundSystem::LoadSample(const char *fileName)
{
@@ -132,30 +125,8 @@ JSample *JSoundSystem::LoadSample(const char *fileName)
return sample;
}
//
// void JSoundSystem::FreeMusic(JMusic *music)
// {
// if (music)
// {
// if (music->mTrack)
// {
// music->mTrack->Release();
// delete music->mTrack;
// }
// delete music;
// }
// }
// void JSoundSystem::FreeSample(JSample *sample)
// {
// if (sample)
// {
// releaseWaveData(sample->mSample);
// delete sample;
// }
// }
void JSoundSystem::PlayMusic(JMusic *music, bool looping)
{
@@ -174,8 +145,8 @@ void JSoundSystem::PlaySample(JSample *sample)
void JSoundSystem::SetVolume(int volume)
{
mVolume = volume;
JMP3 * mp3 = JMP3::mInstance;
if (mp3) mp3->setVolume(volume);
}
@@ -188,7 +159,7 @@ void JSoundSystem::StopMusic(JMusic *music)
void JSoundSystem::ResumeMusic(JMusic *music)
{
ResumeMP3();
ResumeMP3(music->mTrack);
}

View File

@@ -10,6 +10,8 @@
#ifdef WIN32
#pragma warning(disable : 4786)
extern int actualWidth;
extern int actualHeight;
#endif
#include "../../Dependencies/include/png.h"
@@ -192,13 +194,16 @@ void JRenderer::DestroyRenderer()
void JRenderer::BeginScene()
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity (); // Reset The Modelview Matrix
glLoadIdentity ();// Reset The Modelview Matrix
float scaleH = (float)actualHeight/SCREEN_HEIGHT_F;
float scaleW = (float)actualWidth/SCREEN_WIDTH_F;
glScalef(scaleW,scaleW,1.f);
}
void JRenderer::EndScene()
{
glFlush ();
}

View File

@@ -21,6 +21,9 @@ JMusic::JMusic()
}
void JMusic::Update(){
}
JMusic::~JMusic()
{
JSoundSystem::GetInstance()->StopMusic(this);

View File

@@ -10,7 +10,8 @@
* Visit My Site At nehe.gamedev.net
*/
int actualWidth;
int actualHeight;
#include <windows.h> // Header File For Windows
#include <gl\gl.h> // Header File For The OpenGL32 Library
@@ -42,6 +43,7 @@ HINSTANCE hInstance; // Holds The Instance Of The Application
bool active=TRUE; // Window Active Flag Set To TRUE By Default
bool fullscreen=FALSE; // Windowed Mode By Default
DWORD lastTickCount;
BOOL g_keys[256];
@@ -142,17 +144,20 @@ GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize Th
height=1; // Making Height Equal One
}
glViewport(0,0,width,height); // Reset The Current Viewport
actualWidth = width;
actualHeight = height;
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
glScissor(0, 0, width, height);
glViewport (0, 0, width, height); // Reset The Current Viewport
glMatrixMode (GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity (); // Reset The Projection Matrix
gluOrtho2D(0.0f, (float) width-1.0f, 0.0f, (float) height -1.0f);
// Calculate The Aspect Ratio Of The Window
gluPerspective(75.0f,(GLfloat)width/(GLfloat)height,0.5f,1000.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
glMatrixMode (GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity (); // Reset The Modelview Matrix
glDisable (GL_DEPTH_TEST);
}
int InitGL(GLvoid) // All Setup For OpenGL Goes Here
@@ -303,6 +308,11 @@ GLvoid KillGLWindow(GLvoid) // Properly Kill The Window
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
actualWidth = width;
actualHeight = height;
GLuint PixelFormat; // Holds The Results After Searching For A Match
WNDCLASS wc; // Windows Class Structure
DWORD dwExStyle; // Window Extended Style
@@ -373,6 +383,8 @@ BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscree
dwStyle= WS_OVERLAPPED | \
WS_CAPTION | \
WS_MINIMIZEBOX |
WS_SIZEBOX |
WS_MAXIMIZEBOX |
//WS_MINIMIZE |
WS_SYSMENU;// | \
//WS_THICKFRAME ;
@@ -565,6 +577,7 @@ LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window
case WM_SIZE: // Resize The OpenGL Window
{
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height
return 0; // Jump Back
}

View File

@@ -13,7 +13,7 @@ ASFLAGS = $(CXXFLAGS)
INCDIR = ../../JGE/include ../../JGE/include/psp ../../JGE/include/psp/freetype2 ../../JGE/src
LIBDIR = ../../JGE/lib/psp
LDFLAGS =
LIBS = -ljge300 -lhgetools -lfreetype -ljpeg -lgif -lpng -lz -lm -lmikmod -lpsppower -lpspmpeg -lpspaudiocodec -lpspaudiolib -lpspaudio -lpspgum -lpspgu -lpsprtc -lstdc++ -lpspfpu
LIBS = -ljge300 -lhgetools -lfreetype -ljpeg -lgif -lpng -lz -lm -lmikmod -lpsppower -lpspmpeg -lpspaudiocodec -lpspaudiolib -lpspaudio -lpspmp3 -lpspgum -lpspgu -lpsprtc -lstdc++ -lpspfpu
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = WTH?!

View File

@@ -1,50 +1,50 @@
100
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
100
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

View File

@@ -1,92 +1,92 @@
1167
460
1202
525
1340
92
1284
101
1149
20
1264
20
1321
20
1272
437
1126
485
1334
107
1352
91
1279
20
1154
481
1328
551
1335
20
1227
500
1236
489
1186
20
1219
20
1175
459
1136
111
1332
545
1250
21
1204
19
1381
499
1170
484
1097
102
1102
46
1282
485
1378
490
1300
20
1363
495
129665
90
1387
4
129652
5
174957
108
175030
5
130378
107
175031
5
1312
19
130386
97
1275
21
1148
103
135185
20
1100
109
153441
19
1167
460
1202
525
1340
92
1284
101
1149
20
1264
20
1321
20
1272
437
1126
485
1334
107
1352
91
1279
20
1154
481
1328
551
1335
20
1227
500
1236
489
1186
20
1219
20
1175
459
1136
111
1332
545
1250
21
1204
19
1381
499
1170
484
1097
102
1102
46
1282
485
1378
490
1300
20
1363
495
129665
90
1387
4
129652
5
174957
108
175030
5
130378
107
175031
5
1312
19
130386
97
1275
21
1148
103
135185
20
1100
109
153441
19

View File

@@ -80,6 +80,7 @@ class GameApp: public JApp
static JResourceManager * CommonRes;
static hgeParticleSystem * Particles[6];
static int HasMusic;
static JMusic* music;
};

View File

@@ -194,9 +194,13 @@ class GameStateDeckViewer: public GameState, public JGuiListener
welcome_menu->Add(10, "Cancel");
if (GameApp::HasMusic && GameOptions::GetInstance()->values[OPTIONS_MUSICVOLUME] > 0){
if (!bgMusic) bgMusic = JSoundSystem::GetInstance()->LoadMusic("sound/Track1.mp3");
if (bgMusic){
JSoundSystem::GetInstance()->PlayMusic(bgMusic, true);
if (GameApp::music){
JSoundSystem::GetInstance()->StopMusic(GameApp::music);
SAFE_DELETE(GameApp::music);
}
GameApp::music = JSoundSystem::GetInstance()->LoadMusic("sound/track1.mp3");
if (GameApp::music){
JSoundSystem::GetInstance()->PlayMusic(GameApp::music, true);
}
}
colorFilter = ALL_COLORS;
@@ -219,7 +223,10 @@ class GameStateDeckViewer: public GameState, public JGuiListener
virtual void End()
{
//mEngine->EnableVSync(false);
if (bgMusic) JSoundSystem::GetInstance()->StopMusic(bgMusic);
if (GameApp::music){
JSoundSystem::GetInstance()->StopMusic(GameApp::music);
SAFE_DELETE(GameApp::music);
}
SAFE_DELETE(backTex);
SAFE_DELETE(backQuad);
SAFE_DELETE(welcome_menu);

View File

@@ -43,7 +43,7 @@ class GameStateMenu: public GameState, public JGuiListener
JQuad * mMovingW;
float mCreditsYPos;
int currentState;
JMusic * bgMusic;
//JMusic * bgMusic;
int mVolume;
char nbcardsStr[400];
@@ -64,10 +64,11 @@ class GameStateMenu: public GameState, public JGuiListener
mGuiController = NULL;
subMenuController = NULL;
mIconsTexture = NULL;
bgMusic = NULL;
//bgMusic = NULL;
timeIndex = 0;
angleMultiplier = MIN_ANGLE_MULTIPLIER;
yW = 55;
mVolume = 0;
}
virtual ~GameStateMenu()
@@ -90,7 +91,7 @@ class GameStateMenu: public GameState, public JGuiListener
mIconsTexture = JRenderer::GetInstance()->LoadTexture("graphics/menuicons.png", TEX_TYPE_USE_VRAM);
bgTexture = JRenderer::GetInstance()->LoadTexture("graphics/menutitle.png", TEX_TYPE_USE_VRAM);
movingWTexture = JRenderer::GetInstance()->LoadTexture("graphics/movingW.png", TEX_TYPE_USE_VRAM);
mBg = NEW JQuad(bgTexture, 0, 0, 256, 167); // Create background quad for rendering.
mBg = NEW JQuad(bgTexture, 0, 0, 256, 166); // Create background quad for rendering.
mMovingW = NEW JQuad(movingWTexture, 2, 2, 84, 62);
mBg->SetHotSpot(105,50);
mMovingW->SetHotSpot(72,16);
@@ -149,7 +150,7 @@ class GameStateMenu: public GameState, public JGuiListener
if (mBg) delete mBg;
if (mMovingW) delete mMovingW;
SAFE_DELETE (bgMusic);
//SAFE_DELETE (bgMusic);
}
@@ -157,15 +158,17 @@ class GameStateMenu: public GameState, public JGuiListener
JRenderer::GetInstance()->ResetPrivateVRAM();
JRenderer::GetInstance()->EnableVSync(true);
if (GameApp::HasMusic && !bgMusic && GameOptions::GetInstance()->values[OPTIONS_MUSICVOLUME] > 0){
bgMusic = JSoundSystem::GetInstance()->LoadMusic("sound/Track0.mp3");
if (GameApp::HasMusic && !GameApp::music && GameOptions::GetInstance()->values[OPTIONS_MUSICVOLUME] > 0){
GameApp::music = JSoundSystem::GetInstance()->LoadMusic("sound/Track0.mp3");
JSoundSystem::GetInstance()->PlayMusic(GameApp::music, true);
}
if (bgMusic){
mVolume = 0;
JSoundSystem::GetInstance()->SetVolume(mVolume);
JSoundSystem::GetInstance()->PlayMusic(bgMusic, true);
}
if (GameApp::HasMusic && GameApp::music && GameOptions::GetInstance()->values[OPTIONS_MUSICVOLUME] == 0){
JSoundSystem::GetInstance()->StopMusic(GameApp::music);
SAFE_DELETE(GameApp::music);
}
}
@@ -198,19 +201,23 @@ class GameStateMenu: public GameState, public JGuiListener
{
//mEngine->EnableVSync(false);
if (bgMusic)
{
JSoundSystem::GetInstance()->StopMusic(bgMusic);
}
// if (bgMusic)
// {
//JSoundSystem::GetInstance()->StopMusic(bgMusic);
//SAFE_DELETE(bgMusic);
// }
JRenderer::GetInstance()->EnableVSync(false);
}
virtual void Update(float dt)
{
if (bgMusic && mVolume < 2*GameOptions::GetInstance()->values[OPTIONS_MUSICVOLUME]){
mVolume++;
JSoundSystem::GetInstance()->SetVolume(mVolume/2);
if (GameApp::music){
/*if (mVolume < 2*GameOptions::GetInstance()->values[OPTIONS_MUSICVOLUME]){
mVolume++;
JSoundSystem::GetInstance()->SetVolume(mVolume/2);
}*/
}
timeIndex += dt * 2;
@@ -282,7 +289,7 @@ class GameStateMenu: public GameState, public JGuiListener
if (mEngine->GetButtonState(PSP_CTRL_TRIANGLE) && (dt != 0))
{
angleMultiplier = (cos(timeIndex)*angleMultiplier - M_PI/3 - 0.1 - angleW) / dt;
yW = yW + 0.001 + (yW - 55) / 1000;
yW = yW + 5*dt + (yW - 55) *5* dt;
}
else
angleW = cos(timeIndex)*angleMultiplier - M_PI/3 - 0.1;
@@ -290,7 +297,7 @@ class GameStateMenu: public GameState, public JGuiListener
else
{
angleW += angleMultiplier * dt;
yW = yW + 0.001 + (yW - 55) / 1000;
yW = yW + 5*dt + (yW - 55) *5*dt;
}
}

View File

@@ -6,6 +6,8 @@
#endif
#ifdef _DEBUG
//if you get the following error :'_NORMAL_BLOCK' : undeclared identifier,
// try to add #include "crtdbg.h" somewhere in your code before including this file
#define NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#else
#define NEW new

View File

@@ -21,6 +21,7 @@ const char * const GameState::menuTexts[]= {"--NEW--","Deck 1", "Deck 2", "Deck
JResourceManager* GameApp::CommonRes = NEW JResourceManager();
hgeParticleSystem* GameApp::Particles[] = {NULL,NULL,NULL,NULL,NULL,NULL};
int GameApp::HasMusic = 1;
JMusic * GameApp::music = NULL;
GameState::GameState(GameApp* parent): mParent(parent)
{
@@ -75,6 +76,7 @@ void GameApp::Create()
}
CommonRes->CreateTexture("graphics/menuicons.png");
//Creating thes quad in this specific order allows us to have them in the correct order to call them by integer id
CommonRes->CreateQuad("c_artifact", "graphics/menuicons.png", 2 + 6*36, 38, 32, 32);

View File

@@ -181,6 +181,11 @@ void GameStateDuel::Update(float dt)
}
}else if (mGamePhase == DUEL_PLAY){
//Stop the music before starting the game
if (GameApp::music){
JSoundSystem::GetInstance()->StopMusic(GameApp::music);
SAFE_DELETE(GameApp::music);
}
if (!game){
GameObserver::Init(mPlayers, 2);
game = GameObserver::GetInstance();
@@ -209,11 +214,13 @@ void GameStateDuel::Update(float dt)
}else{
mGamePhase = DUEL_END;
}
}else if (mParent->players[0] == PLAYER_TYPE_CPU && mParent->players[1] == PLAYER_TYPE_CPU){
}else
#endif
if (mParent->players[0] == PLAYER_TYPE_CPU && mParent->players[1] == PLAYER_TYPE_CPU){
End();
Start();
}
#endif
mFont->SetColor(ARGB(255,255,255,255));
}
if (mEngine->GetButtonClick(PSP_CTRL_START)){

View File

@@ -1,188 +1,188 @@
#!/usr/bin/python
#
# Requires BeautifulSoup verion 3, available from
# http://www.crummy.com/software/BeautifulSoup/
#
# Usage: python gatherer-builder.py <output file>
#
# Copyright 2006: Nathan Callahan
# Feel free to do what you want with this file, but give credit
# where it's due.
from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup, Tag
import re
import codecs
import sys
import urllib
import os
import os.path
from mtgCommon import *
setinfo=sets['SHM']
stripReminderText = False
conffile = open(setinfo['dir'] + ".conf", 'w')
# FETCH_IMAGES = False
FETCH_IMAGES = True
url = "http://ww2.wizards.com/gatherer/Index.aspx?setfilter=%s\\&output=Spoiler" % setinfo['gathname']
gatherer = urllib.urlopen(url)
soup = BeautifulSoup(gatherer.read(), smartQuotesTo=None)
xml = BeautifulStoneSoup('<?xml version=\'1.0\' encoding=\'latin1\'?><!DOCTYPE ccg-setinfo SYSTEM "../gccg-set.dtd"><ccg-setinfo name="%s" dir="%s" abbrev="%s" game="Magic The Gathering"><cards></cards></ccg-setinfo>' % (setinfo['name'], setinfo['dir'], setinfo['abbrev']),selfClosingTags=['attr'])
rarity_re=re.compile(".*%s_(?P<rarity>.)\.gif.*" % setinfo['gathabbrev'])
def fetchImage(id, filename):
if (not os.path.exists(setinfo['abbrev'] + "/" + filename)):
for i in setinfo['gathdirs']:
url="http://resources.wizards.com/Magic/Cards/%s/Card%s.jpg" % (i, id)
print url
try:
pic = urllib.urlopen(url)
except:
pass
if (not pic): # this is completely wrong, supposed to check if it's not found
raise IOError
if (not os.path.exists(setinfo['abbrev'])):
os.mkdir(setinfo['abbrev'])
else:
assert os.path.isdir(setinfo['abbrev'])
f = open(setinfo['abbrev'] + "/" + filename, 'wb')
f.write(pic.read())
f.close()
for cardRow in soup.find(id="_gridResults").findAll('tr',onmouseover="this.style.backgroundColor='#F5DEB3';"):
name = cardRow('b')[0].string
name = name.replace('"','')
name = name.replace(u'\xe2', 'a')
name = name.replace(u'\xc6', 'AE')
manaCost = replaceSymbols(cardRow('td')[1]('font')[0])
manaCost = ''.join(manaCost.contents)
print manaCost
if manaCost == "&nbsp;":
manaCost="";
htmlText = cardRow('td')[3]
htmlText = replaceSymbols(htmlText)
text = cleanupHTMLText(htmlText, stripReminderText)
supertype, subtype = getCardTypes(cardRow)
splitCard = split_re.match(text)
if splitCard:
text = splitCard.group('t1') + " // " + splitCard.group('t2')
manaCost = manaCost + " // " + splitCard.group('mana2')
supertype = supertype + " // " + splitCard.group('type2')
power = cardRow('td')[4]('font')[0].string
if power == "&nbsp;":
power = None
toughness = cardRow('td')[5]('font')[0].string
if toughness == "&nbsp;":
toughness = None
colors = set()
for c in manaCost:
if c in symbolColors:
colors.add(symbolColors[c].capitalize())
color = ''.join(sorted([c+" " for c in colors])).rstrip()
if not color:
if (supertype.find("Artifact") != -1):
color = "Artifact"
elif (supertype.find("Land") != -1):
color = "Land"
else:
ss = "%s is " % name
start = text.find(ss) + len(ss)
end = text.find('.',start)
color = text[start:end].capitalize()
printings = 1
for printing in cardRow('td')[6].findAll(src=rarity_re):
print name
if name in basic_lands:
rarity = 'L'
else:
rarity = rarity_re.match(str(printing)).group('rarity')
card = Tag(xml, 'card')
cards=xml('ccg-setinfo')[0]('cards')[0]
cards.insert(len(cards),card)
card=cards('card')[-1]
card['name']=name
if printings > 1:
card['graphics']=name.translate(imagetrans)+str(printings)+".jpg"
else:
card['graphics']=name.translate(imagetrans)+".jpg"
id = id_re.match(printing.parent['onclick']).group('id')
if FETCH_IMAGES:
fetchImage(id, id + ".jpg")
text = text.replace(u'\xe2', 'a')
card['text']=text
card.insert(0,Tag(xml,'attr'))
card('attr')[0]['key']='rarity'
card('attr')[0]['value']=rarity
card.insert(1,Tag(xml,'attr'))
card('attr')[1]['key']='color'
card('attr')[1]['value']=color
conffile.write("[card]")
# conffile.write("\nimage=" + card['graphics'])
conffile.write("\ntext=" + text)
conffile.write("\nid=" + id)
conffile.write("\nname=" + name)
conffile.write("\nrarity=" + rarity)
# conffile.write("\ncolor=" + color)
conffile.write("\ntype=" + supertype)
if manaCost:
card.insert(2,Tag(xml,'attr'))
card('attr')[2]['key']='cost'
card('attr')[2]['value']=manaCost
conffile.write("\nmana=" + manaCost)
if power:
card.insert(len(card),Tag(xml,'attr'))
card('attr')[-1]['key']='power'
card('attr')[-1]['value']=power
conffile.write("\npower=" + power)
if subtype:
subtype = subtype.replace(u'\xe2', 'a')
card.insert(len(card),Tag(xml,'attr'))
card('attr')[-1]['key']='subtype'
card('attr')[-1]['value']=subtype
conffile.write("\nsubtype=" + subtype)
if toughness:
card.insert(len(card),Tag(xml,'attr'))
card('attr')[-1]['key']='toughness'
card('attr')[-1]['value']=toughness
conffile.write("\ntoughness=" + toughness)
card.insert(len(card),Tag(xml,'attr'))
card('attr')[-1]['key']='type'
card('attr')[-1]['value']=supertype
printings += 1
conffile.write("\n[/card]\n")
f = file(sys.argv[1],'w')
f.write(xml.prettify('latin1'))
f.close()
conffile.close()
#!/usr/bin/python
#
# Requires BeautifulSoup verion 3, available from
# http://www.crummy.com/software/BeautifulSoup/
#
# Usage: python gatherer-builder.py <output file>
#
# Copyright 2006: Nathan Callahan
# Feel free to do what you want with this file, but give credit
# where it's due.
from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup, Tag
import re
import codecs
import sys
import urllib
import os
import os.path
from mtgCommon import *
setinfo=sets['CK']
stripReminderText = False
conffile = open(setinfo['dir'] + ".conf", 'w')
# FETCH_IMAGES = False
FETCH_IMAGES = True
url = "http://ww2.wizards.com/gatherer/Index.aspx?setfilter=%s\\&output=Spoiler" % setinfo['gathname']
gatherer = urllib.urlopen(url)
soup = BeautifulSoup(gatherer.read(), smartQuotesTo=None)
xml = BeautifulStoneSoup('<?xml version=\'1.0\' encoding=\'latin1\'?><!DOCTYPE ccg-setinfo SYSTEM "../gccg-set.dtd"><ccg-setinfo name="%s" dir="%s" abbrev="%s" game="Magic The Gathering"><cards></cards></ccg-setinfo>' % (setinfo['name'], setinfo['dir'], setinfo['abbrev']),selfClosingTags=['attr'])
rarity_re=re.compile(".*%s_(?P<rarity>.)\.gif.*" % setinfo['gathabbrev'])
def fetchImage(id, filename):
if (not os.path.exists(setinfo['abbrev'] + "/" + filename)):
for i in setinfo['gathdirs']:
url="http://resources.wizards.com/Magic/Cards/%s/Card%s.jpg" % (i, id)
print url
try:
pic = urllib.urlopen(url)
except:
pass
if (not pic): # this is completely wrong, supposed to check if it's not found
raise IOError
if (not os.path.exists(setinfo['abbrev'])):
os.mkdir(setinfo['abbrev'])
else:
assert os.path.isdir(setinfo['abbrev'])
f = open(setinfo['abbrev'] + "/" + filename, 'wb')
f.write(pic.read())
f.close()
for cardRow in soup.find(id="_gridResults").findAll('tr',onmouseover="this.style.backgroundColor='#F5DEB3';"):
name = cardRow('b')[0].string
name = name.replace('"','')
name = name.replace(u'\xe2', 'a')
name = name.replace(u'\xc6', 'AE')
manaCost = replaceSymbols(cardRow('td')[1]('font')[0])
manaCost = ''.join(manaCost.contents)
print manaCost
if manaCost == "&nbsp;":
manaCost="";
htmlText = cardRow('td')[3]
htmlText = replaceSymbols(htmlText)
text = cleanupHTMLText(htmlText, stripReminderText)
supertype, subtype = getCardTypes(cardRow)
splitCard = split_re.match(text)
if splitCard:
text = splitCard.group('t1') + " // " + splitCard.group('t2')
manaCost = manaCost + " // " + splitCard.group('mana2')
supertype = supertype + " // " + splitCard.group('type2')
power = cardRow('td')[4]('font')[0].string
if power == "&nbsp;":
power = None
toughness = cardRow('td')[5]('font')[0].string
if toughness == "&nbsp;":
toughness = None
colors = set()
for c in manaCost:
if c in symbolColors:
colors.add(symbolColors[c].capitalize())
color = ''.join(sorted([c+" " for c in colors])).rstrip()
if not color:
if (supertype.find("Artifact") != -1):
color = "Artifact"
elif (supertype.find("Land") != -1):
color = "Land"
else:
ss = "%s is " % name
start = text.find(ss) + len(ss)
end = text.find('.',start)
color = text[start:end].capitalize()
printings = 1
for printing in cardRow('td')[6].findAll(src=rarity_re):
print name
if name in basic_lands:
rarity = 'L'
else:
rarity = rarity_re.match(str(printing)).group('rarity')
card = Tag(xml, 'card')
cards=xml('ccg-setinfo')[0]('cards')[0]
cards.insert(len(cards),card)
card=cards('card')[-1]
card['name']=name
if printings > 1:
card['graphics']=name.translate(imagetrans)+str(printings)+".jpg"
else:
card['graphics']=name.translate(imagetrans)+".jpg"
id = id_re.match(printing.parent['onclick']).group('id')
if FETCH_IMAGES:
fetchImage(id, id + ".jpg")
text = text.replace(u'\xe2', 'a')
card['text']=text
card.insert(0,Tag(xml,'attr'))
card('attr')[0]['key']='rarity'
card('attr')[0]['value']=rarity
card.insert(1,Tag(xml,'attr'))
card('attr')[1]['key']='color'
card('attr')[1]['value']=color
conffile.write("[card]")
# conffile.write("\nimage=" + card['graphics'])
conffile.write("\ntext=" + text)
conffile.write("\nid=" + id)
conffile.write("\nname=" + name)
conffile.write("\nrarity=" + rarity)
# conffile.write("\ncolor=" + color)
conffile.write("\ntype=" + supertype)
if manaCost:
card.insert(2,Tag(xml,'attr'))
card('attr')[2]['key']='cost'
card('attr')[2]['value']=manaCost
conffile.write("\nmana=" + manaCost)
if power:
card.insert(len(card),Tag(xml,'attr'))
card('attr')[-1]['key']='power'
card('attr')[-1]['value']=power
conffile.write("\npower=" + power)
if subtype:
subtype = subtype.replace(u'\xe2', 'a')
card.insert(len(card),Tag(xml,'attr'))
card('attr')[-1]['key']='subtype'
card('attr')[-1]['value']=subtype
conffile.write("\nsubtype=" + subtype)
if toughness:
card.insert(len(card),Tag(xml,'attr'))
card('attr')[-1]['key']='toughness'
card('attr')[-1]['value']=toughness
conffile.write("\ntoughness=" + toughness)
card.insert(len(card),Tag(xml,'attr'))
card('attr')[-1]['key']='type'
card('attr')[-1]['value']=supertype
printings += 1
conffile.write("\n[/card]\n")
f = file(sys.argv[1],'w')
f.write(xml.prettify('latin1'))
f.close()
conffile.close()

View File

@@ -1,494 +1,495 @@
from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup, Tag
import re
import codecs
import sys
sets ={'BE':{'name':'Beta',
'dir':'BE',
'abbrev':'BE',
'gathabbrev': '2E',
'gathname':'LimitedEditionBeta',
},
'RV':{'name':'Revised',
'dir':'RV',
'abbrev':'RV',
'gathdirs':['3E/en-us'],
'gathabbrev': '3E',
'gathname':'RevisedEdition'
},
'4E':{'name':'4th Edition',
'dir':'4E',
'abbrev':'4E',
'gathdirs':['4E/en-us'],
'gathabbrev': '4E',
'gathname':'FourthEdition',
},
'5E':{'name':'5th Edition',
'dir':'5E',
'abbrev':'5E',
'gathdirs':['5E/en-us'],
'gathabbrev': '5E',
'gathname':'FifthEdition'
},
'6E':{'name':'6th Edition',
'dir':'6E',
'abbrev':'6E',
'gathdirs':['6E/en-us'],
'gathabbrev': '6E',
'gathname':'ClassicSixthEdition',
},
'7E':{'name':'7th Edition',
'dir':'7E',
'abbrev':'7E',
'gathdirs':['7E/en-us'],
'gathabbrev': '7E',
'gathname':'SeventhEdition',
},
'8E':{'name':'8th Edition',
'dir':'8E',
'abbrev':'8E',
'gathdirs':['8ED/en-us'],
'gathabbrev': '8ED',
'gathname':'EighthEdition',
},
'9E':{'name':'9th Edition',
'dir':'9E',
'abbrev':'9E',
'gathdirs':['9ED/en-us'],
'gathabbrev': '9ED',
'gathname':'NinthEdition',
},
'10E':{'name':'10th Edition',
'dir':'10E',
'abbrev':'10E',
'gathdirs':['10E/EN'],
'gathabbrev': '10E',
'gathname':'TenthEdition',
},
'EVE':{'name':'Eventide',
'dir':'EVE',
'abbrev':'EVE',
'gathdirs':['EVE/EN'],
'gathabbrev': 'EVE',
'gathname':'Eventide',
},
'SHM':{'name':'Shadowmoor',
'dir':'SHM',
'abbrev':'SHM',
'gathdirs':['SHM/EN'],
'gathabbrev': 'SHM',
'gathname':'Shadowmoor',
},
'ALA':{'name':'Shards of Alara',
'dir':'ALA',
'abbrev':'ALA',
'gathdirs':['ALA/EN'],
'gathabbrev': 'ALA',
'gathname':'ShardsOfAlara',
},
'UH':{'name':'Unhinged',
'dir':'UH',
'abbrev':'UH',
'gathdirs':['UNH/en-us'],
'gathabbrev': 'UNH',
'gathname':'Unhinged',
},
'UG':{'name':'Unglued',
'dir':'UG',
'abbrev':'UG',
'gathdirs':['UG/en-us'],
'gathabbrev':'UG',
'gathname':'Unglued',
},
'P1':{'name':'Portal',
'dir':'P1',
'abbrev':'P1',
'gathdirs':['P1/en-us'],
'gathabbrev':'P1',
'gathname':'Portal',
},
'P2':{'name':'Portal Second Age',
'dir':'P2',
'abbrev':'P2',
'gathdirs':['P2/en-us'],
'gathabbrev':'P2',
'gathname':'PortalSecondAge',
},
'P3':{'name':'Portal Three Kingdoms',
'dir':'P3',
'abbrev':'P3',
'gathdirs':['PK/en-us'],
'gathabbrev': 'PK',
'gathname':'PortalThreeKingdoms',
},
'AN':{'name':'Arabian Nights',
'dir':'AN',
'abbrev':'AN',
'gathdirs':['AN/en-us'],
'gathabbrev': 'AN',
'gathname':'ArabianNights'
},
'AQ':{'name':'Antiquities',
'dir':'AQ',
'abbrev':'AQ',
'gathdirs':['AQ/en-us'],
'gathabbrev': 'AQ',
'gathname':'Antiquities',
},
'LG':{'name':'Legends',
'dir':'LG',
'abbrev':'LG',
'gathdirs':['LG/en-us'],
'gathabbrev': 'LE',
'gathname':'Legends',
},
'DK':{'name':'The Dark',
'dir':'DK',
'abbrev':'DK',
'gathdirs':['DK/en-us'],
'gathabbrev': 'DK',
'gathname':'TheDark',
},
'FE':{'name':'Fallen Empires',
'dir':'FE',
'abbrev':'FE',
'gathdirs':['FE/en-us'],
'gathabbrev': 'FE',
'gathname':'FallenEmpires',
},
'IA':{'name':'Ice Age',
'dir':'IA',
'abbrev':'IA',
'gathdirs':['IA/en-us'],
'gathabbrev': 'IA',
'gathname':'IceAge',
},
'HL':{'name':'Homelands',
'dir':'HL',
'abbrev':'HL',
'gathdirs':['HM/en-us'],
'gathabbrev': 'HM',
'gathname':'Homelands'
},
'AL':{'name':'Alliances',
'dir':'AL',
'abbrev':'AL',
'gathdirs':['AL/en-us'],
'gathabbrev': 'AL',
'gathname':'Alliances',
},
'MI':{'name':'Mirage',
'dir':'MI',
'abbrev':'MI',
'gathdirs':['MI/en-us'],
'gathabbrev': 'MI',
'gathname':'Mirage',
},
'VI':{'name':'Visions',
'dir':'VI',
'abbrev':'VI',
'gathabbrev': 'VI',
'gathname':'Visions',
},
'WL':{'name':'Weatherlight',
'dir':'WL',
'abbrev':'WL',
'gathabbrev': 'WL',
'gathname':'Weatherlight',
},
'TE':{'name':'Tempest',
'dir':'TE',
'abbrev':'TE',
'gathabbrev': 'TE',
'gathname':'Tempest',
},
'SH':{'name':'Stronghold',
'dir':'SH',
'abbrev':'SH',
'gathabbrev': 'ST',
'gathname':'Stronghold',
},
'EX':{'name':'Exodus',
'dir':'EX',
'abbrev':'EX',
'gathabbrev': 'EX',
'gathname':'Exodus',
},
'US':{'name':'Urza\'s Saga',
'dir':'US',
'abbrev':'US',
'gathabbrev': 'UZ',
'gathname':'UrzasSaga',
},
'UL':{'name':'Urza\'s Legacy',
'dir':'UL',
'abbrev':'UL',
'gathabbrev': 'GU',
'gathname':'UrzasDestiny',
},
'UD':{'name':'Urza\'s Destiny',
'dir':'UD',
'abbrev':'UD',
'gathabbrev': 'CG',
'gathname':'UrzasLegacy',
},
'MM':{'name':'Mercadian Masques',
'dir':'MM',
'abbrev':'MM',
'gathabbrev': 'MM',
'gathname':'MercadianMasques',
},
'NE':{'name':'Nemesis',
'dir':'NE',
'abbrev':'NE',
'gathabbrev': 'NE',
'gathname':'Nemesis',
},
'PY':{'name':'Prophecy',
'dir':'PY',
'abbrev':'PY',
'gathabbrev': 'PR',
'gathname':'Prophecy',
},
'IN':{'name':'Invasion',
'dir':'IN',
'abbrev':'IN',
'gathabbrev': 'IN',
'gathname':'Invasion',
},
'PS':{'name':'Planeshift',
'dir':'PS',
'abbrev':'PS',
'gathabbrev': 'PS',
'gathname':'Planeshift',
},
'AP':{'name':'Apocalypse',
'dir':'AP',
'abbrev':'AP',
'gathabbrev': 'AP',
'gathname':'Apocalypse',
},
'OD':{'name':'Odyssey',
'dir':'OD',
'abbrev':'OD',
'gathabbrev': 'OD',
'gathname':'Odyssey',
},
'TO':{'name':'Torment',
'dir':'TO',
'abbrev':'TO',
'gathabbrev': 'TOR',
'gathname':'Torment',
},
'JD':{'name':'Judgment',
'dir':'JD',
'abbrev':'JD',
'gathabbrev': 'JUD',
'gathname':'Judgment',
},
'ON':{'name':'Onslaught',
'dir':'ON',
'abbrev':'ON',
'gathabbrev': 'ONS',
'gathname':'Onslaught',
},
'LE':{'name':'Legions',
'dir':'LE',
'abbrev':'LE',
'gathabbrev': 'LGN',
'gathname':'Legions',
},
'SC':{'name':'Scourge',
'dir':'SC',
'abbrev':'SC',
'gathabbrev': 'SCG',
'gathname':'Scourge',
},
'MR':{'name':'Mirrodin',
'dir':'MR',
'abbrev':'MR',
'gathabbrev': 'MRD',
'gathname':'Mirrodin',
},
'DS':{'name':'Darksteel',
'dir':'DS',
'abbrev':'DS',
'gathabbrev': 'DST',
'gathname':'Darksteel',
},
'FD':{'name':'Fifth Dawn',
'dir':'FD',
'abbrev':'FD',
'gathabbrev': '5DN',
'gathname':'FifthDawn',
},
'CK':{'name':'Champions of Kamigawa',
'dir':'CK',
'abbrev':'CK',
'gathabbrev': 'CHK',
'gathname':'ChampionsofKamigawa',
},
'BK':{'name':'Betrayers of Kamigawa',
'dir':'BK',
'abbrev':'BK',
'gathabbrev': 'BOK',
'gathname':'BetrayersofKamigawa',
},
'SK':{'name':'Saviors of Kamigawa',
'dir':'SK',
'abbrev':'SK',
'gathabbrev': 'SOK',
'gathname':'SaviorsofKamigawa',
},
'RA':{'name':'Ravnica: City of Guilds',
'dir':'RA',
'abbrev':'RA',
'gathabbrev': 'RAV',
'gathname':'RavnicaCityofGuilds',
},
'GP':{'name':'Guildpact',
'dir':'GP',
'abbrev':'GP',
'gathabbrev': 'GPT',
'gathname':'Guildpact',
},
'DI':{'name':'Dissension',
'dir':'DI',
'abbrev':'DI',
'gathabbrev': 'DIS',
'gathname':'Dissension',
},
'CS':{'name':'Coldsnap',
'dir':'CS',
'abbrev':'CS',
'gathabbrev':'CSP',
'gathname':'Coldsnap',
},
'TS':{'name':'Time Spiral',
'gathname':'TimeSpiralBlock',
'gathabbrev':'(?:(?:TSP)|(?:TSB))',
'dir':'TS',
'abbrev':'TS',
'gathdirs' : ('TSP','TSB'),
},
'PC':{'name':'Planar Chaos',
'gathname':'Planar%20Chaos',
'gathabbrev':'PLC',
'dir':'PC',
'abbrev':'PC',
},
'S1':{'name':'Starter 1999',
'gathname':'Starter%201999',
'gathabbrev':'P3',
'gathdirs':['P3'],
'dir':'S1',
'abbrev':'S1'
},
'S2':{'name':'Starter 2000',
'gathname':'Starter%202000',
'gathabbrev':'P4',
'dir':'S1',
'abbrev':'S1'
},
'FS':{'name':'Future Sight',
'gathname':'Future%20Sight',
'gathabbrev':'FUT',
'gathdirs':['FUT'],
'dir':'FS',
'abbrev':'FS'
},
}
def maketransU(s1, s2, todel=""):
trans_tab = dict( zip( map(ord, s1), map(ord, s2) ) )
trans_tab.update( (ord(c),None) for c in todel )
return trans_tab
imagetrans = maketransU(u'\xe2\xea\xee\xf4\xfb\xe1\xe9\xed\xf3\xfa\xfd\xe4\xeb\xef\xf6\xfc\xff\xe5\xc2\xca\xce\xd4\xdb\xc1\xc9\xcd\xd3\xda\xdd\xc4\xcb\xcf\xd6\xdc\xc5',u'aeiouaeiouyaeiouyaAEIOUAEIOUYAEIOUA',u"'/,. &;!")
imagetrans[198]=u'AE'
nametrans = maketransU(u'\xe2\xea\xee\xf4\xfb\xe1\xe9\xed\xf3\xfa\xfd\xe4\xeb\xef\xf6\xfc\xff\xe5\xc2\xca\xce\xd4\xdb\xc1\xc9\xcd\xd3\xda\xdd\xc4\xcb\xcf\xd6\xdc\xc5',u'aeiouaeiouyaeiouyaAEIOUAEIOUYAEIOUA')
nametrans[198]=u'AE'
cleanuptrans = {ord(u'\r'):u' ',
ord(u'"'):u'&quot;',
ord(u'\u2018'):ord(u'\''),
ord(u'&'):u'&amp;',
}
colorSymbols = {'red':'R',
'green' : 'G',
'blue':'U',
'black':'B',
'white':'W'}
symbolColors = dict([reversed(a) for a in colorSymbols.items()])
basic_lands = ('Mountain','Forest','Island','Swamp','Plains')
color_re = re.compile(".*(?P<color>[Rr]ed|[Gg]reen|[Bb]lue|[Bb]lack|[Ww]hite).*")
mana_re = re.compile(".*Symbol_(?P<type>.*)_mana\.gif.*")
tap_re = re.compile(".*tap.gif.*")
basicLand_re = re.compile("\[(?P<mana>.)\]")
split_re = re.compile("(?P<t1>.*) // (?P<name2>.*) (?P<mana2>\{.*\}) (?P<type2>.*) (?P<t2>.*)")
id_re = re.compile(".*id=(?P<id>\d*).*")
reminder_re = re.compile('(\A[^\(]*)|((?<=\))[^\(]*)')
_stripReminderText = True;
def replaceSymbols(soup):
for symbol in soup.findAll('img'):
m = color_re.match(str(symbol['src']))
if m:
s = colorSymbols[m.group('color').lower()]
symbol.replaceWith('{' + s + '}')
m = mana_re.match(str(symbol))
if m:
if m.group('type') == "Snow":
symbol.replaceWith('{S}')
else:
symbol.replaceWith('{' + m.group('type') + '}')
m = tap_re.match(str(symbol))
if m:
symbol.replaceWith('{T}')
return soup
def getCardTypes(soup):
types = [t.strip()
for t in soup('td')[2]('font')[0].string.split('-',1)]
if (len(types) == 2):
supertype = types[0]
subtype = types[1]
else:
supertype = types[0]
subtype = ''
# replace entities, since gccg doesn't undertand them in attributes
subtype = subtype.replace("&#226;", u"\342")
return supertype, subtype
def cleanupHTMLText(htmlText, stripReminder = _stripReminderText):
for i in htmlText.findAll('br'):
i.replaceWith(' ')
for i in htmlText.findAll('i'):
i.replaceWith(''.join(i.contents))
for i in htmlText.findAll('b'):
i.replaceWith(''.join(i.contents))
text = htmlText('font')[0].renderContents(None)
# add text for Basic Land
m = basicLand_re.match(text)
if m:
text = u"{T}: Add {" + m.group('mana') + u"} to your mana pool."
if text == u"&nbsp;":
text = u""
text = text.translate(cleanuptrans)
if stripReminder:
text = ''.join([''.join(m) for m in reminder_re.findall(text)])
return text
from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup, Tag
import re
import codecs
import sys
sets ={'BE':{'name':'Beta',
'dir':'BE',
'abbrev':'BE',
'gathabbrev': '2E',
'gathname':'LimitedEditionBeta',
},
'RV':{'name':'Revised',
'dir':'RV',
'abbrev':'RV',
'gathdirs':['3E/en-us'],
'gathabbrev': '3E',
'gathname':'RevisedEdition'
},
'4E':{'name':'4th Edition',
'dir':'4E',
'abbrev':'4E',
'gathdirs':['4E/en-us'],
'gathabbrev': '4E',
'gathname':'FourthEdition',
},
'5E':{'name':'5th Edition',
'dir':'5E',
'abbrev':'5E',
'gathdirs':['5E/en-us'],
'gathabbrev': '5E',
'gathname':'FifthEdition'
},
'6E':{'name':'6th Edition',
'dir':'6E',
'abbrev':'6E',
'gathdirs':['6E/en-us'],
'gathabbrev': '6E',
'gathname':'ClassicSixthEdition',
},
'7E':{'name':'7th Edition',
'dir':'7E',
'abbrev':'7E',
'gathdirs':['7E/en-us'],
'gathabbrev': '7E',
'gathname':'SeventhEdition',
},
'8E':{'name':'8th Edition',
'dir':'8E',
'abbrev':'8E',
'gathdirs':['8ED/en-us'],
'gathabbrev': '8ED',
'gathname':'EighthEdition',
},
'9E':{'name':'9th Edition',
'dir':'9E',
'abbrev':'9E',
'gathdirs':['9ED/en-us'],
'gathabbrev': '9ED',
'gathname':'NinthEdition',
},
'10E':{'name':'10th Edition',
'dir':'10E',
'abbrev':'10E',
'gathdirs':['10E/EN'],
'gathabbrev': '10E',
'gathname':'TenthEdition',
},
'EVE':{'name':'Eventide',
'dir':'EVE',
'abbrev':'EVE',
'gathdirs':['EVE/EN'],
'gathabbrev': 'EVE',
'gathname':'Eventide',
},
'SHM':{'name':'Shadowmoor',
'dir':'SHM',
'abbrev':'SHM',
'gathdirs':['SHM/EN'],
'gathabbrev': 'SHM',
'gathname':'Shadowmoor',
},
'ALA':{'name':'Shards of Alara',
'dir':'ALA',
'abbrev':'ALA',
'gathdirs':['ALA/EN'],
'gathabbrev': 'ALA',
'gathname':'ShardsOfAlara',
},
'UH':{'name':'Unhinged',
'dir':'UH',
'abbrev':'UH',
'gathdirs':['UNH/en-us'],
'gathabbrev': 'UNH',
'gathname':'Unhinged',
},
'UG':{'name':'Unglued',
'dir':'UG',
'abbrev':'UG',
'gathdirs':['UG/en-us'],
'gathabbrev':'UG',
'gathname':'Unglued',
},
'P1':{'name':'Portal',
'dir':'P1',
'abbrev':'P1',
'gathdirs':['P1/en-us'],
'gathabbrev':'P1',
'gathname':'Portal',
},
'P2':{'name':'Portal Second Age',
'dir':'P2',
'abbrev':'P2',
'gathdirs':['P2/en-us'],
'gathabbrev':'P2',
'gathname':'PortalSecondAge',
},
'P3':{'name':'Portal Three Kingdoms',
'dir':'P3',
'abbrev':'P3',
'gathdirs':['PK/en-us'],
'gathabbrev': 'PK',
'gathname':'PortalThreeKingdoms',
},
'AN':{'name':'Arabian Nights',
'dir':'AN',
'abbrev':'AN',
'gathdirs':['AN/en-us'],
'gathabbrev': 'AN',
'gathname':'ArabianNights'
},
'AQ':{'name':'Antiquities',
'dir':'AQ',
'abbrev':'AQ',
'gathdirs':['AQ/en-us'],
'gathabbrev': 'AQ',
'gathname':'Antiquities',
},
'LG':{'name':'Legends',
'dir':'LG',
'abbrev':'LG',
'gathdirs':['LG/en-us'],
'gathabbrev': 'LE',
'gathname':'Legends',
},
'DK':{'name':'The Dark',
'dir':'DK',
'abbrev':'DK',
'gathdirs':['DK/en-us'],
'gathabbrev': 'DK',
'gathname':'TheDark',
},
'FE':{'name':'Fallen Empires',
'dir':'FE',
'abbrev':'FE',
'gathdirs':['FE/en-us'],
'gathabbrev': 'FE',
'gathname':'FallenEmpires',
},
'IA':{'name':'Ice Age',
'dir':'IA',
'abbrev':'IA',
'gathdirs':['IA/en-us'],
'gathabbrev': 'IA',
'gathname':'IceAge',
},
'HL':{'name':'Homelands',
'dir':'HL',
'abbrev':'HL',
'gathdirs':['HM/en-us'],
'gathabbrev': 'HM',
'gathname':'Homelands'
},
'AL':{'name':'Alliances',
'dir':'AL',
'abbrev':'AL',
'gathdirs':['AL/en-us'],
'gathabbrev': 'AL',
'gathname':'Alliances',
},
'MI':{'name':'Mirage',
'dir':'MI',
'abbrev':'MI',
'gathdirs':['MI/en-us'],
'gathabbrev': 'MI',
'gathname':'Mirage',
},
'VI':{'name':'Visions',
'dir':'VI',
'abbrev':'VI',
'gathabbrev': 'VI',
'gathname':'Visions',
},
'WL':{'name':'Weatherlight',
'dir':'WL',
'abbrev':'WL',
'gathabbrev': 'WL',
'gathname':'Weatherlight',
},
'TE':{'name':'Tempest',
'dir':'TE',
'abbrev':'TE',
'gathabbrev': 'TE',
'gathname':'Tempest',
},
'SH':{'name':'Stronghold',
'dir':'SH',
'abbrev':'SH',
'gathabbrev': 'ST',
'gathname':'Stronghold',
},
'EX':{'name':'Exodus',
'dir':'EX',
'abbrev':'EX',
'gathabbrev': 'EX',
'gathname':'Exodus',
},
'US':{'name':'Urza\'s Saga',
'dir':'US',
'abbrev':'US',
'gathabbrev': 'UZ',
'gathname':'UrzasSaga',
},
'UL':{'name':'Urza\'s Legacy',
'dir':'UL',
'abbrev':'UL',
'gathabbrev': 'GU',
'gathname':'UrzasDestiny',
},
'UD':{'name':'Urza\'s Destiny',
'dir':'UD',
'abbrev':'UD',
'gathabbrev': 'CG',
'gathname':'UrzasLegacy',
},
'MM':{'name':'Mercadian Masques',
'dir':'MM',
'abbrev':'MM',
'gathabbrev': 'MM',
'gathname':'MercadianMasques',
},
'NE':{'name':'Nemesis',
'dir':'NE',
'abbrev':'NE',
'gathabbrev': 'NE',
'gathname':'Nemesis',
},
'PY':{'name':'Prophecy',
'dir':'PY',
'abbrev':'PY',
'gathabbrev': 'PR',
'gathname':'Prophecy',
},
'IN':{'name':'Invasion',
'dir':'IN',
'abbrev':'IN',
'gathabbrev': 'IN',
'gathname':'Invasion',
},
'PS':{'name':'Planeshift',
'dir':'PS',
'abbrev':'PS',
'gathabbrev': 'PS',
'gathname':'Planeshift',
},
'AP':{'name':'Apocalypse',
'dir':'AP',
'abbrev':'AP',
'gathabbrev': 'AP',
'gathname':'Apocalypse',
},
'OD':{'name':'Odyssey',
'dir':'OD',
'abbrev':'OD',
'gathabbrev': 'OD',
'gathname':'Odyssey',
},
'TO':{'name':'Torment',
'dir':'TO',
'abbrev':'TO',
'gathabbrev': 'TOR',
'gathname':'Torment',
},
'JD':{'name':'Judgment',
'dir':'JD',
'abbrev':'JD',
'gathabbrev': 'JUD',
'gathname':'Judgment',
},
'ON':{'name':'Onslaught',
'dir':'ON',
'abbrev':'ON',
'gathabbrev': 'ONS',
'gathname':'Onslaught',
},
'LE':{'name':'Legions',
'dir':'LE',
'abbrev':'LE',
'gathabbrev': 'LGN',
'gathname':'Legions',
},
'SC':{'name':'Scourge',
'dir':'SC',
'abbrev':'SC',
'gathabbrev': 'SCG',
'gathname':'Scourge',
},
'MR':{'name':'Mirrodin',
'dir':'MR',
'abbrev':'MR',
'gathabbrev': 'MRD',
'gathname':'Mirrodin',
},
'DS':{'name':'Darksteel',
'dir':'DS',
'abbrev':'DS',
'gathabbrev': 'DST',
'gathname':'Darksteel',
},
'FD':{'name':'Fifth Dawn',
'dir':'FD',
'abbrev':'FD',
'gathabbrev': '5DN',
'gathname':'FifthDawn',
},
'CK':{'name':'Champions of Kamigawa',
'dir':'CK',
'abbrev':'CK',
'gathdirs':['CHK/en-us'],
'gathabbrev': 'CHK',
'gathname':'ChampionsofKamigawa',
},
'BK':{'name':'Betrayers of Kamigawa',
'dir':'BK',
'abbrev':'BK',
'gathabbrev': 'BOK',
'gathname':'BetrayersofKamigawa',
},
'SK':{'name':'Saviors of Kamigawa',
'dir':'SK',
'abbrev':'SK',
'gathabbrev': 'SOK',
'gathname':'SaviorsofKamigawa',
},
'RA':{'name':'Ravnica: City of Guilds',
'dir':'RA',
'abbrev':'RA',
'gathabbrev': 'RAV',
'gathname':'RavnicaCityofGuilds',
},
'GP':{'name':'Guildpact',
'dir':'GP',
'abbrev':'GP',
'gathabbrev': 'GPT',
'gathname':'Guildpact',
},
'DI':{'name':'Dissension',
'dir':'DI',
'abbrev':'DI',
'gathabbrev': 'DIS',
'gathname':'Dissension',
},
'CS':{'name':'Coldsnap',
'dir':'CS',
'abbrev':'CS',
'gathabbrev':'CSP',
'gathname':'Coldsnap',
},
'TS':{'name':'Time Spiral',
'gathname':'TimeSpiralBlock',
'gathabbrev':'(?:(?:TSP)|(?:TSB))',
'dir':'TS',
'abbrev':'TS',
'gathdirs' : ('TSP','TSB'),
},
'PC':{'name':'Planar Chaos',
'gathname':'Planar%20Chaos',
'gathabbrev':'PLC',
'dir':'PC',
'abbrev':'PC',
},
'S1':{'name':'Starter 1999',
'gathname':'Starter%201999',
'gathabbrev':'P3',
'gathdirs':['P3'],
'dir':'S1',
'abbrev':'S1'
},
'S2':{'name':'Starter 2000',
'gathname':'Starter%202000',
'gathabbrev':'P4',
'dir':'S1',
'abbrev':'S1'
},
'FS':{'name':'Future Sight',
'gathname':'Future%20Sight',
'gathabbrev':'FUT',
'gathdirs':['FUT'],
'dir':'FS',
'abbrev':'FS'
},
}
def maketransU(s1, s2, todel=""):
trans_tab = dict( zip( map(ord, s1), map(ord, s2) ) )
trans_tab.update( (ord(c),None) for c in todel )
return trans_tab
imagetrans = maketransU(u'\xe2\xea\xee\xf4\xfb\xe1\xe9\xed\xf3\xfa\xfd\xe4\xeb\xef\xf6\xfc\xff\xe5\xc2\xca\xce\xd4\xdb\xc1\xc9\xcd\xd3\xda\xdd\xc4\xcb\xcf\xd6\xdc\xc5',u'aeiouaeiouyaeiouyaAEIOUAEIOUYAEIOUA',u"'/,. &;!")
imagetrans[198]=u'AE'
nametrans = maketransU(u'\xe2\xea\xee\xf4\xfb\xe1\xe9\xed\xf3\xfa\xfd\xe4\xeb\xef\xf6\xfc\xff\xe5\xc2\xca\xce\xd4\xdb\xc1\xc9\xcd\xd3\xda\xdd\xc4\xcb\xcf\xd6\xdc\xc5',u'aeiouaeiouyaeiouyaAEIOUAEIOUYAEIOUA')
nametrans[198]=u'AE'
cleanuptrans = {ord(u'\r'):u' ',
ord(u'"'):u'&quot;',
ord(u'\u2018'):ord(u'\''),
ord(u'&'):u'&amp;',
}
colorSymbols = {'red':'R',
'green' : 'G',
'blue':'U',
'black':'B',
'white':'W'}
symbolColors = dict([reversed(a) for a in colorSymbols.items()])
basic_lands = ('Mountain','Forest','Island','Swamp','Plains')
color_re = re.compile(".*(?P<color>[Rr]ed|[Gg]reen|[Bb]lue|[Bb]lack|[Ww]hite).*")
mana_re = re.compile(".*Symbol_(?P<type>.*)_mana\.gif.*")
tap_re = re.compile(".*tap.gif.*")
basicLand_re = re.compile("\[(?P<mana>.)\]")
split_re = re.compile("(?P<t1>.*) // (?P<name2>.*) (?P<mana2>\{.*\}) (?P<type2>.*) (?P<t2>.*)")
id_re = re.compile(".*id=(?P<id>\d*).*")
reminder_re = re.compile('(\A[^\(]*)|((?<=\))[^\(]*)')
_stripReminderText = True;
def replaceSymbols(soup):
for symbol in soup.findAll('img'):
m = color_re.match(str(symbol['src']))
if m:
s = colorSymbols[m.group('color').lower()]
symbol.replaceWith('{' + s + '}')
m = mana_re.match(str(symbol))
if m:
if m.group('type') == "Snow":
symbol.replaceWith('{S}')
else:
symbol.replaceWith('{' + m.group('type') + '}')
m = tap_re.match(str(symbol))
if m:
symbol.replaceWith('{T}')
return soup
def getCardTypes(soup):
types = [t.strip()
for t in soup('td')[2]('font')[0].string.split('-',1)]
if (len(types) == 2):
supertype = types[0]
subtype = types[1]
else:
supertype = types[0]
subtype = ''
# replace entities, since gccg doesn't undertand them in attributes
subtype = subtype.replace("&#226;", u"\342")
return supertype, subtype
def cleanupHTMLText(htmlText, stripReminder = _stripReminderText):
for i in htmlText.findAll('br'):
i.replaceWith(' ')
for i in htmlText.findAll('i'):
i.replaceWith(''.join(i.contents))
for i in htmlText.findAll('b'):
i.replaceWith(''.join(i.contents))
text = htmlText('font')[0].renderContents(None)
# add text for Basic Land
m = basicLand_re.match(text)
if m:
text = u"{T}: Add {" + m.group('mana') + u"} to your mana pool."
if text == u"&nbsp;":
text = u""
text = text.translate(cleanuptrans)
if stripReminder:
text = ''.join([''.join(m) for m in reminder_re.findall(text)])
return text