From 604c22e16bc6bd68d1eb12b7f3f53bd004208ca8 Mon Sep 17 00:00:00 2001 From: ansstuff <ansstuff@users.sf.net> Date: Tue, 4 Dec 2012 17:03:58 +0000 Subject: [PATCH] * speed up HUD text drawing * Taseditor: speed up consecutive Recordings (when combining) --- changelog.txt | 2 + src/drawing.cpp | 131 +++++++++++++++---------- src/drivers/win/taseditor/history.cpp | 80 ++++++++------- src/drivers/win/taseditor/history.h | 2 +- src/drivers/win/taseditor/inputlog.cpp | 53 +++++++--- src/drivers/win/taseditor/inputlog.h | 2 +- src/drivers/win/taseditor/recorder.cpp | 13 ++- src/drivers/win/taseditor/snapshot.cpp | 17 ++++ src/drivers/win/taseditor/snapshot.h | 3 +- src/movie.cpp | 19 ++-- 10 files changed, 199 insertions(+), 123 deletions(-) diff --git a/changelog.txt b/changelog.txt index 2cbad8e8..f7bd2b56 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,5 @@ +04-Dec-2012 - AnS - speed up HUD text drawing +04-Dec-2012 - AnS - Taseditor: speed up consecutive Recordings (when combining) 03-Dec-2012 - AnS - Taseditor: fixed accelerators when editing Notes 03-Dec-2012 - AnS - fixed "X" button in the "Enter New Input" dialog (Hotkey Mapping); changed "Cancel" button to "OK" 03-Dec-2012 - CaH4e3 - fixed mapper 99 diff --git a/src/drawing.cpp b/src/drawing.cpp index 9cd32bc7..06db044b 100644 --- a/src/drawing.cpp +++ b/src/drawing.cpp @@ -392,7 +392,7 @@ void FCEU_DrawNumberRow(uint8 *XBuf, int *nstatus, int cur) static int FixJoedChar(uint8 ch) { - int c = ch; c -= 32; + int c = ch - 32; return (c < 0 || c > 98) ? 0 : c; } static int JoedCharWidth(uint8 ch) @@ -400,92 +400,123 @@ static int JoedCharWidth(uint8 ch) return Font6x7[FixJoedChar(ch)*8]; } +char target[64][256]; + void DrawTextTransWH(uint8 *dest, uint32 width, uint8 *textmsg, uint8 fgcolor, int max_w, int max_h, int border) { - unsigned beginx=2, x=beginx; - unsigned y=2; + unsigned int beginx=2, x=beginx; + unsigned int y=2; - char target[64][256] = {{0}}; + memset(target, 0, 64 * 256); assert(width==256); if (max_w > 256) max_w = 256; if (max_h > 64) max_h = 64; + int ch, wid, nx, ny, max_x = x, offs; + int pixel_color; for(; *textmsg; ++textmsg) { - int ch, wid; - - if(*textmsg == '\n') { x=beginx; y+=8; continue; } - ch = FixJoedChar(*textmsg); - wid = JoedCharWidth(*textmsg); - - int newx = x+wid; - if(newx >= (int)width) { x=beginx; y+=8; } - - for(int ny=0; ny<7; ++ny) + if(*textmsg == '\n') { - uint8 d = Font6x7[ch*8 + 1+ny]; - for(int nx=0; nx<wid; ++nx) + // new line + x = beginx; + y += 8; + continue; + } + ch = FixJoedChar(*textmsg); + wid = Font6x7[ch * 8]; + + if ((x + wid) >= (int)width) + { + // wrap to new line + x = beginx; + y += 8; + } + + for(ny = 0; ny < 7; ++ny) + { + uint8 d = Font6x7[ch * 8 + 1 + ny]; + for(nx = 0; nx < wid; ++nx) { - int c = (d >> (7-nx)) & 1; - if(c) + pixel_color = (d >> (7 - nx)) & 1; + if (pixel_color) { - if(y+ny >= 62) goto textoverflow; - target[y+ny][x+nx] = 2; + if (y + ny >= 62) + { + // Max border is 2, so the max safe y is 62 (since 64 is the max for the target array + goto textoverflow; + } + target[y + ny][x + nx] = 2; + } else + { + target[y + ny][x + nx] = 1; } - else - target[y+ny][x+nx] = 1; } } - x += wid; + // proceed to next char + x += wid; + if (max_x < x) + max_x = x; } textoverflow: - for(y=0; y<62; ++y) //Max border is 2, so the max safe y is 62 (since 64 is the max for the target array - for(x=0; x<width; ++x) + + max_x += 2; + if (max_x > width) + max_x = width; + int max_y = y + ny + 2; + if (max_y > 62) + max_y = 62; + + // draw target buffer to screen buffer + for (y = 0; y < max_y; ++y) + { + for (x = 0; x < max_x; ++x) { - int offs = y*width+x; - int c = 0; + offs = y * width + x; + pixel_color = target[y][x] * 100; - c += target[y][x] * 100; - - if(border>=1){ - x>=( 1) && (c += target[y][x-1]); - x<(width-1) && (c += target[y][x+1]); - y>=( 1) && (c += target[y-1][x]); - y<(16 -1) && (c += target[y+1][x]); + if(border>=1) + { + x>=( 1) && (pixel_color += target[y][x-1]); + x<(width-1) && (pixel_color += target[y][x+1]); + y>=( 1) && (pixel_color += target[y-1][x]); + y<(16 -1) && (pixel_color += target[y+1][x]); } - if(border>=2){ - x>=( 1) && (c += target[y][x-1]*10); - x<(width-1) && (c += target[y][x+1]*10); - y>=( 1) && (c += target[y-1][x]*10); - y<(16 -1) && (c += target[y+1][x]*10); + if(border>=2) + { + x>=( 1) && (pixel_color += target[y][x-1]*10); + x<(width-1) && (pixel_color += target[y][x+1]*10); + y>=( 1) && (pixel_color += target[y-1][x]*10); + y<(16 -1) && (pixel_color += target[y+1][x]*10); - x>=( 1) && y>=( 1) && (c += target[y-1][x-1]); - x<(width-1) && y>=( 1) && (c += target[y-1][x+1]); - x>=( 1) && y<(16-1) && (c += target[y+1][x-1]); - x<(width-1) && y<(16-1) && (c += target[y+1][x+1]); + x>=( 1) && y>=( 1) && (pixel_color += target[y-1][x-1]); + x<(width-1) && y>=( 1) && (pixel_color += target[y-1][x+1]); + x>=( 1) && y<(16-1) && (pixel_color += target[y+1][x-1]); + x<(width-1) && y<(16-1) && (pixel_color += target[y+1][x+1]); - x>=( 2) && (c += target[y][x-2]); - x<(width-2) && (c += target[y][x+2]); - y>=( 2) && (c += target[y-2][x]); - y<(16 -2) && (c += target[y+2][x]); + x>=( 2) && (pixel_color += target[y][x-2]); + x<(width-2) && (pixel_color += target[y][x+2]); + y>=( 2) && (pixel_color += target[y-2][x]); + y<(16 -2) && (pixel_color += target[y+2][x]); } - if(c >= 200) + if(pixel_color >= 200) dest[offs] = fgcolor; - else if(c >= 10) + else if(pixel_color >= 10) { if(dest[offs] < 0xA0) dest[offs] = 0xC1; else dest[offs] = 0xD1; } - else if(c > 0) + else if(pixel_color > 0) { dest[offs] = 0xCF; } } + } } void DrawTextTrans(uint8 *dest, uint32 width, uint8 *textmsg, uint8 fgcolor) diff --git a/src/drivers/win/taseditor/history.cpp b/src/drivers/win/taseditor/history.cpp index a643ac63..2de0f4de 100644 --- a/src/drivers/win/taseditor/history.cpp +++ b/src/drivers/win/taseditor/history.cpp @@ -104,7 +104,7 @@ char modCaptions[MODTYPES_TOTAL][20] = {" Initialization", " LUA Marker Rename", " LUA Change" }; char LuaCaptionPrefix[6] = " LUA "; -char joypadCaptions[4][5] = {"(1P)", "(2P)", "(3P)", "(4P)"}; +char joypadCaptions[5][11] = {"(Commands)", "(1P)", "(2P)", "(3P)", "(4P)"}; HISTORY::HISTORY() { @@ -797,65 +797,69 @@ int HISTORY::RegisterBranching(int slot, bool markers_changed) first_changes = first_lag_changes; return first_changes; } -void HISTORY::RegisterRecording(int frame_of_change) +void HISTORY::RegisterRecording(int frame_of_change, uint32 joypad_diff_bits) { int real_pos = (history_start_pos + history_cursor_pos) % history_size; - SNAPSHOT snap; - snap.init(currMovieData, taseditor_config.enable_hot_changes); - snap.rec_joypad_diff_bits = snap.inputlog.fillJoypadsDiff(snapshots[real_pos].inputlog, frame_of_change); - // fill description: - snap.mod_type = MODTYPE_RECORD; - strcat(snap.description, modCaptions[MODTYPE_RECORD]); - char framenum[11]; // check if current snapshot is also Recording and maybe it is consecutive recording if (taseditor_config.combine_consecutive - && snapshots[real_pos].mod_type == MODTYPE_RECORD // a) also Recording - && snapshots[real_pos].consecutive_tag == frame_of_change - 1 // b) consecutive (previous frame) - && snapshots[real_pos].rec_joypad_diff_bits == snap.rec_joypad_diff_bits) // c) recorded same set of joysticks + && snapshots[real_pos].mod_type == MODTYPE_RECORD // a) also Recording + && snapshots[real_pos].consecutive_tag == frame_of_change - 1 // b) consecutive (previous frame) + && snapshots[real_pos].rec_joypad_diff_bits == joypad_diff_bits) // c) recorded same set of joysticks/commands { - // clone this snapshot and continue chain of recorded frames - snap.keyframe = snapshots[real_pos].keyframe; - snap.start_frame = snapshots[real_pos].keyframe; - snap.end_frame = frame_of_change; - snap.consecutive_tag = frame_of_change; - // add info which joypads were affected - int num = joysticks_per_frame[snap.inputlog.input_type]; + // reinit current snapshot and set hotchanges + SNAPSHOT* snap = &snapshots[real_pos]; + snap->reinit(currMovieData, taseditor_config.enable_hot_changes, frame_of_change); + // refill description + strcat(snap->description, modCaptions[MODTYPE_RECORD]); + char framenum[11]; + snap->end_frame = frame_of_change; + snap->consecutive_tag = frame_of_change; + // add info if Commands were affected uint32 current_mask = 1; + if ((snap->rec_joypad_diff_bits & current_mask)) + strcat(snap->description, joypadCaptions[0]); + // add info which joypads were affected + int num = joysticks_per_frame[snap->inputlog.input_type]; + current_mask <<= 1; for (int i = 0; i < num; ++i) { - if ((snap.rec_joypad_diff_bits & current_mask)) - strcat(snap.description, joypadCaptions[i]); + if ((snap->rec_joypad_diff_bits & current_mask)) + strcat(snap->description, joypadCaptions[i + 1]); current_mask <<= 1; } // add upper and lower frame to description - strcat(snap.description, " "); - _itoa(snap.start_frame, framenum, 10); - strcat(snap.description, framenum); - strcat(snap.description, "-"); - _itoa(snap.end_frame, framenum, 10); - strcat(snap.description, framenum); - // set hotchanges - if (taseditor_config.enable_hot_changes) - { - snap.inputlog.copyHotChanges(&snapshots[real_pos].inputlog); - snap.inputlog.fillHotChanges(snapshots[real_pos].inputlog, frame_of_change, frame_of_change); - } - // replace current snapshot with this cloned snapshot and truncate history here - snapshots[real_pos] = snap; + strcat(snap->description, " "); + _itoa(snap->start_frame, framenum, 10); + strcat(snap->description, framenum); + strcat(snap->description, "-"); + _itoa(snap->end_frame, framenum, 10); + strcat(snap->description, framenum); + // truncate history here history_total_items = history_cursor_pos+1; UpdateHistoryList(); RedrawHistoryList(); } else { - // not consecutive - add new snapshot to history + // not consecutive - create new snapshot and add it to history + SNAPSHOT snap; + snap.init(currMovieData, taseditor_config.enable_hot_changes); + snap.rec_joypad_diff_bits = joypad_diff_bits; + // fill description: + snap.mod_type = MODTYPE_RECORD; + strcat(snap.description, modCaptions[MODTYPE_RECORD]); + char framenum[11]; snap.keyframe = snap.start_frame = snap.end_frame = snap.consecutive_tag = frame_of_change; + // add info if Commands were affected + uint32 current_mask = 1; + if ((snap.rec_joypad_diff_bits & current_mask)) + strcat(snap.description, joypadCaptions[0]); // add info which joypads were affected int num = joysticks_per_frame[snap.inputlog.input_type]; - uint32 current_mask = 1; + current_mask <<= 1; for (int i = 0; i < num; ++i) { if ((snap.rec_joypad_diff_bits & current_mask)) - strcat(snap.description, joypadCaptions[i]); + strcat(snap.description, joypadCaptions[i + 1]); current_mask <<= 1; } // add upper frame to description diff --git a/src/drivers/win/taseditor/history.h b/src/drivers/win/taseditor/history.h index 8ffc8fff..e893cff7 100644 --- a/src/drivers/win/taseditor/history.h +++ b/src/drivers/win/taseditor/history.h @@ -112,7 +112,7 @@ public: void RegisterBookmarkSet(int slot, BOOKMARK& backup_copy, int old_current_branch); int RegisterBranching(int slot, bool markers_changed); - void RegisterRecording(int frame_of_change); + void RegisterRecording(int frame_of_change, uint32 joypad_diff_bits); int RegisterImport(MovieData& md, char* filename); int RegisterLuaChanges(const char* name, int start, bool InsertionDeletion_was_made); diff --git a/src/drivers/win/taseditor/inputlog.cpp b/src/drivers/win/taseditor/inputlog.cpp index 870931e3..c8d684fc 100644 --- a/src/drivers/win/taseditor/inputlog.cpp +++ b/src/drivers/win/taseditor/inputlog.cpp @@ -58,6 +58,43 @@ void INPUTLOG::init(MovieData& md, bool hotchanges, int force_input_type) already_compressed = false; } +// this function only updates one frame of Input Log and Hot Changes data +// the function should only be used when combining consecutive Recordings +void INPUTLOG::reinit(MovieData& md, bool hotchanges, int frame_of_change) +{ + has_hot_changes = hotchanges; + int num_joys = joysticks_per_frame[input_type]; + int joy; + // retrieve Input data from movie data + size = md.getNumRecords(); + joysticks.resize(BYTES_PER_JOYSTICK * num_joys * size, 0); + commands.resize(size); + if (has_hot_changes) + { + // resize Hot Changes + Init_HotChanges(); + // compare current movie data at the frame_of_change to current state of InputLog at the frame_of_change + uint8 my_joy, their_joy; + for (joy = num_joys - 1; joy >= 0; joy--) + { + my_joy = GetJoystickInfo(frame_of_change, joy); + their_joy = md.records[frame_of_change].joysticks[joy]; + if (my_joy != their_joy) + SetMaxHotChange_Bits(frame_of_change, joy, my_joy ^ their_joy); + } + } else + { + // if user switches Hot Changes off inbetween two consecutive Recordings + hot_changes.resize(0); + } + + // update Input vector + for (joy = num_joys - 1; joy >= 0; joy--) + joysticks[frame_of_change * num_joys * BYTES_PER_JOYSTICK + joy * BYTES_PER_JOYSTICK] = md.records[frame_of_change].joysticks[joy]; + commands[frame_of_change] = md.records[frame_of_change].commands; + already_compressed = false; +} + void INPUTLOG::toMovie(MovieData& md, int start, int end) { if (end < 0 || end >= size) end = size - 1; @@ -203,22 +240,6 @@ bool INPUTLOG::skipLoad(EMUFILE *is) return false; } // -------------------------------------------------------------------------------------------- -// fills map of bits judging on which joypads differ (this function is only used by "Record" modtype) -uint32 INPUTLOG::fillJoypadsDiff(INPUTLOG& their_log, int frame) -{ - uint32 joypad_diff_bits = 0; - uint32 current_mask = 1; - if (frame < their_log.size) - { - for (int joy = 0; joy < joysticks_per_frame[input_type]; ++joy) - { - if (GetJoystickInfo(frame, joy) != their_log.GetJoystickInfo(frame, joy)) - joypad_diff_bits |= current_mask; - current_mask <<= 1; - } - } - return joypad_diff_bits; -} // return number of first frame of difference between two InputLogs int INPUTLOG::findFirstChange(INPUTLOG& their_log, int start, int end) { diff --git a/src/drivers/win/taseditor/inputlog.h b/src/drivers/win/taseditor/inputlog.h index e8e55cee..ed73052d 100644 --- a/src/drivers/win/taseditor/inputlog.h +++ b/src/drivers/win/taseditor/inputlog.h @@ -26,6 +26,7 @@ class INPUTLOG public: INPUTLOG(); void init(MovieData& md, bool hotchanges, int force_input_type = -1); + void reinit(MovieData& md, bool hotchanges, int frame_of_change); // used when combining consecutive Recordings void toMovie(MovieData& md, int start = 0, int end = -1); void save(EMUFILE *os); @@ -35,7 +36,6 @@ public: void compress_data(); bool Get_already_compressed(); - uint32 fillJoypadsDiff(INPUTLOG& their_log, int frame); int findFirstChange(INPUTLOG& their_log, int start = 0, int end = -1); int findFirstChange(MovieData& md, int start = 0, int end = -1); diff --git a/src/drivers/win/taseditor/recorder.cpp b/src/drivers/win/taseditor/recorder.cpp index 8e003af6..40d30ee5 100644 --- a/src/drivers/win/taseditor/recorder.cpp +++ b/src/drivers/win/taseditor/recorder.cpp @@ -240,6 +240,7 @@ void RECORDER::RecheckRecordingRadioButtons() void RECORDER::InputChanged() { bool changes_made = false; + uint32 joypad_diff_bits = 0; int num_joys = joysticks_per_frame[GetInputType(currMovieData)]; // take previous values from current snapshot, new Input from current movie for (int i = 0; i < num_joys; ++i) @@ -266,6 +267,7 @@ void RECORDER::InputChanged() if (new_joy[i] != old_joy[i]) { changes_made = true; + joypad_diff_bits |= (1 << (i + 1)); // bit 0 = Commands, bit 1 = Joypad 1, bit 2 = Joypad 2, bit 3 = Joypad 3, bit 4 = Joypad 4 // set lights for changed buttons for (int button = 0; button < NUM_JOYPAD_BUTTONS; ++button) if ((new_joy[i] & (1 << button)) && !(old_joy[i] & (1 << button))) @@ -289,6 +291,7 @@ void RECORDER::InputChanged() if (new_joy[joy] != old_joy[joy]) { changes_made = true; + joypad_diff_bits |= (1 << (joy + 1)); // bit 0 = Commands, bit 1 = Joypad 1, bit 2 = Joypad 2, bit 3 = Joypad 3, bit 4 = Joypad 4 // set lights for changed buttons for (int button = 0; button < NUM_JOYPAD_BUTTONS; ++button) if ((new_joy[joy] & (1 << button)) && !(old_joy[joy] & (1 << button))) @@ -296,17 +299,17 @@ void RECORDER::InputChanged() } } - if (!changes_made) + // check if new commands were recorded + if (currMovieData.records[currFrameCounter].commands != history.GetCurrentSnapshot().inputlog.GetCommandsInfo(currFrameCounter)) { - // check if new commands were recorded - if (currMovieData.records[currFrameCounter].commands != history.GetCurrentSnapshot().inputlog.GetCommandsInfo(currFrameCounter)) - changes_made = true; + changes_made = true; + joypad_diff_bits |= 1; // bit 0 = Commands, bit 1 = Joypad 1, bit 2 = Joypad 2, bit 3 = Joypad 3, bit 4 = Joypad 4 } // register changes if (changes_made) { - history.RegisterRecording(currFrameCounter); + history.RegisterRecording(currFrameCounter, joypad_diff_bits); greenzone.Invalidate(currFrameCounter); } } diff --git a/src/drivers/win/taseditor/snapshot.cpp b/src/drivers/win/taseditor/snapshot.cpp index 28c4f82d..9916d96f 100644 --- a/src/drivers/win/taseditor/snapshot.cpp +++ b/src/drivers/win/taseditor/snapshot.cpp @@ -49,6 +49,23 @@ void SNAPSHOT::init(MovieData& md, bool hotchanges, int force_input_type) strftime(description, 10, "%H:%M:%S", timeinfo); } +void SNAPSHOT::reinit(MovieData& md, bool hotchanges, int frame_of_change) +{ + inputlog.reinit(md, hotchanges, frame_of_change); + + // take a copy from greenzone.laglog + laglog = greenzone.laglog; + laglog.Reset_already_compressed(); + + // Markers are supposed to be the same, because this is consecutive Recording + + // save current time to description + time_t raw_time; + time(&raw_time); + struct tm * timeinfo = localtime(&raw_time); + strftime(description, 10, "%H:%M:%S", timeinfo); +} + bool SNAPSHOT::MarkersDifferFromCurrent() { return markers_manager.checkMarkersDiff(markers); diff --git a/src/drivers/win/taseditor/snapshot.h b/src/drivers/win/taseditor/snapshot.h index 2ce50622..eb2b6de0 100644 --- a/src/drivers/win/taseditor/snapshot.h +++ b/src/drivers/win/taseditor/snapshot.h @@ -9,6 +9,7 @@ class SNAPSHOT public: SNAPSHOT(); void init(MovieData& md, bool hotchanges, int force_input_type = -1); + void reinit(MovieData& md, bool hotchanges, int frame_of_change); // used when combining consecutive Recordings bool MarkersDifferFromCurrent(); void copyToMarkers(); @@ -28,7 +29,7 @@ public: int start_frame; // for consecutive Draws and "Related items highlighting" int end_frame; // for consecutive Draws and "Related items highlighting" int consecutive_tag; // for consecutive Recordings and Draws - uint32 rec_joypad_diff_bits; // for consecutive Recordings + uint32 rec_joypad_diff_bits; // for consecutive Recordings: bit 0 = Commands, bit 1 = Joypad 1, bit 2 = Joypad 2, bit 3 = Joypad 3, bit 4 = Joypad 4 int mod_type; char description[SNAPSHOT_DESC_MAX_LENGTH]; diff --git a/src/movie.cpp b/src/movie.cpp index 8fd4bc69..253bdb8f 100644 --- a/src/movie.cpp +++ b/src/movie.cpp @@ -105,6 +105,8 @@ MovieData currMovieData; MovieData defaultMovieData; int currRerecordCount; +char lagcounterbuf[32] = {0}; + void MovieData::clearRecordRange(int start, int len) { for(int i=0;i<len;i++) @@ -1138,18 +1140,13 @@ void FCEU_DrawMovies(uint8 *XBuf) void FCEU_DrawLagCounter(uint8 *XBuf) { - uint8 color; - - if (lagFlag) color = 0x16+0x80; //If currently lagging display red - else color = 0x2A+0x80; //else display green - - if(lagCounterDisplay) + if (lagCounterDisplay) { - char counterbuf[32] = {0}; - sprintf(counterbuf,"%d",lagCounter); - - if(counterbuf[0]) - DrawTextTrans(ClipSidesOffset+XBuf+FCEU_TextScanlineOffsetFromBottom(40)+1, 256, (uint8*)counterbuf, color); //0x20+0x80 + // If currently lagging - display red, else display green + uint8 color = (lagFlag) ? (0x16+0x80) : (0x2A+0x80); + sprintf(lagcounterbuf, "%d", lagCounter); + if(lagcounterbuf[0]) + DrawTextTrans(ClipSidesOffset + XBuf + FCEU_TextScanlineOffsetFromBottom(40) + 1, 256, (uint8*)lagcounterbuf, color); } }