War2.ru Slogan
News: Watch live streams at War2TV and replays of
past streams at War2TV Reruns!


Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
Welcome to the forums! We're glad to have you here! :) You can register your account here, then feel free to introduce yourself in the Server.War2.ru board & let us know who you are on the server.

Nerd's Corner 9369  157

Grunt Posts: 100 Karma: +10/-0 ***

Cel

  • Grunt
  • ***
  • *
  • Posts: 100
    • View Profile
*

Cel

Re: Nerd's Corner
« Reply #150 on: October 11, 2018, 08:07:56 AM »
Are these sources somewhere on Github? That would be much handier to read/propose changes or additions :-)

That would help having a global view of the thing too.
I do love C++, ASM is readable I just wonder why work with assembly in the first place, it is very low level and tedious to make even small things  ;D.
But hey what ever works for ya is fine  ^-^

The reason is, I checked your archive and it is flagged as malicious by most common anti viruses, they find a trojan-like pattern/signature in the program which may be avoided.
Given the nature and the simplicity of the program (opening a file and parsing binary / creating an image and saving it) I wanted to see if we could try and find a way to fix the issue.

Also I thought if we have it on Github  maybe I and others could try and help you improve the thing by proposing changes (pull requests, merges, branching all that beauty) to add new features to the thing and/or fix track issues.

The virus detection matters because even if we know it is perfectly safe if we want to put it in the downloads section of the site for everyone to find easily, and google runs a basic automated test like they always do on hosted files, they will flag the whole war2.ru site as malicious, as it happened before. And it is a mess after to make them roll back on these things.

Do you think it could be a good idea? :-)

 :critter:

edit: Also it is a shame we do not have the sources of Alexander cech he did something around these lines (PudImage) and Wardraft which was a map editor that allowed a bit more pud manipulations. :-)
Ogre Posts: 1022 Karma: +64/-0 *******

Lambchops

  • Ogre
  • *******
  • *
  • Posts: 1022
    • View Profile
Re: Nerd's Corner
« Reply #151 on: October 11, 2018, 10:41:05 AM »
The reason is, I checked your archive and it is flagged as malicious by most common anti viruses,


PFFFFFFFF
^Read this^

If anyone wants to actually put any work into programming I am always the first person to help. I have already spent quite a few hours of my time in reply to your request (YOU'RE WELCOME).

I sometimes publish source to try to help people, but mostly I don't do it for 2 reasons:

   1) Vanity

Most programming jobs involve using personal libraries of code and mashing together various bits that I have been writing my entire life.

To publish the source fpr a specific app I would want to go through it all and cut out all the bits that aren't needed for that app, and make sure that there isn't any noobish trashy things I wrote 20 years ago, and I would be embarrassed to have people see without re-writing them properly.

Also source code often ends up with random notes and comments, non-functional first-attempts at things commented out or not... even notes from phone calls I answered while coding.

It can be very time consuming to check, reorganise and sometimes re-write thousands of lines of code to make it appropriate for public viewing. Just publishing hundreds of source files is like emptying out your underwear draw in a public place.

   2) Why would I bother?

Sorry, but quite honestly I've been publishing a large amount of information about programming and the WC2 client for years now, and I'm yet to see one single line of source code that anyone else has written that has helped me with anything.

I have attempted to collaborate with others before and the only thing that happened is I wasted a heap of hours and nobody else contributed anything.

My first thought when you asked for the source was "sure, why not?"

Then I started looking through all the source files for the 3 different elements of PUDPIC and realised it was probably going to take a couple of days to vet and re-assemble the entire lot into a publishable collection and thought... meh - none of these people ever do anything with any of it, why would I waste my time?

If anyone actually wants to do something with it, there is lots to work with here .... go for it!
If anyone can't ....or more likely can't be bothered, to work out even the small amount I have posted here, then there is no way they will ever do anything useful with the rest.

Want to do some programming? Great... there's a BIG start. How about you post your source here and I will help you with it ok? If you can get you own a version of PUDPIC working I will find a way to make the dlls acceptable... the only issue might be copyright because they contain pretty much all the graphics for the game. :-\


The virus detection matters because even if we know it is perfectly safe if we want to put it in the downloads section of the site for everyone to find easily, and google runs a basic automated test like they always do on hosted files, they will flag the whole war2.ru site as malicious, as it happened before.


