Skip to content
Merged
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
7 changes: 6 additions & 1 deletion engine/android/app/jni/openbor/video.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,11 @@ int video_set_mode(s_videomodes videomodes)
return 1;
}

int video_restore_mode(void)
{
return video_set_mode(stored_videomodes);
}

void video_fullscreen_flip()
{
}
Expand Down Expand Up @@ -598,4 +603,4 @@ int video_current_refresh_rate()
if (SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(window), &display_mode) != 0)
return 60;
return display_mode.refresh_rate;
}
}
62 changes: 39 additions & 23 deletions engine/openbor.c
Original file line number Diff line number Diff line change
Expand Up @@ -17265,8 +17265,8 @@ s_model *load_cached_model(char *name, char *owner, char unload)
case CMD_MODEL_ONMOVEZSCRIPT:
pos += lcmHandleCommandScripts(&arglist, buf + pos, newchar->scripts->onmovez_script, "onmovezscript", filename, 1, 0);
break;
case CMD_MODEL_ONMOVEASCRIPT:
pos += lcmHandleCommandScripts(&arglist, buf + pos, newchar->scripts->onmovea_script, "onmoveascript", filename, 1, 0);
case CMD_MODEL_ONMOVEYSCRIPT:
pos += lcmHandleCommandScripts(&arglist, buf + pos, newchar->scripts->onmovea_script, "onmoveyscript", filename, 1, 0);
break;
case CMD_MODEL_ONDEATHSCRIPT:
pos += lcmHandleCommandScripts(&arglist, buf + pos, newchar->scripts->ondeath_script, "ondeathscript", filename, 1, 0);
Expand Down Expand Up @@ -43920,31 +43920,31 @@ int player_check_special()
}
else if (player_keys & FLAG_JUMP && player_keys & FLAG_ATTACK)
{
thekey = FLAG_SPECIAL;
thekey = FLAG_JUMP | FLAG_ATTACK;
}
break;

case AJSPECIAL_KEY_ATTACK2:

if (player_keys & FLAG_ATTACK2)
{
thekey = FLAG_SPECIAL;
thekey = FLAG_ATTACK2;
}
break;

case AJSPECIAL_KEY_ATTACK3:

if (player_keys & FLAG_ATTACK3)
{
thekey = FLAG_SPECIAL;
thekey = FLAG_ATTACK3;
}
break;

case AJSPECIAL_KEY_ATTACK4:

if (player_keys & FLAG_ATTACK4)
{
thekey = FLAG_SPECIAL;
thekey = FLAG_ATTACK4;
}
break;

Expand Down Expand Up @@ -51879,6 +51879,7 @@ int playwebm(const char *path, int noskip)
int retval = 1;
int source_id = -1;
s_movie_playback *playback = NULL;
s_screen *screenshot_frame = NULL;

movie_playback_stop_all();
source_id = movie_source_load(path, MOVIE_LOADING_STREAM);
Expand All @@ -51900,8 +51901,10 @@ int playwebm(const char *path, int noskip)
goto quit;
}

clearscreen(vscreen);
video_copy_screen(vscreen);
/* Legacy playback uses the WebM display size and hardware YUV output. */
movie_playback_set_width(playback, MOVIE_SIZE_NATIVE);
movie_playback_set_height(playback, MOVIE_SIZE_NATIVE);

while(playback->active) {
int interrupt_requested;
int present_frame;
Expand All @@ -51918,24 +51921,38 @@ int playwebm(const char *path, int noskip)
}
present_frame = playback->frame_dirty;
if(present_frame) {
clearscreen(vscreen);
if(!movie_playback_draw_to_screen(vscreen, playback->index)) {
if(!movie_playback_draw_to_yuv(playback->index)) {
retval = 0;
break;
}
}
if(playback->current_frame &&
!noscreenshot &&
(bothnewkeys & FLAG_SCREENSHOT)) {
screenshot(vscreen, getpal, 1);
}
if(present_frame) {
video_copy_screen(vscreen);
if(!screenshot_frame ||
screenshot_frame->width != playback->current_frame->width ||
screenshot_frame->height != playback->current_frame->height) {
if(screenshot_frame) {
freescreen(&screenshot_frame);
}
screenshot_frame = allocscreen(
playback->current_frame->width,
playback->current_frame->height,
PIXEL_32
);
}
if(screenshot_frame) {
yuv_to_rgb(playback->current_frame, screenshot_frame);
screenshot(screenshot_frame, NULL, 0);
}
}
usleep(1000);
}

