Technical Questions to the Game

Use this forum to discuss dungeon editors and other tools, like DMute (by George Gilbert, also working for RTC dungeons), DM Builder (by Sphenx), and ADGE by `rain. Includes DM editing tips and tricks.
Forum rules
Please read the Forum rules and policies before posting.
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Technical Questions to the Game

Post by Cycl0ne »

Hi,

thought i start a new Thread and donst post so much in the other. I have some technical question, mostly graphics/positioning related:

Normally when walking the dungeon, the wall img are horizontally mirrored to keep some kind of motion. but deeper in dungeon, are they also vertically flipped?
Question arises how the crackswitchout graphics is placed on the wall.. -> centered in the midle top <- .. when i open adge, the wall adge uses is flipped vertically and the switch fits perfectly to the wall.
What i get:
Image
Adge:
Image
from my memories ages ago i would say it looked more like the adge version i played. but i could be wrong.
User avatar
ChristopheF
Encyclopedist
Posts: 1538
Joined: Sun Oct 24, 1999 2:36 pm
Location: France
Contact:

Re: Technical Questions to the Game

Post by ChristopheF »

The game engine never flips the wall bitmaps vertically. This must be a quirk of ADGE.
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Re: Technical Questions to the Game

Post by Cycl0ne »

Hmm ok, from my memories i would have said that it was here:
Image
but i couldnt find any coords for this. setup.

Interessting that the button out version is group 2 and button in is group 0 of coords..
User avatar
ChristopheF
Encyclopedist
Posts: 1538
Joined: Sun Oct 24, 1999 2:36 pm
Location: France
Contact:

Re: Technical Questions to the Game

Post by ChristopheF »

There was a bug in DM version 1.0 with this "crack switch" coordinates, see http://dmweb.free.fr/?q=node/1367
It was fixed in all subsequent versions
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Re: Technical Questions to the Game

Post by Cycl0ne »

lol, this:
Item #0558: Offset 0x0c81 '0' replaced by '2'. Fixes the issue with crack switch that was moving up when pressed because the pressed switch image was using a wrong coordinates group.

is still there in ADGE:
The Crack Switch Out is group 2, the Crack Switch in = group 0 ;-)

Do you know where the, here is the object and this is its group is located? Also Lay1?

---

and if you are interessted: here is what im working on:
https://dist-cycl0ne.vercel.app/

Moving is with mouse/touch or keyboard: QWEASD

At first i concentrated on the GFX Engine, and implemented 50% of all gfx assets. Now im moving slowly to the Logic Engine. Future Goal: a complete Engine, where someone can create own dungeon crawler games. GFX/Logic is seperated so you can switch gfx to other gfx engine (even 3d later if you like).
All Levels the Wall Ornates/FloorOrnates are placed random per seed on the tiles that accept that (like original DM did).
At the moment im using original Levels from DM converted to JSON.

Original DM has an own structures later for how the doors look like. i just take this line:
convert.cell({location={ 1,31, 8},flags=0x1c,contents= 343,roomType="DOOR",flags={closed=true}})
need to check how i match this with this later:
convert.door({index= 0,link=65534,type=1,ornat=0,mode=1,switch=true ,openWithFireball=false,openWithAxe=false})

The whole project will be opensource and is coded in TypeSctript/Javascript and is heavy OO/Abstract Things to make extensions to engine quite easy.

Main goal will be to run DM, but the farer Goal: a complete engine for these kind of games.
Maybe even a Deluxe DM (i could imagine to implement also story telling functions in the engine later for "talking" people you know from JRPGs (head + console/textwindow). I have still the graphics from the chinese artist i hired 10 years ago for a android version (which couldnt be implemted due to the limitation android 2.0 had those days (30mb memory limit for code + data +gfx).
Image
Image
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Re: Technical Questions to the Game

Post by Cycl0ne »

Oh and another question, can you tell me what this means:

DAROOU]]]M]AAGEACIKAAAG]CDDCBOCDCNBOCN]DADAAAAAAAAAAABB
All these AADBB?
User avatar
ChristopheF
Encyclopedist
Posts: 1538
Joined: Sun Oct 24, 1999 2:36 pm
Location: France
Contact:

Re: Technical Questions to the Game

Post by ChristopheF »

The dungeon.dat file contains text strings for wall inscriptions and scrolls. In DM, the champion characteristics are also encoded as texts. If you decode a champion string like any regular text, this is the result that you get.
Have a look at http://dmweb.free.fr/?q=node/217#toc30 (scroll down to the last paragraphs about champion initial skills and statistics), it explains how to decode the actual data.
User avatar
ChristopheF
Encyclopedist
Posts: 1538
Joined: Sun Oct 24, 1999 2:36 pm
Location: France
Contact:

Re: Technical Questions to the Game

Post by ChristopheF »

Cycl0ne wrote: Tue Sep 05, 2023 7:41 pm The Crack Switch Out is group 2, the Crack Switch in = group 0 ;-)

Do you know where the, here is the object and this is its group is located? Also Lay1?
LAY1 data is a structured and generic way to store screen coordinates (absolute or relative) for everything and is only found in later versions of the game.

Earlier versions like Atari ST, Apple IIGS, Amiga versions 2.x instead used coordinates that were "hard coded" and declared in separate variables, harder to maintain. This is documented here: http://dmweb.free.fr/?q=node/1394#toc210 for item 558 that is used in Atari ST version. Note that the other versions (Apple IIGS and Amiga 2.x) have the same data (or very similar) stored directly in the executable, not as an item in graphics.dat (this was only required for the Atari ST version because of limitations of the C compiler that was used to develop the game). You may find this data in my ReDMCSB source code in file DUNVIEW.C.
User avatar
ChristopheF
Encyclopedist
Posts: 1538
Joined: Sun Oct 24, 1999 2:36 pm
Location: France
Contact:

Re: Technical Questions to the Game

Post by ChristopheF »

Your project looks nice, even if it is still in the early phases and we all know most projects of this kind are never completed. There is so much work until a complete and polished product can be released. But I wish you luck and perseverance, and I hope to see your goals become reality.
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Re: Technical Questions to the Game

Post by Cycl0ne »

Thanks,
Pits are now finished, pads and doors working, doorbutton working. Fontengine working for Wall + System. Tickmanager working for every 10ticks/s.
Next steps: More logic polish. Im still hassling with OO design and simple ItemDatabase like DSB, RTC, Orig. .. handles ( FloorTrigger Dest: #### set)

Yes you are right. Im just trying out learning Javascript/TS. so i thought to myself: you need a project for this "learning" makes programming easier ;-)

And yes you are right, everywhere are coord data in the game (also in mine). need to polish this too, to be more generic/editor style. I use ADGE for the mapping Group -> Coords.

What really looks strange in the GFX are the Pits in D1 to D2 ..
Image
User avatar
ChristopheF
Encyclopedist
Posts: 1538
Joined: Sun Oct 24, 1999 2:36 pm
Location: France
Contact:

Re: Technical Questions to the Game

Post by ChristopheF »

You must have something wrong here. Pits at D2 are perfectly aligned in the original game.
User avatar
Sphenx
On Master
Posts: 566
Joined: Sun Sep 09, 2001 11:23 am
Contact:

Re: Technical Questions to the Game

Post by Sphenx »

Cycl0ne wrote: Mon Sep 04, 2023 6:33 pm What i get:
Image
Adge:
Image
from my memories ages ago i would say it looked more like the adge version i played. but i could be wrong.
That is because of different versions referred to perspective 1 and 2 (http://dmweb.free.fr/?q=node/247). The front wall images are different. You certainly play the game with a different graphics.dat than the one loaded by Adge.

As for your project, I wish you too good luck with it and I know what I am talking about ;-)
If you have a good amount of time to dedicate to it, then I hope you can reach its completion.
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Re: Technical Questions to the Game

Post by Cycl0ne »

ChristopheF wrote: Sat Sep 09, 2023 6:43 pm You must have something wrong here. Pits at D2 are perfectly aligned in the original game.
Nope, they are not really aligned:
Image

when i pull them out you see that d0/d1 aligns again and d1/d2 looks strange. Using GFX 3.6 Set and also checked on 3.3//3.5. When i look at DSB Graphics. D2 is smaller by 8 pixel in bottom width.. this aligning perfectly again.
Image

Maybe need to scale the D2 in the game?! .. Would be the first time.

When i look up the gfx from V1.0:
Image

here you see that D2 is smaller as D1. which gives you then the correct aspect when blitting the D2 more up later.

Image

im using RTC/DSB with own maps to recheck, but both are using other gfx. Is there an editor for DM3.6 Amiga Version where i could create a simple level with pits to recheck? ;-)
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Re: Technical Questions to the Game

Post by Cycl0ne »

Sphenx wrote: Sat Sep 09, 2023 10:54 pm As for your project, I wish you too good luck with it and I know what I am talking about ;-)
If you have a good amount of time to dedicate to it, then I hope you can reach its completion.
Thanks, thanks to JS/TS handling all GFX/Blitting/Music/Sound/.. Stuff + the Encyclopedia + DSB LUA Files, its just a writing down.

I guess without RTC/DSB/Encyclopedia/... this project would have not existed and not been so far in 6 weeks. And one Motivation i have: RageMole (RTC) wrote, he did it in his Sommerbreak from University.. Here in Germany its 3 Month ;-) so this is my timeline... :D :D
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Re: Technical Questions to the Game

Post by Cycl0ne »

i uploaded my working copy to vercel. you see now doorbutton working, pressurepads + font engine ;-) the pit is only displayed no falling through.
User avatar
ChristopheF
Encyclopedist
Posts: 1538
Joined: Sun Oct 24, 1999 2:36 pm
Location: France
Contact:

Re: Technical Questions to the Game

Post by ChristopheF »

I checked in the original PC version of DM with a test dungeon modified with DM Builder http://dmweb.free.fr/?q=node/695
And you are right, pits are not aligned in the original game. Never noticed that !
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Re: Technical Questions to the Game

Post by Cycl0ne »

Is there a Dungeon Master PC which uses 3.5/3.6 Graphics? I allways boot up UAE and go through levels :-) and look up perspectives
User avatar
Sphenx
On Master
Posts: 566
Joined: Sun Sep 09, 2001 11:23 am
Contact:

Re: Technical Questions to the Game

Post by Sphenx »

I think not, unless someone builds a PC graphics.dat using 3.6 data.
User avatar
ChristopheF
Encyclopedist
Posts: 1538
Joined: Sun Oct 24, 1999 2:36 pm
Location: France
Contact:

Re: Technical Questions to the Game

Post by ChristopheF »

DM for PC is version 3.4 so it does include the new perspective, should be exactly the same as Amiga 3.5/3.6
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Re: Technical Questions to the Game

Post by Cycl0ne »

Real DM 3.4? or CSB? So i need to search for a pirate 3.4 PC (DOS i assume)?
User avatar
ChristopheF
Encyclopedist
Posts: 1538
Joined: Sun Oct 24, 1999 2:36 pm
Location: France
Contact:

Re: Technical Questions to the Game

Post by ChristopheF »

Yes the original DM for PC, which was not copy protected.
Check here for instructions to play the game with DOSbox http://dmweb.free.fr/?q=node/310
and download the game from http://dmweb.free.fr/?q=node/622#toc40
(there is also a link to an archive already containing both the game and emulator)
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Re: Technical Questions to the Game

Post by Cycl0ne »

Ahh thanks.. this is perfect. Ok, the mouse cursor on the dungeonview is flickering like hell.. :) but its nice.. no booting into UAE ;-)
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Re: Technical Questions to the Game

Post by Cycl0ne »

Ok, implementing now the FloorItems / Items.

Question: is the scaling in D1/D2 same handled like scaling in WallOrnate/FloorOrnate? and also darkened?
User avatar
ChristopheF
Encyclopedist
Posts: 1538
Joined: Sun Oct 24, 1999 2:36 pm
Location: France
Contact:

Re: Technical Questions to the Game

Post by ChristopheF »

There are multiple variants for item bitmap scaling in the source code, depending on the game version and old/new perspective.
For the best results, you'll want to use the latest variant (used in version 3.4/3.5 among others), where there are 5 scaling factors in use (defined in variable G2030_auc_ObjectScales in ReDMCSB source code):
27/32 for D1 front row
21/32 for D1 back row
18/32 for D2 front row
14/32 for D2 back row
12/32 for D3 front row

items are invisible on D3 back row. And of course scale is 32/32 = 1 at D0.

If you want to study the code to display things yourself, it is in DUNVIEW.C, function F0115_DUNGEONVIEW_DrawObjectsCreaturesProjectilesExplosions_CPSEF. Search for this line:
AL0150_ui_ShiftSetIndex = (L2475_i_ViewDepth * 2) - 1;
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Re: Technical Questions to the Game

Post by Cycl0ne »

Thanks Christophe you are the best. i had some look at the source, but what makes it confusing are all the #define like: MEDIA488_F20E_F20J/ MEDIA579_X30J_P20JA_P20JB

Have you ever thought putting parts of code into an AI and convert it to more readable C code?
User avatar
ChristopheF
Encyclopedist
Posts: 1538
Joined: Sun Oct 24, 1999 2:36 pm
Location: France
Contact:

Re: Technical Questions to the Game

Post by ChristopheF »

The #define directives allow me to have all code variations in the same place for easy comparison. Each MEDIA tag corresponds to one version of the game, like F20E is DM FM-Towns 2.0, or X30J is DM X68000 3.0.
There is powershell code to "extract" only the source code for any arbitrary set of media tags. This is actually used when compiling for example the Atari ST versions: the common source code is too complex for the Megamax C compiler to handle on atari st, so early in the build process, an intermediary source code containing only the Atari ST code parts is extracted from the common source code and is then used for compilation. You may find this intermediary source code in the ouput folder. This is only used for Atari ST and PC, but the powershell function could be used to extract any version(s) of your choice.
User avatar
Sphenx
On Master
Posts: 566
Joined: Sun Sep 09, 2001 11:23 am
Contact:

Re: Technical Questions to the Game

Post by Sphenx »

Cycl0ne wrote: Thu Sep 21, 2023 8:31 pm Have you ever thought putting parts of code into an AI and convert it to more readable C code?
(Uhuh, knowing where it does come from, Christophe is crazier than your common AI :D)
Not wanting to be off-topic, but are there AI that perform reverse engineering ? or somehow interpret/cleanup a whole code ?
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Re: Technical Questions to the Game

Post by Cycl0ne »

Yes there are "alot". you push code into it and say: convert me this to code y (like ttake this 68k assembly and make it c).

what it doesnt do: take the bin and do something. But 12-15 years ago i had a tool for PC which did this with 68k assembly. this tool did cost me 4000€? Was real good, converted some old 68k source files to c.

but here is an example of what i mean with chatgpt:
My Input:
take this source in 68000 assembly and convert to c:

Code: Select all

SetFunction8:	;A relic that was never needed.
SetFunction:
	    FORBID
	    BSET    #LIBB_CHANGED,LIB_FLAGS(A1)
	    LEA     0(A1,A0.W),A0
	    MOVE.L  2(A0),-(SP)		;Old vector
	    MOVE.W  #JMPINSTR,(A0)
	    MOVE.L  D0,2(A0)
	    MOVE.L  A1,-(SP)
	    JSRSELF CacheClearU		;Flush cache IN SAME DISABLE
	    BSR_PERMIT
	    MOVE.L  (SP)+,A1
	    JSRSELF SumLibrary	;(A1)
	    MOVE.L  (SP)+,D0		;Old vector
cl_RTS:     RTS
here the answer:
The given code is in Motorola 68000 Assembly, specifically for the Amiga's Exec library. Below is a tentative conversion of the assembly code to C, while keeping in mind that there are many low-level operations here that don't have a direct equivalent in high-level languages like C. Due to this, the C conversion is not expected to work as is, and might require adjustments and, likely, some inline assembly or system-specific API calls for exact equivalent functionality.

Here, I'll provide a conceptual translation into C. To make this more practical and executable, you would need to write architecture-specific and OS-specific code and/or use inline assembly where appropriate, as well as include relevant headers for any system or library calls you're making.

Code: Select all

#include <some_system_header.h>  // Placeholder for necessary headers

// Presuming that library is a struct pointer of some type, and funcEntry is a function pointer.
void* SetFunction(void* library, int funcOffset, void (*funcEntry)()) {
    void* oldFunc;
    
    // FORBID: Disable task scheduling or interrupts (system-specific operation)
    Forbid(); 
    
    // Set the LIBB_CHANGED bit in the flags field of the library.
    library->flags |= LIBB_CHANGED;
    
    // Calculate the address where to install the new function pointer.
    void** funcAddress = (void**)((char*)library + funcOffset);
    
    // Save the old function pointer.
    oldFunc = *funcAddress;
    
    // Install a jump instruction followed by the address of the new function.
    *funcAddress = (void*)JMPINSTR;  // Some representation of the JMP instruction.
    *(funcAddress + 1) = funcEntry;
    
    // Clear CPU cache.
    CacheClearU(); 
    
    // PERMIT: Re-enable task scheduling or interrupts (system-specific operation)
    Permit(); 
    
    // Recalculate checksum of the library.
    SumLibrary(library);
    
    return oldFunc;
}
it even comments the source, what is very nice and he even recognized it as Amiga OS Function ;-)

@Sphenx: Can you give me please a peek into your flooritems calc/draw routine? ;-) im sitting here with paper and doing all stuff to convert my enums N,E,W,S with NE, SE, SW, NW -> (var+3)%4 :-D
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Re: Technical Questions to the Game

Post by Cycl0ne »

here another example from my old source:

Input:
can you optimize, clean and comment this source?

Code: Select all

void puts(char *s)
{
    int scan=bootboot.fb_scanline; //, wid=bootboot.fb_width, hei=bootboot.fb_height;
    psf2_t *font = (psf2_t*)&_binary_font_psf_start;
    int x,y,kx=1,line,mask,offs;
    int bpl=(font->width+7)/8;
    while(*s) {
        unsigned char *glyph = (unsigned char*)&_binary_font_psf_start + font->headersize +
            (*s>0&&*s<font->numglyph?*s:0)*font->bytesperglyph;
        offs = (kx * (font->width+1) * 4)+(10*scan);

        for(y=0; y<font->height ; y++) 
        {
            line=offs; 
            mask=1<<(font->width-1);
            for(x=0;x<font->width;x++) {
                *((uint32_t*)((uint64_t)&fb+line))=((int)*glyph) & (mask)?0xFFFFFF:0;
                mask>>=1; line+=4;
            }
            *((uint32_t*)((uint64_t)&fb+line))=0; glyph+=bpl; offs+=bootboot.fb_scanline;
        }
        s++; kx++;
    }
}
Result:
Below is an optimized, cleaned up, and commented version of the provided C function puts. The key enhancements include:

Improved Readability: Use more descriptive variable names.
Code Optimization: Organized declarations and calculations.
Enhanced Consistency: Follow a consistent style and layout.
Improved Comments: Added comments for better understanding.

Code: Select all

void puts(char *s)
{
    // Initialize the scanline
    int scanline = bootboot.fb_scanline;
    
    // Pointer to the font data
    psf2_t *font = (psf2_t*)&_binary_font_psf_start;
    
    // Calculate Bytes Per Line
    int bytesPerLine = (font->width + 7) / 8;
    
    // Initialize the horizontal position
    int horizontalPosition = 1;
    
    // Iterate through each character in the string until the null terminator is reached
    while(*s) 
    {
        // Calculate the offset and get the glyph data for the character
        int offset = (horizontalPosition * (font->width + 1) * 4) + (10 * scanline);
        unsigned char *glyph = (unsigned char*)&_binary_font_psf_start + font->headersize +
            ((*s > 0 && *s < font->numglyph) ? *s : 0) * font->bytesperglyph;
        
        // For each row in the glyph
        for(int y = 0; y < font->height; y++) 
        {
            int line = offset;
            int mask = 1 << (font->width - 1);
            
            // For each pixel in the glyph row
            for(int x = 0; x < font->width; x++) 
            {
                // Write the pixel data to the frame buffer
                *((uint32_t*)((uint64_t)&fb + line)) = ((*glyph) & mask) ? 0xFFFFFF : 0;
                mask >>= 1;
                line += 4;
            }
            
            // Write an additional zero at the end of each row
            *((uint32_t*)((uint64_t)&fb + line)) = 0;
            glyph += bytesPerLine;
            offset += bootboot.fb_scanline;
        }
        
        // Move to the next character in the string and the next horizontal position
        s++;
        horizontalPosition++;
    }
}
Some additional points to consider:

It is assumed that all referenced variables and structures (bootboot, psf2_t, fb, etc.) are defined elsewhere in your code.
This cleaned-up version assumes that the original logic of your code is correct. If there are logical errors or if your requirements change, you might need to adjust the code accordingly.
Ensure to test thoroughly after any modifications to verify that the cleaned-up version behaves as expected in all cases.



And there are others like GitHub Copilot (which is based on ChatGpt).

oh and here the gimmick:
Input:
convert the puts to 68k assembly

Output:
Converting high-level C code to 68000 Assembly code requires carefully mapping each high-level operation to its corresponding low-level operation(s). Below is an illustrative conversion of the optimized C code to a conceptual 68000 Assembly. Keep in mind that the actual conversion might vary depending on the system, hardware registers, memory layout, and other aspects of your environment.

I will use comments ; to denote what each line does. The conversion assumes a rudimentary understanding of assembly language programming and the specificities of the Motorola 68k architecture:

Code: Select all

; Assume D0 holds the address of string s
; Assume A0 holds the base address of the framebuffer fb
; Assume A1 holds the address of the bootboot structure
; Assume A2 holds the address of the font structure

START:
    MOVE.L  #1, D1                    ; Initialize horizontalPosition to 1
    
    ; Initialization, load needed data to registers
    MOVE.W  (A1), D2                  ; Load scanline to D2
    MOVE.W  (A2), D3                  ; Load font->width to D3
    MOVE.W  (A2)+2, D4                ; Load font->height to D4
    MOVE.W  (A2)+4, D5                ; Load font->headersize to D5
    MOVE.W  (A2)+6, D6                ; Load font->bytesperglyph to D6
    MOVE.W  (A2)+8, D7                ; Load font->numglyph to D7
    
LOOP:
    MOVE.B  (D0)+, D8                 ; Load next char from string to D8
    BEQ     END                       ; If null terminator is reached, branch to END
    
    ; Calculate offset and address of the glyph
    MULS    #4, D1                     ; 4 * horizontalPosition
    ADD     D1, D1                     ; 2 * (4 * horizontalPosition) = 8 * horizontalPosition
    ADD     D1, D1                     ; 2 * (8 * horizontalPosition) = 16 * horizontalPosition
    ADD     #10, D2                    ; 10 * scanline
    ADD     D1, D2                     ; offset = (horizontalPosition * (font->width + 1) * 4) + (10 * scanline)
    MOVE.L  D8, D1                     ; Copy char to D1
    BLEU    INVALID_CHAR               ; If char is invalid (either negative or >= numglyph), branch to INVALID_CHAR
    MULU    D6, D1                     ; D1 = char * bytesperglyph
    ADD     D5, D1                     ; D1 = headersize + (char * bytesperglyph)
    ADDA    D1, A2                     ; A2 points to the glyph data
    
GLYPH_LOOP:
    MOVE.L  D2, D1                     ; Copy offset to D1
    MOVE.W  #1, D9                     ; Initialize mask to 1 << (font->width - 1)
    LSL.W   #7, D9                     ; Assume the maximum width is 8
    LSL.W   D3, D9                     ; Left shift to get the actual mask
    
PIXEL_LOOP:
    BTST    D9, (A2)                   ; Test the bit in the glyph data
    BEQ     WHITE_PIXEL                ; If bit is set, branch to WHITE_PIXEL
    MOVE.L  #0, (A0, D1.W)             ; Write black pixel to the framebuffer
    BRA     NEXT_PIXEL                 ; Branch to NEXT_PIXEL
    
WHITE_PIXEL:
    MOVE.L  #0xFFFFFF, (A0, D1.W)      ; Write white pixel to the framebuffer
    
NEXT_PIXEL:
    LSR.W   #1, D9                     ; Right shift the mask
    ADDQ.L  #4, D1                     ; Move to the next pixel in the framebuffer
    SUBQ.W  #1, D3                     ; Decrement the width counter
    BGT     PIXEL_LOOP                 ; If there are more pixels, branch to PIXEL_LOOP
    
    MOVE.L  #0, (A0, D1.W)             ; Write an additional zero at the end of each row
    ADDQ.L  #1, A2                     ; Move to the next row in the glyph data
    ADD     (A1), D2                   ; Add scanline to the offset
    SUBQ.W  #1, D4                     ; Decrement the height counter
    BGT     GLYPH_LOOP                 ; If there are more rows, branch to GLYPH_LOOP
    
    ADDQ.L  #1, D0                     ; Move to the next character in the string
    ADDQ.L  #1, D1                     ; Increment the horizontal position
    BRA     LOOP                       ; Branch to LOOP
    
INVALID_CHAR:
    ; Handle invalid characters (e.g., replace with a default glyph or skip)
    ; Here it’s skipped for simplicity
    BRA     LOOP                       ; Branch to LOOP
    
END:
    ; Here you'd typically have code to return from the subroutine or halt execution
    RTS
Neat or? ;-)

and lastly:
Input:
convert the puts to java

Output:
To convert the provided puts function to Java, you would typically create a class containing a method that represents the functionality of the puts function. Below is an illustrative conversion of the given C function to Java. Note that in a high-level language like Java, direct memory access and manipulation are not possible in the same way as in C or Assembly. Therefore, the equivalent Java code uses higher-level constructs, making some assumptions about how the original C code might be represented in Java.

In this Java conversion, a Font class is presumed, along with a FrameBuffer class, to represent the frame buffer and the font. This is a simplified illustration, and in practical application, you may have to do more adaptations and use appropriate libraries or frameworks that deal with graphics and rendering.

Code: Select all

public class MyGraphics {

    static class Font {
        int width, height, headerSize, bytesPerGlyph, numGlyph;
        byte[] data;

        // Constructor to initialize Font object
        public Font(/* parameters to initialize font object */) {
            // Initialize font properties here
        }

        byte[] getGlyph(char c) {
            if (c > 0 && c < numGlyph) {
                int offset = headerSize + c * bytesPerGlyph;
                // Extract and return the glyph data from font data
            }
            return getDefaultGlyph(); // return default glyph if character is out of range
        }
    }

    static class FrameBuffer {
        int scanline;
        int[] buffer; // Assume each pixel is represented by an integer

        // Method to set pixel at a specific position in the frame buffer
        void setPixel(int x, int y, int color) {
            buffer[y * scanline + x] = color;
        }
    }

    public static void puts(String s, Font font, FrameBuffer fb) {
        int horizontalPosition = 1;
        int offset = 10 * fb.scanline;

        for (char c : s.toCharArray()) {
            byte[] glyph = font.getGlyph(c);

            for (int y = 0; y < font.height; y++) {
                int mask = 1 << (font.width - 1);
                int line = offset;

                for (int x = 0; x < font.width; x++) {
                    int color = (glyph[y] & mask) != 0 ? 0xFFFFFF : 0x000000;
                    fb.setPixel(horizontalPosition * (font.width + 1) + x, y, color);
                    mask >>= 1;
                }

                fb.setPixel(horizontalPosition * (font.width + 1) + font.width, y, 0x000000);
                offset += fb.scanline;
            }

            horizontalPosition++;
        }
    }

    public static void main(String[] args) {
        // Initialize the Font and FrameBuffer objects
        Font font = new Font(/* parameters to initialize font object */);
        FrameBuffer fb = new FrameBuffer(/* parameters to initialize framebuffer object */);

        // Call the puts method to render string on framebuffer
        puts("Hello, World!", font, fb);
    }
}
Cycl0ne
Craftsman
Posts: 103
Joined: Mon Apr 19, 2010 11:33 am

Re: Technical Questions to the Game

Post by Cycl0ne »

ChristopheF wrote: Thu Sep 21, 2023 10:36 pm There is powershell code to "extract" only the source code for any arbitrary set of media tags.
which Powershell i use for the pc version? PC would be interessting, since its the only platform which didnt use BITMAPS/Palettes but Chunkymaps. Could be interessting how they implemented: Make darker too. At the moment i just take the viewport and darken it with a Alphachannel and a black rectangle ;-)
Post Reply

Return to “Editors and Tools (DMute, DM Builder, ADGE, etc.)”