This is a valid issue, if anyone running the server asked me about this because they wanted to host my progs, I would try to find a solution. For PUDPIC probably just uncompressing the files might work, idk I havn't even looked at it because nobody has ever suggested that.

Some things I am less comfortable exposing because they work with the WC2 exe and could potentially be exploited for hacks, but PUDPIC only works with pud files so there is no issue there.


Are these sources somewhere on Github? That would be much handier to read/propose changes or additions  .... / snip /.... Do you think it could be a good idea? :-)


This would be really nice. It would mean a lot of work for me, which I would be much more inclined to do if I thought there was any chance at all that anyone else would actually contribute anything, but going on past experience, that is very unlikely.



         ------------------------------

Just while I'm on the subject .... if there is anyone here paranoid enough to actually be concerned about any real malware in any of my stuff, here's a couple of points to ponder:

All you have to do to spot a trojan is firewall it... if its doing anything nasty it will try to phone home... otherwise what's the point?

...and if you actually think that:

a) I am the type of person that would invade people's privacy for my own petty ends
         or
b) that even if I was that kind of person, that I care enough about anyone here's personal life (or even WC2 life) to bother,

.... then the answer is very easy: don't use my programs, and also eat a large bag of dicks :)

Grunt Posts: 100 Karma: +10/-0 ***

Cel

  • Grunt
  • ***
  • *
  • Posts: 100
    • View Profile
*

Cel

Re: Nerd's Corner
« Reply #152 on: October 11, 2018, 12:20:14 PM »
Well that is the thing with Github you dont host the image files nor do you want to host the binary files, just the sources so no copyright issues there because images and the archives are not included  ^-^

You don't have to bother making your sources look good, unless you really want to use these as a way to get noticed by employers or because you want that to be part of your resume or portfolio. <= which also could be quite a good idea but that is indeed more work

Really if not for the above it is most of the time the matter of two clicks.

The benefits are that sometimes external views see things you might have missed.

Most of us have jobs that don't include warcraft 2, but sometimes we take one or two hours to read some foreign code there and there.
Yes nothing may come out of it but sometimes it does.

I guess these names sound familiar to you:
Daniel Lemberg.
Simon Pelsser.
Lasse Jensen.
These dudes worked on analysing the pud format because of their work it is much easier for people like us to play around with it.
Many others like Alexander Cech did programs that did prettymuch the same things like pudImage.exe and the famous Wardraft.exe

Had we got the sources from these utilities for example maybe we wouldn't have to reinvent the wheel every time, just the tires maybe :P

the strength of open source is that even if you let your project  sit out there and stop working on it someone might one day dig it out and use it as a base for something else.

Now that is your choice, in the end you do what you want just saying if you had your sources out there I would have had a look by curiosity :P

:critter:
Ogre Posts: 1022 Karma: +64/-0 *******

Lambchops

  • Ogre
  • *******
  • *
  • Posts: 1022
    • View Profile
Re: Nerd's Corner
« Reply #153 on: October 11, 2018, 10:49:14 PM »
nless you really want to use these as a way to get noticed by employers or because you want that to be part of your resume or portfolio. <= which also could be quite a good idea but that is indeed more work

Exactly, and perhaps taking a small amount of pride in my work?
Ogre Posts: 1022 Karma: +64/-0 *******

Lambchops

  • Ogre
  • *******
  • *
  • Posts: 1022
    • View Profile
Re: Nerd's Corner
« Reply #154 on: October 13, 2018, 03:20:27 AM »
So for future reference here's a working re-written version of PUDPIC.exe

It draws the terrain and the units.

It doesn't process command line switches or passed filename, just uses the filenames: "this.pud" "this.bmp", and "this.jpg".

I'm sure anyone capable of building it can add those bits if they want.


Lamb.h

Code: [Select]
#include <windows.h>


#ifndef _LAMB_
#define _LAMB_

#define sTYPE 0x45505954 // "TYPE"
#define sVER_ 0x20524556 // "VER "
#define sDESC 0x43534544 // "DESC"
#define sOWNR 0x524E574F // "OWNR"
#define sERA_ 0x20415245 // "ERA "
#define sERAX 0x54415245 // "ERAX"
#define sDIM_ 0x204D4944 // "DIM "
#define sUDTA 0x41544455 // "UDTA"
#define sUNIT 0x54494E55 // "UNIT"
#define sUGRD 0x44524755 // "UGRD"

