Merge with develop

--HG--
branch : compatibility-develop
hg/compatibility-develop
kervala 9 years ago
commit b44b24acd3

@ -106,6 +106,7 @@ ENDIF(WIN32)
FIND_PACKAGE(LibXml2 REQUIRED) FIND_PACKAGE(LibXml2 REQUIRED)
FIND_PACKAGE(PNG REQUIRED) FIND_PACKAGE(PNG REQUIRED)
FIND_PACKAGE(GIF)
FIND_PACKAGE(Jpeg) FIND_PACKAGE(Jpeg)
IF(WITH_STATIC_LIBXML2) IF(WITH_STATIC_LIBXML2)

@ -44,6 +44,7 @@ const uint32 DDS_HEADER = NL_MAKEFOURCC('D', 'D', 'S', ' ');
const uint32 DXT_HEADER = NL_MAKEFOURCC('D', 'X', 'T', '\0'); const uint32 DXT_HEADER = NL_MAKEFOURCC('D', 'X', 'T', '\0');
const uint32 PNG_HEADER = NL_MAKEFOURCC(0x89, 'P', 'N', 'G'); const uint32 PNG_HEADER = NL_MAKEFOURCC(0x89, 'P', 'N', 'G');
const uint32 JPG_HEADER = NL_MAKEFOURCC(0xff, 0xd8, 0xff, 0xe0); const uint32 JPG_HEADER = NL_MAKEFOURCC(0xff, 0xd8, 0xff, 0xe0);
const uint32 GIF_HEADER = NL_MAKEFOURCC('G', 'I', 'F', '8');
// dwLinearSize is valid // dwLinearSize is valid
@ -132,6 +133,15 @@ private :
uint8 readJPG( NLMISC::IStream &f ); uint8 readJPG( NLMISC::IStream &f );
/**
* Read a GIF from an IStream.
* GIF pictures are all converted to 32bit
* \param f IStream (must be a reading stream)
* \return image depth if succeed, 0 else
*/
uint8 readGIF( NLMISC::IStream &f );
/** /**
* Change bitmap format * Change bitmap format
* *

@ -187,6 +187,12 @@ IF(JPEG_FOUND)
TARGET_LINK_LIBRARIES(nelmisc ${JPEG_LIBRARY}) TARGET_LINK_LIBRARIES(nelmisc ${JPEG_LIBRARY})
ENDIF(JPEG_FOUND) ENDIF(JPEG_FOUND)
IF(GIF_FOUND)
INCLUDE_DIRECTORIES(${GIF_INCLUDE_DIR})
ADD_DEFINITIONS(-DUSE_GIF)
TARGET_LINK_LIBRARIES(nelmisc ${GIF_LIBRARY})
ENDIF(GIF_FOUND)
IF(WITH_STATIC OR WIN32) IF(WITH_STATIC OR WIN32)
TARGET_LINK_LIBRARIES(nelmisc ${PNG_LIBRARIES}) TARGET_LINK_LIBRARIES(nelmisc ${PNG_LIBRARIES})
ELSE(WITH_STATIC OR WIN32) ELSE(WITH_STATIC OR WIN32)

@ -134,6 +134,19 @@ uint8 CBitmap::load(NLMISC::IStream &f, uint mipMapSkip)
} }
#endif // USE_JPEG #endif // USE_JPEG
#ifdef USE_GIF
if (fileType == GIF_HEADER)
{
#ifdef NEL_ALL_BITMAP_WHITE
uint8 result = readGIF(f);
MakeWhite (*this);
return result;
#else // NEL_ALL_BITMAP_WHITE
return readGIF(f);
#endif // NEL_ALL_BITMAP_WHITE
}
#endif // USE_GIF
// assuming it's TGA // assuming it's TGA
NLMISC::IStream::TSeekOrigin origin= f.begin; NLMISC::IStream::TSeekOrigin origin= f.begin;
if(!f.seek (0, origin)) if(!f.seek (0, origin))
@ -3149,6 +3162,25 @@ void CBitmap::loadSize(NLMISC::IStream &f, uint32 &retWidth, uint32 &retHeight)
} }
while(!eof); while(!eof);
} }
else if(fileType == GIF_HEADER)
{
// check second part of header ("7a" or "9a" in 'GIF89a')
uint16 s;
f.serial(s);
if (s != 0x6137 && s != 0x6139)
{
nlwarning("Invalid GIF header, expected GIF87a or GIF89a");
return;
}
uint16 lsWidth;
uint16 lsHeight;
f.serial(lsWidth);
f.serial(lsHeight);
retWidth = lsWidth;
retHeight = lsHeight;
}
// assuming it's TGA // assuming it's TGA
else else
{ {

@ -0,0 +1,315 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdmisc.h"
#include "nel/misc/bitmap.h"
#ifdef USE_GIF
#include <gif_lib.h>
#endif
using namespace std;
namespace NLMISC
{
#ifdef USE_GIF
// GIFLIB_MAJOR is defined from version 5
#ifndef GIFLIB_MAJOR
#define GIFLIB_MAJOR 4
#endif
static uint8 GIF_TRANSPARENT_MASK = 0x01;
static uint8 GIF_DISPOSE_MASK = 0x07;
static sint8 GIF_NOT_TRANSPARENT = -1;
static uint8 GIF_DISPOSE_NONE = 0;
static uint8 GIF_DISPOSE_LEAVE = 1;
static uint8 GIF_DISPOSE_BACKGROUND = 2;
static uint8 GIF_DISPOSE_RESTORE = 3;
static NLMISC::IStream *GIFStream = NULL;
#if GIFLIB_MAJOR < 5
static uint8 INTERLACED_OFFSET[] = { 0, 4, 2, 1 };
static uint8 INTERLACED_JUMP[] = { 8, 8, 4, 2 };
#endif
static int readGIFData(GifFileType *gif, GifByteType *data, int length){
NLMISC::IStream *f = static_cast<NLMISC::IStream *>(gif->UserData);
if(!f->isReading()) return 0;
try
{
f->serialBuffer((uint8*) data, length);
}
catch(...)
{
nlwarning("error while reading JPEG image");
return 0;
}
return length;
}
/*-------------------------------------------------------------------*\
readGIF
\*-------------------------------------------------------------------*/
uint8 CBitmap::readGIF( NLMISC::IStream &f )
{
if(!f.isReading()) return false;
{
// check gif canvas dimension
uint16 ver;
uint16 width;
uint16 height;
f.serial(ver);
f.serial(width);
f.serial(height);
// limit image size as we are using 32bit pixels
// 4000x4000x4 ~ 61MiB
if (width*height > 4000*4000)
{
nlwarning("GIF image size is too big (width=%d, height=%d)", width, height);
return 0;
}
// rewind for gif decoder
f.seek(-10, IStream::current);
}
#if GIFLIB_MAJOR >= 5
sint32 errorCode;
GifFileType *gif = DGifOpen(&f, readGIFData, &errorCode);
if (gif == NULL)
{
nlwarning("failed to open gif, error=%d", errorCode);
return 0;
}
#else
GifFileType *gif = DGifOpen(&f, readGIFData);
if (gif == NULL)
{
nlwarning("failed to open gif, error=%d", GifLastError());
return 0;
}
#endif
// this will read and decode all frames
sint32 ret = DGifSlurp(gif);
if (ret != GIF_OK)
{
nlwarning("failed to read gif, error=%d", ret);
#if GIFLIB_MAJOR >= 5 && GIFLIB_MINOR >= 1
DGifCloseFile(gif, &errorCode);
#else
DGifCloseFile(gif);
#endif
return 0;
}
// resize target buffer
uint32 dstChannels = 4; // RGBA
resize (gif->SWidth, gif->SHeight, RGBA);
// make transparent
_Data[0].fill(0);
// make sure background color index exists in global colormap
if (gif->SColorMap && gif->SColorMap->ColorCount < gif->SBackGroundColor)
{
gif->SBackGroundColor = 0;
}
// merge all frames one by one into single target
ColorMapObject *ColorMap;
sint32 transparency = GIF_NOT_TRANSPARENT;
uint8 r, g, b, a;
uint32 offset_x, offset_y, width, height;
// disable loop as we only interested in first frame
// for (uint32 frame = 0; frame < gif->ImageCount; frame++)
{
uint32 frame = 0;
SavedImage *curFrame = &gif->SavedImages[frame];
if (curFrame->ExtensionBlockCount > 0)
{
for(uint e=0; e<curFrame->ExtensionBlockCount; e++){
ExtensionBlock *ext = &curFrame->ExtensionBlocks[e];
if (ext->Function == GRAPHICS_EXT_FUNC_CODE) {
uint8 flag = ext->Bytes[0];
//delay = (ext.Bytes[1] << 8) | ext.Bytes[2];
transparency = (flag & GIF_TRANSPARENT_MASK) ? ext->Bytes[3] : GIF_NOT_TRANSPARENT;
//dispose = ((flag >> 2) & GIF_DISPOSE_MASK);
}
}
}
// select color map for frame
if (curFrame->ImageDesc.ColorMap)
{
ColorMap = curFrame->ImageDesc.ColorMap;
}
else
if (gif->SColorMap)
{
ColorMap = gif->SColorMap;
}
else
{
nlwarning("GIF has no global or local color map");
ColorMap = NULL;
}
// copy frame to canvas
offset_x = curFrame->ImageDesc.Left;
offset_y = curFrame->ImageDesc.Top;
width = curFrame->ImageDesc.Width;
height = curFrame->ImageDesc.Height;
#if GIFLIB_MAJOR < 5
// giflib 4 does not handle interlaced images, so we must do it
if (curFrame->ImageDesc.Interlace)
{
uint32 srcOffset = 0;
for (uint8 pass = 0; pass < 4; pass++)
{
uint32 nextLine = INTERLACED_OFFSET[pass];
// y is destination row
for (uint32 y = 0; y < height; y++)
{
if (y != nextLine)
continue;
uint32 dstOffset = (y + offset_y)*gif->SWidth*dstChannels + offset_x*dstChannels;
nextLine += INTERLACED_JUMP[pass];
for (uint32 x = 0; x < width; x++)
{
srcOffset++;
dstOffset+= dstChannels;
uint32 index = curFrame->RasterBits[srcOffset];
if (index != transparency)
{
// make sure color index is not outside colormap
if (ColorMap)
{
if (index > ColorMap->ColorCount)
{
index = 0;
}
r = ColorMap->Colors[index].Red;
g = ColorMap->Colors[index].Green;
b = ColorMap->Colors[index].Blue;
}
else
{
// broken gif, no colormap
r = g = b = 0;
}
a = 255;
}
else
{
// transparent
r = g = b = a = 0;
}
_Data[0][dstOffset] = r;
_Data[0][dstOffset+1] = g;
_Data[0][dstOffset+2] = b;
_Data[0][dstOffset+3] = a;
} // x loop
} // y loop
} // pass loop
}
else
#endif
for (uint32 y = 0; y < height; y++)
{
uint32 srcOffset = y*width;
uint32 dstOffset = (y + offset_y)*gif->SWidth*dstChannels + offset_x*dstChannels;
for (uint32 x = 0; x < width; x++)
{
srcOffset++;
dstOffset+= dstChannels;
uint32 index = curFrame->RasterBits[srcOffset];
if (index != transparency)
{
// make sure color index is not outside colormap
if (ColorMap)
{
if (index > ColorMap->ColorCount)
{
index = 0;
}
r = ColorMap->Colors[index].Red;
g = ColorMap->Colors[index].Green;
b = ColorMap->Colors[index].Blue;
}
else
{
// broken gif, no colormap
r = g = b = 0;
}
a = 255;
}
else
{
// transparent
r = g = b = a = 0;
}
_Data[0][dstOffset] = r;
_Data[0][dstOffset+1] = g;
_Data[0][dstOffset+2] = b;
_Data[0][dstOffset+3] = a;
} // x loop
} // y loop
}
// clean up after the read, and free any memory allocated
#if GIFLIB_MAJOR >= 5 && GIFLIB_MINOR >= 1
DGifCloseFile(gif, &errorCode);
#else
DGifCloseFile(gif);
#endif
//return the size of a pixel as 32bits
return 32;
}
#else
uint8 CBitmap::readGIF( NLMISC::IStream &/* f */)
{
nlwarning ("You must compile NLMISC with USE_GIF if you want gif support");
return 0;
}
#endif
}//namespace

