Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scale geomod crater texture PPM based on its resolution #293

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Version 1.9.0 (not released yet)
- Add level filename to "Level Initializing" console message
- Properly handle WM_PAINT in dedicated server, may improve performance (DF bug)
- Fix crash when `verify_level` command is run without a level being loaded
- Add correct scaling for geomod crater texture based on resolution
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like how you describe this change. It doesn't fix anything for unmodded game (I assume default texture is 256x256). Instead it allows to add more details to crater texture in HD packs. There's a difference.


Version 1.8.0 (released 2022-09-17)
-----------------------------------
Expand Down
7 changes: 7 additions & 0 deletions game_patch/bmpman/bmpman.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@
#include "../rf/bmpman.h"
#include "../rf/gr/gr.h"

namespace rf
{
static auto& bm_bitmaps = addr_as_ref<void*>(0x017C80C4);
static auto& bm_get_cache_slot = addr_as_ref<int(int)>(0x0050F440);
static auto& geomod_crater_texture_handle = addr_as_ref<int>(0x00646000);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have LevelInfo already defined in Dash source...

}

void bm_set_dynamic(int bm_handle, bool dynamic);
bool bm_is_dynamic(int bm_handle);
void bm_change_format(int bm_handle, rf::bm::Format format);
Expand Down
51 changes: 51 additions & 0 deletions game_patch/misc/g_solid.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <patch_common/FunHook.h>
#include <patch_common/CallHook.h>
#include <patch_common/CodeInjection.h>
#include <patch_common/AsmWriter.h>
#include <xlog/xlog.h>
Expand Down Expand Up @@ -409,6 +410,53 @@ void g_solid_render_ui()
}
}

std::optional<int> bm_get_cache_slot_opt(int handle)
{
int cache_slot = rf::bm_get_cache_slot(handle);
return (cache_slot == -1) ? std::nullopt : std::optional<int>{cache_slot};
}

int bm_get_width(int handle)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's rf::bm::get_dimensions(bitmap_handle, &bm_w, &bm_h);

You really through that there would be no such function?
Also I have no idea why you didn't use BitmapEntry structure definition and instead put a lot of magic numbers into that code...

{
auto cache_slot = bm_get_cache_slot_opt(handle).value_or(0);
if (cache_slot == 0) {
return 0;
}
int index = 27 * cache_slot;
return *((uint16_t*)rf::bm_bitmaps + 2 * index + 22);
}

int bm_get_height(int handle)
{
auto cache_slot = bm_get_cache_slot_opt(handle).value_or(0);
if (cache_slot == 0) {
return 0;
}
int index = 27 * cache_slot;
return *((uint16_t*)rf::bm_bitmaps + 2 * index + 23);
}

float bm_calculate_ppm(int handle)
{
const int width = bm_get_width(handle);
const int height = bm_get_height(handle);

if (width <= 0 || height <= 0) {
// something weird happened, use default value and avoid divide by zero
return 32.0f;
}

const float max_dimension = static_cast<float>(std::max(width, height));
return 32.0f * (max_dimension / 256.0f);
}

using GSolid_SetAutotexture_Type = void __fastcall(rf::GSolid*, float);
CallHook<GSolid_SetAutotexture_Type> set_geo_crater_ppm_hook{
0x00466BD4, [](rf::GSolid* solid, float ppm) {
set_geo_crater_ppm_hook.call_target(solid, bm_calculate_ppm(rf::geomod_crater_texture_handle));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you always use level.default_rock_texture but geomod uses another texture for ice. If someone changes only rock texture it will use wrong ppm for ice.
Selecting a texture is just a line below. It would be nice to make it work properly for ice too.

}
};

void g_solid_do_patch()
{
// Buffer overflows in solid_read
Expand Down Expand Up @@ -465,6 +513,9 @@ void g_solid_do_patch()
AsmWriter{0x004D4409}.jmp(0x004D44B1);
AsmWriter{0x004D44C7}.nop(2);

// Set PPM for geo crater texture based on its resolution instead of static value of 32.0
set_geo_crater_ppm_hook.install();

// Commands
max_decals_cmd.register_cmd();
dbg_room_clip_wnd_cmd.register_cmd();
Expand Down