#define sSIDE 0x45444953 // "SIDE"
#define sSGLD 0x444C4753 // "SGLD"
#define sSLBR 0x52424C53 // "SLBR"
#define sSOIL 0x4C494F53 // "SOIL"
#define sAIPL 0x4C504941 // "AIPL"

#define sMTXM 0x4D58544D // "MTXM"
#define sSQM_ 0x204D5153 // "SQM "
#define sOILM 0x4D4C494F // "OILM"
#define sREGM 0x4D474552 // "REGM"

#define sSIGN 0x4E474953 // "SIGN"
#define sALOW 0x574F4C41 // "ALOW"

#define FOREST     0
#define WINTER     1
#define WASTELAND  2
#define SWAMP      3


#define TILEW  32
#define TILEW2 16


extern "C" {
    typedef struct pudsect {
        DWORD Reserved;
        DWORD name;
        DWORD size;
        LPVOID data;
    }PUDSECT;
}

extern "C" {
    typedef struct hmibmp {
        BITMAPFILEHEADER* pFile;
        BITMAPINFOHEADER* pInfo;
        RGBQUAD*          pPal;
        BYTE*             pBits;
        int               width;
        int               height;
        int               bpp;
        int               linew;
        int               usage;
        int               size;
    }HMIBMP;
}

extern "C" {
    typedef struct pudunit{
    WORD x;
    WORD y;
    BYTE type;
    BYTE owner;
    WORD ai;     // 0-passive 1-active or (gold or oil)/2500
    }PUDUNIT;
}


// LambRES.dll
extern "C" typedef CHAR*   (__stdcall *rfngetname )(int utype);
extern "C" typedef LPVOID  (__stdcall *rfntileset )(int ntileset);
extern "C" typedef LPVOID  (__stdcall *rfngetpal  )(int npalette);
extern "C" typedef LPVOID  (__stdcall *rfngetgrp  )();


//PUDfile.inc
extern "C" typedef LPVOID  (__stdcall *pfnpudload )(CHAR* path);
extern "C" typedef int     (__stdcall *pfnpudsave )(LPVOID hpud,CHAR* path);

//PUDpud.inc
extern "C" typedef int     (__stdcall *pfnsectcnt )(LPVOID hpud);
extern "C" typedef void    (__stdcall *pfndestroy )(LPVOID hpud);
extern "C" typedef LPVOID  (__stdcall *pfndelsect )(LPVOID hpud,LPVOID hsect);
extern "C" typedef PUDSECT*(__stdcall *pfnfindsect)(LPVOID hpud,DWORD sectname);
extern "C" typedef int     (__stdcall *pfnupdsect )(LPVOID hpud,LPVOID hsect,LPVOID lpnew,int nbytes);
extern "C" typedef PUDSECT*(__stdcall *pfngetsect )(LPVOID hpud,int nsect);
extern "C" typedef int     (__stdcall *pfnsectndx )(LPVOID hpud,DWORD sectname);
extern "C" typedef LPVOID  (__stdcall *pfnsectset )(LPVOID hpud,LPVOID hsect,int nsect);
extern "C" typedef BOOL    (__stdcall *pfnsectcre )(LPVOID hpud,DWORD sectname,LPVOID lpnew,int nbytes);
extern "C" typedef LPVOID  (__stdcall *pfnrealloc )(PUDSECT* hSect,int nbytes);

//PUDunit.inc
extern "C" typedef int     (__stdcall *pfnunitsize)(int utype);
extern "C" typedef int     (__stdcall *pfnuniticof)(int utype);
extern "C" typedef int     (__stdcall *pfnlistget )(int list,int ndx);
extern "C" typedef int     (__stdcall *pfnlistnext)(int list,int utype);
extern "C" typedef int     (__stdcall *pfnlistprev)(int list,int utype);
extern "C" typedef LPVOID  (__stdcall *pfnlistname)(int list);