@ -43,6 +43,9 @@
#include "fog_map.h" #include "fog_map.h"
#include "misc.h" #include "misc.h"
#include "interface_v3/interface_manager.h" #include "interface_v3/interface_manager.h"
#include "actions_client.h"
using namespace NLMISC; using namespace NLMISC;
using namespace NL3D; using namespace NL3D;
@ -699,10 +702,27 @@ REGISTER_ACTION_HANDLER( CHandlerDebugUiDumpElementUnderMouse, "debug_ui_inspect
//----------------------------------------------- //-----------------------------------------------
#define DISP_TEXT(x, text) \ #define DISP_TEXT(x, text) \
/* Display the text at the right place */ \ /* Display the text at the right place */ \
TextContext->printfAt(x, line, text); \ TextContext->printfAt(x, line, std::string(text).c_str()); \
/* Change the line */ \ /* Change the line */ \
line += lineStep; \ line += lineStep; \
//---------------------------------------------------
// getActionKey :
// Return action key binding as string.
static std::string getActionKey(const char* name, const char* param = "")
{
std::string category;
CActionsManager *pAM = &Actions;
const CActionsManager::TActionComboMap &acmap = pAM->getActionComboMap();
CActionsManager::TActionComboMap::const_iterator ite = acmap.find(CAction::CName(name, param));
if (ite != acmap.end())
return ite->second.toUCString().toString();
return CI18N::get("uiNotAssigned").toString();
}
//--------------------------------------------------- //---------------------------------------------------
// displayHelp : // displayHelp :
// Display an Help. // Display an Help.
@ -720,54 +740,53 @@ void displayHelp()
// Set the text color // Set the text color
TextContext->setColor(ClientCfg.HelpFontColor); TextContext->setColor(ClientCfg.HelpFontColor);
line = 1.f; line = 1.f;
TextContext->setHotSpot(UTextContext::TopLeft); TextContext->setHotSpot(UTextContext::TopLeft);
DISP_TEXT(0.0f, "SHIFT + F1 : This Menu") DISP_TEXT(0.0f, getActionKey("toggle_help") + " : This Menu");
DISP_TEXT(0.0f, "SHIFT + F2 : Display Debug Infos") DISP_TEXT(0.0f, getActionKey("display_infos") + " : Display Debug Infos");
DISP_TEXT(0.0f, "SHIFT + F3 : Wire mode"); DISP_TEXT(0.0f, getActionKey("render_mode") + " : Wire mode");
DISP_TEXT(0.0f, "SHIFT + F4 : Do not Render the Scene"); DISP_TEXT(0.0f, getActionKey("toggle_render") + " : Do not Render the Scene");
DISP_TEXT(0.0f, "SHIFT + F5 : Toogle Display OSD interfaces"); DISP_TEXT(0.0f, getActionKey("toggle_chat") + " : Toggle Display OSD interfaces");
// DISP_TEXT(0.0f, "SHIFT + F6 : Not used"); // DISP_TEXT(0.0f, "SHIFT + F6 : Not used");
DISP_TEXT(0.0f, "SHIFT + F7 : Compass Mode (User/Camera)"); DISP_TEXT(0.0f, getActionKey("change_compass_mode") + " : Compass Mode (User/Camera)");
DISP_TEXT(0.0f, "SHIFT + F8 : Camera Mode (INSERT to change your position)"); DISP_TEXT(0.0f, getActionKey("toggle_fly") + " : Camera Mode (" + getActionKey("debug", "set_pos") + " to change your position)");
DISP_TEXT(0.0f, "SHIFT + F9 : Free Mouse"); DISP_TEXT(0.0f, getActionKey("free_mouse") + " : Free Mouse");
DISP_TEXT(0.0f, "SHIFT + F10 : Take a Screen Shot (+CTRL) for jpg"); DISP_TEXT(0.0f, getActionKey("screen_shot") + " : Take a Screen Shot (TGA), " + getActionKey("screen_shot_jpg") + " for jpg, " + getActionKey("screen_shot_png") + " for png");
// DISP_TEXT(0.0f, "SHIFT + F11 : Test"); // DISP_TEXT(0.0f, "SHIFT + F11 : Test");
DISP_TEXT(0.0f, "SHIFT + ESCAPE : Quit"); DISP_TEXT(0.0f, getActionKey("enter_modal", "group=ui:interface:quit_dialog") + " : Quit");
DISP_TEXT(0.0f, "SHIFT + C : First/Third Person View"); DISP_TEXT(0.0f, getActionKey("toggle_camera") + " : First/Third Person View");
line = 1.f; line = 1.f;
TextContext->setHotSpot(UTextContext::TopRight); TextContext->setHotSpot(UTextContext::TopRight);
DISP_TEXT(1.0f, "UP : FORWARD"); DISP_TEXT(1.0f, getActionKey("forward") + " : FORWARD");
DISP_TEXT(1.0f, "DOWN : BACKWARD"); DISP_TEXT(1.0f, getActionKey("backward") + " : BACKWARD");
DISP_TEXT(1.0f, "LEFT : ROTATE LEFT"); DISP_TEXT(1.0f, getActionKey("turn_left") + " : ROTATE LEFT");
DISP_TEXT(1.0f, "RIGHT : ROTATE RIGHT"); DISP_TEXT(1.0f, getActionKey("turn_right") + " : ROTATE RIGHT");
DISP_TEXT(1.0f, "CTRL + LEFT : STRAFE LEFT"); DISP_TEXT(1.0f, getActionKey("strafe_left") + " : STRAFE LEFT");
DISP_TEXT(1.0f, "CTRL + RIGHT : STRAFE RIGHT"); DISP_TEXT(1.0f, getActionKey("strafe_right") + " : STRAFE RIGHT");
DISP_TEXT(1.0f, "END : Auto Walk"); DISP_TEXT(1.0f, getActionKey("toggle_auto_walk") + " : Auto Walk");
DISP_TEXT(1.0f, "DELETE : Walk/Run"); DISP_TEXT(1.0f, getActionKey("toggle_run_walk") + " : Walk/Run");
DISP_TEXT(1.0f, "PG UP : Look Up"); DISP_TEXT(1.0f, getActionKey("look_up") + " : Look Up");
DISP_TEXT(1.0f, "PG DOWN : Look Down"); DISP_TEXT(1.0f, getActionKey("look_down") + " : Look Down");
// DISP_TEXT(1.0f, "CTRL + I : Inventory"); // DISP_TEXT(1.0f, getActionKey("show_hide", "inventory") + " : Inventory");
// DISP_TEXT(1.0f, "CTRL + C : Spells composition interface"); // DISP_TEXT(1.0f, getActionKey("show_hide", "phrase_book") + " : Spells composition interface");
// DISP_TEXT(1.0f, "CTRL + S : Memorized Spells interface"); // DISP_TEXT(1.0f, getActionKey("show_hide", "gestionsets") + " : Memorized Spells interface");
DISP_TEXT(1.0f, "CTRL + B : Show/Hide PACS Borders"); DISP_TEXT(1.0f, getActionKey("pacs_borders") + " : Show/Hide PACS Borders");
DISP_TEXT(1.0f, "CTRL + P : Player target himself"); DISP_TEXT(1.0f, getActionKey("self_target") + " : Player target himself");
DISP_TEXT(1.0f, "CTRL + D : Unselect target"); DISP_TEXT(1.0f, getActionKey("no_target") + " : Unselect target");
DISP_TEXT(1.0f, "CTRL + TAB : Next Chat Mode (say/shout"); // DISP_TEXT(1.0f, "CTRL + TAB : Next Chat Mode (say/shout");
DISP_TEXT(1.0f, "CTRL + R : Reload Client.cfg File"); // DISP_TEXT(1.0f, "CTRL + R : Reload Client.cfg File");
// DISP_TEXT(1.0f, "CTRL + N : Toggle Night / Day lighting"); // DISP_TEXT(1.0f, "CTRL + N : Toggle Night / Day lighting");
DISP_TEXT(1.0f, "CTRL + F2 : Profile on / off"); DISP_TEXT(1.0f, getActionKey("profile") + " : Profile on / off");
DISP_TEXT(1.0f, "CTRL + F3 : Movie Shooter record / stop"); DISP_TEXT(1.0f, getActionKey("toggle_movie_recorder") + " : Movie Shooter record / stop");
DISP_TEXT(1.0f, "CTRL + F4 : Movie Shooter replay"); DISP_TEXT(1.0f, getActionKey("replay_movie") + " : Movie Shooter replay");
DISP_TEXT(1.0f, "CTRL + F5 : Movie Shooter save"); DISP_TEXT(1.0f, getActionKey("save_movie") + " : Movie Shooter save");
#ifndef NL_USE_DEFAULT_MEMORY_MANAGER #ifndef NL_USE_DEFAULT_MEMORY_MANAGER
DISP_TEXT(1.0f, "CTRL + F6 : Save memory stat report"); DISP_TEXT(1.0f, getActionKey("memory_report") + " : Save memory stat report");
#endif // NL_USE_DEFAULT_MEMORY_MANAGER #endif // NL_USE_DEFAULT_MEMORY_MANAGER
DISP_TEXT(1.0f, "CTRL + F7 : Show / hide prim file"); DISP_TEXT(1.0f, getActionKey("toggle_primitive") + " : Show / hide prim file");
DISP_TEXT(1.0f, "CTRL + F8 : Change prim file UP"); DISP_TEXT(1.0f, getActionKey("primitive_up") + " : Change prim file UP");
DISP_TEXT(1.0f, "CTRL + F9 : Change prim file DOWN"); DISP_TEXT(1.0f, getActionKey("primitive_down") + " : Change prim file DOWN");
// No more shadow when displaying a text. // No more shadow when displaying a text.
TextContext->setShaded(false); TextContext->setShaded(false);

@ -0,0 +1,6 @@
@echo off
echo Generating words diff...
bin\translation_tools make_words_diff
echo Done.
pause

@ -0,0 +1,6 @@
@echo off
echo Merging words diff...
bin\translation_tools merge_words_diff
echo Done.
pause

@ -0,0 +1,16 @@
@echo off
echo Installing translation file into ryzom...
REM Copy translated files in client directory...
xcopy /Y translated\*.uxt ..\..\client\data\gamedev\language\
xcopy /Y translated\skill_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\item_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\creature_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\sbrick_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\sphrase_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\place_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\faction_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\title_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\outpost_*.txt ..\..\client\data\gamedev\language\
echo Done.

@ -0,0 +1,6 @@
@echo off
echo Cleaning string diff...
bin\translation_tools clean_string_diff
echo Done.
pause

@ -0,0 +1,6 @@
@echo off
echo Generating string diff...
bin\translation_tools make_string_diff
echo Done.
pause

@ -0,0 +1,6 @@
@echo off
echo Merging string diff...
bin\translation_tools merge_string_diff
echo Done.
pause

@ -0,0 +1,24 @@
Please don't update files in "translated" directly!
First, be sure you put "translation_tools" in "bin" directory.
How to update translations in UXT files :
1. Update original texts in "work/wk.uxt"
2. Launch A_make_string_diff script
3. Open files in "diff" directory
4. Replace original text with translation between [ and ]
5. The 2 last lines : // REMOVE THE FOLOWING LINE WHEN TRANSLATION IS DONE and // DIFF NOT TRANSLATED
6. Save files
7. Launch AA_clean_string_diff to delete translations help (old values)
8. Launch B_merge_string_diff to merge your translations in "translated"
How to update translations in words files :
1. Update original texts in "work" directory
2. Launch 5_make_words_diff script
3. Open files in "diff" directory
4. Replace original text with translation (separators are <tab>)
5. The 2 last lines : REMOVE THE FOLOWING TWO LINE WHEN TRANSLATION IS DONE and DIFF NOT TRANSLATED
6. Save files
7. Launch 6_merge_words_diff to merge your translations in "translated"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save