From 73f62a5ba21e4139df4dd96f06411c105bfdac6b Mon Sep 17 00:00:00 2001 From: nmlgc Date: Fri, 20 Nov 2020 22:00:23 +0100 Subject: [PATCH] [Decompilation] [th01] Stage objects: Background allocation and blitting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Continuing the good error handling from the .PTN functions they're based on… if only its sole caller actually cared. Also: A sort-of limit of 102 objects per stage, just because someone didn't use huge pointers where they would have been necessary… :tannedcirno: Part of P0128, funded by Yanga. --- Makefile.mak | 2 +- th01/formats/ptn.cpp | 8 +- th01/formats/ptn.hpp | 6 + th01/main/stage/stageobj.cpp | 101 +++++++++ th01/main/stage/stageobj.hpp | 38 ++++ th01/main_31.cpp | 6 + th01_reiiden.asm | 404 +++-------------------------------- 7 files changed, 185 insertions(+), 380 deletions(-) create mode 100644 th01/main_31.cpp diff --git a/Makefile.mak b/Makefile.mak index 9b1548fe..790abcc4 100644 --- a/Makefile.mak +++ b/Makefile.mak @@ -53,7 +53,7 @@ bin\th01\op.exe: bin\piloadc.obj bin\th01\op.obj th01\op_01.cpp bin\th01\frmdely $** | -bin\th01\reiiden.exe: bin\piloadc.obj bin\th01\reiiden.obj th01\main_01.cpp th01\main_01_.cpp bin\th01\frmdely.obj bin\th01\vsync.obj bin\th01\ztext.obj bin\th01\initexit.obj bin\th01\graph.obj th01\main_07.cpp th01\main_08.cpp th01\main_09.cpp th01\grpinv32.cpp bin\th01\resstuff.obj th01\main_13.cpp th01\main_13_.cpp th01\main_14.cpp th01\main_15.cpp bin\th01\mdrv2.obj th01\main_19.cpp th01\main_20.cpp th01\main_21.cpp th01\main_23.cpp th01\main_25.cpp th01\main_27.cpp th01\main_30.cpp th01\main_38.cpp +bin\th01\reiiden.exe: bin\piloadc.obj bin\th01\reiiden.obj th01\main_01.cpp th01\main_01_.cpp bin\th01\frmdely.obj bin\th01\vsync.obj bin\th01\ztext.obj bin\th01\initexit.obj bin\th01\graph.obj th01\main_07.cpp th01\main_08.cpp th01\main_09.cpp th01\grpinv32.cpp bin\th01\resstuff.obj th01\main_13.cpp th01\main_13_.cpp th01\main_14.cpp th01\main_15.cpp bin\th01\mdrv2.obj th01\main_19.cpp th01\main_20.cpp th01\main_21.cpp th01\main_23.cpp th01\main_25.cpp th01\main_27.cpp th01\main_30.cpp th01\main_31.cpp th01\main_38.cpp $(CC) $(CFLAGS) -ml -3 -Z -DGAME=1 -DBINARY='M' -nbin\th01\ -eREIIDEN.EXE @&&| $** | diff --git a/th01/formats/ptn.cpp b/th01/formats/ptn.cpp index 7180fbd1..4b0e5fe5 100644 --- a/th01/formats/ptn.cpp +++ b/th01/formats/ptn.cpp @@ -107,13 +107,7 @@ void ptn_put_noalpha_8(screen_x_t left, vram_y_t top, int ptn_id) vram_offset_t vram_offset = vram_offset_shift(left, top); ptn_t *ptn = ptn_with_id(ptn_id); for(pixel_t y = 0; y < PTN_H; y++) { - #define put_noalpha(vram_offset, w, ptn) \ - VRAM_CHUNK(B, vram_offset, w) = (ptn->planes.B[y]); \ - VRAM_CHUNK(R, vram_offset, w) = (ptn->planes.R[y]); \ - VRAM_CHUNK(G, vram_offset, w) = (ptn->planes.G[y]); \ - VRAM_CHUNK(E, vram_offset, w) = (ptn->planes.E[y]); - put_noalpha(vram_offset, PTN_W, ptn); - #undef put_noalpha + vram_put_ptn_planar(vram_offset, ptn); vram_offset += ROW_SIZE; } } diff --git a/th01/formats/ptn.hpp b/th01/formats/ptn.hpp index a7b56cf9..bb3a4974 100644 --- a/th01/formats/ptn.hpp +++ b/th01/formats/ptn.hpp @@ -93,6 +93,12 @@ extern bool ptn_unput_before_alpha_put; // 32×32 access // ------------ +#define vram_put_ptn_planar(vo, ptn) \ + VRAM_PUT(B, vo, ptn->planes.B[y], PTN_W); \ + VRAM_PUT(R, vo, ptn->planes.R[y], PTN_W); \ + VRAM_PUT(G, vo, ptn->planes.G[y], PTN_W); \ + VRAM_PUT(E, vo, ptn->planes.E[y], PTN_W); + // Displays the given [ptn_id] at (⌊left/8⌋*8, top), disregarding its alpha // plane. void ptn_put_noalpha_8(screen_x_t left, vram_y_t top, int ptn_id); diff --git a/th01/main/stage/stageobj.cpp b/th01/main/stage/stageobj.cpp index 20471cd6..9a602929 100644 --- a/th01/main/stage/stageobj.cpp +++ b/th01/main/stage/stageobj.cpp @@ -1,2 +1,103 @@ +extern "C" { +#include +#include "platform.h" +#include "pc98.h" +#include "planar.h" +#include "th01/formats/ptn.hpp" +#include "th01/formats/stagedat.hpp" +} + +#include "th01/main/stage/stageobj.hpp" + static const int TURRET_QUICK_INTERVAL = 100; static const int TURRET_SLOW_INTERVAL = 200; + +// Frees [stageobj_bgs] if non-NULL, then allocates new memory for the given +// number of stage object backgrounds. +ptn_error_t stageobj_bgs_new(int image_count) +{ + if(image_count <= 0) { + return PE_IMAGE_COUNT_INVALID; + } + if(stageobj_bgs) { + farfree(stageobj_bgs); + } + + // I suppose calloc() was chosen to conveniently reset the alpha planes? + // It's not like they're used anywhere, though... + // + // Using a far*() function here is actually correct, as it allows more + // than 64 KB to be allocated. Except that [stageobj_bgs] should have also + // been a `huge` pointer, to allow all this memory to be accessed using + // regular array subscripts... This way, the game can still only display + // up to 102 stage objects without glitches, and the wrap-around when + // writing to the 103rd background is guaranteed to corrupt the memory + // block header at the beginning of the returned segment. + stageobj_bgs = reinterpret_cast( + farcalloc(image_count, sizeof(ptn_t)) + ); + if(!stageobj_bgs) { + return PE_OUT_OF_MEMORY; + } + // Also, these factors should have maybe been casted to 32-bit... + // Multiplying two 16-bit values also truncates the result. + stageobj_bgs_size = (image_count * sizeof(ptn_t)); + return PE_OK; +} + +void stageobj_bgs_put_all(void) +{ + int i; + for(i = 0; i < cards.count; i++) { + stageobj_bgs_put_8(cards.left[i], cards.top[i], (i + 0)); + } + for(i = 0; i < obstacles.count; i++) { + stageobj_bgs_put_8( + obstacles.left[i], obstacles.top[i], (i + cards.count) + ); + } +} + +bool16 stageobj_bgs_free(void) +{ + if(stageobj_bgs) { + farfree(stageobj_bgs); + stageobj_bgs_size = 0; + stageobj_bgs = NULL; + } + return 0; +} + +#define vram_put_ptn_bg_fg(plane, vo, bg, fg, y, fg_mask, tmp) \ + tmp = (~fg_mask & bg->planes.plane[y]); \ + VRAM_PUT(plane, vo, ((fg->planes.plane[y] & fg_mask) | tmp), PTN_W); + +void stageobj_put_8(screen_x_t left, vram_y_t top, int ptn_id, int bg_slot) +{ + upixel_t y; + dots_t(PTN_W) fg_mask = 0; + dots_t(PTN_W) bg_dots_masked; + vram_offset_t vo = vram_offset_muldiv(left, top); + + ptn_t *fg; + if(ptn_id != PTN_STAGEOBJ_NONE) { + fg = ptn_with_id(ptn_id); + } + ptn_t *bg = &stageobj_bgs[bg_slot]; + + if(ptn_id != PTN_STAGEOBJ_NONE) { + for(y = 0; y < PTN_H; y++) { + fg_mask = fg->alpha[y]; + vram_put_ptn_bg_fg(B, vo, bg, fg, y, fg_mask, bg_dots_masked); + vram_put_ptn_bg_fg(R, vo, bg, fg, y, fg_mask, bg_dots_masked); + vram_put_ptn_bg_fg(G, vo, bg, fg, y, fg_mask, bg_dots_masked); + vram_put_ptn_bg_fg(E, vo, bg, fg, y, fg_mask, bg_dots_masked); + vo += ROW_SIZE; + } + } else { + for(y = 0; y < PTN_H; y++) { + vram_put_ptn_planar(vo, bg); + vo += ROW_SIZE; + } + } +} diff --git a/th01/main/stage/stageobj.hpp b/th01/main/stage/stageobj.hpp index 48745066..23e0c44a 100644 --- a/th01/main/stage/stageobj.hpp +++ b/th01/main/stage/stageobj.hpp @@ -57,3 +57,41 @@ extern screen_y_t portal_dst_top; // re-entering. extern bool16 portals_blocked; // -------------------- + +// Blitting +// -------- +// Stationary stage objects are blitted to both VRAM pages, which makes it +// possible to efficiently unblit the other entities moving on top of them, by +// simply restoring pixels from VRAM page 1. Since the player can remove +// cards though, the backgrounds behind them also need to be stored somewhere. +// Storing only the 32×32 regions covered by the cards minimizes the memory +// needed for this, and doesn't require the full background .GRP to be stored +// in memory… which the PiLoad library can't do anyway. +// Since obstacles also need to be removed during a stage transition, their +// backgrounds are stored as well. This makes absolutely sure that a .GRP only +// needs to be blitted a single time, when entering a new scene. + +// Planar would have been enough though, since there's no alpha +// plane to be snapped from VRAM anyway... Assumed by everything to contain +// [card_count] card backgrounds first, followed by [obstacle_count] obstacle +// backgrounds. +extern ptn_t *stageobj_bgs; +extern unsigned long stageobj_bgs_size; + +// Frees [stageobj_bgs], if non-NULL. Always returns 0. +bool16 stageobj_bgs_free(void); + +// Blits the backgrounds for all cards and obstacles at their respective +// positions, effectively removing those sprites from VRAM. +void stageobj_bgs_put_all(void); + +// Blits both the stage object background with the given [bg_slot], and the +// given [ptn_id] on top, to (⌊left/8⌋*8, top) in a single blitting operation. +void stageobj_put_8(screen_x_t left, vram_y_t top, int ptn_id, int bg_slot); + +// Blits the stage object background with the given [bg_slot] to +// (⌊left/8⌋*8, top). +#define stageobj_bgs_put_8(left, top, slot) \ + stageobj_put_8(left, top, PTN_STAGEOBJ_NONE, slot) +#define PTN_STAGEOBJ_NONE 9999 +// -------- diff --git a/th01/main_31.cpp b/th01/main_31.cpp new file mode 100644 index 00000000..ded7653b --- /dev/null +++ b/th01/main_31.cpp @@ -0,0 +1,6 @@ +/* ReC98 + * ----- + * Code segment #31 of TH01's REIIDEN.EXE + */ + +#include "th01/main/stage/stageobj.cpp" diff --git a/th01_reiiden.asm b/th01_reiiden.asm index ab0ecae4..757f9e59 100644 --- a/th01_reiiden.asm +++ b/th01_reiiden.asm @@ -53,7 +53,6 @@ BOMBS_MAX = 5 extern _delay:proc extern _execl:proc extern _exit:proc - extern _farcalloc:proc extern _farfree:proc extern _farheapcheck:proc extern _farheapchecknode:proc @@ -81,6 +80,7 @@ main_21 group main_21_TEXT, main_21__TEXT main_25 group main_25_TEXT, main_25__TEXT main_27 group main_27_TEXT, main_27__TEXT main_30 group main_30_TEXT, main_30__TEXT +main_31 group main_31_TEXT, main_31__TEXT ; =========================================================================== @@ -2511,7 +2511,7 @@ loc_D1E3: push offset aAllPtn7lu ; "all ptn = %7lu\n" call _printf add sp, 8 - pushd [dword_39E80] + pushd [_stageobj_bgs_size] push ds push offset aKabeMem7lu ; "kabe mem = %7lu\n" call _printf @@ -2534,7 +2534,7 @@ loc_D1E3: pop eax mov edx, dword_36C1A sub edx, eax - sub edx, dword_39E80 + sub edx, _stageobj_bgs_size push edx push ds push offset aEtcMem7ld ; "etc mem = %7ld\n\n" @@ -2621,7 +2621,7 @@ loc_D2F8: call sub_D095 push ds push offset aKabe ; "KABE" - pushd [off_39E7C] ; node + pushd [_stageobj_bgs] ; node call sub_D095 loc_D317: @@ -2801,7 +2801,7 @@ sub_D340 endp sub_D47D proc far push bp mov bp, sp - call sub_20468 + call @stageobj_bgs_free$qv pop bp retf sub_D47D endp @@ -2815,7 +2815,7 @@ sub_D487 proc far push bp mov bp, sp push si - call sub_20468 + call @stageobj_bgs_free$qv mov si, 2 jmp short loc_D4A9 ; --------------------------------------------------------------------------- @@ -3929,7 +3929,7 @@ loc_DF9A: push 1 call _graph_accesspage_func pop cx - call sub_203F9 + call @stageobj_bgs_put_all$qv push 0 call _graph_accesspage_func pop cx @@ -18411,7 +18411,7 @@ loc_201CF: push 1 call _graph_accesspage_func pop cx - push si + push si ; bg_slot les bx, _cards_hp mov al, es:[bx+si] cbw @@ -18429,22 +18429,22 @@ loc_201CF: add bx, ax mov al, [bx+126Eh] mov ah, 0 - push ax + push ax ; ptn_id mov ax, si add ax, ax les bx, _cards_top add bx, ax - push word ptr es:[bx] + push word ptr es:[bx] ; top mov ax, si add ax, ax les bx, _cards_left add bx, ax - push word ptr es:[bx] - call sub_20496 + push word ptr es:[bx] ; left + call @stageobj_put_8$qiiii push 0 call _graph_accesspage_func add sp, 0Ah - push si + push si ; bg_slot les bx, _cards_hp mov al, es:[bx+si] cbw @@ -18462,18 +18462,18 @@ loc_201CF: add bx, ax mov al, [bx+126Eh] mov ah, 0 - push ax + push ax ; ptn_id mov ax, si add ax, ax les bx, _cards_top add bx, ax - push word ptr es:[bx] + push word ptr es:[bx] ; top mov ax, si add ax, ax les bx, _cards_left add bx, ax - push word ptr es:[bx] - call sub_20496 + push word ptr es:[bx] ; left + call @stageobj_put_8$qiiii add sp, 8 loc_202A6: @@ -18592,7 +18592,14 @@ main_30__TEXT ends ; Segment type: Pure code main_31_TEXT segment byte public 'CODE' use16 - assume cs:main_31_TEXT + extern @stageobj_bgs_new$qi:proc + extern @stageobj_bgs_put_all$qv:proc + extern @stageobj_bgs_free$qv:proc + extern @stageobj_put_8$qiiii:proc +main_31_TEXT ends + +main_31__TEXT segment byte public 'CODE' use16 + assume cs:main_31 ;org 9 assume es:nothing, ss:nothing, ds:_DATA, fs:nothing, gs:nothing @@ -18624,353 +18631,6 @@ OT_BAR_RIGHT = 21 ; =============== S U B R O U T I N E ======================================= ; Attributes: bp-based frame - -sub_20399 proc far - -arg_0 = word ptr 6 - - push bp - mov bp, sp - push si - mov si, [bp+arg_0] - or si, si - jg short loc_203A9 - mov ax, 0FFF7h - jmp short loc_203F6 -; --------------------------------------------------------------------------- - -loc_203A9: - cmp off_39E7C, 0 - jz short loc_203BE - pushd [off_39E7C] - call _farfree - add sp, 4 - -loc_203BE: - pushd 281h ; unitsz - movsx eax, si - push eax ; nunits - call _farcalloc - add sp, 8 - mov word ptr off_39E7C+2, dx - mov word ptr off_39E7C, ax - cmp off_39E7C, 0 - jnz short loc_203E6 - mov ax, 0FFFDh - jmp short loc_203F6 -; --------------------------------------------------------------------------- - -loc_203E6: - mov ax, si - imul ax, 281h - movzx eax, ax - mov dword_39E80, eax - xor ax, ax - -loc_203F6: - pop si - pop bp - retf -sub_20399 endp - - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_203F9 proc far - push bp - mov bp, sp - push si - xor si, si - jmp short loc_20428 -; --------------------------------------------------------------------------- - -loc_20401: - push si - push 9999 - mov ax, si - add ax, ax - les bx, _cards_top - add bx, ax - push word ptr es:[bx] - mov ax, si - add ax, ax - les bx, _cards_left - add bx, ax - push word ptr es:[bx] - nopcall sub_20496 - add sp, 8 - inc si - -loc_20428: - cmp si, _card_count - jl short loc_20401 - xor si, si - jmp short loc_2045F -; --------------------------------------------------------------------------- - -loc_20432: - mov ax, si - add ax, _card_count - push ax - push 9999 - mov ax, si - add ax, ax - les bx, _obstacles_top - add bx, ax - push word ptr es:[bx] - mov ax, si - add ax, ax - les bx, _obstacles_left - add bx, ax - push word ptr es:[bx] - nopcall sub_20496 - add sp, 8 - inc si - -loc_2045F: - cmp si, _obstacle_count - jl short loc_20432 - pop si - pop bp - retf -sub_203F9 endp - - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_20468 proc far - push bp - mov bp, sp - cmp off_39E7C, 0 - jz short loc_20492 - pushd [off_39E7C] - call _farfree - add sp, 4 - mov dword_39E80, 0 - mov off_39E7C, 0 - -loc_20492: - xor ax, ax - pop bp - retf -sub_20468 endp - - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_20496 proc far - -var_10 = dword ptr -10h -@@ptn = dword ptr -0Ch -var_8 = dword ptr -8 -var_4 = dword ptr -4 -arg_0 = word ptr 6 -arg_2 = word ptr 8 -arg_4 = word ptr 0Ah -arg_6 = word ptr 0Ch - - enter 10h, 0 - push si - push di - mov di, [bp+arg_4] - mov [bp+var_4], 0 - mov ax, [bp+arg_2] - imul ax, 50h - push ax - mov ax, [bp+arg_0] - mov bx, 8 - cwd - idiv bx - pop dx - add dx, ax - mov si, dx - cmp di, 9999 - jz short loc_204EF - mov ax, di - mov bx, PTN_IMAGES_PER_SLOT - cwd - idiv bx - shl ax, 2 - mov bx, ax - mov ax, word ptr (_ptn_images + 2)[bx] - mov dx, word ptr _ptn_images[bx] - push ax - mov ax, di - mov bx, PTN_IMAGES_PER_SLOT - push dx - cwd - idiv bx - imul dx, size ptn_t - pop ax - add ax, dx - pop dx - mov word ptr [bp+@@ptn+2], dx - mov word ptr [bp+@@ptn], ax - -loc_204EF: - mov ax, [bp+arg_6] - imul ax, size ptn_t - mov dx, word ptr off_39E7C+2 - mov bx, word ptr off_39E7C - add bx, ax - mov word ptr [bp+var_10+2], dx - mov word ptr [bp+var_10], bx - cmp di, 9999 - jz loc_20622 - xor cx, cx - jmp loc_20619 -; --------------------------------------------------------------------------- - -loc_20513: - mov ax, cx - shl ax, 2 - les bx, [bp+@@ptn] - add bx, ax - mov eax, es:[bx+ptn_t.PTN_alpha] - mov [bp+var_4], eax - not eax - mov dx, cx - shl dx, 2 - les bx, [bp+var_10] - add bx, dx - and eax, es:[bx+ptn_t.planes.PTN_B] - mov [bp+var_8], eax - mov ax, cx - shl ax, 2 - les bx, [bp+@@ptn] - add bx, ax - mov eax, es:[bx+ptn_t.planes.PTN_B] - and eax, [bp+var_4] - or eax, [bp+var_8] - les bx, _VRAM_PLANE_B - add bx, si - mov es:[bx], eax - mov eax, [bp+var_4] - not eax - mov dx, cx - shl dx, 2 - les bx, [bp+var_10] - add bx, dx - and eax, es:[bx+ptn_t.planes.PTN_R] - mov [bp+var_8], eax - mov ax, cx - shl ax, 2 - les bx, [bp+@@ptn] - add bx, ax - mov eax, es:[bx+ptn_t.planes.PTN_R] - and eax, [bp+var_4] - or eax, [bp+var_8] - les bx, _VRAM_PLANE_R - add bx, si - mov es:[bx], eax - mov eax, [bp+var_4] - not eax - mov dx, cx - shl dx, 2 - les bx, [bp+var_10] - add bx, dx - and eax, es:[bx+ptn_t.planes.PTN_G] - mov [bp+var_8], eax - mov ax, cx - shl ax, 2 - les bx, [bp+@@ptn] - add bx, ax - mov eax, es:[bx+ptn_t.planes.PTN_G] - and eax, [bp+var_4] - or eax, [bp+var_8] - les bx, _VRAM_PLANE_G - add bx, si - mov es:[bx], eax - mov eax, [bp+var_4] - not eax - mov dx, cx - shl dx, 2 - les bx, [bp+var_10] - add bx, dx - and eax, es:[bx+ptn_t.planes.PTN_E] - mov [bp+var_8], eax - mov ax, cx - shl ax, 2 - les bx, [bp+@@ptn] - add bx, ax - mov eax, es:[bx+ptn_t.planes.PTN_E] - and eax, [bp+var_4] - or eax, [bp+var_8] - les bx, _VRAM_PLANE_E - add bx, si - mov es:[bx], eax - add si, ROW_SIZE - inc cx - -loc_20619: - cmp cx, PTN_H - jb loc_20513 - jmp short loc_20696 -; --------------------------------------------------------------------------- - -loc_20622: - xor cx, cx - jmp short loc_20691 -; --------------------------------------------------------------------------- - -loc_20626: - mov ax, cx - shl ax, 2 - les bx, [bp+var_10] - add bx, ax - mov eax, es:[bx+ptn_t.planes.PTN_B] - les bx, _VRAM_PLANE_B - add bx, si - mov es:[bx], eax - mov ax, cx - shl ax, 2 - les bx, [bp+var_10] - add bx, ax - mov eax, es:[bx+ptn_t.planes.PTN_R] - les bx, _VRAM_PLANE_R - add bx, si - mov es:[bx], eax - mov ax, cx - shl ax, 2 - les bx, [bp+var_10] - add bx, ax - mov eax, es:[bx+ptn_t.planes.PTN_G] - les bx, _VRAM_PLANE_G - add bx, si - mov es:[bx], eax - mov ax, cx - shl ax, 2 - les bx, [bp+var_10] - add bx, ax - mov eax, es:[bx+ptn_t.planes.PTN_E] - les bx, _VRAM_PLANE_E - add bx, si - mov es:[bx], eax - add si, ROW_SIZE - inc cx - -loc_20691: - cmp cx, PTN_H - jb short loc_20626 - -loc_20696: - pop di - pop si - leave - retf -sub_20496 endp - - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - sub_2069A proc far var_4 = dword ptr -4 @@ -18993,8 +18653,8 @@ arg_4 = word ptr 0Ah mov di, dx mov ax, [bp+arg_4] imul ax, 281h - mov dx, word ptr off_39E7C+2 - mov bx, word ptr off_39E7C + mov dx, word ptr _stageobj_bgs+2 + mov bx, word ptr _stageobj_bgs add bx, ax mov word ptr [bp+var_4+2], dx mov word ptr [bp+var_4], bx @@ -19392,7 +19052,7 @@ loc_2099C: mov ax, _card_count add ax, _obstacle_count push ax - call sub_20399 + call @stageobj_bgs_new$qi pop cx cmp _card_count, 0 jle short loc_20A27 @@ -21064,7 +20724,7 @@ sub_21819 proc far retf sub_21819 endp -main_31_TEXT ends +main_31__TEXT ends ; =========================================================================== @@ -45573,9 +45233,9 @@ word_39E76 dw ? word_39E78 dw ? byte_39E7A db ? db ? -; void far *off_39E7C -off_39E7C dd ? -dword_39E80 dd ? +public _stageobj_bgs, _stageobj_bgs_size +_stageobj_bgs dd ? +_stageobj_bgs_size dd ? public _cards, _obstacles, _cards_score _cards label