//PUDtile.inc
extern "C" typedef void    (__stdcall *pfnrndrmap )(LPVOID hbmp,LPVOID mtxm,int mapw);
extern "C" typedef void    (__stdcall *pfnrndrtile)(LPVOID hbmp,int tile,int x,int y);
extern "C" typedef LPVOID  (__stdcall *pfngettile )(int tile);
extern "C" typedef void    (__stdcall *pfntileset )(LPVOID tileset);
extern "C" typedef void    (__stdcall *pfnblack   )(HDC dc,int x,int y,int w,int h);

//hmibmp.inc
extern "C" typedef HMIBMP* (__stdcall *pfnmakebmp )(int w,int h,int bpp);
extern "C" typedef void    (__stdcall *pfnfreebmp )(HMIBMP* bmp);
extern "C" typedef int     (__stdcall *pfnzerobmp )(HMIBMP* bmp);
extern "C" typedef void    (__stdcall *pfnsavebmp )(CHAR* path,HMIBMP* bmp);
extern "C" typedef void    (__stdcall *pfnsavejpg )(CHAR* path,HMIBMP* bmp,int quality);
extern "C" typedef void    (__stdcall *pfnperfbmp )(HMIBMP* bmp);
extern "C" typedef void    (__stdcall *pfncopyimg )(HMIBMP* src,int scrx,int srcy,int srcw,int scrh,HMIBMP* dst,int dstx,int dsty,int transp);
extern "C" typedef int     (__stdcall *pfncopyfull)(HMIBMP* dstbmp,HMIBMP* srcbmp,int transp);
extern "C" typedef void    (__stdcall *pfndispimg )(HDC destDC,int x,int y,int w,int h,HMIBMP* bmp,int dx,int dy,int dw,int dh);
extern "C" typedef void    (__stdcall *pfnsetpal  )(HMIBMP* bmp,LPVOID palette);
extern "C" typedef void    (__stdcall *pfndrawrect)(HMIBMP* bmp,int x,int y,int w,int h,int color);
extern "C" typedef HMIBMP* (__stdcall *pfnsizebmp )(HMIBMP* bmp,int w,int h);

//PUDgrp.inc
extern "C" typedef LPVOID  (__stdcall *pfngrpinit )(LPVOID grplubase);
extern "C" typedef void    (__stdcall *pfndrawgrp )(int grp,int nframe,LPVOID daddr,int dwidth,int owner,int centre,int mirror);
extern "C" typedef void    (__stdcall *pfndrawbtn )(LPVOID bmp, int xpos, int ypos, int icon, int state);




extern rfngetname      RESgetName;
extern rfntileset      RESgetTileset;
extern rfngetpal       RESgetPalette;
extern rfngetgrp       RESgetGrp;

extern pfnpudload      PUDload;
extern pfnpudsave      PUDsave;

extern pfnsectcnt      PUDsection_count;
extern pfndestroy      PUDdestroy;
extern pfndelsect      PUDdelete_section;
extern pfnfindsect     PUDfind_section;
extern pfnupdsect      PUDupdate_section;
extern pfngetsect      PUDget_section;
extern pfnsectndx      PUDsection_index;
extern pfnsectset      PUDsection_set_index;
extern pfnsectcre      PUDcreate_section;
extern pfnrealloc      PUDsection_realloc;

extern pfnunitsize     PUDunitSize;
extern pfnuniticof     PUDunitIconFrame;
extern pfnlistget      PUDlistGet;
extern pfnlistnext     PUDlistNext;
extern pfnlistprev     PUDlistPrev;
extern pfnlistname     PUDlistName;

extern pfnrndrmap      PUDrenderMap;
extern pfnrndrtile     PUDrenderTile;
extern pfngettile      PUDgetTile;
extern pfntileset      PUDtileset;
extern pfnblack        PUDblack;

extern pfnmakebmp      make_bitmap;
extern pfnfreebmp      free_bitmap;
extern pfnzerobmp      zero_bitmap;
extern pfnsavebmp      save_bitmap;
extern pfnsavejpg      save_jpeg;
extern pfnperfbmp      perforate_bitmap;
extern pfncopyimg      copy_image;
extern pfncopyfull     copy_full_image;
extern pfndispimg      display_image;
extern pfnsetpal       set_palette;
extern pfndrawrect     draw_rect;
extern pfnsizebmp      size_bitmap;