quit:
if(screenshot_frame) {
freescreen(&screenshot_frame);
}
if(playback && playback->failed && retval > 0) {
retval = 0;
}
Expand Down Expand Up @@ -52633,8 +52650,7 @@ static void load_select_screen_info(s_savelevel *save)
int selectplayer(int *players, char *filename, int useSavedGame)
{
s_model *tempmodel;
s_model *model_old = NULL;
s_model *model_new = NULL;
s_model *model_new[MAX_PLAYERS] = { NULL };
int i;
int exit = 0;
int escape = 0;
Expand Down Expand Up @@ -52985,10 +53001,11 @@ int selectplayer(int *players, char *filename, int useSavedGame)
// Transition from select (player selected another model, and the
// select out transition is now finished). Repeat of left/right key
// logic below and probably needs consolidation.
if (example[i]->animnum == ANI_SELECTOUT && model_new)
if (example[i]->animnum == ANI_SELECTOUT && model_new[i])
{
// Apply new model.
ent_set_model(example[i], model_new->name, 0);
ent_set_model(example[i], model_new[i]->name, 0);
model_new[i] = NULL;

// Copy example model name to player name variable.
strcpy(player[i].name, example[i]->model->name);
Expand Down Expand Up @@ -53074,17 +53091,15 @@ int selectplayer(int *players, char *filename, int useSavedGame)
}

// Get model in use right now.
model_old = example[i]->model;

// Let's get the new model. Left key = previous model
// in cycle. Right key = next.
if ((player[i].newkeys & FLAG_MOVELEFT))
{
model_new = prevplayermodeln(model_old, i);
model_new[i] = prevplayermodeln(example[i]->model, i);
}
else
{
model_new = nextplayermodeln(model_old, i);
model_new[i] = nextplayermodeln(example[i]->model, i);
}

// Do we have a select out transition? If so play it here.
Expand All @@ -53096,7 +53111,8 @@ int selectplayer(int *players, char *filename, int useSavedGame)
else
{
// Apply new model.
ent_set_model(example[i], model_new->name, 0);
ent_set_model(example[i], model_new[i]->name, 0);
model_new[i] = NULL;

// Copy example model name to player name variable.
strcpy(player[i].name, example[i]->model->name);
Expand Down
5 changes: 5 additions & 0 deletions engine/sdl/video.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ int video_set_mode(s_videomodes videomodes)
return 1;
}

int video_restore_mode(void)
{
return video_set_mode(stored_videomodes);
}

void video_fullscreen_flip()
{
int restore_yuv = yuv_mode;
Expand Down
2 changes: 1 addition & 1 deletion engine/sdl/video.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ void FramerateDelay();

// Frees all VESA shit when returning to textmode
int video_set_mode(s_videomodes);
int video_restore_mode(void);
int video_copy_screen(s_screen*);
void video_clearscreen();
void video_fullscreen_flip();
Expand All @@ -39,4 +40,3 @@ int video_display_yuv_frame(void);
int video_current_refresh_rate();

#endif

2 changes: 1 addition & 1 deletion engine/source/openborscript/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ List *createModelCommandList(void)
LIST_ADD(CMD_MODEL_ONFALLSCRIPT, "onfallscript");
LIST_ADD(CMD_MODEL_ONKILLSCRIPT, "onkillscript");
LIST_ADD(CMD_MODEL_ONMODELCOPYSCRIPT, "onmodelcopyscript");
LIST_ADD(CMD_MODEL_ONMOVEASCRIPT, "onmoveascript");
LIST_ADD(CMD_MODEL_ONMOVEYSCRIPT, "onmoveyscript");
LIST_ADD(CMD_MODEL_ONMOVEXSCRIPT, "onmovexscript");
LIST_ADD(CMD_MODEL_ONMOVEZSCRIPT, "onmovezscript");
LIST_ADD(CMD_MODEL_ONPAINSCRIPT, "onpainscript");
Expand Down
2 changes: 1 addition & 1 deletion engine/source/openborscript/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ typedef enum modelCommand
CMD_MODEL_ONFALLSCRIPT,
CMD_MODEL_ONKILLSCRIPT,
CMD_MODEL_ONMODELCOPYSCRIPT,
CMD_MODEL_ONMOVEASCRIPT,
CMD_MODEL_ONMOVEYSCRIPT,
CMD_MODEL_ONMOVEXSCRIPT,
CMD_MODEL_ONMOVEZSCRIPT,
CMD_MODEL_ONPAINSCRIPT,
Expand Down
6 changes: 6 additions & 0 deletions engine/source/openborscript/index.c
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,10 @@ const char *Script_GetFunctionName(void *functionRef)
{
return "movie_draw_to_screen";
}
else if (functionRef == ((void *)openbor_movie_draw_to_yuv))
{
return "movie_draw_to_yuv";
}
else if (functionRef == ((void *)openbor_movie_set_sound_channel))
{
return "movie_set_sound_channel";
Expand Down Expand Up @@ -1807,6 +1811,8 @@ void Script_LoadSystemFunctions()
(void *)openbor_movie_play, "movie_play");
List_InsertAfter(&theFunctionList,
(void *)openbor_movie_draw_to_screen, "movie_draw_to_screen");
List_InsertAfter(&theFunctionList,
(void *)openbor_movie_draw_to_yuv, "movie_draw_to_yuv");
List_InsertAfter(&theFunctionList,
(void *)openbor_movie_set_sound_channel, "movie_set_sound_channel");
List_InsertAfter(&theFunctionList,
Expand Down
27 changes: 27 additions & 0 deletions engine/source/openborscript/movie.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,32 @@ HRESULT openbor_movie_draw_to_screen(
return E_FAIL;
}

/*
* Caskey, Damon V.
* 2026-08-18
*
* Present a movie channel directly through the exclusive hardware YUV path.
*/
HRESULT openbor_movie_draw_to_yuv(
ScriptVariant **varlist,
ScriptVariant **pretvar,
int paramCount
)
{
LONG channel;

*pretvar = NULL;
if(paramCount < 1 ||
FAILED(ScriptVariant_IntegerValue(varlist[0], &channel)) ||
channel < 0 ||
(unsigned int)channel >= MOVIE_CHANNEL_COUNT ||
!movie_playback_draw_to_yuv((int)channel)) {
printf("\nScript error: movie_draw_to_yuv(int channel). Movie channel is invalid.\n");
return E_FAIL;
}
return S_OK;
}

/*
* Caskey, Damon V.
* 2026-08-12
Expand Down Expand Up @@ -563,6 +589,7 @@ MOVIE_UNSUPPORTED(openbor_movie_load)
MOVIE_UNSUPPORTED(openbor_movie_unload)
MOVIE_UNSUPPORTED(openbor_movie_play)
MOVIE_UNSUPPORTED(openbor_movie_draw_to_screen)
MOVIE_UNSUPPORTED(openbor_movie_draw_to_yuv)
MOVIE_UNSUPPORTED(openbor_movie_set_sound_channel)
MOVIE_UNSUPPORTED(openbor_movie_stop)
MOVIE_UNSUPPORTED(openbor_movie_get_channel_object)
Expand Down
1 change: 1 addition & 0 deletions engine/source/openborscript/movie.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ HRESULT openbor_movie_load(ScriptVariant **varlist, ScriptVariant **pretvar, int
HRESULT openbor_movie_unload(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount);
HRESULT openbor_movie_play(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount);
HRESULT openbor_movie_draw_to_screen(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount);
HRESULT openbor_movie_draw_to_yuv(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount);
HRESULT openbor_movie_set_sound_channel(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount);
HRESULT openbor_movie_stop(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount);
HRESULT openbor_movie_get_channel_object(ScriptVariant **varlist, ScriptVariant **pretvar, int paramCount);
Expand Down
70 changes: 70 additions & 0 deletions engine/source/webmlib/movie_playback.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ static void *movie_cache_allocate_nonfatal(size_t size)
#include "sound_channel.h"
#include "soundmix.h"
#include "timer.h"
#include "video.h"
#include "vidplay.h"
#include "movie_playback.h"

Expand Down Expand Up @@ -98,6 +99,17 @@ typedef struct s_movie_playback_pool {

static s_movie_playback_pool movie_playback_pool;

/*
* Caskey, Damon V.
* 2026-08-18
*
* Track exclusive hardware YUV presentation independently from decoder
* channels. The overlay replaces the normal game texture until playback
* ends, at which point the configured game video mode is restored.
*/
static int movie_yuv_channel = -1;
static yuv_video_mode movie_yuv_mode;

/*
* Caskey, Damon V.
* 2026-08-17
Expand Down Expand Up @@ -1124,6 +1136,11 @@ void movie_playback_stop(s_movie_playback *playback)
if(channel < 0) {
return;
}
if(movie_yuv_channel == channel) {
movie_yuv_channel = -1;
memset(&movie_yuv_mode, 0, sizeof(movie_yuv_mode));
video_restore_mode();
}
movie_playback_pool.active_mask &= ~(UINT64_C(1) << channel);
movie_playback_reset_record(&movie_playback_pool.channel[channel]);
}
Expand Down Expand Up @@ -1601,6 +1618,59 @@ bool movie_playback_draw_to_screen(s_screen *screen, int channel)
return movie_playback_render_to(playback, screen);
}

/*
* Caskey, Damon V.
* 2026-08-18
*
* Present one retained decoder frame through the hardware YUV path. This is
* an exclusive final-output operation, not a compositing operation. Width and
* height select the overlay's logical display size; zero and native both use
* the WebM display dimensions. Playback timing and transport remain owned by
* the channel and therefore work identically to screen composition.
*/
bool movie_playback_draw_to_yuv(int channel)
{
s_movie_playback *playback;
yuv_video_mode mode;

if(!movie_playback_pool.initialized ||
channel < 0 ||
(unsigned int)channel >= MOVIE_CHANNEL_COUNT) {
return false;
}
playback = &movie_playback_pool.channel[channel];
if(!playback->active ||
!(movie_playback_pool.active_mask & (UINT64_C(1) << channel))) {
return false;
}
if(!playback->current_frame) {
return true;
}

mode = playback->video_mode;
if(playback->width && playback->width != MOVIE_SIZE_NATIVE) {
mode.display_width = (int)playback->width;
}
if(playback->height && playback->height != MOVIE_SIZE_NATIVE) {
mode.display_height = (int)playback->height;
}
if(movie_yuv_channel != channel ||
memcmp(&movie_yuv_mode, &mode, sizeof(mode))) {
if(!video_setup_yuv_overlay(&mode)) {
return false;
}
movie_yuv_channel = channel;
movie_yuv_mode = mode;
}
if(!video_prepare_yuv_frame(playback->current_frame) ||
!video_display_yuv_frame()) {
return false;
}
playback->frame_dirty = 0;
playback->current_frame_presented = 1;
return true;
}

/*
* Caskey, Damon V.
* 2026-08-12
Expand Down
Loading
Loading