Guest ShadowJack Posted November 18, 2010 Share Posted November 18, 2010 I am building GemRB on Armel (Droid2 running debian) I am seeing the following compilation errors. /root/gemrb-0.6.2/gemrb/core/Scriptable/Actor.cpp: In member function 'void Actor::SetupFist()': /root/gemrb-0.6.2/gemrb/core/Scriptable/Actor.cpp:5855: error: cast from 'char (*)[9]' to 'int*' increases required alignment of target type /root/gemrb-0.6.2/gemrb/core/Scriptable/Actor.cpp:5864: error: cast from 'char (*)[9]' to 'int*' increases required alignment of target type make[2]: *** [gemrb/core/CMakeFiles/gemrb_core.dir/Scriptable/Actor.o] Error 1 make[1]: *** [gemrb/core/CMakeFiles/gemrb_core.dir/all] Error 2 make: *** [all] Error 2 I have turned off warnings as errors, so this is an issue I do not know how to fix easily. I assume the Android port will also have the same issues. It appears that issues like these were fixed a few years ago. I would be glad to do the fixing if someone can point me in the right direction. Thanks, ShadlowJack Link to comment
lynx Posted November 18, 2010 Share Posted November 18, 2010 You can comment the whole "if (FistRows<0)" and the last for loop, while we work on a proper fix. Only monks will be ill-affected. Link to comment
lynx Posted November 18, 2010 Share Posted November 18, 2010 This should fix it: http://sprunge.us/BEQL Better yet, just get the git version of gemrb, since maybe you'll run into other issues we'll need to fix. Link to comment
Guest ShadowJack Posted November 18, 2010 Share Posted November 18, 2010 Thanks for the quick response. Actor builds fine now. I did use git, and yes I did find more issues. I have a small change to CMakeLists.txt for those whose are not using OGG. What workflow do you prefer? git push or something more elaborate? -sj Link to comment
fuzzie Posted November 18, 2010 Share Posted November 18, 2010 What workflow do you prefer? git push or something more elaborate? git push to a repository somewhere (e.g. github) and then prodding us is easiest, or just putting patches somewhere. I notice also that I forgot to fix ReadChrHeader last time I tried this myself, meh.. Link to comment
Guest ShadowJack Posted November 29, 2010 Share Posted November 29, 2010 What is any plugins are required? Link to comment
Guest ShadowJack Posted November 29, 2010 Share Posted November 29, 2010 What is any plugins are required? Let me try that again. What, if any, plugins are required? Link to comment
lynx Posted November 29, 2010 Share Posted November 29, 2010 Almost all. PNG/OGG/audio ones are not needed. Link to comment
Avenger Posted November 30, 2010 Share Posted November 30, 2010 Theoretically, you can build a game without items, spells or creatures But that wouldn't be much of a game. Other plugins may have alternatives later. Link to comment
Guest ShadowJack Posted December 2, 2010 Share Posted December 2, 2010 I finally got it built. Several plugins required work for ARM. I am still testing the changes, but here's a patch I would like to promote: From 9c0555fe1b1ba733cc68685dbb63cec46fb582fd Mon Sep 17 00:00:00 2001 From: root <root@localhost.(none)> Date: Thu, 2 Dec 2010 19:01:11 +0000 Subject: [PATCH] Allowed compilation without OGG support. --- CMakeLists.txt | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 598fe9e..ad88c76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -183,7 +183,9 @@ find_path(VORBIS_FILE vorbisfile.h PATH_SUFFIXES vorbis) IF(VORBIS_LIBRARY AND VORBIS_FILE) MESSAGE(STATUS "Looking for Ogg Vorbis support: found") ELSE() - unset(VORBIS_LIBRARY) # disable the build for this plugin + IF(VORBIS_LIBRARY) + unset(VORBIS_LIBRARY) # disable the build for this plugin + ENDIF() MESSAGE(WARNING "Looking for Ogg Vorbis support: not found!") MESSAGE(WARNING "While no original game data is in OGG format, some mod data is and will need conversion.") ENDIF() -- 1.5.6.5 Link to comment
lynx Posted December 2, 2010 Share Posted December 2, 2010 Something cleaner was committed, rendering that patch unneeded. But thanks for bringing it to our attention. Link to comment
Guest ShadowJack Posted December 6, 2010 Share Posted December 6, 2010 Something cleaner was committed, rendering that patch unneeded. But thanks for bringing it to our attention. Thanks, I picked up that code. I see something odd in SDLAudio::Play(...). If I apply the following patch I can compile for arm. diff --git a/gemrb/plugins/SDLAudio/SDLAudio.cpp b/gemrb/plugins/SDLAudio/SDLAudio.cpp index 9bdb3a9..ada1297 100644 --- a/gemrb/plugins/SDLAudio/SDLAudio.cpp +++ b/gemrb/plugins/SDLAudio/SDLAudio.cpp @@ -144,11 +144,10 @@ Holder<SoundHandle> SDLAudio::Play(const char* ResRef, int XPos, int YPos, unsig int cnt = acm->get_length(); int riff_chans = acm->get_channels(); int samplerate = acm->get_samplerate(); - //multiply always by 2 because it is in 16 bits - int rawsize = cnt * 2; - unsigned char * memory = (unsigned char*) malloc(rawsize); + //Use 16-bit word for memory allocation because read_samples takes a 16 bit alignment + short * memory = (short *) malloc(cnt); //multiply always with 2 because it is in 16 bits - int cnt1 = acm->read_samples( ( short* ) memory, cnt ) * 2; + int cnt1 = acm->read_samples( memory, cnt ) * 2; //Sound Length in milliseconds unsigned int time_length = ((cnt / riff_chans) * 1000) / samplerate; @@ -161,7 +160,7 @@ Holder<SoundHandle> SDLAudio::Play(const char* ResRef, int XPos, int YPos, unsig SDL_BuildAudioCVT(&cvt, AUDIO_S16SYS, riff_chans, samplerate, audio_format, audio_channels, audio_rate); cvt.buf = (Uint8*)malloc(cnt1*cvt.len_mult); - memcpy(cvt.buf, memory, cnt1); + memcpy(cvt.buf, (char*) memory, cnt1); cvt.len = cnt1; SDL_ConvertAudio(&cvt); It looks like the code is creating an extra copy of the samples (memory) that is thrown away after it us copied to cvt.buf, but I did not look at the larger picture, so I may be wrong. In any case, please apply this patch or something better. -ShadowJack Link to comment
Guest ShadowJack Posted December 6, 2010 Share Posted December 6, 2010 This set of changes supports ARM5 and runs Baldur's Gate. I tested with PST and it works except for the 16-bit MVE. Where possible I wrote generic code for all machines, but I have some ARM specific code for cases when I think the performance is important and the original code is cleaner/better. I will work on MVE-16 next, but that looks like slow going. -ShadowJack From ad74e1496260c751c1c3d1245ee2c1e889a6bcff Mon Sep 17 00:00:00 2001 From: root <root@localhost.(none)> Date: Mon, 6 Dec 2010 22:04:45 +0000 Subject: [PATCH] Fix unaligned accesses for ARM5 architectures --- gemrb/plugins/BIKPlayer/BIKPlayer.cpp | 36 +++++++++-- gemrb/plugins/BIKPlayer/GetBitContext.cpp | 17 +++++ gemrb/plugins/CREImporter/CREImporter.cpp | 5 +- gemrb/plugins/SDLAudio/SDLAudio.cpp | 9 +-- gemrb/plugins/SDLVideo/SDLVideo.cpp | 95 ++++++++++++++++++++++++++--- gemrb/plugins/WAVReader/WAVReader.cpp | 19 ++++-- 6 files changed, 154 insertions(+), 27 deletions(-) diff --git a/gemrb/plugins/BIKPlayer/BIKPlayer.cpp b/gemrb/plugins/BIKPlayer/BIKPlayer.cpp index 65092ab..580dc15 100644 --- a/gemrb/plugins/BIKPlayer/BIKPlayer.cpp +++ b/gemrb/plugins/BIKPlayer/BIKPlayer.cpp @@ -1153,10 +1153,35 @@ int BIKPlayer::read_colors(Bundle *b) /** number of bits used to store first DC value in bundle */ #define DC_START_BITS 11 +#if defined(__arm__) +#define SET_INT_TYPE uint8_t +#define SET_INT_VALUE(ptr, value)\ + *(ptr) = (value) && 0xff; \ + (ptr)++; \ + *(ptr) = ((value) >> 8) && 0xff; \ + (ptr)++; +#else +#define SET_INT_TYPE int16_t +#define SET_INT_VALUE(ptr, value)\ + *(ptr)++ = (value); +#endif + +#if defined(__arm__) +#define GET_INT_VALUE(value, ptr)\ + (value) = *(ptr); \ + (ptr)++; \ + (value) |= (*(ptr)) << 8; \ + (ptr)++; +#else +#define GET_INT_VALUE(value, ptr)\ + (value) = *(int16_t*)(ptr); \ + (ptr) += 2; +#endif + int BIKPlayer::read_dcs(Bundle *b, int start_bits, int has_sign) { int i, j, len, len2, bsize, v, v2; - int16_t *dst = (int16_t*)b->cur_dec; + SET_INT_TYPE *dst = (SET_INT_TYPE*)b->cur_dec; CHECK_READ_VAL(v_gb, b, len); if (has_sign) { @@ -1166,7 +1191,7 @@ int BIKPlayer::read_dcs(Bundle *b, int start_bits, int has_sign) } else { v = v_gb.get_bits(start_bits); } - *dst++ = v; + SET_INT_VALUE(dst, v); len--; for (i = 0; i < len; i += 8) { len2 = FFMIN(len - i, 8); @@ -1178,14 +1203,14 @@ int BIKPlayer::read_dcs(Bundle *b, int start_bits, int has_sign) v2 = -v2; } v += v2; - *dst++ = v; + SET_INT_VALUE(dst, v); if (v < -32768 || v > 32767) { return -1; } } } else { for (j = 0; j < len2; j++) { - *dst++ = v; + SET_INT_VALUE(dst, v); } } } @@ -1204,8 +1229,7 @@ inline int BIKPlayer::get_value(int bundle) if (bundle == BINK_SRC_X_OFF || bundle == BINK_SRC_Y_OFF) { return (int8_t)*c_bundle[bundle].cur_ptr++; } - ret = *(int16_t*)c_bundle[bundle].cur_ptr; - c_bundle[bundle].cur_ptr += 2; + GET_INT_VALUE(ret, c_bundle[bundle].cur_ptr); return ret; } diff --git a/gemrb/plugins/BIKPlayer/GetBitContext.cpp b/gemrb/plugins/BIKPlayer/GetBitContext.cpp index eaaca2d..ace0cee 100644 --- a/gemrb/plugins/BIKPlayer/GetBitContext.cpp +++ b/gemrb/plugins/BIKPlayer/GetBitContext.cpp @@ -175,6 +175,22 @@ int VLC::alloc_table(int size) return index; } +#if defined(__arm__) +#define GET_DATA(v, table, i, wrap, size) \ +{\ + const uint8_t *ptr = (const uint8_t *)table + i * wrap;\ + v = 0;\ + switch(size) {\ + case 4:\ + v |= *((const uint8_t *)ptr+3) << 24;\ + v |= *((const uint8_t *)ptr+2) << 16;\ + case 2:\ + v |= *((const uint8_t *)ptr+1) << 8;\ + case 1:\ + v |= *(const uint8_t *)ptr;\ + }\ +} +#else #define GET_DATA(v, table, i, wrap, size) \ {\ const uint8_t *ptr = (const uint8_t *)table + i * wrap;\ @@ -190,6 +206,7 @@ int VLC::alloc_table(int size) break;\ }\ } +#endif int VLC::build_table(int table_nb_bits, int nb_codes, const void *bits, int bits_wrap, int bits_size, diff --git a/gemrb/plugins/CREImporter/CREImporter.cpp b/gemrb/plugins/CREImporter/CREImporter.cpp index 84e471c..3f73424 100644 --- a/gemrb/plugins/CREImporter/CREImporter.cpp +++ b/gemrb/plugins/CREImporter/CREImporter.cpp @@ -553,7 +553,6 @@ void CREImporter::ReadChrHeader(Actor *act) ieVariable name; char Signature[8]; ieDword offset, size; - ieDword tmpDword; ieWord tmpWord; ieByte tmpByte; @@ -562,8 +561,8 @@ void CREImporter::ReadChrHeader(Actor *act) str->Read (Signature, 8); str->Read (name, 32); name[32]=0; - tmpDword = *(ieDword *) name; - if (tmpDword != 0 && tmpDword !=1) { + tmpByte = *name; + if (tmpByte != 0 && tmpByte !=1) { act->SetName( name, 0 ); //setting longname } str->ReadDword( &offset); diff --git a/gemrb/plugins/SDLAudio/SDLAudio.cpp b/gemrb/plugins/SDLAudio/SDLAudio.cpp index 9bdb3a9..ada1297 100644 --- a/gemrb/plugins/SDLAudio/SDLAudio.cpp +++ b/gemrb/plugins/SDLAudio/SDLAudio.cpp @@ -144,11 +144,10 @@ Holder<SoundHandle> SDLAudio::Play(const char* ResRef, int XPos, int YPos, unsig int cnt = acm->get_length(); int riff_chans = acm->get_channels(); int samplerate = acm->get_samplerate(); - //multiply always by 2 because it is in 16 bits - int rawsize = cnt * 2; - unsigned char * memory = (unsigned char*) malloc(rawsize); + //Use 16-bit word for memory allocation because read_samples takes a 16 bit alignment + short * memory = (short *) malloc(cnt); //multiply always with 2 because it is in 16 bits - int cnt1 = acm->read_samples( ( short* ) memory, cnt ) * 2; + int cnt1 = acm->read_samples( memory, cnt ) * 2; //Sound Length in milliseconds unsigned int time_length = ((cnt / riff_chans) * 1000) / samplerate; @@ -161,7 +160,7 @@ Holder<SoundHandle> SDLAudio::Play(const char* ResRef, int XPos, int YPos, unsig SDL_BuildAudioCVT(&cvt, AUDIO_S16SYS, riff_chans, samplerate, audio_format, audio_channels, audio_rate); cvt.buf = (Uint8*)malloc(cnt1*cvt.len_mult); - memcpy(cvt.buf, memory, cnt1); + memcpy(cvt.buf, (char*) memory, cnt1); cvt.len = cnt1; SDL_ConvertAudio(&cvt); diff --git a/gemrb/plugins/SDLVideo/SDLVideo.cpp b/gemrb/plugins/SDLVideo/SDLVideo.cpp index f5e0d1c..893a0b7 100644 --- a/gemrb/plugins/SDLVideo/SDLVideo.cpp +++ b/gemrb/plugins/SDLVideo/SDLVideo.cpp @@ -1710,6 +1710,35 @@ void SDLVideoDriver::DrawRectSprite(const Region& rgn, const Color& color, const } inline void ReadPixel(long &val, unsigned char *pixels, int BytesPerPixel) { +#if defined(__arm__) +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + long pixel = 0; + switch (BytesPerPixel) { + case 4: + pixel |= *(pixels+3) << 24; + case 3: + pixel |= *(pixels+2) << 16; + case 2: + pixel |= *(pixels+1) << 8; + case 1: + pixel |= *(pixels); + } + val = pixel; +#else + long pixel = 0; + switch (BytesPerPixel) { + case 4: + pixel |= *(pixels+3); + case 3: + pixel |= *(pixels+2) << 8; + case 2: + pixel |= *(pixels+1) << 16; + case 1: + pixel |= *(pixels) << 24; + } + val = pixel; +#endif +#else if (BytesPerPixel == 1) { val = *pixels; } else if (BytesPerPixel == 2) { @@ -1722,10 +1751,35 @@ inline void ReadPixel(long &val, unsigned char *pixels, int BytesPerPixel) { #endif } else if (BytesPerPixel == 4) { val = *(Uint32 *)pixels; - } +#endif } inline void WritePixel(const long val, unsigned char *pixels, int BytesPerPixel) { +#if defined(__arm__) +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + switch (BytesPerPixel) { + case 4: + *(pixels+3) = val >> 24 & 0xFF; + case 3: + *(pixels+2) = val >> 16 & 0xFF; + case 2: + *(pixels+1) = val >> 8 & 0xFF; + case 1: + *pixels = val & 0xFF; + } +#else + switch (BytesPerPixel) { + case 4: + *(pixels+3) = val & 0xFF; + case 3: + *(pixels+2) = val >> 8 & 0xFF; + case 2: + *(pixels+1) = val >> 16 & 0xFF; + case 1: + *pixels = val >> 24 & 0xFF; + } +#endif +#else if (BytesPerPixel == 1) { *pixels = (unsigned char)val; } else if (BytesPerPixel == 2) { @@ -1742,7 +1796,7 @@ inline void WritePixel(const long val, unsigned char *pixels, int BytesPerPixel) #endif } else if (BytesPerPixel == 4) { *(Uint32 *)pixels = val; - } +#endif } void SDLVideoDriver::SetPixel(short x, short y, const Color& color, bool clipped) @@ -2195,16 +2249,40 @@ void SDLVideoDriver::DrawPolyline(Gem_Polygon* poly, const Color& color, bool fi // Draw a 50% alpha line from (y,lt) to (y,rt) - if (backBuf->format->BytesPerPixel == 2) { + if (backBuf->format->BytesPerPixel == 2) { +#if defined(__arm__) + Uint8* pix = line + (lt + xCorr) * 2; + Uint8* end = pix + (rt - lt) * 2; + for (; pix < end; pix+=2) { + Uint16 pixel = *pix | *(pix+1) << 8; + pixel = ((pixel >> 1)&mask16) + alphacol16; + *pix = pixel & 0xFF; + *(pix+1) = (pixel >> 8) & 0xFF; + } +#else Uint16* pix = (Uint16*)line + lt + xCorr; Uint16* end = pix + (rt - lt); for (; pix < end; pix++) *pix = ((*pix >> 1)&mask16) + alphacol16; +#endif } else if (backBuf->format->BytesPerPixel == 4) { +#if defined(__arm__) + Uint8* pix = line + (lt + xCorr) * 4; + Uint8* end = pix + (rt - lt) * 4; + for (; pix < end; pix+=4) { + Uint32 pixel = *pix | *(pix+1) << 8 | *(pix+2) << 16 | *(pix+3) << 24; + pixel = ((pixel >> 1)&mask32) + alphacol32; + *pix = pixel & 0xFF; + *(pix+1) = (pixel >> 8) & 0xFF; + *(pix+2) = (pixel >> 16) & 0xFF; + *(pix+3) = (pixel >> 24) & 0xFF; + } +#else Uint32* pix = (Uint32*)line + lt + xCorr; Uint32* end = pix + (rt - lt); for (; pix < end; pix++) *pix = ((*pix >> 1)&mask32) + alphacol32; +#endif } else { assert(false); } @@ -2411,12 +2489,13 @@ void SDLVideoDriver::ClickMouse(unsigned int button) void SDLVideoDriver::MouseClickEvent(Uint8 type, Uint8 button) { - SDL_MouseButtonEvent *event = new SDL_MouseButtonEvent(); + SDL_Event *event = new SDL_Event(); event->type = type; - event->button = button; - event->state = (type==SDL_MOUSEBUTTONDOWN)?SDL_PRESSED:SDL_RELEASED; - event->x = CursorPos.x; - event->y = CursorPos.y; + event->button.type = type; + event->button.button = button; + event->button.state = (type==SDL_MOUSEBUTTONDOWN)?SDL_PRESSED:SDL_RELEASED; + event->button.x = CursorPos.x; + event->button.y = CursorPos.y; SDL_PushEvent((SDL_Event *) event); } diff --git a/gemrb/plugins/WAVReader/WAVReader.cpp b/gemrb/plugins/WAVReader/WAVReader.cpp index 5774423..06a7000 100644 --- a/gemrb/plugins/WAVReader/WAVReader.cpp +++ b/gemrb/plugins/WAVReader/WAVReader.cpp @@ -53,6 +53,15 @@ const unsigned char data_4cc[] = { 'd', 'a', 't', 'a' }; +inline bool cmp4cc(char* first, const unsigned char* second) +{ + for (int index = 0; index < 4; index++) { + if (first[index] != second[index]) + return false; + } + return true; +} + bool RawPCMReader::Open(DataStream* stream) { str = stream; @@ -128,8 +137,8 @@ bool WavPCMReader::Open(DataStream* stream) str->ReadDword(&r_hdr.length); //don't swap this str->Read( &wave, 4 ); - if (r_hdr.fourcc != *( unsigned int * ) RIFF_4cc || - wave != *( unsigned int * ) WAVE_4cc) { + if ( ! cmp4cc((char*) &r_hdr.fourcc, RIFF_4cc) || + ! cmp4cc((char*) &wave, WAVE_4cc)) { return false; } @@ -137,7 +146,7 @@ bool WavPCMReader::Open(DataStream* stream) //don't swap this str->Read(&fmt_hdr.fourcc,4); str->ReadDword(&fmt_hdr.length); - if (fmt_hdr.fourcc != *( unsigned int * ) fmt_4cc || + if ( ! cmp4cc((char*) &fmt_hdr.fourcc, fmt_4cc) || fmt_hdr.length > sizeof( cWAVEFORMATEX )) { return false; } @@ -166,13 +175,13 @@ bool WavPCMReader::Open(DataStream* stream) str->Read(&data_hdr.fourcc,4); str->ReadDword(&data_hdr.length); - if (data_hdr.fourcc == *( unsigned int * ) fact_4cc) { + if (cmp4cc((char*) &data_hdr.fourcc, fact_4cc)) { str->Seek( data_hdr.length, GEM_CURRENT_POS ); //str->Read( &data_hdr, sizeof( data_hdr ) ); str->ReadDword(&data_hdr.fourcc); str->ReadDword(&data_hdr.length); } - if (data_hdr.fourcc != *( unsigned int * ) data_4cc) { + if ( ! cmp4cc((char *) &data_hdr.fourcc, data_4cc)) { return false; } -- 1.5.6.5 Link to comment
Avenger Posted December 7, 2010 Share Posted December 7, 2010 - tmpDword = *(ieDword *) name; - if (tmpDword != 0 && tmpDword !=1) { + tmpByte = *name; + if (tmpByte != 0 && tmpByte !=1) { I think checking for the 1 is not needed anymore, it was due to some bug (misunderstanding in the file structure on my part). That's why i used a dword in the first place too. So it could be a simple if (!name[0]) Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.