extern pfngrpinit      GRPinit;
extern pfndrawgrp      GRPdraw;
extern pfndrawbtn      GRPdrawButton;


#endif


PUDPIC.cpp
Code: [Select]
#include <windows.h>
#include <lamb.h>


HMODULE hResDll  = LoadLibraryA("LambRES");
HMODULE hLambDll = LoadLibraryA("LambWC2");


rfngetpal   RESgetPalette       = (rfngetpal  )GetProcAddress(hResDll , "RESgetPalette"       );
rfngetgrp   RESgetGrp           = (rfngetgrp  )GetProcAddress(hResDll , "RESgetGrp"           );
rfngetname  RESgetName          = (rfngetname )GetProcAddress(hResDll , "RESgetName"          );
rfntileset  RESgetTileset       = (rfntileset )GetProcAddress(hResDll , "RESgetTileset"       );


pfnpudload  PUDload             = (pfnpudload )GetProcAddress(hLambDll, "PUDload"             );
pfnpudsave  PUDsave             = (pfnpudsave )GetProcAddress(hLambDll, "PUDsave"             );

pfnsectcnt  PUDsection_count    = (pfnsectcnt )GetProcAddress(hLambDll, "PUDsection_count"    );
pfndestroy  PUDdestroy          = (pfndestroy )GetProcAddress(hLambDll, "PUDdestroy"          );
pfndelsect  PUDdelete_section   = (pfndelsect )GetProcAddress(hLambDll, "PUDdelete_section"   );
pfnfindsect PUDfind_section     = (pfnfindsect)GetProcAddress(hLambDll, "PUDfind_section"     );
pfnupdsect  PUDupdate_section   = (pfnupdsect )GetProcAddress(hLambDll, "PUDupdate_section"   );
pfngetsect  PUDget_section      = (pfngetsect )GetProcAddress(hLambDll, "PUDget_section"      );
pfnsectndx  PUDsection_index    = (pfnsectndx )GetProcAddress(hLambDll, "PUDsection_index"    );
pfnsectset  PUDsection_set_index= (pfnsectset )GetProcAddress(hLambDll, "PUDsection_set_index");
pfnsectcre  PUDcreate_section   = (pfnsectcre )GetProcAddress(hLambDll, "PUDcreate_section"   );
pfnrealloc  PUDsection_realloc  = (pfnrealloc )GetProcAddress(hLambDll, "PUDsection_realloc"   );


pfnunitsize PUDunitSize         = (pfnunitsize)GetProcAddress(hLambDll, "PUDunitSize"         );
pfnuniticof PUDunitIconFrame    = (pfnuniticof)GetProcAddress(hLambDll, "PUDunitIconFrame"    );
pfnlistget  PUDlistGet          = (pfnlistget )GetProcAddress(hLambDll, "PUDlistGet"          );
pfnlistnext PUDlistNext         = (pfnlistnext)GetProcAddress(hLambDll, "PUDlistNext"         );
pfnlistprev PUDlistPrev         = (pfnlistprev)GetProcAddress(hLambDll, "PUDlistPrev"         );
pfnlistname PUDlistName         = (pfnlistname)GetProcAddress(hLambDll, "PUDlistName"         );

pfnrndrmap  PUDrenderMap        = (pfnrndrmap )GetProcAddress(hLambDll, "PUDrenderMap"        );
pfnrndrtile PUDrenderTile       = (pfnrndrtile)GetProcAddress(hLambDll, "PUDrenderTile"       );
pfngettile  PUDgetTile          = (pfngettile )GetProcAddress(hLambDll, "PUDgetTile"          );
pfntileset  PUDtileset          = (pfntileset )GetProcAddress(hLambDll, "PUDtileset"          );
pfnblack    PUDblack            = (pfnblack   )GetProcAddress(hLambDll, "PUDblack"            );

pfnmakebmp  make_bitmap         = (pfnmakebmp )GetProcAddress(hLambDll, "make_bitmap"         );
pfnfreebmp  free_bitmap         = (pfnfreebmp )GetProcAddress(hLambDll, "free_bitmap"         );
pfnzerobmp  zero_bitmap         = (pfnzerobmp )GetProcAddress(hLambDll, "zero_bitmap"         );
pfnsavebmp  save_bitmap         = (pfnsavebmp )GetProcAddress(hLambDll, "save_bitmap"         );
pfnsavejpg  save_jpeg           = (pfnsavejpg )GetProcAddress(hLambDll, "save_jpeg"           );
pfnsizebmp  size_bitmap         = (pfnsizebmp )GetProcAddress(hLambDll, "size_bitmap"         );
pfnperfbmp  perforate_bitmap    = (pfnperfbmp )GetProcAddress(hLambDll, "perforate_bitmap"    );
pfncopyimg  copy_image          = (pfncopyimg )GetProcAddress(hLambDll, "copy_image"          );
pfncopyfull copy_full_image     = (pfncopyfull)GetProcAddress(hLambDll, "copy_full_image"     );
pfndispimg  display_image       = (pfndispimg )GetProcAddress(hLambDll, "display_td_image"    );
pfnsetpal   set_palette         = (pfnsetpal  )GetProcAddress(hLambDll, "set_palette"         );
pfndrawrect draw_rect           = (pfndrawrect)GetProcAddress(hLambDll, "draw_rect"           );

pfngrpinit  GRPinit             = (pfngrpinit )GetProcAddress(hLambDll, "GRPinit"             );
pfndrawgrp  GRPdraw             = (pfndrawgrp )GetProcAddress(hLambDll, "GRPdraw"             );
pfndrawbtn  GRPdrawButton       = (pfndrawbtn )GetProcAddress(hLambDll, "GRPdrawButton"       );


CHAR* pudpath = "this.pud";
CHAR* bmppath = "this.bmp";
CHAR* jpgpath = "this.jpg";

BYTE* sectionData(LPVOID hpud, DWORD sname){
    PUDSECT* sptr = PUDfind_section(hpud,sname);
    if (sptr!=NULL) return (BYTE*)sptr->data;
    return NULL;
}

int sectionSize(LPVOID hpud, DWORD sname){
    PUDSECT* sptr = PUDfind_section(hpud,sname);
    if (sptr!=NULL) return sptr->size;
    return 0;
}

int getPudSize(LPVOID hpud){
    WORD* pdim = (WORD*) sectionData(hpud,sDIM_);
    if(pdim) return (int) *pdim;
    return 0;
}

int getTerrainType(LPVOID hpud){
    WORD* pter = (WORD*) sectionData(hpud,sERA_);
    if(pter) return (int) *pter;
    return 0;
}

BOOL isBuilding(int utype){
    // is the unit a building?
    return utype>=0x3A;
}

void renderUnit(HMIBMP* hbm, PUDUNIT* unit){
    // draw a unit grp
   
    int   frame = 0;
    int   x=(unit->x+1)*TILEW;
    int   y=(unit->y+1)*TILEW;
    int   centre = 0;
    int   rev = 0;
   
   
    if(!isBuilding(unit->type)){
       // units need to be centred and offset
       centre = 1;
       x+=TILEW2;
       y+=TILEW2;
       
       // pick a random direction so they dont all face the same way
       frame = rand()%5;
       rev   = rand()%2;    // draw reversed?
    }
   
    GRPdraw( unit->type, frame, hbm->pBits+x+(y*hbm->linew), hbm->linew, unit->owner, centre, rev );

}


///////// START /////////


    // load the pud file
    LPVOID hPud = PUDload(pudpath);
   
   
    // get some info from the pud
    int mapsize = getPudSize(hPud);
    int terrain = getTerrainType(hPud);
   

    // make a bitmap in memory (tiles are 32x32 pixels)
    HMIBMP* hbm = make_bitmap(mapsize*TILEW,mapsize*TILEW,8);
   
   
   
    /// TERRAIN ///
   
    // use the tiles for the map terrain type
    PUDtileset(RESgetTileset(terrain));
   
    // don't forget this if you are using GRPs, only needs to be done once to initialize
    GRPinit(RESgetGrp());
   
    //paste all the tile graphics for the pud onto the bitmap
    PUDrenderMap( hbm, sectionData(hPud,sMTXM) , mapsize);
   
       
    /// UNITS ///
           
    // get a pointer to the "UNIT" section
    PUDSECT* units = PUDfind_section(hPud,sUNIT);
       
    if(units){
         
        // make a slightly larger bitmap to paste units on
        // --> some units like flyers can be placed in locations where they
        //     will render off the edge of the map (crash and burn).
        //
        // so here we make a bitmap with a safety margin around the edge
       
        HMIBMP* hUbm = make_bitmap((mapsize+2)*TILEW,(mapsize+2)*TILEW,8);
             
        // how many units on the pud?
        // ( includes mines, start locations etc.)
        int nUnits  = units->size/sizeof(PUDUNIT);
       
        // draw the unit GRPs on the 'safe' bitmap
        PUDUNIT* pUnit = (PUDUNIT*)units->data;
        for(int i=0;i<nUnits;i++){
            renderUnit(hUbm,pUnit);
            pUnit++;
        }
       
        // copy the unit bitmap (less the border area) onto the terrain bitmap
        copy_image(hUbm,TILEW,TILEW,hbm->width,hbm->height,hbm,0,0,0); // <- last 0 is the transparent index
                                                                       //    pass -1 for none.
        // dispose of the unit bitmap
        free_bitmap(hUbm);
    }
   
   
    // ensure the bmp file has the correct palette for the terrain type
    set_palette(hbm , RESgetPalette( terrain ));
   
    // save the full bitmap to a .bmp file
    save_bitmap(bmppath,hbm);
   
    // resize the bitmap then save to a .jpg file
    HMIBMP* hJbm = size_bitmap(hbm,1024,1024);
    save_jpeg(jpgpath,hJbm,90); // <-- quality 90 looks nice
   
    // dispose of bitmaps
    free_bitmap(hbm);
    free_bitmap(hJbm);
   
    // dispose of the pud structure
    PUDdestroy(hPud);


                                                            :critter:

Grunt Posts: 100 Karma: +10/-0 ***

Cel

  • Grunt
  • ***
  • *
  • Posts: 100
    • View Profile
*

Cel

Re: Nerd's Corner
« Reply #155 on: October 14, 2018, 12:40:20 AM »
Nice thanks! ^-^ :thumbsup:

Interesting that they save the transition type value from the marching squares algorithm in the pud directly instead of calculating it once at load time. It means your map editor has to save these calculated values in the pud but it also means you can save a pud files with very weird transitions if you would like to that could look funny. (:

 :critter:
Ogre Posts: 1022 Karma: +64/-0 *******

Lambchops

  • Ogre
  • *******
  • *
  • Posts: 1022
    • View Profile
Re: Nerd's Corner
« Reply #156 on: October 14, 2018, 07:42:34 AM »
Nice thanks! ^-^ :thumbsup:

Interesting that they save the transition type value from the marching squares algorithm in the pud directly instead of calculating it once at load time. It means your map editor has to save these calculated values in the pud but it also means you can save a pud files with very weird transitions if you would like to that could look funny. (:

 :critter:



yw :)

The terrain transition tile values can be derived like THIS.

For displaying terrain in the PUDPIC program I cheated - big time ;)

I generated a list of possible MTXM values based on my assumptions of the format, then also searched every pud in my maps directory for any crazy custom values I had missed and added them too.

Then I auto generated maps with arrays of these MTXM values, then loaded the maps, took SS, and then processed the SS to pull out the exact 32x32 block of pixels for each map value.


 ... stuff like this:






Finally I searched all the pixel blocks and weeded out any repeats, then turned them into an array of pixel data indexed by the MTXM value list - with multiple indexes to the same pixels for different tile values that displayed them.

In this way when rendering there is no need to calculate and locate the 4 different 8x8 mini-tiles that make up each MTXM location, it just uses the raw MTXM value to do a lookup in a pointertable  which supplies the exact location of the full 32x32 block.

                                                                                :critter:


 -- edit --

The units are all rendered using the original grp files, using the method detailed HERE


Ogre Posts: 1022 Karma: +64/-0 *******

Lambchops

  • Ogre
  • *******
  • *
  • Posts: 1022
    • View Profile
Re: Nerd's Corner
« Reply #157 on: October 22, 2018, 11:43:31 AM »
u are invited to my xmas party

Thanks @easycompany - as soon as my fairy godmother buys me a plane ticket and pays for me to get a passport, I'll be there with bells on ...

  ... so probably never lol, but it's a nice thought - I'd be happy to help you drink some beers. Maybe one day.